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

63 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.appearance.nayatani95` module.""" 

2 

3from __future__ import annotations 

4 

5from itertools import product 

6 

7import numpy as np 

8 

9from colour.appearance import XYZ_to_Nayatani95 

10from colour.constants import TOLERANCE_ABSOLUTE_TESTS 

11from colour.utilities import as_float_array, 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_Nayatani95", 

22] 

23 

24 

25class TestXYZ_to_Nayatani95: 

26 """ 

27 Define :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition 

28 unit tests methods. 

29 """ 

30 

31 def test_XYZ_to_Nayatani95(self) -> None: 

32 """ 

33 Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` 

34 definition. 

35 

36 Notes 

37 ----- 

38 - The test values have been generated from data of the following file 

39 by *Fairchild (2013)*: 

40 http://rit-mcsl.org/fairchild//files/AppModEx.xls 

41 """ 

42 

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

44 XYZ_n = np.array([95.05, 100.00, 108.88]) 

45 Y_o = 20 

46 E_o = 5000 

47 E_or = 1000 

48 np.testing.assert_allclose( 

49 XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), 

50 np.array([50, 0.01, 257.5, 0.01, 62.6, 0.02, np.nan, np.nan, 50]), 

51 atol=0.05, 

52 ) 

53 

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

55 E_o = 500 

56 np.testing.assert_allclose( 

57 XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), 

58 np.array([73, 48.3, 21.6, 37.1, 67.3, 42.9, np.nan, np.nan, 75.9]), 

59 atol=0.05, 

60 ) 

61 

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

63 XYZ_n = np.array([109.85, 100.00, 35.58]) 

64 E_o = 5000 

65 np.testing.assert_allclose( 

66 XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), 

67 np.array([24.5, 49.3, 190.6, 81.3, 37.5, 62.1, np.nan, np.nan, 29.7]), 

68 atol=0.05, 

69 ) 

70 

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

72 E_o = 500 

73 np.testing.assert_allclose( 

74 XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), 

75 np.array([49.4, 39.9, 236.3, 40.2, 44.2, 35.8, np.nan, np.nan, 49.4]), 

76 atol=0.05, 

77 ) 

78 

79 def test_n_dimensional_XYZ_to_Nayatani95(self) -> None: 

80 """ 

81 Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition 

82 n-dimensional support. 

83 """ 

84 

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

86 XYZ_n = np.array([95.05, 100.00, 108.88]) 

87 Y_o = 20 

88 E_o = 5000 

89 E_or = 1000 

90 specification = XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or) 

91 

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

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

94 np.testing.assert_allclose( 

95 XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), 

96 specification, 

97 atol=TOLERANCE_ABSOLUTE_TESTS, 

98 ) 

99 

100 XYZ_n = np.tile(XYZ_n, (6, 1)) 

101 np.testing.assert_allclose( 

102 XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), 

103 specification, 

104 atol=TOLERANCE_ABSOLUTE_TESTS, 

105 ) 

106 

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

108 XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) 

109 specification = np.reshape(specification, (2, 3, 9)) 

110 np.testing.assert_allclose( 

111 XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), 

112 specification, 

113 atol=TOLERANCE_ABSOLUTE_TESTS, 

114 ) 

115 

116 def test_domain_range_scale_XYZ_to_Nayatani95(self) -> None: 

117 """ 

118 Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition 

119 domain and range scale support. 

120 """ 

121 

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

123 XYZ_n = np.array([95.05, 100.00, 108.88]) 

124 Y_o = 20.0 

125 E_o = 5000.0 

126 E_or = 1000.0 

127 specification = XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or) 

128 

129 d_r = ( 

130 ("reference", 1, 1), 

131 ("1", 0.01, np.array([1, 1, 1 / 360, 1, 1, 1, np.nan, np.nan, 1])), 

132 ( 

133 "100", 

134 1, 

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

136 ), 

137 ) 

138 for scale, factor_a, factor_b in d_r: 

139 with domain_range_scale(scale): 

140 np.testing.assert_allclose( 

141 XYZ_to_Nayatani95(XYZ * factor_a, XYZ_n * factor_a, Y_o, E_o, E_or), 

142 as_float_array(specification) * factor_b, 

143 atol=TOLERANCE_ABSOLUTE_TESTS, 

144 ) 

145 

146 @ignore_numpy_errors 

147 def test_nan_XYZ_to_Nayatani95(self) -> None: 

148 """ 

149 Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition 

150 nan support. 

151 """ 

152 

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

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

155 XYZ_to_Nayatani95(cases, cases, cases[..., 0], cases[..., 0], cases[..., 0])