Coverage for temperature/krystek1985.py: 55%

1"""

2 Krystek (1985) Correlated Colour Temperature

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

4

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

6 computation 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

15 References

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

22 from __future__ import annotations

23

24 import typing

25

26 import numpy as np

27

28 if typing.TYPE_CHECKING:

29 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat

30

31 from 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")

47 def 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

130 def 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])