Coverage for colour/temperature/hernandez1999.py: 100%

36 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-15 19:01 +1300

1""" 

2Hernandez-Andres, Lee and Romero (1999) Correlated Colour Temperature 

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

4 

5Define *Hernandez-Andres et al. (1999)* correlated colour temperature 

6:math:`T_{cp}` computation objects. 

7 

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

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

10 coordinates using *Hernandez-Andres, Lee and Romero (1999)* method. 

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

12 chromaticity coordinates from specified correlated colour temperature 

13 :math:`T_{cp}` using *Hernandez-Andres, Lee and Romero (1999)* method. 

14 

15References 

16---------- 

17- :cite:`Hernandez-Andres1999a` : Hernández-Andrés, J., Lee, R. L., & 

18 Romero, J. (1999). Calculating correlated color temperatures across the 

19 entire gamut of daylight and skylight chromaticities. Applied Optics, 

20 38(27), 5703. doi:10.1364/AO.38.005703 

21""" 

22 

23from __future__ import annotations 

24 

25import typing 

26 

27import numpy as np 

28 

29from colour.algebra import sdiv, sdiv_mode 

30from colour.colorimetry import CCS_ILLUMINANTS 

31 

32if typing.TYPE_CHECKING: 

33 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat 

34 

35from colour.utilities import as_float, as_float_array, required, tsplit, usage_warning 

36 

37__author__ = "Colour Developers" 

38__copyright__ = "Copyright 2013 Colour Developers" 

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

40__maintainer__ = "Colour Developers" 

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

42__status__ = "Production" 

43 

44__all__ = [ 

45 "xy_to_CCT_Hernandez1999", 

46 "CCT_to_xy_Hernandez1999", 

47] 

48 

49 

50@required("SciPy") 

51def xy_to_CCT_Hernandez1999(xy: ArrayLike) -> NDArrayFloat: 

52 """ 

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

54 specified *CIE xy* chromaticity coordinates using 

55 *Hernandez-Andres et al. (1999)* method. 

56 

57 Parameters 

58 ---------- 

59 xy 

60 *CIE xy* chromaticity coordinates. 

61 

62 Returns 

63 ------- 

64 :class:`numpy.ndarray` 

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

66 

67 References 

68 ---------- 

69 :cite:`Hernandez-Andres1999a` 

70 

71 Examples 

72 -------- 

73 >>> xy = np.array([0.31270, 0.32900]) 

74 >>> xy_to_CCT_Hernandez1999(xy) # doctest: +ELLIPSIS 

75 6500.7420431... 

76 """ 

77 

78 x, y = tsplit(xy) 

79 

80 with sdiv_mode(): 

81 n = sdiv(x - 0.3366, y - 0.1735) 

82 

83 CCT = ( 

84 -949.86315 

85 + 6253.80338 * np.exp(-n / 0.92159) 

86 + 28.70599 * np.exp(-n / 0.20039) 

87 + 0.00004 * np.exp(-n / 0.07125) 

88 ) 

89 

90 n = np.where(CCT > 50000, (x - 0.3356) / (y - 0.1691), n) 

91 

92 CCT = np.where( 

93 CCT > 50000, 

94 36284.48953 

95 + 0.00228 * np.exp(-n / 0.07861) 

96 + 5.4535e-36 * np.exp(-n / 0.01543), 

97 CCT, 

98 ) 

99 

100 return as_float(CCT) 

101 

102 

103def CCT_to_xy_Hernandez1999( 

104 CCT: ArrayLike, optimisation_kwargs: dict | None = None 

105) -> NDArrayFloat: 

106 """ 

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

108 correlated colour temperature :math:`T_{cp}` using 

109 *Hernandez-Andres et al. (1999)* method. 

110 

111 Parameters 

112 ---------- 

113 CCT 

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

115 optimisation_kwargs 

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

117 

118 Returns 

119 ------- 

120 :class:`numpy.ndarray` 

121 *CIE xy* chromaticity coordinates. 

122 

123 Warnings 

124 -------- 

125 *Hernandez-Andres et al. (1999)* method for computing *CIE xy* 

126 chromaticity coordinates from the specified correlated colour temperature 

127 is not a bijective function and might produce unexpected results. It is 

128 provided for consistency with other correlated colour temperature 

129 computation methods but should be avoided for practical applications. The 

130 current implementation relies on optimisation using 

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

132 and poor performance. 

133 

134 References 

135 ---------- 

136 :cite:`Hernandez-Andres1999a` 

137 

138 Examples 

139 -------- 

140 >>> CCT_to_xy_Hernandez1999(6500.7420431786531) # doctest: +ELLIPSIS 

141 array([ 0.3127..., 0.329...]) 

142 """ 

143 

144 from scipy.optimize import minimize # noqa: PLC0415 

145 

146 usage_warning( 

147 '"Hernandez-Andres et al. (1999)" method for computing "CIE xy" ' 

148 "chromaticity coordinates from given correlated colour temperature is " 

149 "not a bijective function and might produce unexpected results. It is " 

150 "given for consistency with other correlated colour temperature " 

151 "computation methods but should be avoided for practical applications." 

152 ) 

153 

154 CCT = as_float_array(CCT) 

155 shape = list(CCT.shape) 

156 CCT = np.atleast_1d(np.reshape(CCT, (-1, 1))) 

157 

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

159 """Objective function.""" 

160 

161 objective = np.linalg.norm(xy_to_CCT_Hernandez1999(xy) - CCT) 

162 

163 return as_float(objective) 

164 

165 optimisation_settings = { 

166 "method": "Nelder-Mead", 

167 "options": { 

168 "fatol": 1e-10, 

169 }, 

170 } 

171 if optimisation_kwargs is not None: 

172 optimisation_settings.update(optimisation_kwargs) 

173 

174 xy = as_float_array( 

175 [ 

176 minimize( 

177 objective_function, 

178 x0=CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"], 

179 args=(CCT_i,), 

180 **optimisation_settings, 

181 ).x 

182 for CCT_i in CCT 

183 ] 

184 ) 

185 

186 return np.reshape(xy, ([*shape, 2]))