Coverage for appearance/tests/test_kim2009.py: 100%

1"""Define the unit tests for the :mod:`colour.appearance.kim2009` module."""

2

3 from __future__ import annotations

4

5 from itertools import product

6

7 import numpy as np

8 import pytest

9

10 from colour.appearance import (

11 MEDIA_PARAMETERS_KIM2009,

12 VIEWING_CONDITIONS_KIM2009,

13 CAM_Specification_Kim2009,

14 InductionFactors_Kim2009,

15 Kim2009_to_XYZ,

16 MediaParameters_Kim2009,

17 XYZ_to_Kim2009,

18)

19 from colour.constants import TOLERANCE_ABSOLUTE_TESTS

20 from colour.utilities import (

21 as_float_array,

22 domain_range_scale,

23 ignore_numpy_errors,

24 tsplit,

25)

26

27 __author__ = "Colour Developers"

28 __copyright__ = "Copyright 2013 Colour Developers"

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

30 __maintainer__ = "Colour Developers"

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

32 __status__ = "Production"

33

34 __all__ = [

35 "TestXYZ_to_Kim2009",

36 "TestKim2009_to_XYZ",

37]

38

39

40 class TestXYZ_to_Kim2009:

41 """

42 Define :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition unit

43 tests methods.

44 """

45

46 def test_XYZ_to_Kim2009(self) -> None:

47 """Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition."""

48

49 XYZ = np.array([19.01, 20.00, 21.78])

50 XYZ_w = np.array([95.05, 100.00, 108.88])

51 L_a = 318.31

52 media = MEDIA_PARAMETERS_KIM2009["CRT Displays"]

53 surround = VIEWING_CONDITIONS_KIM2009["Average"]

54 np.testing.assert_allclose(

55 XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround),

56 np.array(

57 [

58 28.86190898,

59 0.55924559,

60 219.04806678,

61 9.38377973,

62 52.71388839,

63 0.46417384,

64 278.06028246,

65 np.nan,

66 ]

67 ),

68 atol=TOLERANCE_ABSOLUTE_TESTS,

69 )

70

71 XYZ = np.array([57.06, 43.06, 31.96])

72 L_a = 31.83

73 np.testing.assert_allclose(

74 XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround),

75 np.array(

76 [

77 70.15940419,

78 57.89295872,

79 21.27017200,

80 61.23630434,

81 128.14034598,

82 48.05115573,

83 1.41841443,

84 np.nan,

85 ]

86 ),

87 atol=TOLERANCE_ABSOLUTE_TESTS,

88 )

89

90 XYZ = np.array([3.53, 6.56, 2.14])

91 XYZ_w = np.array([109.85, 100.00, 35.58])

92 L_a = 318.31

93 np.testing.assert_allclose(

94 XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround),

95 np.array(

96 [

97 -4.83430022,

98 37.42013921,

99 177.12166057,

100 np.nan,

101 -8.82944930,

102 31.05871555,

103 220.36270343,

104 np.nan,

105 ]

106 ),

107 atol=TOLERANCE_ABSOLUTE_TESTS,

108 )

109

110 XYZ = np.array([19.01, 20.00, 21.78])

111 L_a = 31.83

112 np.testing.assert_allclose(

113 XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround),

114 np.array(

115 [

116 47.20460719,

117 56.35723637,

118 241.04877377,

119 73.65830083,

120 86.21530880,

121 46.77650619,

122 301.77516676,

123 np.nan,

124 ]

125 ),

126 atol=TOLERANCE_ABSOLUTE_TESTS,

127 )

128

129 def test_n_dimensional_XYZ_to_Kim2009(self) -> None:

130 """

131 Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition

132 n-dimensional support.

133 """

134

135 XYZ = np.array([19.01, 20.00, 21.78])

136 XYZ_w = np.array([95.05, 100.00, 108.88])

137 L_a = 318.31

138 media = MEDIA_PARAMETERS_KIM2009["CRT Displays"]

139 surround = VIEWING_CONDITIONS_KIM2009["Average"]

140 specification = XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround)

141

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

143 specification = np.tile(specification, (6, 1))

144 np.testing.assert_allclose(

145 XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround),

146 specification,

147 atol=TOLERANCE_ABSOLUTE_TESTS,

148 )

149

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

151 np.testing.assert_allclose(

152 XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround),

153 specification,

154 atol=TOLERANCE_ABSOLUTE_TESTS,

155 )

156

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

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

159 specification = np.reshape(specification, (2, 3, 8))

160 np.testing.assert_allclose(

161 XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround),

162 specification,

163 atol=TOLERANCE_ABSOLUTE_TESTS,

164 )

165

166 @ignore_numpy_errors

167 def test_domain_range_scale_XYZ_to_Kim2009(self) -> None:

168 """

169 Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition

170 domain and range scale support.

171 """

172

173 XYZ = np.array([19.01, 20.00, 21.78])

174 XYZ_w = np.array([95.05, 100.00, 108.88])

175 L_a = 318.31

176 media = MEDIA_PARAMETERS_KIM2009["CRT Displays"]

177 surround = VIEWING_CONDITIONS_KIM2009["Average"]

178 specification = XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround)

179

180 d_r = (

181 ("reference", 1, 1),

182 (

183 "1",

184 0.01,

185 np.array(

186 [

187 1 / 100,

188 1 / 100,

189 1 / 360,

190 1 / 100,

191 1 / 100,

192 1 / 100,

193 1 / 400,

194 np.nan,

195 ]

196 ),

197 ),

198 (

199 "100",

200 1,

201 np.array([1, 1, 100 / 360, 1, 1, 1, 100 / 400, np.nan]),

202 ),

203 )

204 for scale, factor_a, factor_b in d_r:

205 with domain_range_scale(scale):

206 np.testing.assert_allclose(

207 XYZ_to_Kim2009(

208 XYZ * factor_a, XYZ_w * factor_a, L_a, media, surround

209 ),

210 as_float_array(specification) * factor_b,

211 atol=TOLERANCE_ABSOLUTE_TESTS,

212 )

213

214 @ignore_numpy_errors

215 def test_nan_XYZ_to_Kim2009(self) -> None:

216 """

217 Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition

218 nan support.

219 """

220

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

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

223 media = MediaParameters_Kim2009(cases[0, 0])

224 surround = InductionFactors_Kim2009(cases[0, 0], cases[0, 0], cases[0, 0])

225 XYZ_to_Kim2009(cases, cases, cases[0, 0], media, surround)

226

227

228 class TestKim2009_to_XYZ:

229 """

230 Define :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition unit

231 tests methods.

232 """

233

234 def test_Kim2009_to_XYZ(self) -> None:

235 """Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition."""

236

237 specification = CAM_Specification_Kim2009(

238 28.86190898,

239 0.55924559,

240 219.04806678,

241 9.38377973,

242 52.71388839,

243 0.46417384,

244 278.06028246,

245 np.nan,

246 )

247 XYZ_w = np.array([95.05, 100.00, 108.88])

248 L_a = 318.31

249 media = MEDIA_PARAMETERS_KIM2009["CRT Displays"]

250 surround = VIEWING_CONDITIONS_KIM2009["Average"]

251 np.testing.assert_allclose(

252 Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround),

253 np.array([19.01, 20.00, 21.78]),

254 atol=0.01,

255 )

256

257 specification = CAM_Specification_Kim2009(

258 70.15940419,

259 57.89295872,

260 21.27017200,

261 61.23630434,

262 128.14034598,

263 48.05115573,

264 1.41841443,

265 np.nan,

266 )

267 L_a = 31.83

268 np.testing.assert_allclose(

269 Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround),

270 np.array([57.06, 43.06, 31.96]),

271 atol=0.01,

272 )

273

274 specification = CAM_Specification_Kim2009(

275 -4.83430022,

276 37.42013921,

277 177.12166057,

278 np.nan,

279 -8.82944930,

280 31.05871555,

281 220.36270343,

282 np.nan,

283 )

284 XYZ_w = np.array([109.85, 100.00, 35.58])

285 L_a = 318.31

286 np.testing.assert_allclose(

287 Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround),

288 np.array([3.53, 6.56, 2.14]),

289 atol=0.01,

290 )

291

292 specification = CAM_Specification_Kim2009(

293 47.20460719,

294 56.35723637,

295 241.04877377,

296 73.65830083,

297 86.21530880,

298 46.77650619,

299 301.77516676,

300 np.nan,

301 )

302 L_a = 31.83

303 np.testing.assert_allclose(

304 Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround),

305 np.array([19.01, 20.00, 21.78]),

306 atol=0.01,

307 )

308

309 def test_n_dimensional_Kim2009_to_XYZ(self) -> None:

310 """

311 Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition

312 n-dimensional support.

313 """

314

315 XYZ = np.array([19.01, 20.00, 21.78])

316 XYZ_w = np.array([95.05, 100.00, 108.88])

317 L_a = 318.31

318 media = MEDIA_PARAMETERS_KIM2009["CRT Displays"]

319 surround = VIEWING_CONDITIONS_KIM2009["Average"]

320 specification = XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround)

321 XYZ = Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround)

322

323 specification = CAM_Specification_Kim2009(

324 *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist()

325 )

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

327 np.testing.assert_allclose(

328 Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround),

329 XYZ,

330 atol=TOLERANCE_ABSOLUTE_TESTS,

331 )

332

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

334 np.testing.assert_allclose(

335 Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround),

336 XYZ,

337 atol=TOLERANCE_ABSOLUTE_TESTS,

338 )

339

340 specification = CAM_Specification_Kim2009(

341 *tsplit(np.reshape(specification, (2, 3, 8))).tolist()

342 )

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

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

345 np.testing.assert_allclose(

346 Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround),

347 XYZ,

348 atol=TOLERANCE_ABSOLUTE_TESTS,

349 )

350

351 @ignore_numpy_errors

352 def test_domain_range_scale_Kim2009_to_XYZ(self) -> None:

353 """

354 Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition

355 domain and range scale support.

356 """

357

358 XYZ_i = np.array([19.01, 20.00, 21.78])

359 XYZ_w = np.array([95.05, 100.00, 108.88])

360 L_a = 318.31

361 media = MEDIA_PARAMETERS_KIM2009["CRT Displays"]

362 surround = VIEWING_CONDITIONS_KIM2009["Average"]

363 specification = XYZ_to_Kim2009(XYZ_i, XYZ_w, L_a, media, surround)

364 XYZ = Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround)

365

366 d_r = (

367 ("reference", 1, 1),

368 (

369 "1",

370 np.array(

371 [

372 1 / 100,

373 1 / 100,

374 1 / 360,

375 1 / 100,

376 1 / 100,

377 1 / 100,

378 1 / 400,

379 np.nan,

380 ]

381 ),

382 0.01,

383 ),

384 (

385 "100",

386 np.array([1, 1, 100 / 360, 1, 1, 1, 100 / 400, np.nan]),

387 1,

388 ),

389 )

390 for scale, factor_a, factor_b in d_r:

391 with domain_range_scale(scale):

392 np.testing.assert_allclose(

393 Kim2009_to_XYZ(

394 specification * factor_a,

395 XYZ_w * factor_b,

396 L_a,

397 media,

398 surround,

399 ),

400 XYZ * factor_b,

401 atol=TOLERANCE_ABSOLUTE_TESTS,

402 )

403

404 @ignore_numpy_errors

405 def test_raise_exception_Kim2009_to_XYZ(self) -> None:

406 """

407 Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition

408 raised exception.

409 """

410

411 pytest.raises(

412 ValueError,

413 Kim2009_to_XYZ,

414 CAM_Specification_Kim2009(

415 41.731091132513917,

416 None,

417 219.04843265831178,

418 ),

419 np.array([95.05, 100.00, 108.88]),

420 318.31,

421 20.0,

422 VIEWING_CONDITIONS_KIM2009["Average"],

423 )

424

425 @ignore_numpy_errors

426 def test_nan_Kim2009_to_XYZ(self) -> None:

427 """

428 Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition nan

429 support.

430 """

431

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

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

434 media = MediaParameters_Kim2009(cases[0, 0])

435 surround = InductionFactors_Kim2009(cases[0, 0], cases[0, 0], cases[0, 0])

436 Kim2009_to_XYZ(

437 CAM_Specification_Kim2009(

438 cases[..., 0], cases[..., 0], cases[..., 0], M=50

439 ),

440 cases,

441 cases[0, 0],

442 media,

443 surround,

444 )