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

117 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.yrg` 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 LMS_to_Yrg, XYZ_to_Yrg, Yrg_to_LMS, Yrg_to_XYZ 

11from colour.utilities import domain_range_scale, ignore_numpy_errors 

12 

13__author__ = "Colour Developers" 

14__copyright__ = "Copyright 2013 Colour Developers" 

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

16__maintainer__ = "Colour Developers" 

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

18__status__ = "Production" 

19 

20__all__ = [ 

21 "TestLMS_to_Yrg", 

22 "TestYrg_to_LMS", 

23 "TestXYZ_to_Yrg", 

24 "TestYrg_to_XYZ", 

25] 

26 

27 

28class TestLMS_to_Yrg: 

29 """ 

30 Define :func:`colour.models.yrg.TestLMS_to_Yrg` definition unit tests 

31 methods. 

32 """ 

33 

34 def test_LMS_to_Yrg(self) -> None: 

35 """Test :func:`colour.models.yrg.LMS_to_Yrg` definition.""" 

36 

37 np.testing.assert_allclose( 

38 LMS_to_Yrg(np.array([0.15639195, 0.06741689, 0.03281398])), 

39 np.array([0.13137801, 0.49037644, 0.37777391]), 

40 atol=TOLERANCE_ABSOLUTE_TESTS, 

41 ) 

42 

43 np.testing.assert_allclose( 

44 LMS_to_Yrg(np.array([0.23145723, 0.22601133, 0.05033211])), 

45 np.array([0.23840767, 0.20110504, 0.69668437]), 

46 atol=TOLERANCE_ABSOLUTE_TESTS, 

47 ) 

48 

49 np.testing.assert_allclose( 

50 LMS_to_Yrg(np.array([1.07423297, 0.91295620, 0.61375713])), 

51 np.array([1.05911888, 0.22010094, 0.53660290]), 

52 atol=TOLERANCE_ABSOLUTE_TESTS, 

53 ) 

54 

55 def test_n_dimensional_LMS_to_Yrg(self) -> None: 

56 """ 

57 Test :func:`colour.models.yrg.LMS_to_Yrg` definition n-dimensional 

58 support. 

59 """ 

60 

61 LMS = np.array([0.15639195, 0.06741689, 0.03281398]) 

62 Yrg = LMS_to_Yrg(LMS) 

63 

64 LMS = np.tile(LMS, (6, 1)) 

65 Yrg = np.tile(Yrg, (6, 1)) 

66 np.testing.assert_allclose(LMS_to_Yrg(LMS), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS) 

67 

68 LMS = np.reshape(LMS, (2, 3, 3)) 

69 Yrg = np.reshape(Yrg, (2, 3, 3)) 

70 np.testing.assert_allclose(LMS_to_Yrg(LMS), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS) 

71 

72 def test_domain_range_scale_LMS_to_Yrg(self) -> None: 

73 """ 

74 Test :func:`colour.models.yrg.LMS_to_Yrg` definition domain and range 

75 scale support. 

76 """ 

77 

78 LMS = np.array([0.15639195, 0.06741689, 0.03281398]) 

79 Yrg = LMS_to_Yrg(LMS) 

80 

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

82 for scale, factor in d_r: 

83 with domain_range_scale(scale): 

84 np.testing.assert_allclose( 

85 LMS_to_Yrg(LMS * factor), 

86 Yrg * factor, 

87 atol=TOLERANCE_ABSOLUTE_TESTS, 

88 ) 

89 

90 @ignore_numpy_errors 

91 def test_nan_LMS_to_Yrg(self) -> None: 

92 """Test :func:`colour.models.yrg.LMS_to_Yrg` definition nan support.""" 

93 

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

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

96 LMS_to_Yrg(cases) 

97 

98 

99class TestYrg_to_LMS: 

100 """ 

101 Define :func:`colour.models.yrg.Yrg_to_LMS` definition unit tests methods. 

102 """ 

103 

104 def test_Yrg_to_LMS(self) -> None: 

105 """Test :func:`colour.models.yrg.Yrg_to_LMS` definition.""" 

106 

107 np.testing.assert_allclose( 

108 Yrg_to_LMS(np.array([0.13137801, 0.49037644, 0.37777391])), 

109 np.array([0.15639195, 0.06741689, 0.03281398]), 

110 atol=1e-4, 

111 ) 

112 

113 np.testing.assert_allclose( 

114 Yrg_to_LMS(np.array([0.23840767, 0.20110504, 0.69668437])), 

115 np.array([0.23145723, 0.22601133, 0.05033211]), 

116 atol=1e-4, 

117 ) 

118 

119 np.testing.assert_allclose( 

120 Yrg_to_LMS(np.array([1.05911888, 0.22010094, 0.53660290])), 

121 np.array([1.07423297, 0.91295620, 0.61375713]), 

122 atol=1e-4, 

123 ) 

124 

125 def test_n_dimensional_Yrg_to_LMS(self) -> None: 

126 """ 

127 Test :func:`colour.models.yrg.Yrg_to_LMS` definition n-dimensional 

128 support. 

129 """ 

130 

131 Yrg = np.array([0.00535048, 0.00924302, 0.00526007]) 

132 LMS = Yrg_to_LMS(Yrg) 

133 

134 Yrg = np.tile(Yrg, (6, 1)) 

135 LMS = np.tile(LMS, (6, 1)) 

136 np.testing.assert_allclose(Yrg_to_LMS(Yrg), LMS, atol=TOLERANCE_ABSOLUTE_TESTS) 

137 

138 Yrg = np.reshape(Yrg, (2, 3, 3)) 

139 LMS = np.reshape(LMS, (2, 3, 3)) 

140 np.testing.assert_allclose(Yrg_to_LMS(Yrg), LMS, atol=TOLERANCE_ABSOLUTE_TESTS) 

141 

142 def test_domain_range_scale_Yrg_to_LMS(self) -> None: 

143 """ 

144 Test :func:`colour.models.yrg.Yrg_to_LMS` definition domain and range 

145 scale support. 

146 """ 

147 

148 Yrg = np.array([0.00535048, 0.00924302, 0.00526007]) 

149 LMS = Yrg_to_LMS(Yrg) 

150 

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

152 for scale, factor in d_r: 

153 with domain_range_scale(scale): 

154 np.testing.assert_allclose( 

155 Yrg_to_LMS(Yrg * factor), 

156 LMS * factor, 

157 atol=TOLERANCE_ABSOLUTE_TESTS, 

158 ) 

159 

160 @ignore_numpy_errors 

161 def test_nan_Yrg_to_LMS(self) -> None: 

162 """Test :func:`colour.models.yrg.Yrg_to_LMS` definition nan support.""" 

163 

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

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

166 Yrg_to_LMS(cases) 

167 

168 

169class TestXYZ_to_Yrg: 

170 """ 

171 Define :func:`colour.models.yrg.TestXYZ_to_Yrg` definition unit tests 

172 methods. 

173 """ 

174 

175 def test_XYZ_to_Yrg(self) -> None: 

176 """Test :func:`colour.models.yrg.XYZ_to_Yrg` definition.""" 

177 

178 np.testing.assert_allclose( 

179 XYZ_to_Yrg(np.array([0.20654008, 0.12197225, 0.05136952])), 

180 np.array([0.13137801, 0.49037645, 0.37777388]), 

181 atol=TOLERANCE_ABSOLUTE_TESTS, 

182 ) 

183 

184 np.testing.assert_allclose( 

185 XYZ_to_Yrg(np.array([0.14222010, 0.23042768, 0.10495772])), 

186 np.array([0.23840767, 0.20110503, 0.69668437]), 

187 atol=TOLERANCE_ABSOLUTE_TESTS, 

188 ) 

189 

190 np.testing.assert_allclose( 

191 XYZ_to_Yrg(np.array([0.96907232, 1.00000000, 1.12179215])), 

192 np.array([1.05911888, 0.22010094, 0.53660290]), 

193 atol=TOLERANCE_ABSOLUTE_TESTS, 

194 ) 

195 

196 def test_n_dimensional_XYZ_to_Yrg(self) -> None: 

197 """ 

198 Test :func:`colour.models.yrg.XYZ_to_Yrg` definition n-dimensional 

199 support. 

200 """ 

201 

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

203 Yrg = XYZ_to_Yrg(XYZ) 

204 

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

206 Yrg = np.tile(Yrg, (6, 1)) 

207 np.testing.assert_allclose(XYZ_to_Yrg(XYZ), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS) 

208 

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

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

211 np.testing.assert_allclose(XYZ_to_Yrg(XYZ), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS) 

212 

213 def test_domain_range_scale_XYZ_to_Yrg(self) -> None: 

214 """ 

215 Test :func:`colour.models.yrg.XYZ_to_Yrg` definition domain and range 

216 scale support. 

217 """ 

218 

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

220 Yrg = XYZ_to_Yrg(XYZ) 

221 

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

223 for scale, factor in d_r: 

224 with domain_range_scale(scale): 

225 np.testing.assert_allclose( 

226 XYZ_to_Yrg(XYZ * factor), 

227 Yrg * factor, 

228 atol=TOLERANCE_ABSOLUTE_TESTS, 

229 ) 

230 

231 @ignore_numpy_errors 

232 def test_nan_XYZ_to_Yrg(self) -> None: 

233 """Test :func:`colour.models.yrg.XYZ_to_Yrg` definition nan support.""" 

234 

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

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

237 XYZ_to_Yrg(cases) 

238 

239 

240class TestYrg_to_XYZ: 

241 """ 

242 Define :func:`colour.models.yrg.Yrg_to_XYZ` definition unit tests methods. 

243 """ 

244 

245 def test_Yrg_to_XYZ(self) -> None: 

246 """Test :func:`colour.models.yrg.Yrg_to_XYZ` definition.""" 

247 

248 np.testing.assert_allclose( 

249 Yrg_to_XYZ(np.array([0.13137801, 0.49037645, 0.37777388])), 

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

251 atol=1e-4, 

252 ) 

253 

254 np.testing.assert_allclose( 

255 Yrg_to_XYZ(np.array([0.23840767, 0.20110503, 0.69668437])), 

256 np.array([0.14222010, 0.23042768, 0.10495772]), 

257 atol=2e-4, 

258 ) 

259 

260 np.testing.assert_allclose( 

261 Yrg_to_XYZ(np.array([1.05911888, 0.22010094, 0.53660290])), 

262 np.array([0.96907232, 1.00000000, 1.12179215]), 

263 atol=2e-4, 

264 ) 

265 

266 def test_n_dimensional_Yrg_to_XYZ(self) -> None: 

267 """ 

268 Test :func:`colour.models.yrg.Yrg_to_XYZ` definition n-dimensional 

269 support. 

270 """ 

271 

272 Yrg = np.array([0.13137801, 0.49037645, 0.37777388]) 

273 XYZ = Yrg_to_XYZ(Yrg) 

274 

275 Yrg = np.tile(Yrg, (6, 1)) 

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

277 np.testing.assert_allclose(Yrg_to_XYZ(Yrg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS) 

278 

279 Yrg = np.reshape(Yrg, (2, 3, 3)) 

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

281 np.testing.assert_allclose(Yrg_to_XYZ(Yrg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS) 

282 

283 def test_domain_range_scale_Yrg_to_XYZ(self) -> None: 

284 """ 

285 Test :func:`colour.models.yrg.Yrg_to_XYZ` definition domain and range 

286 scale support. 

287 """ 

288 

289 Yrg = np.array([0.13137801, 0.49037645, 0.37777388]) 

290 XYZ = Yrg_to_XYZ(Yrg) 

291 

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

293 for scale, factor in d_r: 

294 with domain_range_scale(scale): 

295 np.testing.assert_allclose( 

296 Yrg_to_XYZ(Yrg * factor), 

297 XYZ * factor, 

298 atol=1e-4, 

299 ) 

300 

301 @ignore_numpy_errors 

302 def test_nan_Yrg_to_XYZ(self) -> None: 

303 """Test :func:`colour.models.yrg.Yrg_to_XYZ` definition nan support.""" 

304 

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

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

307 Yrg_to_XYZ(cases)