Coverage for temperature/krystek1985.py: 55%

31 statements  

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

1""" 

2Krystek (1985) Correlated Colour Temperature 

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

4 

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

6computation objects. 

7 

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

9 colour temperature :math:`T_{cp}` from specified *CIE UCS* colourspace 

10 *uv* chromaticity coordinates using the *Krystek (1985)* method. 

11- :func:`colour.temperature.CCT_to_uv_Krystek1985`: Compute *CIE UCS* 

12 colourspace *uv* chromaticity coordinates from specified correlated 

13 colour temperature :math:`T_{cp}` using the *Krystek (1985)* method. 

14 

15References 

16---------- 

17- :cite:`Krystek1985b` : Krystek, M. (1985). An algorithm to calculate 

18 correlated colour temperature. Color Research & Application, 10(1), 38-40. 

19 doi:10.1002/col.5080100109 

20""" 

21 

22from __future__ import annotations 

23 

24import typing 

25 

26import numpy as np 

27 

28if typing.TYPE_CHECKING: 

29 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat 

30 

31from colour.utilities import as_float, as_float_array, required, tstack 

32 

33__author__ = "Colour Developers" 

34__copyright__ = "Copyright 2013 Colour Developers" 

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

36__maintainer__ = "Colour Developers" 

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

38__status__ = "Production" 

39 

40__all__ = [ 

41 "uv_to_CCT_Krystek1985", 

42 "CCT_to_uv_Krystek1985", 

43] 

44 

45 

46@required("SciPy") 

47def uv_to_CCT_Krystek1985( 

48 uv: ArrayLike, optimisation_kwargs: dict | None = None 

49) -> NDArrayFloat: 

50 """ 

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

52 specified *CIE UCS* colourspace *uv* chromaticity coordinates using 

53 *Krystek (1985)* method. 

54 

55 Parameters 

56 ---------- 

57 uv 

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

59 optimisation_kwargs 

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

61 

62 Returns 

63 ------- 

64 :class:`numpy.ndarray` 

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

66 

67 Warnings 

68 -------- 

69 *Krystek (1985)* does not provide an analytical inverse transformation 

70 to compute the correlated colour temperature :math:`T_{cp}` from the 

71 specified *CIE UCS* colourspace *uv* chromaticity coordinates. The 

72 current implementation relies on optimisation using 

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

74 precision and poor performance. 

75 

76 Notes 

77 ----- 

78 - *Krystek (1985)* method computations are valid for correlated 

79 colour temperature :math:`T_{cp}` normalised to domain 

80 [1000, 15000]. 

81 

82 References 

83 ---------- 

84 :cite:`Krystek1985b` 

85 

86 Examples 

87 -------- 

88 >>> uv_to_CCT_Krystek1985(np.array([0.20047203, 0.31029290])) 

89 ... # doctest: +ELLIPSIS 

90 6504.3894290... 

91 """ 

92 

93 from scipy.optimize import minimize # noqa: PLC0415 

94 

95 uv = as_float_array(uv) 

96 shape = uv.shape 

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

98 

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

100 """Objective function.""" 

101 

102 objective = np.linalg.norm(CCT_to_uv_Krystek1985(CCT) - uv) 

103 

104 return as_float(objective) 

105 

106 optimisation_settings = { 

107 "method": "Nelder-Mead", 

108 "options": { 

109 "fatol": 1e-10, 

110 }, 

111 } 

112 if optimisation_kwargs is not None: 

113 optimisation_settings.update(optimisation_kwargs) 

114 

115 CCT = as_float_array( 

116 [ 

117 minimize( 

118 objective_function, 

119 x0=[6500], 

120 args=(uv_i,), 

121 **optimisation_settings, 

122 ).x 

123 for uv_i in uv 

124 ] 

125 ) 

126 

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

128 

129 

130def CCT_to_uv_Krystek1985(CCT: ArrayLike) -> NDArrayFloat: 

131 """ 

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

133 specified correlated colour temperature :math:`T_{cp}` using the 

134 *Krystek (1985)* method. 

135 

136 Parameters 

137 ---------- 

138 CCT 

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

140 

141 Returns 

142 ------- 

143 :class:`numpy.ndarray` 

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

145 

146 Notes 

147 ----- 

148 - *Krystek (1985)* method computations are valid for correlated colour 

149 temperature :math:`T_{cp}` normalised to domain [1000, 15000]. 

150 

151 References 

152 ---------- 

153 :cite:`Krystek1985b` 

154 

155 Examples 

156 -------- 

157 >>> CCT_to_uv_Krystek1985(6504.38938305) # doctest: +ELLIPSIS 

158 array([ 0.2004720..., 0.3102929...]) 

159 """ 

160 

161 T = as_float_array(CCT) 

162 

163 T_2 = T**2 

164 

165 u = (0.860117757 + 1.54118254 * 10**-4 * T + 1.28641212 * 10**-7 * T_2) / ( 

166 1 + 8.42420235 * 10**-4 * T + 7.08145163 * 10**-7 * T_2 

167 ) 

168 v = (0.317398726 + 4.22806245 * 10**-5 * T + 4.20481691 * 10**-8 * T_2) / ( 

169 1 - 2.89741816 * 10**-5 * T + 1.61456053 * 10**-7 * T_2 

170 ) 

171 

172 return tstack([u, v])