Coverage for temperature/mccamy1992.py: 53%

34 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1""" 

2McCamy (1992) Correlated Colour Temperature 

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

4 

5Define the *McCamy (1992)* correlated colour temperature :math:`T_{cp}` 

6computation objects. 

7 

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

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

10 coordinates using the *McCamy (1992)* method. 

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

12 chromaticity coordinates from specified correlated colour temperature 

13 :math:`T_{cp}` using the *McCamy (1992)* method. 

14 

15References 

16---------- 

17- :cite:`Wikipedia2001` : Wikipedia. (2001). Approximation. Retrieved June 

18 28, 2014, from http://en.wikipedia.org/wiki/Color_temperature#Approximation 

19""" 

20 

21from __future__ import annotations 

22 

23import typing 

24 

25import numpy as np 

26 

27from colour.algebra import sdiv, sdiv_mode 

28from colour.colorimetry import CCS_ILLUMINANTS 

29 

30if typing.TYPE_CHECKING: 

31 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat 

32 

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

34 

35__author__ = "Colour Developers" 

36__copyright__ = "Copyright 2013 Colour Developers" 

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

38__maintainer__ = "Colour Developers" 

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

40__status__ = "Production" 

41 

42__all__ = [ 

43 "xy_to_CCT_McCamy1992", 

44 "CCT_to_xy_McCamy1992", 

45] 

46 

47 

48@required("SciPy") 

49def xy_to_CCT_McCamy1992(xy: ArrayLike) -> NDArrayFloat: 

50 """ 

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

52 specified *CIE xy* chromaticity coordinates using the *McCamy (1992)* 

53 method. 

54 

55 Parameters 

56 ---------- 

57 xy 

58 *CIE xy* chromaticity coordinates. 

59 

60 Returns 

61 ------- 

62 :class:`numpy.ndarray` 

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

64 

65 References 

66 ---------- 

67 :cite:`Wikipedia2001` 

68 

69 Examples 

70 -------- 

71 >>> import numpy as np 

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

73 >>> xy_to_CCT_McCamy1992(xy) # doctest: +ELLIPSIS 

74 6505.0805913... 

75 """ 

76 

77 x, y = tsplit(xy) 

78 

79 with sdiv_mode(): 

80 n = sdiv(x - 0.3320, y - 0.1858) 

81 

82 CCT = -449 * n**3 + 3525 * n**2 - 6823.3 * n + 5520.33 

83 

84 return as_float(CCT) 

85 

86 

87def CCT_to_xy_McCamy1992( 

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

89) -> NDArrayFloat: 

90 """ 

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

92 correlated colour temperature :math:`T_{cp}` using the *McCamy (1992)* 

93 method. 

94 

95 Parameters 

96 ---------- 

97 CCT 

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

99 optimisation_kwargs 

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

101 

102 Returns 

103 ------- 

104 :class:`numpy.ndarray` 

105 *CIE xy* chromaticity coordinates. 

106 

107 Warnings 

108 -------- 

109 The *McCamy (1992)* method for computing *CIE xy* chromaticity coordinates 

110 from the specified correlated colour temperature is not a bijective 

111 function and might produce unexpected results. It is provided for 

112 consistency with other correlated colour temperature computation methods 

113 but should be avoided for practical applications. The current 

114 implementation relies on optimisation using 

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

116 and poor performance. 

117 

118 References 

119 ---------- 

120 :cite:`Wikipedia2001` 

121 

122 Examples 

123 -------- 

124 >>> CCT_to_xy_McCamy1992(6505.0805913074782) # doctest: +ELLIPSIS 

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

126 """ 

127 

128 from scipy.optimize import minimize # noqa: PLC0415 

129 

130 usage_warning( 

131 '"McCamy (1992)" method for computing "CIE xy" chromaticity ' 

132 "coordinates from given correlated colour temperature is not a " 

133 "bijective function and might produce unexpected results. It is given " 

134 "for consistency with other correlated colour temperature computation " 

135 "methods but should be avoided for practical applications." 

136 ) 

137 

138 CCT = as_float_array(CCT) 

139 shape = list(CCT.shape) 

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

141 

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

143 """Objective function.""" 

144 

145 objective = np.linalg.norm(xy_to_CCT_McCamy1992(xy) - CCT) 

146 

147 return as_float(objective) 

148 

149 optimisation_settings = { 

150 "method": "Nelder-Mead", 

151 "options": { 

152 "fatol": 1e-10, 

153 }, 

154 } 

155 if optimisation_kwargs is not None: 

156 optimisation_settings.update(optimisation_kwargs) 

157 

158 xy = as_float_array( 

159 [ 

160 minimize( 

161 objective_function, 

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

163 args=(CCT_i,), 

164 **optimisation_settings, 

165 ).x 

166 for CCT_i in CCT 

167 ] 

168 ) 

169 

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