Coverage for models/tests/test_hdr_ipt.py: 100%

120 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-16 22:49 +1300

1"""Define the unit tests for the :mod:`colour.models.hdr_ipt` module.""" 

2 

3from __future__ import annotations 

4 

5from itertools import product 

6 

7import numpy as np 

8 

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 

13 

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" 

20 

21__all__ = [ 

22 "TestExponent_hdr_IPT", 

23 "TestXYZ_to_hdr_IPT", 

24 "TestHdr_IPT_to_XYZ", 

25] 

26 

27 

28class TestExponent_hdr_IPT: 

29 """ 

30 Define :func:`colour.models.hdr_ipt.exponent_hdr_IPT` 

31 definition unit tests methods. 

32 """ 

33 

34 def test_exponent_hdr_IPT(self) -> None: 

35 """Test :func:`colour.models.hdr_ipt.exponent_hdr_IPT` definition.""" 

36 

37 np.testing.assert_allclose( 

38 exponent_hdr_IPT(0.2, 100), 

39 0.482020919845900, 

40 atol=TOLERANCE_ABSOLUTE_TESTS, 

41 ) 

42 

43 np.testing.assert_allclose( 

44 exponent_hdr_IPT(0.4, 100), 

45 0.667413581325092, 

46 atol=TOLERANCE_ABSOLUTE_TESTS, 

47 ) 

48 

49 np.testing.assert_allclose( 

50 exponent_hdr_IPT(0.4, 100, method="Fairchild 2010"), 

51 1.219933220992410, 

52 atol=TOLERANCE_ABSOLUTE_TESTS, 

53 ) 

54 

55 np.testing.assert_allclose( 

56 exponent_hdr_IPT(0.2, 1000), 

57 0.723031379768850, 

58 atol=TOLERANCE_ABSOLUTE_TESTS, 

59 ) 

60 

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 """ 

66 

67 Y_s = 0.2 

68 Y_abs = 100 

69 epsilon = exponent_hdr_IPT(Y_s, Y_abs) 

70 

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 ) 

79 

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 ) 

88 

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 ) 

97 

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 """ 

103 

104 Y_s = 0.2 

105 Y_abs = 100 

106 epsilon = exponent_hdr_IPT(Y_s, Y_abs) 

107 

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 ) 

116 

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 """ 

123 

124 cases = np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) 

125 exponent_hdr_IPT(cases, cases) 

126 

127 

128class TestXYZ_to_hdr_IPT: 

129 """ 

130 Define :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition unit tests 

131 methods. 

132 """ 

133 

134 def test_XYZ_to_hdr_IPT(self) -> None: 

135 """Test :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition.""" 

136 

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 ) 

142 

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 ) 

151 

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 ) 

157 

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 ) 

163 

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 """ 

169 

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) 

174 

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 ) 

182 

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 ) 

190 

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 ) 

200 

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 """ 

206 

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) 

211 

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 ) 

220 

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 """ 

227 

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

231 

232 

233class TestHdr_IPT_to_XYZ: 

234 """ 

235 Define :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition unit tests 

236 methods. 

237 """ 

238 

239 def test_hdr_IPT_to_XYZ(self) -> None: 

240 """Test :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition.""" 

241 

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 ) 

247 

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 ) 

256 

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 ) 

262 

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 ) 

270 

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 """ 

276 

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) 

281 

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 ) 

289 

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 ) 

297 

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 ) 

307 

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 """ 

313 

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) 

318 

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 ) 

327 

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 """ 

334 

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