Coverage for temperature/planck1900.py: 54%

1"""

2 Blackbody - Planck (1900) - Correlated Colour Temperature

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

4

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

6 computation objects based on the spectral radiance of a planckian

7 radiator:

8

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

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

11

12 References

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

19 from __future__ import annotations

20

21 import typing

22

23 import numpy as np

24

25 from colour.colorimetry import (

26 MultiSpectralDistributions,

27 handle_spectral_arguments,

28 msds_to_XYZ_integration,

29 planck_law,

30)

31

32 if typing.TYPE_CHECKING:

33 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat

34

35 from colour.models import UCS_to_uv, XYZ_to_UCS

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

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

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