Coverage for colour/models/tests/test_hunter_rdab.py: 100%
104 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"""Define the unit tests for the :mod:`colour.models.hunter_rdab` module."""
3from __future__ import annotations
5from itertools import product
7import numpy as np
9from colour.colorimetry import TVS_ILLUMINANTS_HUNTERLAB
10from colour.constants import TOLERANCE_ABSOLUTE_TESTS
11from colour.models import Hunter_Rdab_to_XYZ, XYZ_to_Hunter_Rdab
12from colour.utilities import domain_range_scale, ignore_numpy_errors
14__author__ = "Colour Developers"
15__copyright__ = "Copyright 2013 Colour Developers"
16__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause"
17__maintainer__ = "Colour Developers"
18__email__ = "colour-developers@colour-science.org"
19__status__ = "Production"
21__all__ = [
22 "TestXYZ_to_Hunter_Rdab",
23 "TestHunter_Rdab_to_XYZ",
24]
27class TestXYZ_to_Hunter_Rdab:
28 """
29 Define :func:`colour.models.hunter_rdab.XYZ_to_Hunter_Rdab` definition
30 unit tests methods.
31 """
33 def test_XYZ_to_Hunter_Rdab(self) -> None:
34 """Test :func:`colour.models.hunter_rdab.XYZ_to_Hunter_Rdab` definition."""
36 np.testing.assert_allclose(
37 XYZ_to_Hunter_Rdab(np.array([0.20654008, 0.12197225, 0.05136952]) * 100),
38 np.array([12.19722500, 57.12537874, 17.46241341]),
39 atol=TOLERANCE_ABSOLUTE_TESTS,
40 )
42 np.testing.assert_allclose(
43 XYZ_to_Hunter_Rdab(np.array([0.14222010, 0.23042768, 0.10495772]) * 100),
44 np.array([23.04276800, -32.40057474, 20.96542183]),
45 atol=TOLERANCE_ABSOLUTE_TESTS,
46 )
48 np.testing.assert_allclose(
49 XYZ_to_Hunter_Rdab(np.array([0.07818780, 0.06157201, 0.28099326]) * 100),
50 np.array([6.15720100, 18.13400284, -67.14408607]),
51 atol=TOLERANCE_ABSOLUTE_TESTS,
52 )
54 h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"]
55 A = h_i["A"]
56 np.testing.assert_allclose(
57 XYZ_to_Hunter_Rdab(
58 np.array([0.20654008, 0.12197225, 0.05136952]) * 100,
59 A.XYZ_n,
60 A.K_ab,
61 ),
62 np.array([12.19722500, 42.53572838, -3.00653110]),
63 atol=TOLERANCE_ABSOLUTE_TESTS,
64 )
66 D65 = h_i["D65"]
67 np.testing.assert_allclose(
68 XYZ_to_Hunter_Rdab(
69 np.array([0.20654008, 0.12197225, 0.05136952]) * 100,
70 D65.XYZ_n,
71 D65.K_ab,
72 ),
73 np.array([12.19722500, 57.12537874, 17.46241341]),
74 atol=TOLERANCE_ABSOLUTE_TESTS,
75 )
77 np.testing.assert_allclose(
78 XYZ_to_Hunter_Rdab(
79 np.array([0.20654008, 0.12197225, 0.05136952]) * 100,
80 D65.XYZ_n,
81 K_ab=None,
82 ),
83 np.array([12.19722500, 57.11906384, 17.45962317]),
84 atol=TOLERANCE_ABSOLUTE_TESTS,
85 )
87 def test_n_dimensional_XYZ_to_Hunter_Rdab(self) -> None:
88 """
89 Test :func:`colour.models.hunter_rdab.XYZ_to_Hunter_Rdab` definition
90 n-dimensional support.
91 """
93 h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"]
94 D65 = h_i["D65"]
96 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) * 100
97 XYZ_n = D65.XYZ_n
98 K_ab = D65.K_ab
99 R_d_ab = XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab)
101 XYZ = np.tile(XYZ, (6, 1))
102 R_d_ab = np.tile(R_d_ab, (6, 1))
103 np.testing.assert_allclose(
104 XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab),
105 R_d_ab,
106 atol=TOLERANCE_ABSOLUTE_TESTS,
107 )
109 XYZ_n = np.tile(XYZ_n, (6, 1))
110 K_ab = np.tile(K_ab, (6, 1))
111 np.testing.assert_allclose(
112 XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab),
113 R_d_ab,
114 atol=TOLERANCE_ABSOLUTE_TESTS,
115 )
117 XYZ = np.reshape(XYZ, (2, 3, 3))
118 XYZ_n = np.reshape(XYZ_n, (2, 3, 3))
119 K_ab = np.reshape(K_ab, (2, 3, 2))
120 R_d_ab = np.reshape(R_d_ab, (2, 3, 3))
121 np.testing.assert_allclose(
122 XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab),
123 R_d_ab,
124 atol=TOLERANCE_ABSOLUTE_TESTS,
125 )
127 def test_domain_range_scale_XYZ_to_Hunter_Rdab(self) -> None:
128 """
129 Test :func:`colour.models.hunter_lab.XYZ_to_Hunter_Rdab` definition
130 domain and range scale support.
131 """
133 h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"]
134 D65 = h_i["D65"]
136 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) * 100
137 XYZ_n = D65.XYZ_n
138 K_ab = D65.K_ab
139 R_d_ab = XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab)
141 d_r = (("reference", 1), ("1", 0.01), ("100", 1))
142 for scale, factor in d_r:
143 with domain_range_scale(scale):
144 np.testing.assert_allclose(
145 XYZ_to_Hunter_Rdab(XYZ * factor, XYZ_n * factor, K_ab),
146 R_d_ab * factor,
147 atol=TOLERANCE_ABSOLUTE_TESTS,
148 )
150 @ignore_numpy_errors
151 def test_nan_XYZ_to_Hunter_Rdab(self) -> None:
152 """
153 Test :func:`colour.models.hunter_rdab.XYZ_to_Hunter_Rdab` definition
154 nan support.
155 """
157 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
158 cases = np.array(list(set(product(cases, repeat=3))))
159 XYZ_to_Hunter_Rdab(cases, cases, cases[..., 0:2])
162class TestHunter_Rdab_to_XYZ:
163 """
164 Define :func:`colour.models.hunter_rdab.Hunter_Rdab_to_XYZ` definition
165 unit tests methods.
166 """
168 def test_Hunter_Rdab_to_XYZ(self) -> None:
169 """Test :func:`colour.models.hunter_rdab.Hunter_Rdab_to_XYZ` definition."""
171 np.testing.assert_allclose(
172 Hunter_Rdab_to_XYZ(np.array([12.19722500, 57.12537874, 17.46241341])),
173 np.array([0.20654008, 0.12197225, 0.05136952]) * 100,
174 atol=TOLERANCE_ABSOLUTE_TESTS,
175 )
177 np.testing.assert_allclose(
178 Hunter_Rdab_to_XYZ(np.array([23.04276800, -32.40057474, 20.96542183])),
179 np.array([0.14222010, 0.23042768, 0.10495772]) * 100,
180 atol=TOLERANCE_ABSOLUTE_TESTS,
181 )
183 np.testing.assert_allclose(
184 Hunter_Rdab_to_XYZ(np.array([6.15720100, 18.13400284, -67.14408607])),
185 np.array([0.07818780, 0.06157201, 0.28099326]) * 100,
186 atol=TOLERANCE_ABSOLUTE_TESTS,
187 )
189 h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"]
190 A = h_i["A"]
191 np.testing.assert_allclose(
192 Hunter_Rdab_to_XYZ(
193 np.array([12.19722500, 42.53572838, -3.00653110]),
194 A.XYZ_n,
195 A.K_ab,
196 ),
197 np.array([0.20654008, 0.12197225, 0.05136952]) * 100,
198 atol=TOLERANCE_ABSOLUTE_TESTS,
199 )
201 D65 = h_i["D65"]
202 np.testing.assert_allclose(
203 Hunter_Rdab_to_XYZ(
204 np.array([12.19722500, 57.12537874, 17.46241341]),
205 D65.XYZ_n,
206 D65.K_ab,
207 ),
208 np.array([0.20654008, 0.12197225, 0.05136952]) * 100,
209 atol=TOLERANCE_ABSOLUTE_TESTS,
210 )
212 np.testing.assert_allclose(
213 Hunter_Rdab_to_XYZ(
214 np.array([12.19722500, 57.11906384, 17.45962317]),
215 D65.XYZ_n,
216 K_ab=None,
217 ),
218 np.array([0.20654008, 0.12197225, 0.05136952]) * 100,
219 atol=TOLERANCE_ABSOLUTE_TESTS,
220 )
222 def test_n_dimensional_Hunter_Rdab_to_XYZ(self) -> None:
223 """
224 Test :func:`colour.models.hunter_rdab.Hunter_Rdab_to_XYZ` definition
225 n-dimensional support.
226 """
228 h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"]
229 D65 = h_i["D65"]
231 R_d_ab = np.array([12.19722500, 57.12537874, 17.46241341])
232 XYZ_n = D65.XYZ_n
233 K_ab = D65.K_ab
234 XYZ = Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab)
236 R_d_ab = np.tile(R_d_ab, (6, 1))
237 XYZ = np.tile(XYZ, (6, 1))
238 np.testing.assert_allclose(
239 Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab),
240 XYZ,
241 atol=TOLERANCE_ABSOLUTE_TESTS,
242 )
244 K_ab = np.tile(K_ab, (6, 1))
245 XYZ_n = np.tile(XYZ_n, (6, 1))
246 np.testing.assert_allclose(
247 Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab),
248 XYZ,
249 atol=TOLERANCE_ABSOLUTE_TESTS,
250 )
252 R_d_ab = np.reshape(R_d_ab, (2, 3, 3))
253 XYZ_n = np.reshape(XYZ_n, (2, 3, 3))
254 K_ab = np.reshape(K_ab, (2, 3, 2))
255 XYZ = np.reshape(XYZ, (2, 3, 3))
256 np.testing.assert_allclose(
257 Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab),
258 XYZ,
259 atol=TOLERANCE_ABSOLUTE_TESTS,
260 )
262 def test_domain_range_scale_Hunter_Rdab_to_XYZ(self) -> None:
263 """
264 Test :func:`colour.models.hunter_lab.Hunter_Rdab_to_XYZ` definition
265 domain and range scale support.
266 """
268 h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"]
269 D65 = h_i["D65"]
271 R_d_ab = np.array([12.19722500, 57.12537874, 17.46241341])
272 XYZ_n = D65.XYZ_n
273 K_ab = D65.K_ab
274 XYZ = Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab)
276 d_r = (("reference", 1), ("1", 0.01), ("100", 1))
277 for scale, factor in d_r:
278 with domain_range_scale(scale):
279 np.testing.assert_allclose(
280 Hunter_Rdab_to_XYZ(R_d_ab * factor, XYZ_n * factor, K_ab),
281 XYZ * factor,
282 atol=TOLERANCE_ABSOLUTE_TESTS,
283 )
285 @ignore_numpy_errors
286 def test_nan_Hunter_Rdab_to_XYZ(self) -> None:
287 """
288 Test :func:`colour.models.hunter_rdab.Hunter_Rdab_to_XYZ` definition
289 nan support.
290 """
292 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
293 cases = np.array(list(set(product(cases, repeat=3))))
294 Hunter_Rdab_to_XYZ(cases, cases, cases[..., 0:2])