Coverage for colour/models/tests/test_icacb.py: 100%

67 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-15 19:01 +1300

1"""Define the unit tests for the :mod:`colour.models.hunter_rdab` 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 ICaCb_to_XYZ, XYZ_to_ICaCb 

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

22 "TestICaCb_to_XYZ", 

23] 

24 

25 

26class TestXYZ_to_ICaCb: 

27 """ 

28 Define :func:`colour.models.icacb.XYZ_to_ICaCb` definition unit tests 

29 methods. 

30 """ 

31 

32 def test_XYZ_to_ICaCb(self) -> None: 

33 """Test :func:`colour.models.icacb.XYZ_to_ICaCb` definition.""" 

34 

35 np.testing.assert_allclose( 

36 XYZ_to_ICaCb(np.array([0.20654008, 0.12197225, 0.05136952])), 

37 np.array([0.06875297, 0.05753352, 0.02081548]), 

38 atol=TOLERANCE_ABSOLUTE_TESTS, 

39 ) 

40 

41 np.testing.assert_allclose( 

42 XYZ_to_ICaCb(np.array([0.14222010, 0.23042768, 0.10495772])), 

43 np.array([0.08666353, -0.02479011, 0.03099396]), 

44 atol=TOLERANCE_ABSOLUTE_TESTS, 

45 ) 

46 

47 np.testing.assert_allclose( 

48 XYZ_to_ICaCb(np.array([0.07818780, 0.06157201, 0.28099326])), 

49 np.array([0.05102472, -0.00965461, -0.05150706]), 

50 atol=TOLERANCE_ABSOLUTE_TESTS, 

51 ) 

52 

53 np.testing.assert_allclose( 

54 XYZ_to_ICaCb(np.array([0.00000000, 0.00000000, 1.00000000])), 

55 np.array([1702.0656419, 14738.00583456, 1239.66837927]), 

56 atol=TOLERANCE_ABSOLUTE_TESTS, 

57 ) 

58 

59 def test_n_dimensional_XYZ_to_ICaCb(self) -> None: 

60 """ 

61 Test :func:`colour.models.icacb.XYZ_to_ICaCb` definition 

62 n-dimensional support. 

63 """ 

64 

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

66 ICaCb = XYZ_to_ICaCb(XYZ) 

67 

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

69 ICaCb = np.tile(ICaCb, (6, 1)) 

70 np.testing.assert_allclose( 

71 XYZ_to_ICaCb(XYZ), ICaCb, atol=TOLERANCE_ABSOLUTE_TESTS 

72 ) 

73 

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

75 ICaCb = np.reshape(ICaCb, (2, 3, 3)) 

76 np.testing.assert_allclose( 

77 XYZ_to_ICaCb(XYZ), ICaCb, atol=TOLERANCE_ABSOLUTE_TESTS 

78 ) 

79 

80 def test_domain_range_scale_XYZ_to_ICaCb(self) -> None: 

81 """ 

82 Test :func:`colour.models.icacb.XYZ_to_ICaCb` definition domain and 

83 range scale support. 

84 """ 

85 

86 XYZ = np.array([0.07818780, 0.06157201, 0.28099326]) 

87 ICaCb = XYZ_to_ICaCb(XYZ) 

88 

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

90 for scale, factor in d_r: 

91 with domain_range_scale(scale): 

92 np.testing.assert_allclose( 

93 XYZ_to_ICaCb(XYZ * factor), 

94 ICaCb * factor, 

95 atol=TOLERANCE_ABSOLUTE_TESTS, 

96 ) 

97 

98 @ignore_numpy_errors 

99 def test_nan_XYZ_to_ICaCb(self) -> None: 

100 """Test :func:`colour.models.cie_lab.XYZ_to_Lab` definition nan support.""" 

101 

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

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

104 XYZ_to_ICaCb(cases) 

105 

106 

107class TestICaCb_to_XYZ: 

108 """Test :func:`colour.models.icacb.ICaCb_to_XYZ` definition.""" 

109 

110 def test_XYZ_to_ICaCb(self) -> None: 

111 """Test :func:`colour.models.icacb.ICaCb_to_XYZ` definition.""" 

112 

113 np.testing.assert_allclose( 

114 ICaCb_to_XYZ(np.array([0.06875297, 0.05753352, 0.02081548])), 

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

116 atol=TOLERANCE_ABSOLUTE_TESTS, 

117 ) 

118 

119 np.testing.assert_allclose( 

120 ICaCb_to_XYZ(np.array([0.08666353, -0.02479011, 0.03099396])), 

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

122 atol=TOLERANCE_ABSOLUTE_TESTS, 

123 ) 

124 

125 np.testing.assert_allclose( 

126 ICaCb_to_XYZ(np.array([0.05102472, -0.00965461, -0.05150706])), 

127 np.array([0.07818780, 0.06157201, 0.28099326]), 

128 atol=TOLERANCE_ABSOLUTE_TESTS, 

129 ) 

130 

131 np.testing.assert_allclose( 

132 ICaCb_to_XYZ(np.array([1702.0656419, 14738.00583456, 1239.66837927])), 

133 np.array([0.00000000, 0.00000000, 1.00000000]), 

134 atol=TOLERANCE_ABSOLUTE_TESTS, 

135 ) 

136 

137 def test_n_dimensional_ICaCb_to_XYZ(self) -> None: 

138 """ 

139 Test :func:`colour.models.icacb.ICaCb_to_XYZ` definition 

140 n-dimensional support. 

141 """ 

142 

143 ICaCb = np.array([0.06875297, 0.05753352, 0.02081548]) 

144 XYZ = ICaCb_to_XYZ(ICaCb) 

145 

146 ICaCb = np.tile(ICaCb, (6, 1)) 

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

148 np.testing.assert_allclose( 

149 ICaCb_to_XYZ(ICaCb), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS 

150 ) 

151 

152 ICaCb = np.reshape(ICaCb, (2, 3, 3)) 

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

154 np.testing.assert_allclose( 

155 ICaCb_to_XYZ(ICaCb), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS 

156 ) 

157 

158 def test_domain_range_scale_ICaCb_to_XYZ(self) -> None: 

159 """ 

160 Test :func:`colour.models.icacb.ICaCb_to_XYZ` definition domain and 

161 range scale support. 

162 """ 

163 

164 ICaCb = np.array([0.06875297, 0.05753352, 0.02081548]) 

165 XYZ = ICaCb_to_XYZ(ICaCb) 

166 

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

168 for scale, factor in d_r: 

169 with domain_range_scale(scale): 

170 np.testing.assert_allclose( 

171 ICaCb_to_XYZ(ICaCb * factor), 

172 XYZ * factor, 

173 atol=TOLERANCE_ABSOLUTE_TESTS, 

174 ) 

175 

176 @ignore_numpy_errors 

177 def test_nan_ICaCb_to_XYZ(self) -> None: 

178 """Test :func:`colour.models.cie_lab.XYZ_to_Lab` definition nan support.""" 

179 

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

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

182 ICaCb_to_XYZ(cases)