Coverage for colour/models/rgb/transfer_functions/tests/test_log.py: 100%

161 statements  

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

1""" 

2Define the unit tests for the 

3:mod:`colour.models.rgb.transfer_functions.log` module. 

4""" 

5 

6import numpy as np 

7 

8from colour.constants import TOLERANCE_ABSOLUTE_TESTS 

9from colour.models.rgb.transfer_functions import ( 

10 log_decoding_Log2, 

11 log_encoding_Log2, 

12 logarithmic_function_basic, 

13 logarithmic_function_camera, 

14 logarithmic_function_quasilog, 

15) 

16from colour.utilities import ignore_numpy_errors 

17 

18__author__ = "Colour Developers" 

19__copyright__ = "Copyright 2013 Colour Developers" 

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

21__maintainer__ = "Colour Developers" 

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

23__status__ = "Production" 

24 

25__all__ = [ 

26 "TestLogarithmFunction_Basic", 

27 "TestLogarithmFunction_Quasilog", 

28 "TestLogarithmFunction_Camera", 

29 "TestLogEncoding_Log2", 

30 "TestLogDecoding_Log2", 

31] 

32 

33 

34class TestLogarithmFunction_Basic: 

35 """ 

36 Define :func:`colour.models.rgb.transfer_functions.log.\ 

37logarithmic_function_basic` definition unit tests methods. 

38 """ 

39 

40 def test_logarithmic_function_basic(self) -> None: 

41 """ 

42 Test :func:`colour.models.rgb.transfer_functions.log.\ 

43logarithmic_function_basic` definition. 

44 """ 

45 

46 np.testing.assert_allclose( 

47 logarithmic_function_basic(0.18), 

48 -2.473931188332412, 

49 atol=TOLERANCE_ABSOLUTE_TESTS, 

50 ) 

51 

52 np.testing.assert_allclose( 

53 logarithmic_function_basic(-2.473931188332412, "antiLog2"), 

54 0.180000000000000, 

55 atol=TOLERANCE_ABSOLUTE_TESTS, 

56 ) 

57 

58 np.testing.assert_allclose( 

59 logarithmic_function_basic(0.18, "log10"), 

60 -0.744727494896694, 

61 atol=TOLERANCE_ABSOLUTE_TESTS, 

62 ) 

63 

64 np.testing.assert_allclose( 

65 logarithmic_function_basic(-0.744727494896694, "antiLog10"), 

66 0.179999999999999, 

67 atol=TOLERANCE_ABSOLUTE_TESTS, 

68 ) 

69 

70 np.testing.assert_allclose( 

71 logarithmic_function_basic(0.18, "logB", 3), 

72 -1.560876795007312, 

73 atol=TOLERANCE_ABSOLUTE_TESTS, 

74 ) 

75 

76 np.testing.assert_allclose( 

77 logarithmic_function_basic(-1.560876795007312, "antiLogB", 3), 

78 0.180000000000000, 

79 atol=TOLERANCE_ABSOLUTE_TESTS, 

80 ) 

81 

82 def test_n_dimensional_logarithmic_function_basic(self) -> None: 

83 """ 

84 Test :func:`colour.models.rgb.transfer_functions.log.\ 

85logarithmic_function_basic` definition n-dimensional arrays support. 

86 """ 

87 

88 styles = ["log10", "antiLog10", "log2", "antiLog2", "logB", "antiLogB"] 

89 

90 for style in styles: 

91 a = 0.18 

92 a_p = logarithmic_function_basic(a, style) 

93 

94 a = np.tile(a, 6) 

95 a_p = np.tile(a_p, 6) 

96 np.testing.assert_allclose( 

97 logarithmic_function_basic(a, style), 

98 a_p, 

99 atol=TOLERANCE_ABSOLUTE_TESTS, 

100 ) 

101 

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

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

104 np.testing.assert_allclose( 

105 logarithmic_function_basic(a, style), 

106 a_p, 

107 atol=TOLERANCE_ABSOLUTE_TESTS, 

108 ) 

109 

110 a = np.reshape(a, (2, 3, 1)) 

111 a_p = np.reshape(a_p, (2, 3, 1)) 

112 np.testing.assert_allclose( 

113 logarithmic_function_basic(a, style), 

114 a_p, 

115 atol=TOLERANCE_ABSOLUTE_TESTS, 

116 ) 

117 

118 @ignore_numpy_errors 

119 def test_nan_logarithmic_function_basic(self) -> None: 

120 """ 

121 Test :func:`colour.models.rgb.transfer_functions.log.\ 

122logarithmic_function_basic` definition nan support. 

123 """ 

124 

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

126 styles = ["log10", "antiLog10", "log2", "antiLog2", "logB", "antiLogB"] 

127 for style in styles: 

128 logarithmic_function_basic(cases, style) 

129 

130 

131class TestLogarithmFunction_Quasilog: 

132 """ 

133 Define :func:`colour.models.rgb.transfer_functions.log.\ 

134logarithmic_function_quasilog` definition unit tests methods. 

135 """ 

136 

137 def test_logarithmic_function_quasilog(self) -> None: 

138 """ 

139 Test :func:`colour.models.rgb.transfer_functions.log.\ 

140logarithmic_function_quasilog` definition. 

141 """ 

142 

143 np.testing.assert_allclose( 

144 logarithmic_function_quasilog(0.18), 

145 -2.473931188332412, 

146 atol=TOLERANCE_ABSOLUTE_TESTS, 

147 ) 

148 

149 np.testing.assert_allclose( 

150 logarithmic_function_quasilog(-2.473931188332412, "logToLin"), 

151 0.18, 

152 atol=TOLERANCE_ABSOLUTE_TESTS, 

153 ) 

154 

155 np.testing.assert_allclose( 

156 logarithmic_function_quasilog(0.18, "linToLog", 10), 

157 -0.744727494896694, 

158 atol=TOLERANCE_ABSOLUTE_TESTS, 

159 ) 

160 

161 np.testing.assert_allclose( 

162 logarithmic_function_quasilog(-0.744727494896694, "logToLin", 10), 

163 0.18, 

164 atol=TOLERANCE_ABSOLUTE_TESTS, 

165 ) 

166 

167 np.testing.assert_allclose( 

168 logarithmic_function_quasilog(0.18, "linToLog", 10, 0.75), 

169 -0.558545621172520, 

170 atol=TOLERANCE_ABSOLUTE_TESTS, 

171 ) 

172 

173 np.testing.assert_allclose( 

174 logarithmic_function_quasilog(-0.558545621172520, "logToLin", 10, 0.75), 

175 0.18, 

176 atol=TOLERANCE_ABSOLUTE_TESTS, 

177 ) 

178 

179 np.testing.assert_allclose( 

180 logarithmic_function_quasilog(0.18, "linToLog", 10, 0.75, 0.75), 

181 -0.652249673628745, 

182 atol=TOLERANCE_ABSOLUTE_TESTS, 

183 ) 

184 

185 np.testing.assert_allclose( 

186 logarithmic_function_quasilog( 

187 -0.652249673628745, "logToLin", 10, 0.75, 0.75 

188 ), 

189 0.18, 

190 atol=TOLERANCE_ABSOLUTE_TESTS, 

191 ) 

192 

193 np.testing.assert_allclose( 

194 logarithmic_function_quasilog(0.18, "linToLog", 10, 0.75, 0.75, 0.001), 

195 -0.651249673628745, 

196 atol=TOLERANCE_ABSOLUTE_TESTS, 

197 ) 

198 

199 np.testing.assert_allclose( 

200 logarithmic_function_quasilog( 

201 -0.651249673628745, "logToLin", 10, 0.75, 0.75, 0.001 

202 ), 

203 0.18, 

204 atol=TOLERANCE_ABSOLUTE_TESTS, 

205 ) 

206 

207 np.testing.assert_allclose( 

208 logarithmic_function_quasilog( 

209 0.18, "linToLog", 10, 0.75, 0.75, 0.001, 0.01 

210 ), 

211 -0.627973998323769, 

212 atol=TOLERANCE_ABSOLUTE_TESTS, 

213 ) 

214 

215 np.testing.assert_allclose( 

216 logarithmic_function_quasilog( 

217 -0.627973998323769, "logToLin", 10, 0.75, 0.75, 0.001, 0.01 

218 ), 

219 0.18, 

220 atol=TOLERANCE_ABSOLUTE_TESTS, 

221 ) 

222 

223 def test_n_dimensional_logarithmic_function_quasilog(self) -> None: 

224 """ 

225 Test :func:`colour.models.rgb.transfer_functions.log.\ 

226logarithmic_function_quasilog` definition n-dimensional arrays support. 

227 """ 

228 

229 styles = ["lintolog", "logtolin"] 

230 

231 for style in styles: 

232 a = 0.18 

233 a_p = logarithmic_function_quasilog(a, style) 

234 

235 a = np.tile(a, 6) 

236 a_p = np.tile(a_p, 6) 

237 np.testing.assert_allclose( 

238 logarithmic_function_quasilog(a, style), 

239 a_p, 

240 atol=TOLERANCE_ABSOLUTE_TESTS, 

241 ) 

242 

243 a = np.reshape(a, (2, 3)) 

244 a_p = np.reshape(a_p, (2, 3)) 

245 np.testing.assert_allclose( 

246 logarithmic_function_quasilog(a, style), 

247 a_p, 

248 atol=TOLERANCE_ABSOLUTE_TESTS, 

249 ) 

250 

251 a = np.reshape(a, (2, 3, 1)) 

252 a_p = np.reshape(a_p, (2, 3, 1)) 

253 np.testing.assert_allclose( 

254 logarithmic_function_quasilog(a, style), 

255 a_p, 

256 atol=TOLERANCE_ABSOLUTE_TESTS, 

257 ) 

258 

259 @ignore_numpy_errors 

260 def test_nan_logarithmic_function_quasilog(self) -> None: 

261 """ 

262 Test :func:`colour.models.rgb.transfer_functions.log.\ 

263logarithmic_function_quasilog` definition nan support. 

264 """ 

265 

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

267 styles = ["lintolog", "logtolin"] 

268 for style in styles: 

269 logarithmic_function_quasilog(cases, style) 

270 

271 

272class TestLogarithmFunction_Camera: 

273 """ 

274 Define :func:`colour.models.rgb.transfer_functions.log.\ 

275logarithmic_function_camera` definition unit tests methods. 

276 """ 

277 

278 def test_logarithmic_function_camera(self) -> None: 

279 """ 

280 Test :func:`colour.models.rgb.transfer_functions.log.\ 

281logarithmic_function_camera` definition. 

282 """ 

283 

284 np.testing.assert_allclose( 

285 logarithmic_function_camera(0, "cameraLinToLog"), 

286 -9.08655123066369, 

287 atol=TOLERANCE_ABSOLUTE_TESTS, 

288 ) 

289 

290 np.testing.assert_allclose( 

291 logarithmic_function_camera(-9.08655123066369, "cameraLogToLin"), 

292 0.000000000000000, 

293 atol=TOLERANCE_ABSOLUTE_TESTS, 

294 ) 

295 

296 np.testing.assert_allclose( 

297 logarithmic_function_camera(0.18, "cameraLinToLog"), 

298 -2.473931188332412, 

299 atol=TOLERANCE_ABSOLUTE_TESTS, 

300 ) 

301 

302 np.testing.assert_allclose( 

303 logarithmic_function_camera(-2.473931188332412, "cameraLogToLin"), 

304 0.180000000000000, 

305 atol=TOLERANCE_ABSOLUTE_TESTS, 

306 ) 

307 

308 np.testing.assert_allclose( 

309 logarithmic_function_camera(1, "cameraLinToLog"), 

310 0.000000000000000, 

311 atol=TOLERANCE_ABSOLUTE_TESTS, 

312 ) 

313 

314 np.testing.assert_allclose( 

315 logarithmic_function_camera(0, "cameraLogToLin"), 

316 1.000000000000000, 

317 atol=TOLERANCE_ABSOLUTE_TESTS, 

318 ) 

319 

320 np.testing.assert_allclose( 

321 logarithmic_function_camera(0.18, "cameraLinToLog", 10), 

322 -0.744727494896693, 

323 atol=TOLERANCE_ABSOLUTE_TESTS, 

324 ) 

325 

326 np.testing.assert_allclose( 

327 logarithmic_function_camera(-0.744727494896693, "cameraLogToLin", 10), 

328 0.180000000000000, 

329 atol=TOLERANCE_ABSOLUTE_TESTS, 

330 ) 

331 

332 np.testing.assert_allclose( 

333 logarithmic_function_camera(0.18, "cameraLinToLog", 10, 0.25), 

334 -0.186181873724173, 

335 atol=TOLERANCE_ABSOLUTE_TESTS, 

336 ) 

337 

338 np.testing.assert_allclose( 

339 logarithmic_function_camera(-0.186181873724173, "cameraLogToLin", 10, 0.25), 

340 0.180000000000000, 

341 atol=TOLERANCE_ABSOLUTE_TESTS, 

342 ) 

343 

344 np.testing.assert_allclose( 

345 logarithmic_function_camera(0.18, "cameraLinToLog", 10, 0.25, 0.95), 

346 -0.191750972401961, 

347 atol=TOLERANCE_ABSOLUTE_TESTS, 

348 ) 

349 

350 np.testing.assert_allclose( 

351 logarithmic_function_camera( 

352 -0.191750972401961, "cameraLogToLin", 10, 0.25, 0.95 

353 ), 

354 0.180000000000000, 

355 atol=TOLERANCE_ABSOLUTE_TESTS, 

356 ) 

357 

358 np.testing.assert_allclose( 

359 logarithmic_function_camera(0.18, "cameraLinToLog", 10, 0.25, 0.95, 0.6), 

360 0.408249027598038, 

361 atol=TOLERANCE_ABSOLUTE_TESTS, 

362 ) 

363 

364 np.testing.assert_allclose( 

365 logarithmic_function_camera( 

366 0.408249027598038, "cameraLogToLin", 10, 0.25, 0.95, 0.6 

367 ), 

368 0.179999999999999, 

369 atol=TOLERANCE_ABSOLUTE_TESTS, 

370 ) 

371 

372 np.testing.assert_allclose( 

373 logarithmic_function_camera( 

374 0.18, "cameraLinToLog", 10, 0.25, 0.95, 0.6, 0.01 

375 ), 

376 0.414419643717296, 

377 atol=TOLERANCE_ABSOLUTE_TESTS, 

378 ) 

379 

380 np.testing.assert_allclose( 

381 logarithmic_function_camera( 

382 0.414419643717296, "cameraLogToLin", 10, 0.25, 0.95, 0.6, 0.01 

383 ), 

384 0.180000000000000, 

385 atol=TOLERANCE_ABSOLUTE_TESTS, 

386 ) 

387 

388 np.testing.assert_allclose( 

389 logarithmic_function_camera( 

390 0.005, "cameraLinToLog", 10, 0.25, 0.95, 0.6, 0.01, 0.01 

391 ), 

392 0.146061232468316, 

393 atol=TOLERANCE_ABSOLUTE_TESTS, 

394 ) 

395 

396 np.testing.assert_allclose( 

397 logarithmic_function_camera( 

398 0.146061232468316, 

399 "cameraLogToLin", 

400 10, 

401 0.25, 

402 0.95, 

403 0.6, 

404 0.01, 

405 0.01, 

406 ), 

407 0.005000000000000, 

408 atol=TOLERANCE_ABSOLUTE_TESTS, 

409 ) 

410 

411 np.testing.assert_allclose( 

412 logarithmic_function_camera( 

413 0.005, "cameraLinToLog", 10, 0.25, 0.95, 0.6, 0.01, 0.01, 6 

414 ), 

415 0.142508652840630, 

416 atol=TOLERANCE_ABSOLUTE_TESTS, 

417 ) 

418 

419 np.testing.assert_allclose( 

420 logarithmic_function_camera( 

421 0.142508652840630, 

422 "cameraLogToLin", 

423 10, 

424 0.25, 

425 0.95, 

426 0.6, 

427 0.01, 

428 0.01, 

429 6, 

430 ), 

431 0.005000000000000, 

432 atol=TOLERANCE_ABSOLUTE_TESTS, 

433 ) 

434 

435 def test_n_dimensional_logarithmic_function_camera(self) -> None: 

436 """ 

437 Test :func:`colour.models.rgb.transfer_functions.log.\ 

438logarithmic_function_camera` definition n-dimensional arrays support. 

439 """ 

440 

441 styles = ["cameraLinToLog", "cameraLogToLin"] 

442 

443 for style in styles: 

444 a = 0.18 

445 a_p = logarithmic_function_camera(a, style) 

446 

447 a = np.tile(a, 6) 

448 a_p = np.tile(a_p, 6) 

449 np.testing.assert_allclose( 

450 logarithmic_function_camera(a, style), 

451 a_p, 

452 atol=TOLERANCE_ABSOLUTE_TESTS, 

453 ) 

454 

455 a = np.reshape(a, (2, 3)) 

456 a_p = np.reshape(a_p, (2, 3)) 

457 np.testing.assert_allclose( 

458 logarithmic_function_camera(a, style), 

459 a_p, 

460 atol=TOLERANCE_ABSOLUTE_TESTS, 

461 ) 

462 

463 a = np.reshape(a, (2, 3, 1)) 

464 a_p = np.reshape(a_p, (2, 3, 1)) 

465 np.testing.assert_allclose( 

466 logarithmic_function_camera(a, style), 

467 a_p, 

468 atol=TOLERANCE_ABSOLUTE_TESTS, 

469 ) 

470 

471 @ignore_numpy_errors 

472 def test_nan_logarithmic_function_camera(self) -> None: 

473 """ 

474 Test :func:`colour.models.rgb.transfer_functions.log.\ 

475logarithmic_function_camera` definition nan support. 

476 """ 

477 

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

479 styles = ["cameraLinToLog", "cameraLogToLin"] 

480 for style in styles: 

481 logarithmic_function_camera(cases, style) 

482 

483 

484class TestLogEncoding_Log2: 

485 """ 

486 Define :func:`colour.models.rgb.transfer_functions.log.\ 

487log_encoding_Log2` definition unit tests methods. 

488 """ 

489 

490 def test_log_encoding_Log2(self) -> None: 

491 """ 

492 Test :func:`colour.models.rgb.transfer_functions.log.\ 

493log_encoding_Log2` definition. 

494 """ 

495 

496 np.testing.assert_allclose( 

497 log_encoding_Log2(0.0), -np.inf, atol=TOLERANCE_ABSOLUTE_TESTS 

498 ) 

499 

500 np.testing.assert_allclose( 

501 log_encoding_Log2(0.18), 0.5, atol=TOLERANCE_ABSOLUTE_TESTS 

502 ) 

503 

504 np.testing.assert_allclose( 

505 log_encoding_Log2(1.0), 

506 0.690302399102493, 

507 atol=TOLERANCE_ABSOLUTE_TESTS, 

508 ) 

509 

510 np.testing.assert_allclose( 

511 log_encoding_Log2(0.18, 0.12), 

512 0.544997115440089, 

513 atol=TOLERANCE_ABSOLUTE_TESTS, 

514 ) 

515 

516 np.testing.assert_allclose( 

517 log_encoding_Log2(0.18, 0.12, 2**-10), 

518 0.089857490719529, 

519 atol=TOLERANCE_ABSOLUTE_TESTS, 

520 ) 

521 

522 np.testing.assert_allclose( 

523 log_encoding_Log2(0.18, 0.12, 2**-10, 2**10), 

524 0.000570299311674, 

525 atol=TOLERANCE_ABSOLUTE_TESTS, 

526 ) 

527 

528 def test_n_dimensional_log_encoding_Log2(self) -> None: 

529 """ 

530 Test :func:`colour.models.rgb.transfer_functions.log.\ 

531log_encoding_Log2` definition n-dimensional arrays support. 

532 """ 

533 

534 x = 0.18 

535 y = log_encoding_Log2(x) 

536 

537 x = np.tile(x, 6) 

538 y = np.tile(y, 6) 

539 np.testing.assert_allclose( 

540 log_encoding_Log2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS 

541 ) 

542 

543 x = np.reshape(x, (2, 3)) 

544 y = np.reshape(y, (2, 3)) 

545 np.testing.assert_allclose( 

546 log_encoding_Log2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS 

547 ) 

548 

549 x = np.reshape(x, (2, 3, 1)) 

550 y = np.reshape(y, (2, 3, 1)) 

551 np.testing.assert_allclose( 

552 log_encoding_Log2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS 

553 ) 

554 

555 @ignore_numpy_errors 

556 def test_nan_log_encoding_Log2(self) -> None: 

557 """ 

558 Test :func:`colour.models.rgb.transfer_functions.log.\ 

559log_encoding_Log2` definition nan support. 

560 """ 

561 

562 log_encoding_Log2(np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan])) 

563 

564 

565class TestLogDecoding_Log2: 

566 """ 

567 Define :func:`colour.models.rgb.transfer_functions.log.\ 

568log_decoding_Log2` definition unit tests methods. 

569 """ 

570 

571 def test_log_decoding_Log2(self) -> None: 

572 """ 

573 Test :func:`colour.models.rgb.transfer_functions.log.\ 

574log_decoding_Log2` definition. 

575 """ 

576 

577 np.testing.assert_allclose( 

578 log_decoding_Log2(0.0), 

579 0.001988737822087, 

580 atol=TOLERANCE_ABSOLUTE_TESTS, 

581 ) 

582 

583 np.testing.assert_allclose( 

584 log_decoding_Log2(0.5), 0.18, atol=TOLERANCE_ABSOLUTE_TESTS 

585 ) 

586 

587 np.testing.assert_allclose( 

588 log_decoding_Log2(0.690302399102493), 

589 1.0, 

590 atol=TOLERANCE_ABSOLUTE_TESTS, 

591 ) 

592 

593 np.testing.assert_allclose( 

594 log_decoding_Log2(0.544997115440089, 0.12), 

595 0.18, 

596 atol=TOLERANCE_ABSOLUTE_TESTS, 

597 ) 

598 

599 np.testing.assert_allclose( 

600 log_decoding_Log2(0.089857490719529, 0.12, 2**-10), 

601 0.180000000000000, 

602 atol=TOLERANCE_ABSOLUTE_TESTS, 

603 ) 

604 

605 np.testing.assert_allclose( 

606 log_decoding_Log2(0.000570299311674, 0.12, 2**-10, 2**10), 

607 0.180000000000000, 

608 atol=TOLERANCE_ABSOLUTE_TESTS, 

609 ) 

610 

611 def test_n_dimensional_log_decoding_Log2(self) -> None: 

612 """ 

613 Test :func:`colour.models.rgb.transfer_functions.log.\ 

614log_decoding_Log2` definition n-dimensional arrays support. 

615 """ 

616 

617 y = 0.5 

618 x = log_decoding_Log2(y) 

619 

620 y = np.tile(y, 6) 

621 x = np.tile(x, 6) 

622 np.testing.assert_allclose( 

623 log_decoding_Log2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS 

624 ) 

625 

626 y = np.reshape(y, (2, 3)) 

627 x = np.reshape(x, (2, 3)) 

628 np.testing.assert_allclose( 

629 log_decoding_Log2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS 

630 ) 

631 

632 y = np.reshape(y, (2, 3, 1)) 

633 x = np.reshape(x, (2, 3, 1)) 

634 np.testing.assert_allclose( 

635 log_decoding_Log2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS 

636 ) 

637 

638 @ignore_numpy_errors 

639 def test_nan_log_decoding_Log2(self) -> None: 

640 """ 

641 Test :func:`colour.models.rgb.transfer_functions.log.\ 

642log_decoding_Log2` definition nan support. 

643 """ 

644 

645 log_decoding_Log2(np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]))