Coverage for colour/temperature/krystek1985.py: 100%
31 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-15 19:01 +1300
« prev ^ index » next coverage.py v7.11.0, created at 2025-11-15 19:01 +1300
1"""
2Krystek (1985) Correlated Colour Temperature
3============================================
5Define the *Krystek (1985)* correlated colour temperature :math:`T_{cp}`
6computation objects.
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.
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"""
22from __future__ import annotations
24import typing
26import numpy as np
28if typing.TYPE_CHECKING:
29 from colour.hints import ArrayLike, DTypeFloat, NDArrayFloat
31from colour.utilities import as_float, as_float_array, required, tstack
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"
40__all__ = [
41 "uv_to_CCT_Krystek1985",
42 "CCT_to_uv_Krystek1985",
43]
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.
55 Parameters
56 ----------
57 uv
58 *CIE UCS* colourspace *uv* chromaticity coordinates.
59 optimisation_kwargs
60 Parameters for :func:`scipy.optimize.minimize` definition.
62 Returns
63 -------
64 :class:`numpy.ndarray`
65 Correlated colour temperature :math:`T_{cp}`.
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.
76 Notes
77 -----
78 - *Krystek (1985)* method computations are valid for correlated
79 colour temperature :math:`T_{cp}` normalised to domain
80 [1000, 15000].
82 References
83 ----------
84 :cite:`Krystek1985b`
86 Examples
87 --------
88 >>> uv_to_CCT_Krystek1985(np.array([0.20047203, 0.31029290]))
89 ... # doctest: +ELLIPSIS
90 6504.3894290...
91 """
93 from scipy.optimize import minimize # noqa: PLC0415
95 uv = as_float_array(uv)
96 shape = uv.shape
97 uv = np.atleast_1d(np.reshape(uv, (-1, 2)))
99 def objective_function(CCT: NDArrayFloat, uv: NDArrayFloat) -> DTypeFloat:
100 """Objective function."""
102 objective = np.linalg.norm(CCT_to_uv_Krystek1985(CCT) - uv)
104 return as_float(objective)
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)
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 )
127 return as_float(np.reshape(CCT, shape[:-1]))
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.
136 Parameters
137 ----------
138 CCT
139 Correlated colour temperature :math:`T_{cp}`.
141 Returns
142 -------
143 :class:`numpy.ndarray`
144 *CIE UCS* colourspace *uv* chromaticity coordinates.
146 Notes
147 -----
148 - *Krystek (1985)* method computations are valid for correlated colour
149 temperature :math:`T_{cp}` normalised to domain [1000, 15000].
151 References
152 ----------
153 :cite:`Krystek1985b`
155 Examples
156 --------
157 >>> CCT_to_uv_Krystek1985(6504.38938305) # doctest: +ELLIPSIS
158 array([ 0.2004720..., 0.3102929...])
159 """
161 T = as_float_array(CCT)
163 T_2 = T**2
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 )
172 return tstack([u, v])