Coverage for adaptation/tests/test_cmccat2000.py: 100%

104 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.adaptation.cmccat2000.""" 

2 

3from __future__ import annotations 

4 

5from itertools import product 

6 

7import numpy as np 

8 

9from colour.adaptation.cmccat2000 import ( 

10 chromatic_adaptation_CMCCAT2000, 

11 chromatic_adaptation_forward_CMCCAT2000, 

12 chromatic_adaptation_inverse_CMCCAT2000, 

13) 

14from colour.constants import TOLERANCE_ABSOLUTE_TESTS 

15from colour.utilities import domain_range_scale, ignore_numpy_errors 

16 

17__author__ = "Colour Developers" 

18__copyright__ = "Copyright 2013 Colour Developers" 

19__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" 

20__maintainer__ = "Colour Developers" 

21__email__ = "colour-developers@colour-science.org" 

22__status__ = "Production" 

23 

24__all__ = [ 

25 "TestChromaticAdaptationForwardCMCCAT2000", 

26 "TestChromaticAdaptationInverseCMCCAT2000", 

27 "TestChromaticAdaptationCMCCAT2000", 

28] 

29 

30 

31class TestChromaticAdaptationForwardCMCCAT2000: 

32 """ 

33 Define :func:`colour.adaptation.cmccat2000.\ 

34chromatic_adaptation_forward_CMCCAT2000` definition unit tests methods. 

35 """ 

36 

37 def test_chromatic_adaptation_forward_CMCCAT2000(self) -> None: 

38 """ 

39 Test :func:`colour.adaptation.cmccat2000.\ 

40chromatic_adaptation_forward_CMCCAT2000` definition. 

41 """ 

42 

43 np.testing.assert_allclose( 

44 chromatic_adaptation_forward_CMCCAT2000( 

45 np.array([22.48, 22.74, 8.54]), 

46 np.array([111.15, 100.00, 35.20]), 

47 np.array([94.81, 100.00, 107.30]), 

48 200, 

49 200, 

50 ), 

51 np.array([19.52698326, 23.06833960, 24.97175229]), 

52 atol=TOLERANCE_ABSOLUTE_TESTS, 

53 ) 

54 

55 np.testing.assert_allclose( 

56 chromatic_adaptation_forward_CMCCAT2000( 

57 np.array([0.14222010, 0.23042768, 0.10495772]) * 100, 

58 np.array([0.95045593, 1.00000000, 1.08905775]) * 100, 

59 np.array([1.09846607, 1.00000000, 0.35582280]) * 100, 

60 100, 

61 100, 

62 ), 

63 np.array([17.90511171, 22.75299363, 3.79837384]), 

64 atol=TOLERANCE_ABSOLUTE_TESTS, 

65 ) 

66 

67 np.testing.assert_allclose( 

68 chromatic_adaptation_forward_CMCCAT2000( 

69 np.array([0.07818780, 0.06157201, 0.28099326]) * 100, 

70 np.array([0.95045593, 1.00000000, 1.08905775]) * 100, 

71 np.array([0.99144661, 1.00000000, 0.67315942]) * 100, 

72 100, 

73 100, 

74 ), 

75 np.array([6.76564344, 5.86585763, 18.40577315]), 

76 atol=TOLERANCE_ABSOLUTE_TESTS, 

77 ) 

78 

79 def test_n_dimensional_chromatic_adaptation_forward_CMCCAT2000(self) -> None: 

80 """ 

81 Test :func:`colour.adaptation.cmccat2000.\ 

82chromatic_adaptation_forward_CMCCAT2000` definition n-dimensional arrays 

83 support. 

84 """ 

85 

86 XYZ = np.array([22.48, 22.74, 8.54]) 

87 XYZ_w = np.array([111.15, 100.00, 35.20]) 

88 XYZ_wr = np.array([94.81, 100.00, 107.30]) 

89 L_A1 = 200 

90 L_A2 = 200 

91 XYZ_c = chromatic_adaptation_forward_CMCCAT2000(XYZ, XYZ_w, XYZ_wr, L_A1, L_A2) 

92 

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

94 XYZ_c = np.tile(XYZ_c, (6, 1)) 

95 np.testing.assert_allclose( 

96 chromatic_adaptation_forward_CMCCAT2000(XYZ, XYZ_w, XYZ_wr, L_A1, L_A2), 

97 XYZ_c, 

98 atol=TOLERANCE_ABSOLUTE_TESTS, 

99 ) 

100 

101 XYZ_w = np.tile(XYZ_w, (6, 1)) 

102 XYZ_wr = np.tile(XYZ_wr, (6, 1)) 

103 L_A1 = np.tile(L_A1, 6) 

104 L_A2 = np.tile(L_A2, 6) 

105 np.testing.assert_allclose( 

106 chromatic_adaptation_forward_CMCCAT2000(XYZ, XYZ_w, XYZ_wr, L_A1, L_A2), 

107 XYZ_c, 

108 atol=TOLERANCE_ABSOLUTE_TESTS, 

109 ) 

110 

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

112 XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) 

113 XYZ_wr = np.reshape(XYZ_wr, (2, 3, 3)) 

114 L_A1 = np.reshape(L_A1, (2, 3)) 

115 L_A2 = np.reshape(L_A2, (2, 3)) 

116 XYZ_c = np.reshape(XYZ_c, (2, 3, 3)) 

117 np.testing.assert_allclose( 

118 chromatic_adaptation_forward_CMCCAT2000(XYZ, XYZ_w, XYZ_wr, L_A1, L_A2), 

119 XYZ_c, 

120 atol=TOLERANCE_ABSOLUTE_TESTS, 

121 ) 

122 

123 def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self) -> None: 

124 """ 

125 Test :func:`colour.adaptation.cmccat2000.\ 

126chromatic_adaptation_forward_CMCCAT2000` definition domain and range scale 

127 support. 

128 """ 

129 

130 XYZ = np.array([22.48, 22.74, 8.54]) 

131 XYZ_w = np.array([111.15, 100.00, 35.20]) 

132 XYZ_wr = np.array([94.81, 100.00, 107.30]) 

133 L_A1 = 200 

134 L_A2 = 200 

135 XYZ_c = chromatic_adaptation_forward_CMCCAT2000(XYZ, XYZ_w, XYZ_wr, L_A1, L_A2) 

136 

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

138 for scale, factor in d_r: 

139 with domain_range_scale(scale): 

140 np.testing.assert_allclose( 

141 chromatic_adaptation_forward_CMCCAT2000( 

142 XYZ * factor, 

143 XYZ_w * factor, 

144 XYZ_wr * factor, 

145 L_A1, 

146 L_A2, 

147 ), 

148 XYZ_c * factor, 

149 atol=TOLERANCE_ABSOLUTE_TESTS, 

150 ) 

151 

152 @ignore_numpy_errors 

153 def test_nan_chromatic_adaptation_forward_CMCCAT2000(self) -> None: 

154 """ 

155 Test :func:`colour.adaptation.cmccat2000.\ 

156chromatic_adaptation_forward_CMCCAT2000` definition nan support. 

157 """ 

158 

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

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

161 chromatic_adaptation_forward_CMCCAT2000( 

162 cases, cases, cases, cases[..., 0], cases[..., 0] 

163 ) 

164 

165 

166class TestChromaticAdaptationInverseCMCCAT2000: 

167 """ 

168 Define :func:`colour.adaptation.cmccat2000.\ 

169chromatic_adaptation_inverse_CMCCAT2000` definition unit tests methods. 

170 """ 

171 

172 def test_chromatic_adaptation_inverse_CMCCAT2000(self) -> None: 

173 """ 

174 Test :func:`colour.adaptation.cmccat2000.\ 

175chromatic_adaptation_inverse_CMCCAT2000` definition. 

176 """ 

177 

178 np.testing.assert_allclose( 

179 chromatic_adaptation_inverse_CMCCAT2000( 

180 np.array([19.52698326, 23.06833960, 24.97175229]), 

181 np.array([111.15, 100.00, 35.20]), 

182 np.array([94.81, 100.00, 107.30]), 

183 200, 

184 200, 

185 ), 

186 np.array([22.48, 22.74, 8.54]), 

187 atol=TOLERANCE_ABSOLUTE_TESTS, 

188 ) 

189 

190 np.testing.assert_allclose( 

191 chromatic_adaptation_inverse_CMCCAT2000( 

192 np.array([17.90511171, 22.75299363, 3.79837384]), 

193 np.array([0.95045593, 1.00000000, 1.08905775]) * 100, 

194 np.array([1.09846607, 1.00000000, 0.35582280]) * 100, 

195 100, 

196 100, 

197 ), 

198 np.array([0.14222010, 0.23042768, 0.10495772]) * 100, 

199 atol=TOLERANCE_ABSOLUTE_TESTS, 

200 ) 

201 

202 np.testing.assert_allclose( 

203 chromatic_adaptation_inverse_CMCCAT2000( 

204 np.array([6.76564344, 5.86585763, 18.40577315]), 

205 np.array([0.95045593, 1.00000000, 1.08905775]) * 100, 

206 np.array([0.99144661, 1.00000000, 0.67315942]) * 100, 

207 100, 

208 100, 

209 ), 

210 np.array([0.07818780, 0.06157201, 0.28099326]) * 100, 

211 atol=TOLERANCE_ABSOLUTE_TESTS, 

212 ) 

213 

214 def test_n_dimensional_chromatic_adaptation_inverse_CMCCAT2000(self) -> None: 

215 """ 

216 Test :func:`colour.adaptation.cmccat2000.\ 

217chromatic_adaptation_inverse_CMCCAT2000` definition n-dimensional arrays 

218 support. 

219 """ 

220 

221 XYZ_c = np.array([19.52698326, 23.06833960, 24.97175229]) 

222 XYZ_w = np.array([111.15, 100.00, 35.20]) 

223 XYZ_wr = np.array([94.81, 100.00, 107.30]) 

224 L_A1 = 200 

225 L_A2 = 200 

226 XYZ = chromatic_adaptation_inverse_CMCCAT2000(XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2) 

227 

228 XYZ_c = np.tile(XYZ_c, (6, 1)) 

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

230 np.testing.assert_allclose( 

231 chromatic_adaptation_inverse_CMCCAT2000(XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2), 

232 XYZ, 

233 atol=TOLERANCE_ABSOLUTE_TESTS, 

234 ) 

235 

236 XYZ_w = np.tile(XYZ_w, (6, 1)) 

237 XYZ_wr = np.tile(XYZ_wr, (6, 1)) 

238 L_A1 = np.tile(L_A1, 6) 

239 L_A2 = np.tile(L_A2, 6) 

240 np.testing.assert_allclose( 

241 chromatic_adaptation_inverse_CMCCAT2000(XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2), 

242 XYZ, 

243 atol=TOLERANCE_ABSOLUTE_TESTS, 

244 ) 

245 

246 XYZ_c = np.reshape(XYZ_c, (2, 3, 3)) 

247 XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) 

248 XYZ_wr = np.reshape(XYZ_wr, (2, 3, 3)) 

249 L_A1 = np.reshape(L_A1, (2, 3)) 

250 L_A2 = np.reshape(L_A2, (2, 3)) 

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

252 np.testing.assert_allclose( 

253 chromatic_adaptation_inverse_CMCCAT2000(XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2), 

254 XYZ, 

255 atol=TOLERANCE_ABSOLUTE_TESTS, 

256 ) 

257 

258 def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self) -> None: 

259 """ 

260 Test :func:`colour.adaptation.cmccat2000.\ 

261chromatic_adaptation_inverse_CMCCAT2000` definition domain and range scale 

262 support. 

263 """ 

264 

265 XYZ_c = np.array([19.52698326, 23.06833960, 24.97175229]) 

266 XYZ_w = np.array([111.15, 100.00, 35.20]) 

267 XYZ_wr = np.array([94.81, 100.00, 107.30]) 

268 L_A1 = 200 

269 L_A2 = 200 

270 XYZ = chromatic_adaptation_inverse_CMCCAT2000(XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2) 

271 

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

273 for scale, factor in d_r: 

274 with domain_range_scale(scale): 

275 np.testing.assert_allclose( 

276 chromatic_adaptation_inverse_CMCCAT2000( 

277 XYZ_c * factor, 

278 XYZ_w * factor, 

279 XYZ_wr * factor, 

280 L_A1, 

281 L_A2, 

282 ), 

283 XYZ * factor, 

284 atol=TOLERANCE_ABSOLUTE_TESTS, 

285 ) 

286 

287 @ignore_numpy_errors 

288 def test_nan_chromatic_adaptation_inverse_CMCCAT2000(self) -> None: 

289 """ 

290 Test :func:`colour.adaptation.cmccat2000.\ 

291chromatic_adaptation_inverse_CMCCAT2000` definition nan support. 

292 """ 

293 

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

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

296 chromatic_adaptation_inverse_CMCCAT2000( 

297 cases, cases, cases, cases[..., 0], cases[..., 0] 

298 ) 

299 

300 

301class TestChromaticAdaptationCMCCAT2000: 

302 """ 

303 Define :func:`colour.adaptation.cmccat2000.\ 

304chromatic_adaptation_CMCCAT2000` wrapper definition unit tests methods. 

305 """ 

306 

307 def test_chromatic_adaptation_CMCCAT2000(self) -> None: 

308 """ 

309 Test :func:`colour.adaptation.cmccat2000.\ 

310chromatic_adaptation_CMCCAT2000` wrapper definition. 

311 """ 

312 

313 np.testing.assert_allclose( 

314 chromatic_adaptation_CMCCAT2000( 

315 np.array([0.14222010, 0.23042768, 0.10495772]) * 100, 

316 np.array([0.95045593, 1.00000000, 1.08905775]) * 100, 

317 np.array([1.09846607, 1.00000000, 0.35582280]) * 100, 

318 100, 

319 100, 

320 ), 

321 np.array([17.90511171, 22.75299363, 3.79837384]), 

322 atol=TOLERANCE_ABSOLUTE_TESTS, 

323 ) 

324 

325 np.testing.assert_allclose( 

326 chromatic_adaptation_CMCCAT2000( 

327 np.array([0.14222010, 0.23042768, 0.10495772]) * 100, 

328 np.array([0.95045593, 1.00000000, 1.08905775]) * 100, 

329 np.array([1.09846607, 1.00000000, 0.35582280]) * 100, 

330 100, 

331 100, 

332 direction="Forward", 

333 ), 

334 np.array([17.90511171, 22.75299363, 3.79837384]), 

335 atol=TOLERANCE_ABSOLUTE_TESTS, 

336 ) 

337 

338 np.testing.assert_allclose( 

339 chromatic_adaptation_CMCCAT2000( 

340 np.array([17.90511171, 22.75299363, 3.79837384]), 

341 np.array([0.95045593, 1.00000000, 1.08905775]) * 100, 

342 np.array([1.09846607, 1.00000000, 0.35582280]) * 100, 

343 100, 

344 100, 

345 direction="Inverse", 

346 ), 

347 np.array([0.14222010, 0.23042768, 0.10495772]) * 100, 

348 atol=TOLERANCE_ABSOLUTE_TESTS, 

349 )