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

35 statements  

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

1""" 

2Blackbody - Planck (1900) - Correlated Colour Temperature 

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

4 

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

6computation objects based on the spectral radiance of a planckian 

7radiator: 

8 

9- :func:`colour.temperature.uv_to_CCT_Planck1900` 

10- :func:`colour.temperature.CCT_to_uv_Planck1900` 

11 

12References 

13---------- 

14- :cite:`CIETC1-482004i` : CIE TC 1-48. (2004). APPENDIX E. INFORMATION ON 

15 THE USE OF PLANCK'S EQUATION FOR STANDARD AIR. In CIE 015:2004 Colorimetry, 

16 3rd Edition (pp. 77-82). ISBN:978-3-901906-33-6 

17""" 

18 

19from __future__ import annotations 

20 

21import typing 

22 

23import numpy as np 

24 

25from colour.colorimetry import ( 

26 MultiSpectralDistributions, 

27 handle_spectral_arguments, 

28 msds_to_XYZ_integration, 

29 planck_law, 

30) 

31 

32if typing.TYPE_CHECKING: 

33 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat 

34 

35from colour.models import UCS_to_uv, XYZ_to_UCS 

36from colour.utilities import as_float, as_float_array, required 

37 

38__author__ = "Colour Developers" 

39__copyright__ = "Copyright 2013 Colour Developers" 

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

41__maintainer__ = "Colour Developers" 

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

43__status__ = "Production" 

44 

45__all__ = [ 

46 "uv_to_CCT_Planck1900", 

47 "CCT_to_uv_Planck1900", 

48] 

49 

50 

51@required("SciPy") 

52def uv_to_CCT_Planck1900( 

53 uv: ArrayLike, 

54 cmfs: MultiSpectralDistributions | None = None, 

55 optimisation_kwargs: dict | None = None, 

56) -> NDArrayFloat: 

57 """ 

58 Compute the correlated colour temperature :math:`T_{cp}` of a blackbody 

59 from specified *CIE UCS* colourspace *uv* chromaticity coordinates using 

60 colour matching functions. 

61 

62 Parameters 

63 ---------- 

64 uv 

65 *CIE UCS* colourspace *uv* chromaticity coordinates. 

66 cmfs 

67 Standard observer colour matching functions, default to the 

68 *CIE 1931 2 Degree Standard Observer*. 

69 optimisation_kwargs 

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

71 

72 Returns 

73 ------- 

74 :class:`numpy.ndarray` 

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

76 

77 Warnings 

78 -------- 

79 The current implementation relies on optimisation using 

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

81 precision and poor performance. 

82 

83 References 

84 ---------- 

85 :cite:`CIETC1-482004i` 

86 

87 Examples 

88 -------- 

89 >>> uv_to_CCT_Planck1900(np.array([0.20042808, 0.31033343])) 

90 ... # doctest: +ELLIPSIS 

91 6504.0000617... 

92 """ 

93 

94 from scipy.optimize import minimize # noqa: PLC0415 

95 

96 uv = as_float_array(uv) 

97 cmfs, _illuminant = handle_spectral_arguments(cmfs) 

98 

99 shape = uv.shape 

100 uv = np.atleast_1d(np.reshape(uv, (-1, 2))) 

101 

102 def objective_function(CCT: NDArrayFloat, uv: NDArrayFloat) -> DTypeFloat: 

103 """Objective function.""" 

104 

105 objective = np.linalg.norm(CCT_to_uv_Planck1900(CCT, cmfs) - uv) 

106 

107 return as_float(objective) 

108 

109 optimisation_settings = { 

110 "method": "Nelder-Mead", 

111 "options": { 

112 "fatol": 1e-10, 

113 }, 

114 } 

115 if optimisation_kwargs is not None: 

116 optimisation_settings.update(optimisation_kwargs) 

117 

118 CCT = as_float_array( 

119 [ 

120 minimize( 

121 objective_function, 

122 x0=[6500], 

123 args=(uv_i,), 

124 **optimisation_settings, 

125 ).x 

126 for uv_i in uv 

127 ] 

128 ) 

129 

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

131 

132 

133def CCT_to_uv_Planck1900( 

134 CCT: ArrayLike, cmfs: MultiSpectralDistributions | None = None 

135) -> NDArrayFloat: 

136 """ 

137 Compute the *CIE UCS* colourspace *uv* chromaticity coordinates from the 

138 specified correlated colour temperature :math:`T_{cp}` and colour 

139 matching functions using the spectral radiance of a blackbody at the 

140 specified thermodynamic temperature. 

141 

142 Parameters 

143 ---------- 

144 CCT 

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

146 cmfs 

147 Standard observer colour matching functions, default to the 

148 *CIE 1931 2 Degree Standard Observer*. 

149 

150 Returns 

151 ------- 

152 :class:`numpy.ndarray` 

153 *CIE UCS* colourspace *uv* chromaticity coordinates. 

154 

155 References 

156 ---------- 

157 :cite:`CIETC1-482004i` 

158 

159 Examples 

160 -------- 

161 >>> CCT_to_uv_Planck1900(6504) # doctest: +ELLIPSIS 

162 array([ 0.2004280..., 0.3103334...]) 

163 """ 

164 

165 CCT = as_float_array(CCT) 

166 cmfs, _illuminant = handle_spectral_arguments(cmfs) 

167 

168 XYZ = msds_to_XYZ_integration( 

169 np.transpose(planck_law(cmfs.wavelengths * 1e-9, np.ravel(CCT)) * 1e-9), 

170 cmfs, 

171 shape=cmfs.shape, 

172 ) 

173 

174 UVW = XYZ_to_UCS(XYZ) 

175 uv = UCS_to_uv(UVW) 

176 

177 return np.reshape(uv, [*list(CCT.shape), 2])