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

130 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_cie_lab` 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_CIELab, hdr_CIELab_to_XYZ 

11from colour.models.hdr_cie_lab import exponent_hdr_CIELab 

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

23 "TestXYZ_to_hdr_CIELab", 

24 "TestHdr_CIELab_to_XYZ", 

25] 

26 

27 

28class TestExponent_hdr_CIELab: 

29 """ 

30 Define :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab` 

31 definition unit tests methods. 

32 """ 

33 

34 def test_exponent_hdr_CIELab(self) -> None: 

35 """ 

36 Test :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab` 

37 definition. 

38 """ 

39 

40 np.testing.assert_allclose( 

41 exponent_hdr_CIELab(0.2, 100), 

42 0.473851073746817, 

43 atol=TOLERANCE_ABSOLUTE_TESTS, 

44 ) 

45 

46 np.testing.assert_allclose( 

47 exponent_hdr_CIELab(0.4, 100), 

48 0.656101486726362, 

49 atol=TOLERANCE_ABSOLUTE_TESTS, 

50 ) 

51 

52 np.testing.assert_allclose( 

53 exponent_hdr_CIELab(0.4, 100, method="Fairchild 2010"), 

54 1.326014370643925, 

55 atol=TOLERANCE_ABSOLUTE_TESTS, 

56 ) 

57 

58 np.testing.assert_allclose( 

59 exponent_hdr_CIELab(0.2, 1000), 

60 0.710776610620225, 

61 atol=TOLERANCE_ABSOLUTE_TESTS, 

62 ) 

63 

64 def test_n_dimensional_exponent_hdr_CIELab(self) -> None: 

65 """ 

66 Test :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab` 

67 definition n-dimensional arrays support. 

68 """ 

69 

70 Y_s = 0.2 

71 Y_abs = 100 

72 epsilon = exponent_hdr_CIELab(Y_s, Y_abs) 

73 

74 Y_s = np.tile(Y_s, 6) 

75 Y_abs = np.tile(Y_abs, 6) 

76 epsilon = np.tile(epsilon, 6) 

77 np.testing.assert_allclose( 

78 exponent_hdr_CIELab(Y_s, Y_abs), 

79 epsilon, 

80 atol=TOLERANCE_ABSOLUTE_TESTS, 

81 ) 

82 

83 Y_s = np.reshape(Y_s, (2, 3)) 

84 Y_abs = np.reshape(Y_abs, (2, 3)) 

85 epsilon = np.reshape(epsilon, (2, 3)) 

86 np.testing.assert_allclose( 

87 exponent_hdr_CIELab(Y_s, Y_abs), 

88 epsilon, 

89 atol=TOLERANCE_ABSOLUTE_TESTS, 

90 ) 

91 

92 Y_s = np.reshape(Y_s, (2, 3, 1)) 

93 Y_abs = np.reshape(Y_abs, (2, 3, 1)) 

94 epsilon = np.reshape(epsilon, (2, 3, 1)) 

95 np.testing.assert_allclose( 

96 exponent_hdr_CIELab(Y_s, Y_abs), 

97 epsilon, 

98 atol=TOLERANCE_ABSOLUTE_TESTS, 

99 ) 

100 

101 def test_domain_range_scale_exponent_hdr_CIELab(self) -> None: 

102 """ 

103 Test :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab` definition 

104 domain and range scale support. 

105 """ 

106 

107 Y_s = 0.2 

108 Y_abs = 100 

109 epsilon = exponent_hdr_CIELab(Y_s, Y_abs) 

110 

111 d_r = (("reference", 1), ("1", 1), ("100", 100)) 

112 for scale, factor in d_r: 

113 with domain_range_scale(scale): 

114 np.testing.assert_allclose( 

115 exponent_hdr_CIELab(Y_s * factor, Y_abs), 

116 epsilon, 

117 atol=TOLERANCE_ABSOLUTE_TESTS, 

118 ) 

119 

120 @ignore_numpy_errors 

121 def test_nan_exponent_hdr_CIELab(self) -> None: 

122 """ 

123 Test :func:`colour.models.hdr_cie_lab.exponent_hdr_CIELab` 

124 definition nan support. 

125 """ 

126 

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

128 exponent_hdr_CIELab(cases, cases) 

129 

130 

131class TestXYZ_to_hdr_CIELab: 

132 """ 

133 Define :func:`colour.models.hdr_cie_lab.XYZ_to_hdr_CIELab` definition unit 

134 tests methods. 

135 """ 

136 

137 def test_XYZ_to_hdr_CIELab(self) -> None: 

138 """Test :func:`colour.models.hdr_cie_lab.XYZ_to_hdr_CIELab` definition.""" 

139 

140 np.testing.assert_allclose( 

141 XYZ_to_hdr_CIELab(np.array([0.20654008, 0.12197225, 0.05136952])), 

142 np.array([51.87002062, 60.47633850, 32.14551912]), 

143 atol=TOLERANCE_ABSOLUTE_TESTS, 

144 ) 

145 

146 np.testing.assert_allclose( 

147 XYZ_to_hdr_CIELab( 

148 np.array([0.20654008, 0.12197225, 0.05136952]), 

149 np.array([0.44757, 0.40745]), 

150 ), 

151 np.array([51.87002062, 44.49667330, -6.69619196]), 

152 atol=TOLERANCE_ABSOLUTE_TESTS, 

153 ) 

154 

155 np.testing.assert_allclose( 

156 XYZ_to_hdr_CIELab( 

157 np.array([0.20654008, 0.12197225, 0.05136952]), 

158 np.array([0.44757, 0.40745]), 

159 method="Fairchild 2010", 

160 ), 

161 np.array([31.99621114, 95.08564341, -14.14047055]), 

162 atol=TOLERANCE_ABSOLUTE_TESTS, 

163 ) 

164 

165 np.testing.assert_allclose( 

166 XYZ_to_hdr_CIELab(np.array([0.20654008, 0.12197225, 0.05136952]), Y_s=0.5), 

167 np.array([23.10388654, 59.31425004, 23.69960142]), 

168 atol=TOLERANCE_ABSOLUTE_TESTS, 

169 ) 

170 

171 np.testing.assert_allclose( 

172 XYZ_to_hdr_CIELab( 

173 np.array([0.20654008, 0.12197225, 0.05136952]), Y_abs=1000 

174 ), 

175 np.array([29.77261805, 62.58315675, 27.31232673]), 

176 atol=TOLERANCE_ABSOLUTE_TESTS, 

177 ) 

178 

179 def test_n_dimensional_XYZ_to_hdr_CIELab(self) -> None: 

180 """ 

181 Test :func:`colour.models.hdr_cie_lab.XYZ_to_hdr_CIELab` definition 

182 n-dimensional support. 

183 """ 

184 

185 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) 

186 illuminant = np.array([0.31270, 0.32900]) 

187 Y_s = 0.2 

188 Y_abs = 100 

189 Lab_hdr = XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs) 

190 

191 XYZ = np.tile(XYZ, (6, 1)) 

192 Lab_hdr = np.tile(Lab_hdr, (6, 1)) 

193 np.testing.assert_allclose( 

194 XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), 

195 Lab_hdr, 

196 atol=TOLERANCE_ABSOLUTE_TESTS, 

197 ) 

198 

199 illuminant = np.tile(illuminant, (6, 1)) 

200 Y_s = np.tile(Y_s, 6) 

201 Y_abs = np.tile(Y_abs, 6) 

202 np.testing.assert_allclose( 

203 XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), 

204 Lab_hdr, 

205 atol=TOLERANCE_ABSOLUTE_TESTS, 

206 ) 

207 

208 XYZ = np.reshape(XYZ, (2, 3, 3)) 

209 illuminant = np.reshape(illuminant, (2, 3, 2)) 

210 Y_s = np.reshape(Y_s, (2, 3)) 

211 Y_abs = np.reshape(Y_abs, (2, 3)) 

212 Lab_hdr = np.reshape(Lab_hdr, (2, 3, 3)) 

213 np.testing.assert_allclose( 

214 XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), 

215 Lab_hdr, 

216 atol=TOLERANCE_ABSOLUTE_TESTS, 

217 ) 

218 

219 def test_domain_range_scale_XYZ_to_hdr_CIELab(self) -> None: 

220 """ 

221 Test :func:`colour.models.hdr_cie_lab.XYZ_to_hdr_CIELab` definition 

222 domain and range scale support. 

223 """ 

224 

225 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) 

226 illuminant = np.array([0.31270, 0.32900]) 

227 Y_s = 0.2 

228 Y_abs = 100 

229 Lab_hdr = XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs) 

230 

231 d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) 

232 for scale, factor_a, factor_b in d_r: 

233 with domain_range_scale(scale): 

234 np.testing.assert_allclose( 

235 XYZ_to_hdr_CIELab( 

236 XYZ * factor_a, illuminant, Y_s * factor_a, Y_abs 

237 ), 

238 Lab_hdr * factor_b, 

239 atol=TOLERANCE_ABSOLUTE_TESTS, 

240 ) 

241 

242 @ignore_numpy_errors 

243 def test_nan_XYZ_to_hdr_CIELab(self) -> None: 

244 """ 

245 Test :func:`colour.models.hdr_cie_lab.XYZ_to_hdr_CIELab` definition 

246 nan support. 

247 """ 

248 

249 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] 

250 cases = np.array(list(set(product(cases, repeat=3)))) 

251 XYZ_to_hdr_CIELab(cases, cases[..., 0:2], cases[..., 0], cases[..., 0]) 

252 

253 

254class TestHdr_CIELab_to_XYZ: 

255 """ 

256 Define :func:`colour.models.hdr_cie_lab.hdr_CIELab_to_XYZ` definition unit 

257 tests methods. 

258 """ 

259 

260 def test_hdr_CIELab_to_XYZ(self) -> None: 

261 """Test :func:`colour.models.hdr_cie_lab.hdr_CIELab_to_XYZ` definition.""" 

262 

263 np.testing.assert_allclose( 

264 hdr_CIELab_to_XYZ(np.array([51.87002062, 60.47633850, 32.14551912])), 

265 np.array([0.20654008, 0.12197225, 0.05136952]), 

266 atol=TOLERANCE_ABSOLUTE_TESTS, 

267 ) 

268 

269 np.testing.assert_allclose( 

270 hdr_CIELab_to_XYZ( 

271 np.array([51.87002062, 44.49667330, -6.69619196]), 

272 np.array([0.44757, 0.40745]), 

273 ), 

274 np.array([0.20654008, 0.12197225, 0.05136952]), 

275 atol=TOLERANCE_ABSOLUTE_TESTS, 

276 ) 

277 

278 np.testing.assert_allclose( 

279 hdr_CIELab_to_XYZ( 

280 np.array([31.99621114, 95.08564341, -14.14047055]), 

281 np.array([0.44757, 0.40745]), 

282 method="Fairchild 2010", 

283 ), 

284 np.array([0.20654008, 0.12197225, 0.05136952]), 

285 atol=TOLERANCE_ABSOLUTE_TESTS, 

286 ) 

287 

288 np.testing.assert_allclose( 

289 hdr_CIELab_to_XYZ( 

290 np.array([23.10388654, 59.31425004, 23.69960142]), Y_s=0.5 

291 ), 

292 np.array([0.20654008, 0.12197225, 0.05136952]), 

293 atol=TOLERANCE_ABSOLUTE_TESTS, 

294 ) 

295 

296 np.testing.assert_allclose( 

297 hdr_CIELab_to_XYZ( 

298 np.array([29.77261805, 62.58315675, 27.31232673]), Y_abs=1000 

299 ), 

300 np.array([0.20654008, 0.12197225, 0.05136952]), 

301 atol=TOLERANCE_ABSOLUTE_TESTS, 

302 ) 

303 

304 def test_n_dimensional_hdr_CIELab_to_XYZ(self) -> None: 

305 """ 

306 Test :func:`colour.models.hdr_cie_lab.hdr_CIELab_to_XYZ` definition 

307 n-dimensional support. 

308 """ 

309 

310 Lab_hdr = np.array([51.87002062, 60.47633850, 32.14551912]) 

311 illuminant = np.array([0.31270, 0.32900]) 

312 Y_s = 0.2 

313 Y_abs = 100 

314 XYZ = hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs) 

315 

316 Lab_hdr = np.tile(Lab_hdr, (6, 1)) 

317 XYZ = np.tile(XYZ, (6, 1)) 

318 np.testing.assert_allclose( 

319 hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), 

320 XYZ, 

321 atol=TOLERANCE_ABSOLUTE_TESTS, 

322 ) 

323 

324 illuminant = np.tile(illuminant, (6, 1)) 

325 Y_s = np.tile(Y_s, 6) 

326 Y_abs = np.tile(Y_abs, 6) 

327 np.testing.assert_allclose( 

328 hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), 

329 XYZ, 

330 atol=TOLERANCE_ABSOLUTE_TESTS, 

331 ) 

332 

333 Lab_hdr = np.reshape(Lab_hdr, (2, 3, 3)) 

334 illuminant = np.reshape(illuminant, (2, 3, 2)) 

335 Y_s = np.reshape(Y_s, (2, 3)) 

336 Y_abs = np.reshape(Y_abs, (2, 3)) 

337 XYZ = np.reshape(XYZ, (2, 3, 3)) 

338 np.testing.assert_allclose( 

339 hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), 

340 XYZ, 

341 atol=TOLERANCE_ABSOLUTE_TESTS, 

342 ) 

343 

344 def test_domain_range_scale_hdr_CIELab_to_XYZ(self) -> None: 

345 """ 

346 Test :func:`colour.models.hdr_cie_lab.hdr_CIELab_to_XYZ` definition 

347 domain and range scale support. 

348 """ 

349 

350 Lab_hdr = np.array([26.46461067, -24.61332600, -4.84796811]) 

351 illuminant = np.array([0.31270, 0.32900]) 

352 Y_s = 0.2 

353 Y_abs = 100 

354 XYZ = hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs) 

355 

356 d_r = (("reference", 1, 1, 1), ("1", 0.01, 1, 1), ("100", 1, 100, 100)) 

357 for scale, factor_a, factor_b, factor_c in d_r: 

358 with domain_range_scale(scale): 

359 np.testing.assert_allclose( 

360 hdr_CIELab_to_XYZ( 

361 Lab_hdr * factor_a, illuminant, Y_s * factor_b, Y_abs 

362 ), 

363 XYZ * factor_c, 

364 atol=TOLERANCE_ABSOLUTE_TESTS, 

365 ) 

366 

367 @ignore_numpy_errors 

368 def test_nan_hdr_CIELab_to_XYZ(self) -> None: 

369 """ 

370 Test :func:`colour.models.hdr_cie_lab.hdr_CIELab_to_XYZ` definition 

371 nan support. 

372 """ 

373 

374 cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] 

375 cases = np.array(list(set(product(cases, repeat=3)))) 

376 hdr_CIELab_to_XYZ(cases, cases[..., 0:2], cases[..., 0], cases[..., 0])