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

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

2

3 from __future__ import annotations

4

5 from itertools import product

6

7 import numpy as np

8

9 from colour.constants import TOLERANCE_ABSOLUTE_TESTS

10 from colour.models import XYZ_to_hdr_IPT, hdr_IPT_to_XYZ

11 from colour.models.hdr_ipt import exponent_hdr_IPT

12 from 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

28 class 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

128 class 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

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