Coverage for io/luts/tests/test_cinespace_csp.py: 100%

1"""Define the unit tests for the :mod:`colour.io.luts.cinespace_csp` module."""

2

3 from __future__ import annotations

4

5 import os

6 import shutil

7 import tempfile

8

9 import numpy as np

10 import pytest

11

12 from colour.constants import TOLERANCE_ABSOLUTE_TESTS

13 from colour.hints import cast

14 from colour.io import (

15 LUT1D,

16 LUT3D,

17 LUT3x1D,

18 LUTSequence,

19 read_LUT_Cinespace,

20 write_LUT_Cinespace,

21)

22 from colour.utilities import tstack

23

24 __author__ = "Colour Developers"

25 __copyright__ = "Copyright 2013 Colour Developers"

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

27 __maintainer__ = "Colour Developers"

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

29 __status__ = "Production"

30

31 __all__ = [

32 "ROOT_LUTS",

33 "TestReadLUTCinespace",

34 "TestWriteLUTCinespace",

35]

36

37 ROOT_LUTS: str = os.path.join(os.path.dirname(__file__), "resources", "cinespace")

38

39

40 class TestReadLUTCinespace:

41 """

42 Define :func:`colour.io.luts.cinespace_csp.read_LUT_Cinespace` definition

43 unit tests methods.

44 """

45

46 def test_read_LUT_Cinespace(self) -> None:

47 """

48 Test :func:`colour.io.luts.cinespace_csp.read_LUT_Cinespace`

49 definition.

50 """

51

52 LUT_1 = cast(

53 "LUT3x1D",

54 read_LUT_Cinespace(os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.csp")),

55 )

56

57 np.testing.assert_allclose(

58 LUT_1.table,

59 np.array(

60 [

61 [4.88300000e-04, 4.88300000e-04, 4.88300000e-04],

62 [7.71400000e-04, 7.71400000e-04, 7.71400000e-04],

63 [1.21900000e-03, 1.21900000e-03, 1.21900000e-03],

64 [1.92600000e-03, 1.92600000e-03, 1.92600000e-03],

65 [3.04400000e-03, 3.04400000e-03, 3.04400000e-03],

66 [4.80900000e-03, 4.80900000e-03, 4.80900000e-03],

67 [7.59900000e-03, 7.59900000e-03, 7.59900000e-03],

68 [1.20100000e-02, 1.20100000e-02, 1.20100000e-02],

69 [1.89700000e-02, 1.89700000e-02, 1.89700000e-02],

70 [2.99800000e-02, 2.99800000e-02, 2.99800000e-02],

71 [4.73700000e-02, 4.73700000e-02, 4.73700000e-02],

72 [7.48400000e-02, 7.48400000e-02, 7.48400000e-02],

73 [1.18300000e-01, 1.18300000e-01, 1.18300000e-01],

74 [1.86900000e-01, 1.86900000e-01, 1.86900000e-01],

75 [2.95200000e-01, 2.95200000e-01, 2.95200000e-01],

76 [4.66500000e-01, 4.66500000e-01, 4.66500000e-01],

77 [7.37100000e-01, 7.37100000e-01, 7.37100000e-01],

78 [1.16500000e00, 1.16500000e00, 1.16500000e00],

79 [1.84000000e00, 1.84000000e00, 1.84000000e00],

80 [2.90800000e00, 2.90800000e00, 2.90800000e00],

81 [4.59500000e00, 4.59500000e00, 4.59500000e00],

82 [7.26000000e00, 7.26000000e00, 7.26000000e00],

83 [1.14700000e01, 1.14700000e01, 1.14700000e01],

84 [1.81300000e01, 1.81300000e01, 1.81300000e01],

85 [2.86400000e01, 2.86400000e01, 2.86400000e01],

86 [4.52500000e01, 4.52500000e01, 4.52500000e01],

87 [7.15100000e01, 7.15100000e01, 7.15100000e01],

88 [1.13000000e02, 1.13000000e02, 1.13000000e02],

89 [1.78500000e02, 1.78500000e02, 1.78500000e02],

90 [2.82100000e02, 2.82100000e02, 2.82100000e02],

91 [4.45700000e02, 4.45700000e02, 4.45700000e02],

92 [7.04300000e02, 7.04300000e02, 7.04300000e02],

93 ]

94 ),

95 atol=TOLERANCE_ABSOLUTE_TESTS,

96 )

97 assert LUT_1.name == "ACES Proxy 10 to ACES"

98 assert LUT_1.dimensions == 2

99 np.testing.assert_array_equal(LUT_1.domain, np.array([[0, 0, 0], [1, 1, 1]]))

100 assert LUT_1.size == 32

101 assert LUT_1.comments == []

102

103 LUT_2 = cast("LUT3x1D", read_LUT_Cinespace(os.path.join(ROOT_LUTS, "Demo.csp")))

104 assert LUT_2.comments == ["Comments are ignored by most parsers"]

105 np.testing.assert_array_equal(LUT_2.domain, np.array([[0, 0, 0], [1, 2, 3]]))

106

107 LUT_3 = cast(

108 "LUT3D",

109 read_LUT_Cinespace(os.path.join(ROOT_LUTS, "Three_Dimensional_Table.csp")),

110 )

111 assert LUT_3.dimensions == 3

112 assert LUT_3.size == 2

113

114 LUT_4 = cast(

115 "LUTSequence",

116 read_LUT_Cinespace(os.path.join(ROOT_LUTS, "Explicit_Domain.csp")),

117 )

118 assert LUT_4[0].is_domain_explicit() is True

119 assert LUT_4[1].table.shape == (2, 3, 4, 3)

120

121 LUT_5 = cast(

122 "LUTSequence",

123 read_LUT_Cinespace(

124 os.path.join(ROOT_LUTS, "Uncommon_3x1D_With_Pre_Lut.csp")

125 ),

126 )

127 assert isinstance(LUT_5[0], LUT3x1D)

128 assert isinstance(LUT_5[1], LUT3x1D)

129

130

131 class TestWriteLUTCinespace:

132 """

133 Define :func:`colour.io.luts.cinespace_csp.write_LUT_Cinespace` definition

134 unit tests methods.

135 """

136

137 def setup_method(self) -> None:

138 """Initialise the common tests attributes."""

139

140 self._temporary_directory = tempfile.mkdtemp()

141

142 def teardown_method(self) -> None:

143 """After tests actions."""

144

145 shutil.rmtree(self._temporary_directory)

146

147 def test_write_LUT_Cinespace(self) -> None:

148 """

149 Test :func:`colour.io.luts.cinespace_csp.write_LUT_Cinespace`

150 definition.

151 """

152

153 LUT_1_r = read_LUT_Cinespace(

154 os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.csp")

155 )

156 write_LUT_Cinespace(

157 LUT_1_r,

158 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.csp"),

159 )

160 LUT_1_t = read_LUT_Cinespace(

161 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.csp")

162 )

163 assert LUT_1_r == LUT_1_t

164 assert LUT_1_r == LUT_1_t

165

166 LUT_2_r = cast(

167 "LUT3x1D", read_LUT_Cinespace(os.path.join(ROOT_LUTS, "Demo.csp"))

168 )

169 write_LUT_Cinespace(

170 LUT_2_r, os.path.join(self._temporary_directory, "Demo.csp")

171 )

172 LUT_2_t = cast(

173 "LUT3x1D",

174 read_LUT_Cinespace(os.path.join(self._temporary_directory, "Demo.csp")),

175 )

176 assert LUT_2_r == LUT_2_t

177 assert LUT_2_r.comments == LUT_2_t.comments

178

179 LUT_3_r = cast(

180 "LUT3D",

181 read_LUT_Cinespace(os.path.join(ROOT_LUTS, "Three_Dimensional_Table.csp")),

182 )

183 write_LUT_Cinespace(

184 LUT_3_r,

185 os.path.join(self._temporary_directory, "Three_Dimensional_Table.csp"),

186 )

187 LUT_3_t = cast(

188 "LUT3D",

189 read_LUT_Cinespace(

190 os.path.join(self._temporary_directory, "Three_Dimensional_Table.csp")

191 ),

192 )

193 assert LUT_3_r == LUT_3_t

194

195 domain = tstack(

196 (

197 np.array([0.0, 0.1, 0.2, 0.4, 0.8, 1.2]),

198 np.array([-0.1, 0.5, 1.0, np.nan, np.nan, np.nan]),

199 np.array([-1.0, -0.5, 0.0, 0.5, 1.0, np.nan]),

200 )

201 )

202 LUT_4_t = LUT3x1D(domain=domain, table=domain * 2, name="Ragged Domain")

203 write_LUT_Cinespace(

204 LUT_4_t,

205 os.path.join(self._temporary_directory, "Ragged_Domain.csp"),

206 )

207 LUT_4_r = cast(

208 "LUT3x1D", read_LUT_Cinespace(os.path.join(ROOT_LUTS, "Ragged_Domain.csp"))

209 )

210 np.testing.assert_allclose(

211 LUT_4_t.domain, LUT_4_r.domain, atol=TOLERANCE_ABSOLUTE_TESTS

212 )

213 np.testing.assert_allclose(LUT_4_t.table, LUT_4_r.table, atol=5e-5)

214

215 LUT_5_r = cast(

216 "LUTSequence",

217 read_LUT_Cinespace(

218 os.path.join(ROOT_LUTS, "Three_Dimensional_Table_With_Shaper.csp")

219 ),

220 )

221 LUT_5_r.sequence[0] = LUT_5_r.sequence[0].convert( # pyright: ignore

222 LUT1D, force_conversion=True

223 )

224 write_LUT_Cinespace(

225 LUT_5_r,

226 os.path.join(

227 self._temporary_directory,

228 "Three_Dimensional_Table_With_Shaper.csp",

229 ),

230 )

231 LUT_5_r = cast(

232 "LUTSequence",

233 read_LUT_Cinespace(

234 os.path.join(ROOT_LUTS, "Three_Dimensional_Table_With_Shaper.csp")

235 ),

236 )

237 LUT_5_t = cast(

238 "LUTSequence",

239 read_LUT_Cinespace(

240 os.path.join(

241 self._temporary_directory,

242 "Three_Dimensional_Table_With_Shaper.csp",

243 )

244 ),

245 )

246 assert LUT_5_r == LUT_5_t

247

248 LUT_6_r = cast(

249 "LUTSequence",

250 read_LUT_Cinespace(

251 os.path.join(ROOT_LUTS, "Three_Dimensional_Table_With_Shaper.csp")

252 ),

253 )

254 LUT_6_r.sequence[0] = LUT_6_r.sequence[0].convert( # pyright: ignore

255 LUT3x1D, force_conversion=True

256 )

257 write_LUT_Cinespace(

258 LUT_6_r,

259 os.path.join(

260 self._temporary_directory,

261 "Three_Dimensional_Table_With_Shaper.csp",

262 ),

263 )

264 LUT_6_r = cast(

265 "LUTSequence",

266 read_LUT_Cinespace(

267 os.path.join(ROOT_LUTS, "Three_Dimensional_Table_With_Shaper.csp")

268 ),

269 )

270 LUT_6_t = cast(

271 "LUTSequence",

272 read_LUT_Cinespace(

273 os.path.join(

274 self._temporary_directory,

275 "Three_Dimensional_Table_With_Shaper.csp",

276 )

277 ),

278 )

279 assert LUT_6_r == LUT_6_t

280

281 LUT_7_r = cast(

282 "LUT3x1D",

283 read_LUT_Cinespace(os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.csp")),

284 )

285 write_LUT_Cinespace(

286 cast("LUT1D", LUT_7_r.convert(LUT1D, force_conversion=True)),

287 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.csp"),

288 )

289 LUT_7_t = cast(

290 "LUT3x1D",

291 read_LUT_Cinespace(

292 os.path.join(self._temporary_directory, "ACES_Proxy_10_to_ACES.csp")

293 ),

294 )

295 assert LUT_7_r == LUT_7_t

296

297 def test_raise_exception_write_LUT_Cinespace(self) -> None:

298 """

299 Test :func:`colour.io.luts.cinespace_csp.write_LUT_Cinespace`

300 definition raised exception.

301 """

302

303 pytest.raises(TypeError, write_LUT_Cinespace, object(), "")