Coverage for colour/models/tests/test_hdr_ipt.py: 100%
120 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.hdr_ipt` module."""
3from __future__ import annotations
5from itertools import product
7import numpy as np
9from colour.constants import TOLERANCE_ABSOLUTE_TESTS
10from colour.models import XYZ_to_hdr_IPT, hdr_IPT_to_XYZ
11from colour.models.hdr_ipt import exponent_hdr_IPT
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 "TestExponent_hdr_IPT",
23 "TestXYZ_to_hdr_IPT",
24 "TestHdr_IPT_to_XYZ",
25]
28class TestExponent_hdr_IPT:
29 """
30 Define :func:`colour.models.hdr_ipt.exponent_hdr_IPT`
31 definition unit tests methods.
32 """
34 def test_exponent_hdr_IPT(self) -> None:
35 """Test :func:`colour.models.hdr_ipt.exponent_hdr_IPT` definition."""
37 np.testing.assert_allclose(
38 exponent_hdr_IPT(0.2, 100),
39 0.482020919845900,
40 atol=TOLERANCE_ABSOLUTE_TESTS,
41 )
43 np.testing.assert_allclose(
44 exponent_hdr_IPT(0.4, 100),
45 0.667413581325092,
46 atol=TOLERANCE_ABSOLUTE_TESTS,
47 )
49 np.testing.assert_allclose(
50 exponent_hdr_IPT(0.4, 100, method="Fairchild 2010"),
51 1.219933220992410,
52 atol=TOLERANCE_ABSOLUTE_TESTS,
53 )
55 np.testing.assert_allclose(
56 exponent_hdr_IPT(0.2, 1000),
57 0.723031379768850,
58 atol=TOLERANCE_ABSOLUTE_TESTS,
59 )
61 def test_n_dimensional_exponent_hdr_IPT(self) -> None:
62 """
63 Test :func:`colour.models.hdr_ipt.exponent_hdr_IPT` definition
64 n-dimensional arrays support.
65 """
67 Y_s = 0.2
68 Y_abs = 100
69 epsilon = exponent_hdr_IPT(Y_s, Y_abs)
71 Y_s = np.tile(Y_s, 6)
72 Y_abs = np.tile(Y_abs, 6)
73 epsilon = np.tile(epsilon, 6)
74 np.testing.assert_allclose(
75 exponent_hdr_IPT(Y_s, Y_abs),
76 epsilon,
77 atol=TOLERANCE_ABSOLUTE_TESTS,
78 )
80 Y_s = np.reshape(Y_s, (2, 3))
81 Y_abs = np.reshape(Y_abs, (2, 3))
82 epsilon = np.reshape(epsilon, (2, 3))
83 np.testing.assert_allclose(
84 exponent_hdr_IPT(Y_s, Y_abs),
85 epsilon,
86 atol=TOLERANCE_ABSOLUTE_TESTS,
87 )
89 Y_s = np.reshape(Y_s, (2, 3, 1))
90 Y_abs = np.reshape(Y_abs, (2, 3, 1))
91 epsilon = np.reshape(epsilon, (2, 3, 1))
92 np.testing.assert_allclose(
93 exponent_hdr_IPT(Y_s, Y_abs),
94 epsilon,
95 atol=TOLERANCE_ABSOLUTE_TESTS,
96 )
98 def test_domain_range_scale_exponent_hdr_IPT(self) -> None:
99 """
100 Test :func:`colour.models.hdr_ipt.exponent_hdr_IPT` definition domain
101 and range scale support.
102 """
104 Y_s = 0.2
105 Y_abs = 100
106 epsilon = exponent_hdr_IPT(Y_s, Y_abs)
108 d_r = (("reference", 1), ("1", 1), ("100", 100))
109 for scale, factor in d_r:
110 with domain_range_scale(scale):
111 np.testing.assert_allclose(
112 exponent_hdr_IPT(Y_s * factor, Y_abs),
113 epsilon,
114 atol=TOLERANCE_ABSOLUTE_TESTS,
115 )
117 @ignore_numpy_errors
118 def test_nan_exponent_hdr_IPT(self) -> None:
119 """
120 Test :func:`colour.models.hdr_ipt.exponent_hdr_IPT` definition nan
121 support.
122 """
124 cases = np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan])
125 exponent_hdr_IPT(cases, cases)
128class TestXYZ_to_hdr_IPT:
129 """
130 Define :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition unit tests
131 methods.
132 """
134 def test_XYZ_to_hdr_IPT(self) -> None:
135 """Test :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition."""
137 np.testing.assert_allclose(
138 XYZ_to_hdr_IPT(np.array([0.20654008, 0.12197225, 0.05136952])),
139 np.array([48.39376346, 42.44990202, 22.01954033]),
140 atol=TOLERANCE_ABSOLUTE_TESTS,
141 )
143 np.testing.assert_allclose(
144 XYZ_to_hdr_IPT(
145 np.array([0.20654008, 0.12197225, 0.05136952]),
146 method="Fairchild 2010",
147 ),
148 np.array([30.02873147, 83.93845061, 34.90287382]),
149 atol=TOLERANCE_ABSOLUTE_TESTS,
150 )
152 np.testing.assert_allclose(
153 XYZ_to_hdr_IPT(np.array([0.20654008, 0.12197225, 0.05136952]), Y_s=0.5),
154 np.array([20.75088680, 37.98300971, 16.66974299]),
155 atol=TOLERANCE_ABSOLUTE_TESTS,
156 )
158 np.testing.assert_allclose(
159 XYZ_to_hdr_IPT(np.array([0.07818780, 0.06157201, 0.28099326]), Y_abs=1000),
160 np.array([23.83205010, -5.98739209, -32.74311745]),
161 atol=TOLERANCE_ABSOLUTE_TESTS,
162 )
164 def test_n_dimensional_XYZ_to_hdr_IPT(self) -> None:
165 """
166 Test :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition
167 n-dimensional support.
168 """
170 XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
171 Y_s = 0.2
172 Y_abs = 100
173 IPT_hdr = XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs)
175 XYZ = np.tile(XYZ, (6, 1))
176 IPT_hdr = np.tile(IPT_hdr, (6, 1))
177 np.testing.assert_allclose(
178 XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs),
179 IPT_hdr,
180 atol=TOLERANCE_ABSOLUTE_TESTS,
181 )
183 Y_s = np.tile(Y_s, 6)
184 Y_abs = np.tile(Y_abs, 6)
185 np.testing.assert_allclose(
186 XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs),
187 IPT_hdr,
188 atol=TOLERANCE_ABSOLUTE_TESTS,
189 )
191 XYZ = np.reshape(XYZ, (2, 3, 3))
192 Y_s = np.reshape(Y_s, (2, 3))
193 Y_abs = np.reshape(Y_abs, (2, 3))
194 IPT_hdr = np.reshape(IPT_hdr, (2, 3, 3))
195 np.testing.assert_allclose(
196 XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs),
197 IPT_hdr,
198 atol=TOLERANCE_ABSOLUTE_TESTS,
199 )
201 def test_domain_range_scale_XYZ_to_hdr_IPT(self) -> None:
202 """
203 Test :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition domain
204 and range scale support.
205 """
207 XYZ = np.array([0.20654008, 0.12197225, 0.05136952])
208 Y_s = 0.2
209 Y_abs = 100
210 IPT_hdr = XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs)
212 d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1))
213 for scale, factor_a, factor_b in d_r:
214 with domain_range_scale(scale):
215 np.testing.assert_allclose(
216 XYZ_to_hdr_IPT(XYZ * factor_a, Y_s * factor_a, Y_abs),
217 IPT_hdr * factor_b,
218 atol=TOLERANCE_ABSOLUTE_TESTS,
219 )
221 @ignore_numpy_errors
222 def test_nan_XYZ_to_hdr_IPT(self) -> None:
223 """
224 Test :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition nan
225 support.
226 """
228 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
229 cases = np.array(list(set(product(cases, repeat=3))))
230 XYZ_to_hdr_IPT(cases, cases[..., 0], cases[..., 0])
233class TestHdr_IPT_to_XYZ:
234 """
235 Define :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition unit tests
236 methods.
237 """
239 def test_hdr_IPT_to_XYZ(self) -> None:
240 """Test :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition."""
242 np.testing.assert_allclose(
243 hdr_IPT_to_XYZ(np.array([48.39376346, 42.44990202, 22.01954033])),
244 np.array([0.20654008, 0.12197225, 0.05136952]),
245 atol=TOLERANCE_ABSOLUTE_TESTS,
246 )
248 np.testing.assert_allclose(
249 hdr_IPT_to_XYZ(
250 np.array([30.02873147, 83.93845061, 34.90287382]),
251 method="Fairchild 2010",
252 ),
253 np.array([0.20654008, 0.12197225, 0.05136952]),
254 atol=TOLERANCE_ABSOLUTE_TESTS,
255 )
257 np.testing.assert_allclose(
258 hdr_IPT_to_XYZ(np.array([20.75088680, 37.98300971, 16.66974299]), Y_s=0.5),
259 np.array([0.20654008, 0.12197225, 0.05136952]),
260 atol=TOLERANCE_ABSOLUTE_TESTS,
261 )
263 np.testing.assert_allclose(
264 hdr_IPT_to_XYZ(
265 np.array([23.83205010, -5.98739209, -32.74311745]), Y_abs=1000
266 ),
267 np.array([0.07818780, 0.06157201, 0.28099326]),
268 atol=TOLERANCE_ABSOLUTE_TESTS,
269 )
271 def test_n_dimensional_hdr_IPT_to_XYZ(self) -> None:
272 """
273 Test :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition
274 n-dimensional support.
275 """
277 IPT_hdr = np.array([48.39376346, 42.44990202, 22.01954033])
278 Y_s = 0.2
279 Y_abs = 100
280 XYZ = hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs)
282 IPT_hdr = np.tile(IPT_hdr, (6, 1))
283 XYZ = np.tile(XYZ, (6, 1))
284 np.testing.assert_allclose(
285 hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs),
286 XYZ,
287 atol=TOLERANCE_ABSOLUTE_TESTS,
288 )
290 Y_s = np.tile(Y_s, 6)
291 Y_abs = np.tile(Y_abs, 6)
292 np.testing.assert_allclose(
293 hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs),
294 XYZ,
295 atol=TOLERANCE_ABSOLUTE_TESTS,
296 )
298 IPT_hdr = np.reshape(IPT_hdr, (2, 3, 3))
299 Y_s = np.reshape(Y_s, (2, 3))
300 Y_abs = np.reshape(Y_abs, (2, 3))
301 XYZ = np.reshape(XYZ, (2, 3, 3))
302 np.testing.assert_allclose(
303 hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs),
304 XYZ,
305 atol=TOLERANCE_ABSOLUTE_TESTS,
306 )
308 def test_domain_range_scale_hdr_IPT_to_XYZ(self) -> None:
309 """
310 Test :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition domain
311 and range scale support.
312 """
314 IPT_hdr = np.array([24.88927680, -11.44574144, 1.63147707])
315 Y_s = 0.2
316 Y_abs = 100
317 XYZ = hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs)
319 d_r = (("reference", 1, 1, 1), ("1", 0.01, 1, 1), ("100", 1, 100, 100))
320 for scale, factor_a, factor_b, factor_c in d_r:
321 with domain_range_scale(scale):
322 np.testing.assert_allclose(
323 hdr_IPT_to_XYZ(IPT_hdr * factor_a, Y_s * factor_b, Y_abs),
324 XYZ * factor_c,
325 atol=TOLERANCE_ABSOLUTE_TESTS,
326 )
328 @ignore_numpy_errors
329 def test_nan_hdr_IPT_to_XYZ(self) -> None:
330 """
331 Test :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition nan
332 support.
333 """
335 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]
336 cases = np.array(list(set(product(cases, repeat=3))))
337 hdr_IPT_to_XYZ(cases, cases[..., 0], cases[..., 0])