Coverage for temperature/kang2002.py: 65%

1"""

2 Kang, Moon, Hong, Lee, Cho and Kim (2002) Correlated Colour Temperature

3=======================================================================

4

5 Define the *Kang et al. (2002)* correlated colour temperature :math:`T_{cp}`

6 computation objects.

7

8- :func:`colour.temperature.xy_to_CCT_Kang2002`: Compute correlated colour

9 temperature :math:`T_{cp}` from specified *CIE xy* chromaticity

10 coordinates using the *Kang, Moon, Hong, Lee, Cho and Kim (2002)* method.

11- :func:`colour.temperature.CCT_to_xy_Kang2002`: Compute *CIE xy*

12 chromaticity coordinates from specified correlated colour temperature

13 :math:`T_{cp}` using the *Kang, Moon, Hong, Lee, Cho and Kim (2002)*

14 method.

15

16 References

17----------

18- :cite:`Kang2002a` : Kang, B., Moon, O., Hong, C., Lee, H., Cho, B., & Kim,

19 Y. (2002). Design of advanced color: Temperature control system for HDTV

20 applications. Journal of the Korean Physical Society, 41(6), 865-871.

21"""

22

23 from __future__ import annotations

24

25 import typing

26

27 import numpy as np

28

29 if typing.TYPE_CHECKING:

30 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat

31

32 from colour.utilities import as_float, as_float_array, required, tstack, usage_warning

33

34 __author__ = "Colour Developers"

35 __copyright__ = "Copyright 2013 Colour Developers"

36 __license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"

37 __maintainer__ = "Colour Developers"

38 __email__ = "colour-developers@colour-science.org"

39 __status__ = "Production"

40

41 __all__ = [

42 "xy_to_CCT_Kang2002",

43 "CCT_to_xy_Kang2002",

44]

45

46

47@required("SciPy")

48 def xy_to_CCT_Kang2002(

49 xy: ArrayLike, optimisation_kwargs: dict | None = None

50) -> NDArrayFloat:

51 """

52 Compute the correlated colour temperature :math:`T_{cp}` from the

53 specified *CIE xy* chromaticity coordinates using *Kang et al. (2002)*

54 method.

55

56 Parameters

57 ----------

58 xy

59 *CIE xy* chromaticity coordinates.

60 optimisation_kwargs

61 Parameters for :func:`scipy.optimize.minimize` definition.

62

63 Returns

64 -------

65 :class:`numpy.ndarray`

66 Correlated colour temperature :math:`T_{cp}`.

67

68 Warnings

69 --------

70 The *Kang et al. (2002)* method does not provide an analytical inverse

71 transformation to compute the correlated colour temperature

72 :math:`T_{cp}` from the specified *CIE xy* chromaticity coordinates.

73 The current implementation relies on optimisation using

74 :func:`scipy.optimize.minimize` definition and thus has reduced

75 precision and poor performance.

76

77 References

78 ----------

79 :cite:`Kang2002a`

80

81 Examples

82 --------

83 >>> xy_to_CCT_Kang2002(np.array([0.31342600, 0.32359597]))

84 ... # doctest: +ELLIPSIS

85 6504.3893128...

86 """

87

88 from scipy.optimize import minimize # noqa: PLC0415

89

90 xy = as_float_array(xy)

91 shape = xy.shape

92 xy = np.atleast_1d(np.reshape(xy, (-1, 2)))

93

94 def objective_function(CCT: NDArrayFloat, xy: NDArrayFloat) -> DTypeFloat:

95 """Objective function."""

96

97 objective = np.linalg.norm(CCT_to_xy_Kang2002(CCT) - xy)

98

99 return as_float(objective)

100

101 optimisation_settings = {

102 "method": "Nelder-Mead",

103 "options": {

104 "fatol": 1e-10,

105 },

106 }

107 if optimisation_kwargs is not None:

108 optimisation_settings.update(optimisation_kwargs)

109

110 CCT = as_float_array(

111 [

112 minimize(

113 objective_function,

114 x0=[6500],

115 args=(xy_i,),

116 **optimisation_settings,

117 ).x

118 for xy_i in xy

119 ]

120 )

121

122 return as_float(np.reshape(CCT, shape[:-1]))

123

124

125 def CCT_to_xy_Kang2002(CCT: ArrayLike) -> NDArrayFloat:

126 """

127 Compute the *CIE xy* chromaticity coordinates from the specified

128 correlated colour temperature :math:`T_{cp}` using *Kang et al. (2002)*

129 method.

130

131 Parameters

132 ----------

133 CCT

134 Correlated colour temperature :math:`T_{cp}`.

135

136 Returns

137 -------

138 :class:`numpy.ndarray`

139 *CIE xy* chromaticity coordinates.

140

141 Raises

142 ------

143 ValueError

144 If the correlated colour temperature is not in appropriate domain.

145

146 References

147 ----------

148 :cite:`Kang2002a`

149

150 Examples

151 --------

152 >>> CCT_to_xy_Kang2002(6504.38938305) # doctest: +ELLIPSIS

153 array([ 0.313426 ..., 0.3235959...])

154 """

155

156 CCT = as_float_array(CCT)

157

158 if np.any(CCT[np.asarray(np.logical_or(CCT < 1667, CCT > 25000))]):

159 usage_warning(

160 "Correlated colour temperature must be in domain "

161 "[1667, 25000], unpredictable results may occur!"

162 )

163

164 CCT_3 = CCT**3

165 CCT_2 = CCT**2

166

167 x = np.where(

168 CCT <= 4000,

169 -0.2661239 * 10**9 / CCT_3

170 - 0.2343589 * 10**6 / CCT_2

171 + 0.8776956 * 10**3 / CCT

172 + 0.179910,

173 -3.0258469 * 10**9 / CCT_3

174 + 2.1070379 * 10**6 / CCT_2

175 + 0.2226347 * 10**3 / CCT

176 + 0.24039,

177 )

178

179 x_3 = x**3

180 x_2 = x**2

181

182 cnd_l = [CCT <= 2222, np.logical_and(CCT > 2222, CCT <= 4000), CCT > 4000]

183 i = -1.1063814 * x_3 - 1.34811020 * x_2 + 2.18555832 * x - 0.20219683

184 j = -0.9549476 * x_3 - 1.37418593 * x_2 + 2.09137015 * x - 0.16748867

185 k = 3.0817580 * x_3 - 5.8733867 * x_2 + 3.75112997 * x - 0.37001483

186 y = np.select(cnd_l, [i, j, k])

187

188 return tstack([x, y])