Coverage for temperature/hernandez1999.py: 56%
36 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-16 22:49 +1300
1"""
2Hernandez-Andres, Lee and Romero (1999) Correlated Colour Temperature
3=====================================================================
5Define *Hernandez-Andres et al. (1999)* correlated colour temperature
6:math:`T_{cp}` computation objects.
8- :func:`colour.temperature.xy_to_CCT_Hernandez1999`: Compute correlated
9 colour temperature :math:`T_{cp}` from specified *CIE xy* chromaticity
10 coordinates using *Hernandez-Andres, Lee and Romero (1999)* method.
11- :func:`colour.temperature.CCT_to_xy_Hernandez1999`: Compute *CIE xy*
12 chromaticity coordinates from specified correlated colour temperature
13 :math:`T_{cp}` using *Hernandez-Andres, Lee and Romero (1999)* method.
15References
16----------
17- :cite:`Hernandez-Andres1999a` : Hernández-Andrés, J., Lee, R. L., &
18 Romero, J. (1999). Calculating correlated color temperatures across the
19 entire gamut of daylight and skylight chromaticities. Applied Optics,
20 38(27), 5703. doi:10.1364/AO.38.005703
21"""
23from __future__ import annotations
25import typing
27import numpy as np
29from colour.algebra import sdiv, sdiv_mode
30from colour.colorimetry import CCS_ILLUMINANTS
32if typing.TYPE_CHECKING:
33 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat
35from colour.utilities import as_float, as_float_array, required, tsplit, usage_warning
37__author__ = "Colour Developers"
38__copyright__ = "Copyright 2013 Colour Developers"
39__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
40__maintainer__ = "Colour Developers"
41__email__ = "colour-developers@colour-science.org"
42__status__ = "Production"
44__all__ = [
45 "xy_to_CCT_Hernandez1999",
46 "CCT_to_xy_Hernandez1999",
47]
50@required("SciPy")
51def xy_to_CCT_Hernandez1999(xy: ArrayLike) -> NDArrayFloat:
52 """
53 Compute the correlated colour temperature :math:`T_{cp}` from the
54 specified *CIE xy* chromaticity coordinates using
55 *Hernandez-Andres et al. (1999)* method.
57 Parameters
58 ----------
59 xy
60 *CIE xy* chromaticity coordinates.
62 Returns
63 -------
64 :class:`numpy.ndarray`
65 Correlated colour temperature :math:`T_{cp}`.
67 References
68 ----------
69 :cite:`Hernandez-Andres1999a`
71 Examples
72 --------
73 >>> xy = np.array([0.31270, 0.32900])
74 >>> xy_to_CCT_Hernandez1999(xy) # doctest: +ELLIPSIS
75 6500.7420431...
76 """
78 x, y = tsplit(xy)
80 with sdiv_mode():
81 n = sdiv(x - 0.3366, y - 0.1735)
83 CCT = (
84 -949.86315
85 + 6253.80338 * np.exp(-n / 0.92159)
86 + 28.70599 * np.exp(-n / 0.20039)
87 + 0.00004 * np.exp(-n / 0.07125)
88 )
90 n = np.where(CCT > 50000, (x - 0.3356) / (y - 0.1691), n)
92 CCT = np.where(
93 CCT > 50000,
94 36284.48953
95 + 0.00228 * np.exp(-n / 0.07861)
96 + 5.4535e-36 * np.exp(-n / 0.01543),
97 CCT,
98 )
100 return as_float(CCT)
103def CCT_to_xy_Hernandez1999(
104 CCT: ArrayLike, optimisation_kwargs: dict | None = None
105) -> NDArrayFloat:
106 """
107 Compute the *CIE xy* chromaticity coordinates from the specified
108 correlated colour temperature :math:`T_{cp}` using
109 *Hernandez-Andres et al. (1999)* method.
111 Parameters
112 ----------
113 CCT
114 Correlated colour temperature :math:`T_{cp}`.
115 optimisation_kwargs
116 Parameters for :func:`scipy.optimize.minimize` definition.
118 Returns
119 -------
120 :class:`numpy.ndarray`
121 *CIE xy* chromaticity coordinates.
123 Warnings
124 --------
125 *Hernandez-Andres et al. (1999)* method for computing *CIE xy*
126 chromaticity coordinates from the specified correlated colour temperature
127 is not a bijective function and might produce unexpected results. It is
128 provided for consistency with other correlated colour temperature
129 computation methods but should be avoided for practical applications. The
130 current implementation relies on optimisation using
131 :func:`scipy.optimize.minimize` definition and thus has reduced precision
132 and poor performance.
134 References
135 ----------
136 :cite:`Hernandez-Andres1999a`
138 Examples
139 --------
140 >>> CCT_to_xy_Hernandez1999(6500.7420431786531) # doctest: +ELLIPSIS
141 array([ 0.3127..., 0.329...])
142 """
144 from scipy.optimize import minimize # noqa: PLC0415
146 usage_warning(
147 '"Hernandez-Andres et al. (1999)" method for computing "CIE xy" '
148 "chromaticity coordinates from given correlated colour temperature is "
149 "not a bijective function and might produce unexpected results. It is "
150 "given for consistency with other correlated colour temperature "
151 "computation methods but should be avoided for practical applications."
152 )
154 CCT = as_float_array(CCT)
155 shape = list(CCT.shape)
156 CCT = np.atleast_1d(np.reshape(CCT, (-1, 1)))
158 def objective_function(xy: NDArrayFloat, CCT: NDArrayFloat) -> DTypeFloat:
159 """Objective function."""
161 objective = np.linalg.norm(xy_to_CCT_Hernandez1999(xy) - CCT)
163 return as_float(objective)
165 optimisation_settings = {
166 "method": "Nelder-Mead",
167 "options": {
168 "fatol": 1e-10,
169 },
170 }
171 if optimisation_kwargs is not None:
172 optimisation_settings.update(optimisation_kwargs)
174 xy = as_float_array(
175 [
176 minimize(
177 objective_function,
178 x0=CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"],
179 args=(CCT_i,),
180 **optimisation_settings,
181 ).x
182 for CCT_i in CCT
183 ]
184 )
186 return np.reshape(xy, ([*shape, 2]))