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

81 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.cie_uvw` 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 UVW_to_XYZ, XYZ_to_UVW 

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

22 "TestUVW_to_XYZ", 

23] 

24 

25 

26class TestXYZ_to_UVW: 

27 """ 

28 Define :func:`colour.models.cie_uvw.XYZ_to_UVW` definition unit tests 

29 methods. 

30 """ 

31 

32 def test_XYZ_to_UVW(self) -> None: 

33 """Test :func:`colour.models.cie_uvw.XYZ_to_UVW` definition.""" 

34 

35 np.testing.assert_allclose( 

36 XYZ_to_UVW(np.array([0.20654008, 0.12197225, 0.05136952]) * 100), 

37 np.array([94.55035725, 11.55536523, 40.54757405]), 

38 atol=TOLERANCE_ABSOLUTE_TESTS, 

39 ) 

40 

41 np.testing.assert_allclose( 

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

43 np.array([-36.92762376, 28.90425105, 54.14071478]), 

44 atol=TOLERANCE_ABSOLUTE_TESTS, 

45 ) 

46 

47 np.testing.assert_allclose( 

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

49 np.array([-10.60111550, -41.94580000, 28.82134002]), 

50 atol=TOLERANCE_ABSOLUTE_TESTS, 

51 ) 

52 

53 np.testing.assert_allclose( 

54 XYZ_to_UVW( 

55 np.array([0.20654008, 0.12197225, 0.05136952]) * 100, 

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

57 ), 

58 np.array([63.90676310, -8.11466183, 40.54757405]), 

59 atol=TOLERANCE_ABSOLUTE_TESTS, 

60 ) 

61 

62 np.testing.assert_allclose( 

63 XYZ_to_UVW( 

64 np.array([0.20654008, 0.12197225, 0.05136952]) * 100, 

65 np.array([0.34570, 0.35850]), 

66 ), 

67 np.array([88.56798946, 4.61154385, 40.54757405]), 

68 atol=TOLERANCE_ABSOLUTE_TESTS, 

69 ) 

70 

71 np.testing.assert_allclose( 

72 XYZ_to_UVW( 

73 np.array([0.20654008, 0.12197225, 0.05136952]) * 100, 

74 np.array([0.34570, 0.35850, 1.00000]), 

75 ), 

76 np.array([88.56798946, 4.61154385, 40.54757405]), 

77 atol=TOLERANCE_ABSOLUTE_TESTS, 

78 ) 

79 

80 def test_n_dimensional_XYZ_to_UVW(self) -> None: 

81 """ 

82 Test :func:`colour.models.cie_uvw.XYZ_to_UVW` definition n-dimensional 

83 support. 

84 """ 

85 

86 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) * 100 

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

88 UVW = XYZ_to_UVW(XYZ, illuminant) 

89 

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

91 UVW = np.tile(UVW, (6, 1)) 

92 np.testing.assert_allclose( 

93 XYZ_to_UVW(XYZ, illuminant), UVW, atol=TOLERANCE_ABSOLUTE_TESTS 

94 ) 

95 

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

97 np.testing.assert_allclose( 

98 XYZ_to_UVW(XYZ, illuminant), UVW, atol=TOLERANCE_ABSOLUTE_TESTS 

99 ) 

100 

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

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

103 UVW = np.reshape(UVW, (2, 3, 3)) 

104 np.testing.assert_allclose( 

105 XYZ_to_UVW(XYZ, illuminant), UVW, atol=TOLERANCE_ABSOLUTE_TESTS 

106 ) 

107 

108 def test_domain_range_scale_XYZ_to_UVW(self) -> None: 

109 """ 

110 Test :func:`colour.models.cie_uvw.XYZ_to_UVW` definition domain and 

111 range scale support. 

112 """ 

113 

114 XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) * 100 

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

116 UVW = XYZ_to_UVW(XYZ, illuminant) 

117 

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

119 for scale, factor in d_r: 

120 with domain_range_scale(scale): 

121 np.testing.assert_allclose( 

122 XYZ_to_UVW(XYZ * factor, illuminant), 

123 UVW * factor, 

124 atol=TOLERANCE_ABSOLUTE_TESTS, 

125 ) 

126 

127 @ignore_numpy_errors 

128 def test_nan_XYZ_to_UVW(self) -> None: 

129 """Test :func:`colour.models.cie_uvw.XYZ_to_UVW` definition nan support.""" 

130 

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

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

133 XYZ_to_UVW(cases, cases[..., 0:2]) 

134 

135 

136class TestUVW_to_XYZ: 

137 """ 

138 Define :func:`colour.models.cie_uvw.UVW_to_XYZ` definition unit tests 

139 methods. 

140 """ 

141 

142 def test_UVW_to_XYZ(self) -> None: 

143 """Test :func:`colour.models.cie_uvw.UVW_to_XYZ` definition.""" 

144 

145 np.testing.assert_allclose( 

146 UVW_to_XYZ(np.array([94.55035725, 11.55536523, 40.54757405])), 

147 np.array([0.20654008, 0.12197225, 0.05136952]) * 100, 

148 atol=TOLERANCE_ABSOLUTE_TESTS, 

149 ) 

150 

151 np.testing.assert_allclose( 

152 UVW_to_XYZ(np.array([-36.92762376, 28.90425105, 54.14071478])), 

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

154 atol=TOLERANCE_ABSOLUTE_TESTS, 

155 ) 

156 

157 np.testing.assert_allclose( 

158 UVW_to_XYZ(np.array([-10.60111550, -41.94580000, 28.82134002])), 

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

160 atol=TOLERANCE_ABSOLUTE_TESTS, 

161 ) 

162 

163 np.testing.assert_allclose( 

164 UVW_to_XYZ( 

165 np.array([63.90676310, -8.11466183, 40.54757405]), 

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

167 ), 

168 np.array([0.20654008, 0.12197225, 0.05136952]) * 100, 

169 atol=TOLERANCE_ABSOLUTE_TESTS, 

170 ) 

171 

172 np.testing.assert_allclose( 

173 UVW_to_XYZ( 

174 np.array([88.56798946, 4.61154385, 40.54757405]), 

175 np.array([0.34570, 0.35850]), 

176 ), 

177 np.array([0.20654008, 0.12197225, 0.05136952]) * 100, 

178 atol=TOLERANCE_ABSOLUTE_TESTS, 

179 ) 

180 

181 np.testing.assert_allclose( 

182 UVW_to_XYZ( 

183 np.array([88.56798946, 4.61154385, 40.54757405]), 

184 np.array([0.34570, 0.35850, 1.00000]), 

185 ), 

186 np.array([0.20654008, 0.12197225, 0.05136952]) * 100, 

187 atol=TOLERANCE_ABSOLUTE_TESTS, 

188 ) 

189 

190 def test_n_dimensional_UVW_to_XYZ(self) -> None: 

191 """ 

192 Test :func:`colour.models.cie_uvw.UVW_to_XYZ` definition n-dimensional 

193 support. 

194 """ 

195 

196 UVW = np.array([94.55035725, 11.55536523, 40.54757405]) 

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

198 XYZ = UVW_to_XYZ(UVW, illuminant) 

199 

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

201 UVW = np.tile(UVW, (6, 1)) 

202 np.testing.assert_allclose( 

203 UVW_to_XYZ(UVW, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS 

204 ) 

205 

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

207 np.testing.assert_allclose( 

208 UVW_to_XYZ(UVW, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS 

209 ) 

210 

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

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

213 UVW = np.reshape(UVW, (2, 3, 3)) 

214 np.testing.assert_allclose( 

215 UVW_to_XYZ(UVW, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS 

216 ) 

217 

218 def test_domain_range_scale_UVW_to_XYZ(self) -> None: 

219 """ 

220 Test :func:`colour.models.cie_uvw.UVW_to_XYZ` definition domain and 

221 range scale support. 

222 """ 

223 

224 UVW = np.array([94.55035725, 11.55536523, 40.54757405]) 

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

226 XYZ = UVW_to_XYZ(UVW, illuminant) 

227 

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

229 for scale, factor in d_r: 

230 with domain_range_scale(scale): 

231 np.testing.assert_allclose( 

232 UVW_to_XYZ(UVW * factor, illuminant), 

233 XYZ * factor, 

234 atol=TOLERANCE_ABSOLUTE_TESTS, 

235 ) 

236 

237 @ignore_numpy_errors 

238 def test_nan_UVW_to_XYZ(self) -> None: 

239 """Test :func:`colour.models.cie_uvw.UVW_to_XYZ` definition nan support.""" 

240 

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

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

243 UVW_to_XYZ(cases, cases[..., 0:2])