diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml index e54ece627c..4010192dbe 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.yml +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -1,7 +1,7 @@ name: Bug Report description: Report an issue or a bug. title: "[BUG]: << Please use a comprehensive title... >>" -labels: [ Defect ] +labels: [Defect] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/documentation-improvement.yml b/.github/ISSUE_TEMPLATE/documentation-improvement.yml index 91ed3e5445..27581a1d96 100644 --- a/.github/ISSUE_TEMPLATE/documentation-improvement.yml +++ b/.github/ISSUE_TEMPLATE/documentation-improvement.yml @@ -1,7 +1,7 @@ name: Documentation Improvement description: Report a documentation improvement. title: "[DOCUMENTATION]: << Please use a comprehensive title... >>" -labels: [ Documentation ] +labels: [Documentation] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml index e859646d57..05ca55db18 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.yml +++ b/.github/ISSUE_TEMPLATE/feature-request.yml @@ -1,7 +1,7 @@ name: Feature Request description: Suggest a new feature to implement. title: "[FEATURE]: << Please use a comprehensive title... >>" -labels: [ Feature ] +labels: [Feature] body: - type: markdown diff --git a/.github/ISSUE_TEMPLATE/question.yml b/.github/ISSUE_TEMPLATE/question.yml index fbd9e95eb7..9bf9427862 100644 --- a/.github/ISSUE_TEMPLATE/question.yml +++ b/.github/ISSUE_TEMPLATE/question.yml @@ -1,7 +1,7 @@ name: Question description: Ask a question. title: "[DISCUSSION]: << Please use a comprehensive title... >>" -labels: [ Discussion ] +labels: [Discussion] body: - type: markdown diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 856123b45c..adc2413ada 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,7 @@ is available to guide the process: https://www.colour-science.org/contributing/. - [ ] Unit tests have been implemented and passed. - [ ] Pyright static checking has been run and passed. - [ ] Pre-commit hooks have been run and passed. -- [ ] New transformations have been added to the *Automatic Colour Conversion Graph*. +- [ ] New transformations have been added to the _Automatic Colour Conversion Graph_. - [ ] New transformations have been exported to the relevant namespaces, e.g. `colour`, `colour.models`. diff --git a/.github/workflows/continuous-integration-documentation.yml b/.github/workflows/continuous-integration-documentation.yml index dbafd4fa88..6e9f0d8178 100644 --- a/.github/workflows/continuous-integration-documentation.yml +++ b/.github/workflows/continuous-integration-documentation.yml @@ -12,45 +12,45 @@ jobs: fail-fast: false runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v1 - - name: Environment Variables - run: | - echo "CI_PYTHON_VERSION=${{ matrix.python-version }}" >> $GITHUB_ENV - echo "CI_PACKAGE=colour" >> $GITHUB_ENV - echo "CI_SHA=${{ github.sha }}" >> $GITHUB_ENV - echo "MPLBACKEND=AGG" >> $GITHUB_ENV - echo "COLOUR_SCIENCE__DOCUMENTATION_BUILD=True" >> $GITHUB_ENV - shell: bash - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Install Dependencies - run: | - sudo apt-get update - sudo apt-get --yes install graphviz graphviz-dev latexmk texlive-full - - name: Install Poetry - env: - POETRY_VERSION: 1.4.0 - run: | - curl -sSL https://install.python-poetry.org | POETRY_HOME=$HOME/.poetry python3 - - echo "$HOME/.poetry/bin" >> $GITHUB_PATH - shell: bash - - name: Install Package Dependencies - run: | - poetry run python -m pip install --upgrade pip - poetry install - poetry run python -c "import imageio;imageio.plugins.freeimage.download()" - shell: bash - - name: Build Documentation - run: | - poetry run invoke docs - shell: bash - - uses: actions/upload-artifact@v2 - with: - name: ${{ env.CI_PACKAGE }}-plots - path: | - docs/_static/Basics_*.png - docs/_static/Examples_*.png - docs/_static/Plotting_*.png - docs/_static/Tutorial_*.png + - uses: actions/checkout@v1 + - name: Environment Variables + run: | + echo "CI_PYTHON_VERSION=${{ matrix.python-version }}" >> $GITHUB_ENV + echo "CI_PACKAGE=colour" >> $GITHUB_ENV + echo "CI_SHA=${{ github.sha }}" >> $GITHUB_ENV + echo "MPLBACKEND=AGG" >> $GITHUB_ENV + echo "COLOUR_SCIENCE__DOCUMENTATION_BUILD=True" >> $GITHUB_ENV + shell: bash + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies + run: | + sudo apt-get update + sudo apt-get --yes install graphviz graphviz-dev latexmk texlive-full + - name: Install Poetry + env: + POETRY_VERSION: 1.4.0 + run: | + curl -sSL https://install.python-poetry.org | POETRY_HOME=$HOME/.poetry python3 - + echo "$HOME/.poetry/bin" >> $GITHUB_PATH + shell: bash + - name: Install Package Dependencies + run: | + poetry run python -m pip install --upgrade pip + poetry install + poetry run python -c "import imageio;imageio.plugins.freeimage.download()" + shell: bash + - name: Build Documentation + run: | + poetry run invoke docs + shell: bash + - uses: actions/upload-artifact@v2 + with: + name: ${{ env.CI_PACKAGE }}-plots + path: | + docs/_static/Basics_*.png + docs/_static/Examples_*.png + docs/_static/Plotting_*.png + docs/_static/Tutorial_*.png diff --git a/.github/workflows/continuous-integration-quality-unit-tests.yml b/.github/workflows/continuous-integration-quality-unit-tests.yml index 3e2b923543..35ecdfe0c8 100644 --- a/.github/workflows/continuous-integration-quality-unit-tests.yml +++ b/.github/workflows/continuous-integration-quality-unit-tests.yml @@ -8,74 +8,74 @@ jobs: strategy: matrix: os: [macOS-latest, ubuntu-22.04, windows-latest] - python-version: [3.9, '3.10', 3.11] + python-version: [3.9, "3.10", 3.11, 3.12] fail-fast: false runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v1 - - name: Environment Variables - run: | - echo "CI_PYTHON_VERSION=${{ matrix.python-version }}" >> $GITHUB_ENV - echo "CI_PACKAGE=colour" >> $GITHUB_ENV - echo "CI_SHA=${{ github.sha }}" >> $GITHUB_ENV - echo "COVERALLS_REPO_TOKEN=${{ secrets.COVERALLS_REPO_TOKEN }}" >> $GITHUB_ENV - echo "MPLBACKEND=AGG" >> $GITHUB_ENV - shell: bash - - name: Set up Python 3.9 for Pre-Commit - uses: actions/setup-python@v1 - with: - python-version: 3.9 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Install Dependencies (Ubuntu) - if: matrix.os == 'ubuntu-22.04' - run: | - sudo apt-get update - sudo apt-get --yes install graphviz graphviz-dev libboost-all-dev libilmbase-dev libopenexr-dev libpng-dev libtiff5-dev - - name: Install Poetry - env: - POETRY_VERSION: 1.4.0 - run: | - curl -sSL https://install.python-poetry.org | POETRY_HOME=$HOME/.poetry python3 - - echo "$HOME/.poetry/bin" >> $GITHUB_PATH - shell: bash - - name: Install Package Dependencies (Ubuntu) - if: matrix.os == 'ubuntu-22.04' - run: | - poetry run python -m pip install --upgrade pip - poetry install - poetry run python -c "import imageio;imageio.plugins.freeimage.download()" - shell: bash - - name: Install Package Dependencies (macOS & Windows) - if: matrix.os == 'macOS-latest' || matrix.os == 'windows-latest' - run: | - poetry run python -m pip install --upgrade pip - poetry install --without graphviz - poetry run python -c "import imageio;imageio.plugins.freeimage.download()" - shell: bash - - name: Install OpenImageIO (macOs) - if: matrix.os == 'macOS-latest' && matrix.python-version == '3.11' - run: | - brew install openimageio - ls /usr/local/Cellar/openimageio/*/lib/python*/site-packages/OpenImageIO/ - ln -s /usr/local/Cellar/openimageio/*/lib/python*/site-packages/OpenImageIO/OpenImageIO*.so /Library/Frameworks/Python.framework/Versions/${{ matrix.python-version }}/lib/python${{ matrix.python-version }}/site-packages/OpenImageIO.so - shell: bash - - name: Pre-Commit (All Files) - run: | - poetry run pre-commit run --all-files - shell: bash - - name: Test Optimised Python Execution - run: | - poetry run python -OO -c "import $CI_PACKAGE" - shell: bash - - name: Test with Pytest - run: | - poetry run python -W ignore -m pytest --doctest-modules --ignore=$CI_PACKAGE/examples --cov=$CI_PACKAGE $CI_PACKAGE - shell: bash - - name: Upload Coverage to coveralls.io - if: matrix.os == 'macOS-latest' && matrix.python-version == '3.11' - run: | - if [ -z "$COVERALLS_REPO_TOKEN" ]; then echo \"COVERALLS_REPO_TOKEN\" secret is undefined!; else poetry run coveralls; fi - shell: bash + - uses: actions/checkout@v1 + - name: Environment Variables + run: | + echo "CI_PYTHON_VERSION=${{ matrix.python-version }}" >> $GITHUB_ENV + echo "CI_PACKAGE=colour" >> $GITHUB_ENV + echo "CI_SHA=${{ github.sha }}" >> $GITHUB_ENV + echo "COVERALLS_REPO_TOKEN=${{ secrets.COVERALLS_REPO_TOKEN }}" >> $GITHUB_ENV + echo "MPLBACKEND=AGG" >> $GITHUB_ENV + shell: bash + - name: Set up Python 3.9 for Pre-Commit + uses: actions/setup-python@v4 + with: + python-version: 3.9 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies (Ubuntu) + if: matrix.os == 'ubuntu-22.04' + run: | + sudo apt-get update + sudo apt-get --yes install graphviz graphviz-dev libboost-all-dev libilmbase-dev libopenexr-dev libpng-dev libtiff5-dev + - name: Install Poetry + env: + POETRY_VERSION: 1.4.0 + run: | + curl -sSL https://install.python-poetry.org | POETRY_HOME=$HOME/.poetry python3 - + echo "$HOME/.poetry/bin" >> $GITHUB_PATH + shell: bash + - name: Install Package Dependencies (Ubuntu) + if: matrix.os == 'ubuntu-22.04' + run: | + poetry run python -m pip install --upgrade pip + poetry install + poetry run python -c "import imageio;imageio.plugins.freeimage.download()" + shell: bash + - name: Install Package Dependencies (macOS & Windows) + if: matrix.os == 'macOS-latest' || matrix.os == 'windows-latest' + run: | + poetry run python -m pip install --upgrade pip + poetry install --without graphviz + poetry run python -c "import imageio;imageio.plugins.freeimage.download()" + shell: bash + - name: Install OpenImageIO (macOs) + if: matrix.os == 'macOS-latest' && matrix.python-version == '3.11' + run: | + brew install openimageio + ls /usr/local/Cellar/openimageio/*/lib/python*/site-packages/OpenImageIO/ + ln -s /usr/local/Cellar/openimageio/*/lib/python*/site-packages/OpenImageIO/OpenImageIO*.so /Library/Frameworks/Python.framework/Versions/${{ matrix.python-version }}/lib/python${{ matrix.python-version }}/site-packages/OpenImageIO.so + shell: bash + - name: Pre-Commit (All Files) + run: | + poetry run pre-commit run --all-files + shell: bash + - name: Test Optimised Python Execution + run: | + poetry run python -OO -c "import $CI_PACKAGE" + shell: bash + - name: Test with Pytest + run: | + poetry run python -W ignore -m pytest --doctest-modules --ignore=$CI_PACKAGE/examples --cov=$CI_PACKAGE $CI_PACKAGE + shell: bash + - name: Upload Coverage to coveralls.io + if: matrix.os == 'macOS-latest' && matrix.python-version == '3.11' + run: | + if [ -z "$COVERALLS_REPO_TOKEN" ]; then echo \"COVERALLS_REPO_TOKEN\" secret is undefined!; else poetry run coveralls; fi + shell: bash diff --git a/.github/workflows/continuous-integration-static-type-checking.yml b/.github/workflows/continuous-integration-static-type-checking.yml index 269467af6b..9fcc2a16de 100644 --- a/.github/workflows/continuous-integration-static-type-checking.yml +++ b/.github/workflows/continuous-integration-static-type-checking.yml @@ -12,24 +12,24 @@ jobs: fail-fast: false runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v1 - - name: Environment Variables - run: | - echo "CI_PACKAGE=colour" >> $GITHUB_ENV - shell: bash - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v1 - with: - python-version: ${{ matrix.python-version }} - - name: Install Dependencies (macOS) - if: matrix.os == 'macOS-latest' - run: | - brew install graphviz - export GRAPHVIZ_DIR="/usr/local/Cellar/graphviz/" - pip install pygraphviz --global-option=build_ext --global-option="-I$GRAPHVIZ_DIR/include" --global-option="-L$GRAPHVIZ_DIR/lib" - - name: Install Package Dependencies - run: | - pip install -r requirements.txt - - name: Static Type Checking - run: | - pyright --skipunannotated + - uses: actions/checkout@v1 + - name: Environment Variables + run: | + echo "CI_PACKAGE=colour" >> $GITHUB_ENV + shell: bash + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install Dependencies (macOS) + if: matrix.os == 'macOS-latest' + run: | + brew install graphviz + export GRAPHVIZ_DIR="/usr/local/Cellar/graphviz/" + pip install pygraphviz --global-option=build_ext --global-option="-I$GRAPHVIZ_DIR/include" --global-option="-L$GRAPHVIZ_DIR/lib" + - name: Install Package Dependencies + run: | + pip install -r requirements.txt + - name: Static Type Checking + run: | + pyright --skipunannotated diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b527df66ff..bf8cbc0bcf 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,19 +1,57 @@ repos: -- repo: https://github.com/ikamensh/flynt/ - rev: '1.0.1' + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: "v4.5.0" hooks: - - id: flynt -- repo: https://github.com/charliermarsh/ruff-pre-commit - rev: 'v0.0.285' + - id: check-added-large-files + - id: check-case-conflict + - id: check-merge-conflict + - id: check-symlinks + - id: check-yaml + exclude: config-aces-reference.ocio.yaml + - id: debug-statements + - id: end-of-file-fixer + - id: mixed-line-ending + - id: name-tests-test + args: ["--pytest-test-first"] + - id: requirements-txt-fixer + - id: trailing-whitespace + - repo: https://github.com/codespell-project/codespell + rev: v2.2.6 hooks: - - id: ruff -- repo: https://github.com/psf/black - rev: 23.7.0 + - id: codespell + args: ["--ignore-words-list=co-ordinates,exitance,fro,hart,ist"] + exclude: "BIBLIOGRAPHY.bib|CONTRIBUTORS.rst" + - repo: https://github.com/ikamensh/flynt + rev: "1.0.1" hooks: - - id: black - language_version: python3.9 -- repo: https://github.com/keewis/blackdoc - rev: v0.3.8 + - id: flynt + args: [--verbose] + - repo: https://github.com/PyCQA/isort + rev: "5.12.0" hooks: - - id: blackdoc - language_version: python3.9 + - id: isort + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: "v0.1.6" + hooks: + - id: ruff + - repo: https://github.com/psf/black-pre-commit-mirror + rev: 23.11.0 + hooks: + - id: black + language_version: python3.9 + - repo: https://github.com/adamchainz/blacken-docs + rev: 1.16.0 + hooks: + - id: blacken-docs + language_version: python3.9 + - repo: https://github.com/pre-commit/mirrors-prettier + rev: "v3.1.0" + hooks: + - id: prettier + exclude: config-aces-reference.ocio.yaml + - repo: https://github.com/pre-commit/pygrep-hooks + rev: "v1.10.0" + hooks: + - id: rst-backticks + - id: rst-directive-colons + - id: rst-inline-touching-normal diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 9fddb85068..46e7436ba6 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,7 +9,7 @@ build: - graphviz-dev sphinx: - configuration: docs/conf.py + configuration: docs/conf.py formats: - htmlzip @@ -17,4 +17,4 @@ formats: python: install: - - requirements: docs/requirements.txt \ No newline at end of file + - requirements: docs/requirements.txt diff --git a/BIBLIOGRAPHY.bib b/BIBLIOGRAPHY.bib index 226afcfd03..fab24e24b2 100644 --- a/BIBLIOGRAPHY.bib +++ b/BIBLIOGRAPHY.bib @@ -90,7 +90,7 @@ @article{Abebe2017 pages = {1--19}, issn = 15443558, doi = {10.1145/3086577}, - abstract = {\textcopyright{} 2017 ACM. The human visual system + abstract = {{\textcopyright} 2017 ACM. The human visual system (HVS) non-linearly processes light from the real world, allowing us to perceive detail over a wide range of illumination. Although models that describe this non-linearity are constructed based on @@ -141,6 +141,12 @@ @misc{AppleInc.2019 urldate = {2019-12-18}, howpublished = {https://developer.apple.com/documentation/coregraphics/cgcolorspace/1408916-displayp3}, } +@misc{AppleInc.2023, + title = {Apple {{Log Profile White Paper}}}, + author = {{Apple Inc.}}, + year = 2023, + langid = {english}, +} @misc{AssociationofRadioIndustriesandBusinesses2015a, title = {Essential {{Parameter Values}} for the {{Extended Image Dynamic Range Television}} ({{EIDRTV}}) {{System}} for @@ -239,7 +245,7 @@ @article{Bodhaine1999a number = 11, pages = {1854--1861}, issn = {0739-0572}, - doi = {10.1175/1520-0426(1999)016{$<$}1854:ORODC{$>$}2.0.CO;2}, + doi = {10.1175/1520-0426(1999)016<1854:ORODC>2.0.CO;2}, urldate = {2014-09-25}, abstract = {Many different techniques are used for the calculation of Rayleigh optical depth in the atmosphere. In some @@ -362,8 +368,8 @@ @misc{Broadbent2009a Co-Ordinates}} and {{Color Matching Functions}}.}, author = {Broadbent, A. D.}, year = 2009, - journal = {Qu\'ebec, Canada: D\'epartement de g\'enie chimique, - \ldots}, + journal = {Qu{\'e}bec, Canada: D{\'e}partement de g{\'e}nie + chimique, {\ldots}}, pages = {1--17}, urldate = {2014-06-12}, abstract = {This paper describes all the steps in the @@ -664,7 +670,7 @@ @article{Cao2013 of numerical methods. After optimization, ANN gave a better performance with a mean error (DeltaEXYZ) of 1.0x10(-4) and a conversion time of less than 1 s for 1891 samples.}, - isbn = {1520-8532 (Electronic)\textbackslash r1084-7529 + isbn = {1520-8532 (Electronic){\textbackslash}r1084-7529 (Linking)}, pmid = 24323208, } @@ -894,11 +900,11 @@ @article{Cui2002 CIE94 colour-difference formulas and only slightly worse than CIEDE2000 (which was optimized on the experimental data). However, these formulas all have an associated UCS. The spaces are similar - in form to L*a*b*. \textcopyright{} 2002 Wiley Periodicals, Inc. - Col Res Appl, 27, 282\textendash 290, 2002; Published online in + in form to L*a*b*. {\textcopyright} 2002 Wiley Periodicals, Inc. + Col Res Appl, 27, 282{\textendash}290, 2002; Published online in Wiley InterScience (www.interscience.wiley.com). DOI 10.1002/col.10066}, - copyright = {Copyright \textcopyright{} 2002 Wiley Periodicals, + copyright = {Copyright {\textcopyright} 2002 Wiley Periodicals, Inc.}, langid = {english}, keywords = {colour discrimination ellipses,colour-difference @@ -974,7 +980,7 @@ @article{Davis2010a doi = {10.1117/1.3360335}, abstract = {The color rendering index (CRI) has been shown to have deficiencies when applied to white - light-emitting-diode\textendash based sources. Furthermore, + light-emitting-diode{\textendash}based sources. Furthermore, evidence suggests that the restricted scope of the CRI unnecessarily penalizes some light sources with desirable color qualities. To solve the problems of the CRI and include other @@ -1173,7 +1179,7 @@ @article{Fairchild1996a number = 5, pages = {338--346}, issn = {0361-2317}, - doi = {10.1002/(SICI)1520-6378(199610)21:5{$<$}338::AID-COL3{$>$}3.0.CO;2-Z}, + doi = {10.1002/(SICI)1520-6378(199610)21:5<338::AID-COL3>3.0.CO;2-Z}, abstract = {The prediction of color appearance using the RLAB color space has been tested for a variety of viewing conditions and stimulus types. These tests have shown that RLAB performs well @@ -1339,7 +1345,7 @@ @article{Fairchild2020 of the von Kries chromatic adaptation transform, referred to as vK20, that can account for the asymmetry in chromatic adaptation through inclusion of previous adapting conditions. Also introduced - is a new reference chromaticity (\textasciitilde 15000K) for + is a new reference chromaticity ({\textasciitilde}15000K) for degree of adaptation that seems more physiologically plausible than the commonly used equal-energy (EE) illuminant or CIE illuminant D65.}, @@ -1378,7 +1384,7 @@ @article{Fairman1997 number = 1, pages = {11--23}, issn = {0361-2317}, - doi = {10.1002/(SICI)1520-6378(199702)22:1{$<$}11::AID-COL4{$>$}3.0.CO;2-7}, + doi = {10.1002/(SICI)1520-6378(199702)22:1<11::AID-COL4>3.0.CO;2-7}, urldate = {2014-09-27}, abstract = {Page 1. How the CIE 1931 Color-Matching Functions Were Derived from Wright-Guild Data Hugh S. Fairman, 1 Michael H. @@ -1408,9 +1414,9 @@ @article{Finlayson2015 doi = {10.1109/TIP.2015.2405336}, abstract = {Cameras record three color responses (RGB) which are device dependent. Camera coordinates are mapped to a standard - color space, such as XYZ\textemdash useful for color - measurement\textemdash by amapping function, e.g., the simple - 3\texttimes 3 linear transform (usually derived through + color space, such as XYZ{\textemdash}useful for color + measurement{\textemdash}by amapping function, e.g., the simple + 3{\texttimes}3 linear transform (usually derived through regression). This mapping, which we will refer to as linear color correction (LCC), has been demonstrated to work well in the number of studies. However, it can map RGBs to XYZs with high error. The @@ -1444,56 +1450,57 @@ @misc{Frohlich2017 Imagery}, author = {Fr{\"o}hlich, Jan}, year = 2017, - publisher = {{Universit\"at Stuttgart}}, + publisher = {{Universit{\"a}t Stuttgart}}, urldate = {2021-08-07}, abstract = {In dieser Dissertation wird ein szenischer Bewegtbilddatensatz mit erweitertem Dynamikumfang (High Dynamic - Range, HDR) und gro\ss em Farbumfang (Wide Color Gamut, WCG) - eingef\"uhrt und es werden Modelle zur Kodierung von HDR und WCG + Range, HDR) und gro{\ss}em Farbumfang (Wide Color Gamut, WCG) + eingef{\"u}hrt und es werden Modelle zur Kodierung von HDR und WCG Bildern vorgestellt. Die objektive und visuelle Evaluation neuer HDR und WCG Bildverarbeitungsalgorithmen, Kompressionsverfahren - und Bildwiedergabeger\"ate erfordert einen Referenzdatensatz hoher - Qualit\"at. Daher wird ein neuer HDR- und WCG-Video-Datensatz mit - einem Dynamikumfang von bis zu 18 fotografischen Blenden - eingef\"uhrt. Er enth\"alt inszenierte und dokumentarische Szenen. - Die einzelnen Szenen sind konzipiert um eine Herausforderung f\"ur - Tone Mapping Operatoren, Gamut Mapping Algorithmen, - Kompressionscodecs und HDR und WCG Bildanzeigeger\"ate - darzustellen. Die Szenen sind mit professionellem Licht, Maske und - Filmausstattung aufgenommen. Um einen cinematischen Bildeindruck - zu erhalten, werden digitale Filmkameras mit `Super-35 mm' - Sensorgr\"o\ss e verwendet. Der zus\"atzliche Informationsgehalt - von HDR- und WCG-Videosignalen erfordert im Vergleich zu Signalen - mit herk\"ommlichem Dynamikumfang eine neue und effizientere - Signalkodierung. Ein Farbraum f\"ur HDR und WCG Video sollte nicht - nur effizient quantisieren, sondern wegen der unterschiedlichen - Monitoreigenschaften auf der Empf\"angerseite auch f\"ur die + und Bildwiedergabeger{\"a}te erfordert einen Referenzdatensatz + hoher Qualit{\"a}t. Daher wird ein neuer HDR- und + WCG-Video-Datensatz mit einem Dynamikumfang von bis zu 18 + fotografischen Blenden eingef{\"u}hrt. Er enth{\"a}lt inszenierte + und dokumentarische Szenen. Die einzelnen Szenen sind konzipiert + um eine Herausforderung f{\"u}r Tone Mapping Operatoren, Gamut + Mapping Algorithmen, Kompressionscodecs und HDR und WCG + Bildanzeigeger{\"a}te darzustellen. Die Szenen sind mit + professionellem Licht, Maske und Filmausstattung aufgenommen. Um + einen cinematischen Bildeindruck zu erhalten, werden digitale + Filmkameras mit `Super-35 mm' Sensorgr{\"o}{\ss}e verwendet. Der + zus{\"a}tzliche Informationsgehalt von HDR- und WCG-Videosignalen + erfordert im Vergleich zu Signalen mit herk{\"o}mmlichem + Dynamikumfang eine neue und effizientere Signalkodierung. Ein + Farbraum f{\"u}r HDR und WCG Video sollte nicht nur effizient + quantisieren, sondern wegen der unterschiedlichen + Monitoreigenschaften auf der Empf{\"a}ngerseite auch f{\"u}r die Dynamik- und Farbumfangsanpassung geeignet sein. Bisher wurden - Methoden f\"ur die Quantisierung von HDR Luminanzsignalen + Methoden f{\"u}r die Quantisierung von HDR Luminanzsignalen vorgeschlagen. Es fehlt jedoch noch ein entsprechendes Modell - f\"ur Farbdifferenzsignale. Es werden daher zwei neue Farbr\"aume - eingef\"uhrt, die sich sowohl f\"ur die effiziente Kodierung von - HDR und WCG Signalen als auch f\"ur die Dynamik- und - Farbumfangsanpassung eignen. Diese Farbr\"aume werden mit - existierenden HDR und WCG Farbsignalkodierungen des aktuellen - Stands der Technik verglichen. Die vorgestellten + f{\"u}r Farbdifferenzsignale. Es werden daher zwei neue + Farbr{\"a}ume eingef{\"u}hrt, die sich sowohl f{\"u}r die + effiziente Kodierung von HDR und WCG Signalen als auch f{\"u}r die + Dynamik- und Farbumfangsanpassung eignen. Diese Farbr{\"a}ume + werden mit existierenden HDR und WCG Farbsignalkodierungen des + aktuellen Stands der Technik verglichen. Die vorgestellten Kodierungsschemata erlauben es, HDR- und WCG-Video mittels drei - Farbkan\"alen mit 12 Bits tonaler Aufl\"osung zu quantisieren, - ohne dass Quantisierungsartefakte sichtbar werden. W\"ahrend die - Speicherung und \"Ubertragung von HDR und WCG Video mit 12-Bit - Farbtiefe pro Kanal angestrebt wird, unterst\"utzen aktuell + Farbkan{\"a}len mit 12 Bits tonaler Aufl{\"o}sung zu quantisieren, + ohne dass Quantisierungsartefakte sichtbar werden. W{\"a}hrend die + Speicherung und {\"U}bertragung von HDR und WCG Video mit 12-Bit + Farbtiefe pro Kanal angestrebt wird, unterst{\"u}tzen aktuell verbreitete Dateiformate, Videoschnittstellen und Kompressionscodecs oft nur niedrigere Bittiefen. Um diese - existierende Infrastruktur f\"ur die HDR Video\"ubertragung und - -speicherung nutzen zu k\"onnen, wird ein neues - bildinhaltsabh\"angiges Quantisierungsschema eingef\"uhrt. Diese - Quantisierungsmethode nutzt Bildeigenschaften wie Rauschen und - Textur um die ben\"otigte tonale Aufl\"osung f\"ur die visuell - verlustlose Quantisierung zu sch\"atzen. Die vorgestellte Methode - erlaubt es HDR Video mit einer Bittiefe von 10 Bits ohne sichtbare - Unterschiede zum Original zu quantisieren und kommt mit weniger - Rechenkraft im Vergleich zu aktuellen HDR Bilddifferenzmetriken - aus.}, + existierende Infrastruktur f{\"u}r die HDR Video{\"u}bertragung + und -speicherung nutzen zu k{\"o}nnen, wird ein neues + bildinhaltsabh{\"a}ngiges Quantisierungsschema eingef{\"u}hrt. + Diese Quantisierungsmethode nutzt Bildeigenschaften wie Rauschen + und Textur um die ben{\"o}tigte tonale Aufl{\"o}sung f{\"u}r die + visuell verlustlose Quantisierung zu sch{\"a}tzen. Die + vorgestellte Methode erlaubt es HDR Video mit einer Bittiefe von + 10 Bits ohne sichtbare Unterschiede zum Original zu quantisieren + und kommt mit weniger Rechenkraft im Vergleich zu aktuellen HDR + Bilddifferenzmetriken aus.}, collaborator = {Universit{\"a}t Stuttgart and Universit{\"a}t Stuttgart}, langid = {english}, @@ -1590,9 +1597,9 @@ @inproceedings{Guth1995a doi = {10.1117/12.206546}, urldate = {2014-09-26}, abstract = {Previous and recent revisions of the ATD model for - color perception\textbackslash nand visual adaption are - incorporated into the version that is fully\textbackslash - ndescribed in this paper.}, + color perception{\textbackslash}nand visual adaption are + incorporated into the version that is + fully{\textbackslash}ndescribed in this paper.}, keywords = {chromatic adaptation,color appearances,color discriminations,color models}, } @@ -1679,7 +1686,7 @@ @article{Hellwig2022 } @article{Hellwig2022a, title = {Extending {{CIECAM02}} and {{CAM16}} for the - {{Helmholtz}}\textendash{{Kohlrausch}} Effect}, + {{Helmholtz}}{\textendash}{{Kohlrausch}} Effect}, shorttitle = {Extending}, author = {Hellwig, Luke and Stolitzka, Dale and Fairchild, Mark D.}, @@ -2322,7 +2329,7 @@ @article{Luo1996b pages = {412--429}, publisher = {{Wiley Subscription Services, Inc., A Wiley Company}}, issn = {0361-2317}, - doi = {10.1002/(SICI)1520-6378(199612)21:6{$<$}412::AID-COL4{$>$}3.0.CO;2-Z}, + doi = {10.1002/(SICI)1520-6378(199612)21:6<412::AID-COL4>3.0.CO;2-Z}, abstract = {A new colour model, named LLAB(l:c) is derived. It includes two parts: the BFD chromatic adaptation transform derived by Lam and Rigg, and a modified CIELAB uniform colour space. The @@ -2343,7 +2350,7 @@ @article{Luo1996b constancy, and quantification of colour-rendering properties. The model does not give predictions for chroma (as distinct from colourfulness), or for brightness, and it does not include any rod - response. \textcopyright{} 1996 John Wiley \& Sons, Inc.}, + response. {\textcopyright} 1996 John Wiley \& Sons, Inc.}, keywords = {chromatic adaptation transform,colour appearance,colour appearance model,colour difference,colour difference formula,corresponding colours,uniform colour space}, @@ -2353,7 +2360,7 @@ @inproceedings{Luo1996c {{Colour Appearance}} and {{Gamut Mapping}}}, booktitle = {Conference: 5th {{International Conference}} on {{High Technology}}: {{Imaging Science}} and {{Technology}} - \textendash{} {{Evolution}} \& {{Promise}}}, + {\textendash} {{Evolution}} \& {{Promise}}}, author = {Luo, Ming Ronnier and Morovic, J{\'a}n}, year = 1996, pages = {136--147}, @@ -2368,7 +2375,7 @@ @article{Luo1999 number = 4, pages = {295--296}, issn = {0361-2317}, - doi = {10.1002/(SICI)1520-6378(199908)24:4{$<$}295::AID-COL10{$>$}3.0.CO;2-K}, + doi = {10.1002/(SICI)1520-6378(199908)24:4<295::AID-COL10>3.0.CO;2-K}, abstract = {Predicting the binding mode of flexible polypeptides to proteins is an important task that falls outside the domain of applicability of most small molecule and protein-protein docking @@ -2379,7 +2386,7 @@ @article{Luo1999 poses was improved by post-processing with physics-based implicit solvent MM- GBSA calculations. Using the best RMSD among the top 10 scoring poses as a metric, the success rate (RMSD {$\leq$} 2.0 - \AA{} for the interface backbone atoms) increased from 21\% with + {\AA} for the interface backbone atoms) increased from 21\% with default Glide SP settings to 58\% with the enhanced peptide sampling and scoring protocol in the case of redocking to the native protein structure. This approaches the accuracy of the @@ -2770,7 +2777,7 @@ @article{Morovic2000 Descriptor obtained using the Segment Maxima Method. Throughout the article, the focus is both on colour reproduction media and colour images as well as on the suitability of the methods for use - in gamut mapping. \textcopyright{} 2000 John Wiley \& Sons. Inc.}, + in gamut mapping. {\textcopyright} 2000 John Wiley \& Sons. Inc.}, keywords = {Cross-media reproduction,Gamut boundary calculation,Gamut mapping}, } @@ -2815,7 +2822,7 @@ @article{Nayatani1995a } @article{Nayatani1997, title = {Simple Estimation Methods for the - {{Helmholtz}}\textemdash{{Kohlrausch}} Effect}, + {{Helmholtz}}{\textemdash}{{Kohlrausch}} Effect}, author = {Nayatani, Yoshinobu}, year = 1997, journal = {Color Research \& Application}, @@ -2823,34 +2830,34 @@ @article{Nayatani1997 number = 6, pages = {385--401}, issn = {1520-6378}, - doi = {10.1002/(SICI)1520-6378(199712)22:6{$<$}385::AID-COL6{$>$}3.0.CO;2-R}, + doi = {10.1002/(SICI)1520-6378(199712)22:6<385::AID-COL6>3.0.CO;2-R}, urldate = {2021-06-22}, abstract = {Four kinds of simple estimation equations are - proposed for the Helmholtz\textemdash Kohlrausch effect. Two of + proposed for the Helmholtz{\textemdash}Kohlrausch effect. Two of them can be used for luminous colors, and the other two for object colors. In each of luminous and object colors, the two estimation equations are given to each of the Variable-Achromatic-Color (VAC) and the Variable-Chromatic-Color (VCC) methods. All the equations - are similar in type to the Ware\textemdash Cowan equation. They + are similar in type to the Ware{\textemdash}Cowan equation. They give the ratio between luminance (or metric lightness) of test color stimulus and its equivalent luminance (or equivalent lightness) directly. Though their computations are simple, they - can apply to various H\textemdash K effects including their + can apply to various H{\textemdash}K effects including their adapting luminance dependency. The applicable fields of the - proposed equations are wider than those of the Ware\textemdash - Cowan equation. The proposed equations can be applied to predict - the H\textemdash K effect within the whole chromaticity gamut - including spectral colors, spectral luminosity functions based on - direct color matching from 0.01 Td to 100 000 Td using the - photopic and the scotopic spectral luminosity functions specified - by CIE, equivalent lightness values of NCS colors, and others. - \textcopyright{} 1997 John Wiley \& Sons, Inc. Col Res Appl. 22, - 385\textendash 401, 1997}, - copyright = {Copyright \textcopyright{} 1997 John Wiley \& Sons, + proposed equations are wider than those of the + Ware{\textemdash}Cowan equation. The proposed equations can be + applied to predict the H{\textemdash}K effect within the whole + chromaticity gamut including spectral colors, spectral luminosity + functions based on direct color matching from 0.01 Td to 100 000 + Td using the photopic and the scotopic spectral luminosity + functions specified by CIE, equivalent lightness values of NCS + colors, and others. {\textcopyright} 1997 John Wiley \& Sons, Inc. + Col Res Appl. 22, 385{\textendash}401, 1997}, + copyright = {Copyright {\textcopyright} 1997 John Wiley \& Sons, Inc.}, langid = {english}, keywords = {CIELUV formula,color appearance,equivalent - lightness,equivalent luminance,Helmholtz\textemdash Kohlrausch + lightness,equivalent luminance,Helmholtz{\textemdash}Kohlrausch effect}, } @article{Newhall1943a, @@ -3166,20 +3173,20 @@ @article{Sharma2005b doi = {10.1002/col.20070}, urldate = {2014-09-27}, abstract = {This article and the associated data and - programs\textbackslash nprovided with it are intended to assist - color engineers and\textbackslash nscientists in correctly - implementing the recently developed\textbackslash nCIEDE2000 - color-difference formula. We indicate several\textbackslash - npotential implementation errors that are not uncovered - in\textbackslash ntests performed using the original sample data - published\textbackslash nwith the standard. A supplemental set of - data is provided for\textbackslash ncomprehensive testing of - implementations. The test data,\textbackslash nMicrosoft Excel - spreadsheets, and MATLAB scripts for\textbackslash nevaluating the - CIEDE2000 color difference are made avail-\textbackslash nable at - the first author's website. Finally, we also point - out\textbackslash nsmall mathematical discontinuities in the - formula.}, + programs{\textbackslash}nprovided with it are intended to assist + color engineers and{\textbackslash}nscientists in correctly + implementing the recently developed{\textbackslash}nCIEDE2000 + color-difference formula. We indicate + several{\textbackslash}npotential implementation errors that are + not uncovered in{\textbackslash}ntests performed using the + original sample data published{\textbackslash}nwith the standard. + A supplemental set of data is provided + for{\textbackslash}ncomprehensive testing of implementations. The + test data,{\textbackslash}nMicrosoft Excel spreadsheets, and + MATLAB scripts for{\textbackslash}nevaluating the CIEDE2000 color + difference are made avail-{\textbackslash}nable at the first + author's website. Finally, we also point out{\textbackslash}nsmall + mathematical discontinuities in the formula.}, keywords = {CIE,CIE94,CIEDE2000,CIELAB,CMC,Color-difference metrics}, } @@ -3301,7 +3308,7 @@ @misc{SocietyofMotionPictureandTelevisionEngineers2014a } @misc{SocietyofMotionPictureandTelevisionEngineers2019, title = {{{ST}} 428-1:2019 - {{D-Cinema Distribution Master}} - \textemdash{} {{Image Characteristic}}}, + {\textemdash} {{Image Characteristic}}}, author = {{Society of Motion Picture and Television Engineers}}, year = 2019, doi = {10.5594/SMPTE.ST428-1.2019}, @@ -3402,16 +3409,17 @@ @misc{Susstrunk1999a there if necessary. When applied correctly, a standard RGB space can minimize color space conversions in an imaging workflow, improve image reproducibility, and facilitate - accountability.\textbackslash nThe digital image color workflow is - examined with emphasis on when an RGB color space is appropriate, - and when to apply color management by profile. An RGB space is - ``standard'' because either it is defined in an official standards - document (a de jure standard) or it is supported by commonly used - tools (a de facto standard). Examples of standard RGB color spaces - are ISO RGB, sRGB, ROMM RGB, Adobe RGB 98, Apple RGB, and video - RGB spaces (NTSC, EBU, ITU-R BT.709). As there is no one RGB color - space that is suitable for all imaging needs, factors to consider - when choosing an RGB color space are discussed.}, + accountability.{\textbackslash}nThe digital image color workflow + is examined with emphasis on when an RGB color space is + appropriate, and when to apply color management by profile. An RGB + space is ``standard'' because either it is defined in an official + standards document (a de jure standard) or it is supported by + commonly used tools (a de facto standard). Examples of standard + RGB color spaces are ISO RGB, sRGB, ROMM RGB, Adobe RGB 98, Apple + RGB, and video RGB spaces (NTSC, EBU, ITU-R BT.709). As there is + no one RGB color space that is suitable for all imaging needs, + factors to consider when choosing an RGB color space are + discussed.}, keywords = {are becoming a thing,color communication,color image workflow,color management,color spaces,color standards,it is quite common,of the,past,skilled operators manage color,to be scanned @@ -3555,6 +3563,12 @@ @misc{TheAcademyofMotionPictureArtsandSciences2020a pages = {1--7}, urldate = {2023-06-05}, } +@misc{TheAcademyofMotionPictureArtsandSciences2023, + title = {{{IDT}}.{{Apple}}.{{AppleLog}}\_{{BT2020}}.Ctl}, + author = {{The Academy of Motion Picture Arts and Sciences}}, + year = 2023, + urldate = {2023-12-17}, +} @misc{TheAcademyofMotionPictureArtsandSciencesa, title = {{{ACESutil}}.{{Lin}}\_to\_{{Log2}}\_param.Ctl}, author = {{The Academy of Motion Picture Arts and Sciences} @@ -3776,12 +3790,11 @@ @misc{Wikipedia2003e howpublished = {https://en.wikipedia.org/wiki/Vandermonde\_matrix}, } @misc{Wikipedia2003f, - title = {Rayleigh\textendash{{Jeans}} Law}, + title = {Rayleigh{\textendash}{{Jeans}} Law}, author = {{Wikipedia}}, year = 2003, urldate = {2022-02-12}, - howpublished = {https://en.wikipedia.org/wiki/Rayleigh\textendash - Jeans\_law}, + howpublished = {https://en.wikipedia.org/wiki/Rayleigh{\textendash}Jeans\_law}, } @misc{Wikipedia2004, title = {Peak Signal-to-Noise Ratio}, diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 67ab8e5ad3..58ec1de535 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -8,23 +8,22 @@ In the interest of fostering an open and welcoming environment, we as contributo Examples of behavior that contributes to creating a positive environment include: -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community -* Showing empathy towards other community members +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members Examples of unacceptable behavior by participants include: -* The use of sexualized language or imagery and unwelcome sexual attention or advances -* Trolling, insulting/derogatory comments, and personal or political attacks -* Public or private harassment -* Publishing others’ private information, such as a physical or electronic address, without explicit permission -* Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting ## Our Responsibilities - Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. @@ -35,7 +34,6 @@ This Code of Conduct applies within all project spaces, and it also applies when ## Enforcement - Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting Thomas Mansencal and Michael Mauderer via email at thomas@colour-science.org and michael@colour-science.org respectively. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project’s leadership. @@ -46,6 +44,5 @@ This Code of Conduct is adapted from the Contributor Covenant, version 1.4, avai For answers to common questions about this code of conduct, see [https://www.contributor-covenant.org/faq][faq]. - [homepage]: https://www.contributor-covenant.org/version/1/4/code-of-conduct.html -[faq]: https://www.contributor-covenant.org/faq \ No newline at end of file +[faq]: https://www.contributor-covenant.org/faq diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst index 190ab2a821..e43153ff4b 100644 --- a/CONTRIBUTORS.rst +++ b/CONTRIBUTORS.rst @@ -204,6 +204,14 @@ Development & Technical Support Spectral Similarity Index computation improvements. +- **Thomas A Caswell**, *Computational Scientist @ Brookhaven National Laboratory* + + Typing annotations improvements. + +- **Liam Collod**, *VFX Software Developer @ Mikros Animation* + + Documentation improvements. + Acknowledgements ---------------- - **Steve Agland**, *Supervising Lighting Technical Director @ Animal Logic* @@ -263,12 +271,14 @@ Issues & Discussions - @AndersAtEndian - @Apoorva-13 - @Artoria2e5 +- @BQ-Octantis - @CHRIBUR0309 - @Chandler - @ChunHsinWang - @Edwardlin-zlt - @EricFlyMeToTheMoon - @Floschoe +- @GuillemRamisa - @JarrettR - @JayPalm - @Jerry2001 @@ -298,6 +308,7 @@ Issues & Discussions - @TFiFiE - @TomFryers - @ValZapod +- @Voultapher - @Wagyx - @Wangld5 - @Willingo @@ -308,6 +319,7 @@ Issues & Discussions - @alban-sol - @alianoroozi - @altert +- @alyfreym - @am-ac - @andurilhuang - @anshulxyz @@ -333,6 +345,7 @@ Issues & Discussions - @digital-prepress - @diuming - @dofuuz +- @domisjustanumber - @dtbulmerJRs - @eitanlees - @ema2159 @@ -354,6 +367,8 @@ Issues & Discussions - @iinnovations - @jaguarondi - @jamesmyatt +- @jamesmyatt +- @juneleung - @kaihagseth - @kamikaze - @kljumat @@ -368,6 +383,7 @@ Issues & Discussions - @matt-roberts - @matthiasbirkich - @meshing +- @mesvam - @mforbes - @mokincha - @monkeywithacupcake @@ -413,6 +429,7 @@ Issues & Discussions - @vibhoothi - @vidakDK - @volkerjaenisch +- @volrak - @vsohler - @vvclin-git - @whornsby diff --git a/README.rst b/README.rst index ab37dd02fe..0b995c4323 100644 --- a/README.rst +++ b/README.rst @@ -1,4 +1,14 @@ -.. image:: https://raw.githubusercontent.com/colour-science/colour-branding/master/images/Colour_Logo_001.png +.. begin-trim-long-description + +.. raw:: html + + + + + + + +.. end-trim-long-description | @@ -21,20 +31,20 @@ .. |version| image:: https://img.shields.io/pypi/v/colour-science.svg?style=flat-square :target: https://pypi.org/project/colour-science :alt: Package Version -.. |zenodo| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.8284953-blue.svg?style=flat-square - :target: https://dx.doi.org/10.5281/zenodo.8284953 +.. |zenodo| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.10396329-blue.svg?style=flat-square + :target: https://dx.doi.org/10.5281/zenodo.10396329 :alt: DOI .. end-badges `Colour `__ is an open-source -`Python `__ package providing a comprehensive number +`Python `__ package providing a comprehensive number of algorithms and datasets for colour science. It is freely available under the `BSD-3-Clause `__ terms. -**Colour** is an affiliated project of `NumFOCUS `__, a +**Colour** is an affiliated project of `NumFOCUS `__, a 501(c)(3) nonprofit in the United States. .. contents:: **Table of Contents** @@ -257,7 +267,7 @@ Most of the objects are available from the ``colour`` namespace: .. code-block:: python - >>> import colour + import colour Automatic Colour Conversion Graph - ``colour.graph`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -269,12 +279,10 @@ conversion graph enabling easier colour conversions. .. code-block:: python - >>> sd = colour.SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] - >>> colour.convert( - ... sd, "Spectral Distribution", "sRGB", verbose={"mode": "Short"} - ... ) + sd = colour.SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] + colour.convert(sd, "Spectral Distribution", "sRGB", verbose={"mode": "Short"}) -:: +.. code-block:: text =============================================================================== * * @@ -287,13 +295,16 @@ conversion graph enabling easier colour conversions. .. code-block:: python - >>> illuminant = colour.SDS_ILLUMINANTS["FL2"] - >>> colour.convert( - ... sd, - ... "Spectral Distribution", - ... "sRGB", - ... sd_to_XYZ={"illuminant": illuminant}, - ... ) + illuminant = colour.SDS_ILLUMINANTS["FL2"] + colour.convert( + sd, + "Spectral Distribution", + "sRGB", + sd_to_XYZ={"illuminant": illuminant}, + ) + +.. code-block:: text + array([ 0.47924575, 0.31676968, 0.17362725]) Chromatic Adaptation - ``colour.adaptation`` @@ -301,16 +312,21 @@ Chromatic Adaptation - ``colour.adaptation`` .. code-block:: python - >>> XYZ = [0.20654008, 0.12197225, 0.05136952] - >>> D65 = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][ - ... "D65" - ... ] - >>> A = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["A"] - >>> colour.chromatic_adaptation( - ... XYZ, colour.xy_to_XYZ(D65), colour.xy_to_XYZ(A) - ... ) + XYZ = [0.20654008, 0.12197225, 0.05136952] + D65 = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"] + A = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["A"] + colour.chromatic_adaptation(XYZ, colour.xy_to_XYZ(D65), colour.xy_to_XYZ(A)) + +.. code-block:: text + array([ 0.2533053 , 0.13765138, 0.01543307]) - >>> sorted(colour.CHROMATIC_ADAPTATION_METHODS) + +.. code-block:: python + + sorted(colour.CHROMATIC_ADAPTATION_METHODS) + +.. code-block:: text + ['CIE 1994', 'CMCCAT2000', 'Fairchild 1990', 'Von Kries', 'Zhai 2018'] Algebra - ``colour.algebra`` @@ -321,9 +337,12 @@ Kernel Interpolation .. code-block:: python - >>> y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] - >>> x = range(len(y)) - >>> colour.KernelInterpolator(x, y)([0.25, 0.75, 5.50]) + y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] + x = range(len(y)) + colour.KernelInterpolator(x, y)([0.25, 0.75, 5.50]) + +.. code-block:: text + array([ 6.18062083, 8.08238488, 57.85783403]) Sprague (1880) Interpolation @@ -331,9 +350,12 @@ Sprague (1880) Interpolation .. code-block:: python - >>> y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] - >>> x = range(len(y)) - >>> colour.SpragueInterpolator(x, y)([0.25, 0.75, 5.50]) + y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] + x = range(len(y)) + colour.SpragueInterpolator(x, y)([0.25, 0.75, 5.50]) + +.. code-block:: text + array([ 6.72951612, 7.81406251, 43.77379185]) Colour Appearance Models - ``colour.appearance`` @@ -341,21 +363,54 @@ Colour Appearance Models - ``colour.appearance`` .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> XYZ_w = [95.05, 100.00, 108.88] - >>> L_A = 318.31 - >>> Y_b = 20.0 - >>> colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + XYZ_w = [95.05, 100.00, 108.88] + L_A = 318.31 + Y_b = 20.0 + colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_CIECAM02(J=34.434525727858997, C=67.365010921125943, h=22.279164147957065, s=62.81485585332716, Q=177.47124941102123, M=70.024939419291414, H=2.6896085344238898, HC=None) - >>> colour.XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: python + + colour.XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_CIECAM16(J=34.434525727858997, C=67.365010921125943, h=22.279164147957065, s=62.81485585332716, Q=177.47124941102123, M=70.024939419291414, H=2.6896085344238898, HC=None) - >>> colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: python + + colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_CAM16(J=33.880368498111686, C=69.444353357408033, h=19.510887327451748, s=64.03612114840314, Q=176.03752758512178, M=72.18638534116765, H=399.52975599115319, HC=None) - >>> colour.XYZ_to_Hellwig2022(XYZ, XYZ_w, L_A) + +.. code-block:: python + + colour.XYZ_to_Hellwig2022(XYZ, XYZ_w, L_A) + +.. code-block:: text + CAM_Specification_Hellwig2022(J=33.880368498111686, C=40.347043294550311, h=19.510887327451748, s=117.38555017188679, Q=45.34489577734751, M=53.228355383108031, H=399.52975599115319, HC=None) - >>> colour.XYZ_to_Kim2009(XYZ, XYZ_w, L_A) + +.. code-block:: python + + colour.XYZ_to_Kim2009(XYZ, XYZ_w, L_A) + +.. code-block:: text + CAM_Specification_Kim2009(J=19.879918542450902, C=55.839055250876946, h=22.013388165090046, s=112.97979354939129, Q=36.309026130161449, M=46.346415858227864, H=2.3543198369639931, HC=None) - >>> colour.XYZ_to_ZCAM(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: python + + colour.XYZ_to_ZCAM(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_ZCAM(J=38.347186278956357, C=21.12138989208518, h=33.711578931095197, s=81.444585609489536, Q=76.986725284523772, M=42.403805833900506, H=0.45779200212219573, HC=None, V=43.623590687423544, K=43.20894953152817, W=34.829588380192149) Colour Blindness - ``colour.blindness`` @@ -363,15 +418,23 @@ Colour Blindness - ``colour.blindness`` .. code-block:: python - >>> import numpy as np - >>> cmfs = colour.LMS_CMFS["Stockman & Sharpe 2 Degree Cone Fundamentals"] - >>> colour.msds_cmfs_anomalous_trichromacy_Machado2009( - ... cmfs, np.array([15, 0, 0]) - ... )[450] + import numpy as np + + cmfs = colour.LMS_CMFS["Stockman & Sharpe 2 Degree Cone Fundamentals"] + colour.msds_cmfs_anomalous_trichromacy_Machado2009(cmfs, np.array([15, 0, 0]))[450] + +.. code-block:: text + array([ 0.08912884, 0.0870524 , 0.955393 ]) - >>> primaries = colour.MSDS_DISPLAY_PRIMARIES["Apple Studio Display"] - >>> d_LMS = (15, 0, 0) - >>> colour.matrix_anomalous_trichromacy_Machado2009(cmfs, primaries, d_LMS) + +.. code-block:: python + + primaries = colour.MSDS_DISPLAY_PRIMARIES["Apple Studio Display"] + d_LMS = (15, 0, 0) + colour.matrix_anomalous_trichromacy_Machado2009(cmfs, primaries, d_LMS) + +.. code-block:: text + array([[-0.27774652, 2.65150084, -1.37375432], [ 0.27189369, 0.20047862, 0.52762768], [ 0.00644047, 0.25921579, 0.73434374]]) @@ -381,13 +444,23 @@ Colour Correction - ``colour characterisation`` .. code-block:: python - >>> import numpy as np - >>> RGB = [0.17224810, 0.09170660, 0.06416938] - >>> M_T = np.random.random((24, 3)) - >>> M_R = M_T + (np.random.random((24, 3)) - 0.5) * 0.5 - >>> colour.colour_correction(RGB, M_T, M_R) + import numpy as np + + RGB = [0.17224810, 0.09170660, 0.06416938] + M_T = np.random.random((24, 3)) + M_R = M_T + (np.random.random((24, 3)) - 0.5) * 0.5 + colour.colour_correction(RGB, M_T, M_R) + +.. code-block:: text + array([ 0.1806237 , 0.07234791, 0.07848845]) - >>> sorted(colour.COLOUR_CORRECTION_METHODS) + +.. code-block:: python + + sorted(colour.COLOUR_CORRECTION_METHODS) + +.. code-block:: text + ['Cheung 2004', 'Finlayson 2015', 'Vandermonde'] ACES Input Transform - ``colour characterisation`` @@ -395,9 +468,12 @@ ACES Input Transform - ``colour characterisation`` .. code-block:: python - >>> sensitivities = colour.MSDS_CAMERA_SENSITIVITIES["Nikon 5100 (NPL)"] - >>> illuminant = colour.SDS_ILLUMINANTS["D55"] - >>> colour.matrix_idt(sensitivities, illuminant) + sensitivities = colour.MSDS_CAMERA_SENSITIVITIES["Nikon 5100 (NPL)"] + illuminant = colour.SDS_ILLUMINANTS["D55"] + colour.matrix_idt(sensitivities, illuminant) + +.. code-block:: text + (array([[ 0.59368175, 0.30418371, 0.10213454], [ 0.00457979, 1.14946003, -0.15403982], [ 0.03552213, -0.16312291, 1.12760077]]), array([ 1.58214188, 1. , 1.28910346])) @@ -410,9 +486,18 @@ Spectral Computations .. code-block:: python - >>> colour.sd_to_XYZ(colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"]) + colour.sd_to_XYZ(colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"]) + +.. code-block:: text + array([ 36.94726204, 32.62076174, 13.0143849 ]) - >>> sorted(colour.SPECTRAL_TO_XYZ_METHODS) + +.. code-block:: python + + sorted(colour.SPECTRAL_TO_XYZ_METHODS) + +.. code-block:: text + ['ASTM E308', 'Integration', 'astm2015'] @@ -421,119 +506,122 @@ Multi-Spectral Computations .. code-block:: python - >>> msds = np.array( - ... [ - ... [ - ... [ - ... 0.01367208, - ... 0.09127947, - ... 0.01524376, - ... 0.02810712, - ... 0.19176012, - ... 0.04299992, - ... ], - ... [ - ... 0.00959792, - ... 0.25822842, - ... 0.41388571, - ... 0.22275120, - ... 0.00407416, - ... 0.37439537, - ... ], - ... [ - ... 0.01791409, - ... 0.29707789, - ... 0.56295109, - ... 0.23752193, - ... 0.00236515, - ... 0.58190280, - ... ], - ... ], - ... [ - ... [ - ... 0.01492332, - ... 0.10421912, - ... 0.02240025, - ... 0.03735409, - ... 0.57663846, - ... 0.32416266, - ... ], - ... [ - ... 0.04180972, - ... 0.26402685, - ... 0.03572137, - ... 0.00413520, - ... 0.41808194, - ... 0.24696727, - ... ], - ... [ - ... 0.00628672, - ... 0.11454948, - ... 0.02198825, - ... 0.39906919, - ... 0.63640803, - ... 0.01139849, - ... ], - ... ], - ... [ - ... [ - ... 0.04325933, - ... 0.26825359, - ... 0.23732357, - ... 0.05175860, - ... 0.01181048, - ... 0.08233768, - ... ], - ... [ - ... 0.02484169, - ... 0.12027161, - ... 0.00541695, - ... 0.00654612, - ... 0.18603799, - ... 0.36247808, - ... ], - ... [ - ... 0.03102159, - ... 0.16815442, - ... 0.37186235, - ... 0.08610666, - ... 0.00413520, - ... 0.78492409, - ... ], - ... ], - ... [ - ... [ - ... 0.11682307, - ... 0.78883040, - ... 0.74468607, - ... 0.83375293, - ... 0.90571451, - ... 0.70054168, - ... ], - ... [ - ... 0.06321812, - ... 0.41898224, - ... 0.15190357, - ... 0.24591440, - ... 0.55301750, - ... 0.00657664, - ... ], - ... [ - ... 0.00305180, - ... 0.11288624, - ... 0.11357290, - ... 0.12924391, - ... 0.00195315, - ... 0.21771573, - ... ], - ... ], - ... ] - ... ) - >>> colour.msds_to_XYZ( - ... msds, - ... method="Integration", - ... shape=colour.SpectralShape(400, 700, 60), - ... ) + msds = np.array( + [ + [ + [ + 0.01367208, + 0.09127947, + 0.01524376, + 0.02810712, + 0.19176012, + 0.04299992, + ], + [ + 0.00959792, + 0.25822842, + 0.41388571, + 0.22275120, + 0.00407416, + 0.37439537, + ], + [ + 0.01791409, + 0.29707789, + 0.56295109, + 0.23752193, + 0.00236515, + 0.58190280, + ], + ], + [ + [ + 0.01492332, + 0.10421912, + 0.02240025, + 0.03735409, + 0.57663846, + 0.32416266, + ], + [ + 0.04180972, + 0.26402685, + 0.03572137, + 0.00413520, + 0.41808194, + 0.24696727, + ], + [ + 0.00628672, + 0.11454948, + 0.02198825, + 0.39906919, + 0.63640803, + 0.01139849, + ], + ], + [ + [ + 0.04325933, + 0.26825359, + 0.23732357, + 0.05175860, + 0.01181048, + 0.08233768, + ], + [ + 0.02484169, + 0.12027161, + 0.00541695, + 0.00654612, + 0.18603799, + 0.36247808, + ], + [ + 0.03102159, + 0.16815442, + 0.37186235, + 0.08610666, + 0.00413520, + 0.78492409, + ], + ], + [ + [ + 0.11682307, + 0.78883040, + 0.74468607, + 0.83375293, + 0.90571451, + 0.70054168, + ], + [ + 0.06321812, + 0.41898224, + 0.15190357, + 0.24591440, + 0.55301750, + 0.00657664, + ], + [ + 0.00305180, + 0.11288624, + 0.11357290, + 0.12924391, + 0.00195315, + 0.21771573, + ], + ], + ] + ) + colour.msds_to_XYZ( + msds, + method="Integration", + shape=colour.SpectralShape(400, 700, 60), + ) + +.. code-block:: text + array([[[ 7.68544647, 4.09414317, 8.49324254], [ 17.12567298, 27.77681821, 25.52573685], [ 19.10280411, 34.45851476, 29.76319628]], @@ -546,7 +634,13 @@ Multi-Spectral Computations [[ 80.00969553, 80.39810464, 76.08184429], [ 33.27611427, 24.38947838, 39.34919287], [ 8.89425686, 11.05185138, 10.86767594]]]) - >>> sorted(colour.MSDS_TO_XYZ_METHODS) + +.. code-block:: python + + sorted(colour.MSDS_TO_XYZ_METHODS) + +.. code-block:: text + ['ASTM E308', 'Integration', 'astm2015'] Blackbody Spectral Radiance Computation @@ -554,7 +648,10 @@ Blackbody Spectral Radiance Computation .. code-block:: python - >>> colour.sd_blackbody(5000) + colour.sd_blackbody(5000) + +.. code-block:: text + SpectralDistribution([[ 3.60000000e+02, 6.65427827e+12], [ 3.61000000e+02, 6.70960528e+12], [ 3.62000000e+02, 6.76482512e+12], @@ -572,9 +669,12 @@ Dominant, Complementary Wavelength & Colour Purity Computation .. code-block:: python - >>> xy = [0.54369557, 0.32107944] - >>> xy_n = [0.31270000, 0.32900000] - >>> colour.dominant_wavelength(xy, xy_n) + xy = [0.54369557, 0.32107944] + xy_n = [0.31270000, 0.32900000] + colour.dominant_wavelength(xy, xy_n) + +.. code-block:: text + (array(616.0), array([ 0.68354746, 0.31628409]), array([ 0.68354746, 0.31628409])) @@ -584,10 +684,19 @@ Lightness Computation .. code-block:: python - >>> colour.lightness(12.19722535) + colour.lightness(12.19722535) + +.. code-block:: text + 41.527875844653451 - >>> sorted(colour.LIGHTNESS_METHODS) - ['Abebe 2017' + +.. code-block:: python + + sorted(colour.LIGHTNESS_METHODS) + +.. code-block:: text + + ['Abebe 2017', 'CIE 1976', 'Fairchild 2010', 'Fairchild 2011', @@ -600,9 +709,18 @@ Luminance Computation .. code-block:: python - >>> colour.luminance(41.52787585) + colour.luminance(41.52787585) + +.. code-block:: text + 12.197225353400775 - >>> sorted(colour.LUMINANCE_METHODS) + +.. code-block:: python + + sorted(colour.LUMINANCE_METHODS) + +.. code-block:: text + ['ASTM D1535', 'CIE 1976', 'Fairchild 2010', @@ -616,11 +734,20 @@ Whiteness Computation .. code-block:: python - >>> XYZ = [95.00000000, 100.00000000, 105.00000000] - >>> XYZ_0 = [94.80966767, 100.00000000, 107.30513595] - >>> colour.whiteness(XYZ, XYZ_0) + XYZ = [95.00000000, 100.00000000, 105.00000000] + XYZ_0 = [94.80966767, 100.00000000, 107.30513595] + colour.whiteness(XYZ, XYZ_0) + +.. code-block:: text + array([ 93.756 , -1.33000001]) - >>> sorted(colour.WHITENESS_METHODS) + +.. code-block:: python + + sorted(colour.WHITENESS_METHODS) + +.. code-block:: text + ['ASTM E313', 'Berger 1959', 'CIE 2004', @@ -634,10 +761,19 @@ Yellowness Computation .. code-block:: python - >>> XYZ = [95.00000000, 100.00000000, 105.00000000] - >>> colour.yellowness(XYZ) + XYZ = [95.00000000, 100.00000000, 105.00000000] + colour.yellowness(XYZ) + +.. code-block:: text + 4.3400000000000034 - >>> sorted(colour.YELLOWNESS_METHODS) + +.. code-block:: python + + sorted(colour.YELLOWNESS_METHODS) + +.. code-block:: text + ['ASTM D1925', 'ASTM E313', 'ASTM E313 Alternative'] Luminous Flux, Efficiency & Efficacy Computation @@ -645,14 +781,29 @@ Luminous Flux, Efficiency & Efficacy Computation .. code-block:: python - >>> sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] - >>> colour.luminous_flux(sd) + sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] + colour.luminous_flux(sd) + +.. code-block:: text + 23807.655527367202 - >>> sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] - >>> colour.luminous_efficiency(sd) + +.. code-block:: python + + sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] + colour.luminous_efficiency(sd) + +.. code-block:: text + 0.19943935624521045 - >>> sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] - >>> colour.luminous_efficacy(sd) + +.. code-block:: python + + sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] + colour.luminous_efficacy(sd) + +.. code-block:: text + 136.21708031547874 Contrast Sensitivity Function - ``colour.contrast`` @@ -660,22 +811,39 @@ Contrast Sensitivity Function - ``colour.contrast`` .. code-block:: python - >>> colour.contrast_sensitivity_function(u=4, X_0=60, E=65) + colour.contrast_sensitivity_function(u=4, X_0=60, E=65) + +.. code-block:: text + 358.51180789884984 - >>> sorted(colour.CONTRAST_SENSITIVITY_METHODS) - ['Barten 1999'] +.. code-block:: python + + sorted(colour.CONTRAST_SENSITIVITY_METHODS) + +.. code-block:: text + + ['Barten 1999'] Colour Difference - ``colour.difference`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python - >>> Lab_1 = [100.00000000, 21.57210357, 272.22819350] - >>> Lab_2 = [100.00000000, 426.67945353, 72.39590835] - >>> colour.delta_E(Lab_1, Lab_2) + Lab_1 = [100.00000000, 21.57210357, 272.22819350] + Lab_2 = [100.00000000, 426.67945353, 72.39590835] + colour.delta_E(Lab_1, Lab_2) + +.. code-block:: text + 94.035649026659485 - >>> sorted(colour.DELTA_E_METHODS) + +.. code-block:: python + + sorted(colour.DELTA_E_METHODS) + +.. code-block:: text + ['CAM02-LCD', 'CAM02-SCD', 'CAM02-UCS', @@ -700,8 +868,11 @@ Images .. code-block:: python - >>> RGB = colour.read_image("Ishihara_Colour_Blindness_Test_Plate_3.png") - >>> RGB.shape + RGB = colour.read_image("Ishihara_Colour_Blindness_Test_Plate_3.png") + RGB.shape + +.. code-block:: text + (276, 281, 3) Look Up Table (LUT) Data @@ -709,10 +880,10 @@ Look Up Table (LUT) Data .. code-block:: python - >>> LUT = colour.read_LUT("ACES_Proxy_10_to_ACES.cube") - >>> print(LUT) + LUT = colour.read_LUT("ACES_Proxy_10_to_ACES.cube") + print(LUT) -:: +.. code-block:: text LUT3x1D - ACES Proxy 10 to ACES ------------------------------- @@ -723,8 +894,11 @@ Look Up Table (LUT) Data .. code-block:: python - >>> RGB = [0.17224810, 0.09170660, 0.06416938] - >>> LUT.apply(RGB) + RGB = [0.17224810, 0.09170660, 0.06416938] + LUT.apply(RGB) + +.. code-block:: text + array([ 0.00575674, 0.00181493, 0.00121419]) Colour Models - ``colour.models`` @@ -735,7 +909,10 @@ CIE xyY Colourspace .. code-block:: python - >>> colour.XYZ_to_xyY([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_xyY([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.54369557, 0.32107944, 0.12197225]) CIE L*a*b* Colourspace @@ -743,7 +920,10 @@ CIE L*a*b* Colourspace .. code-block:: python - >>> colour.XYZ_to_Lab([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Lab([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 41.52787529, 52.63858304, 26.92317922]) CIE L*u*v* Colourspace @@ -751,7 +931,10 @@ CIE L*u*v* Colourspace .. code-block:: python - >>> colour.XYZ_to_Luv([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Luv([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 41.52787529, 96.83626054, 17.75210149]) CIE 1960 UCS Colourspace @@ -759,7 +942,10 @@ CIE 1960 UCS Colourspace .. code-block:: python - >>> colour.XYZ_to_UCS([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_UCS([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.13769339, 0.12197225, 0.1053731 ]) CIE 1964 U*V*W* Colourspace @@ -767,8 +953,11 @@ CIE 1964 U*V*W* Colourspace .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_UVW(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_UVW(XYZ) + +.. code-block:: text + array([ 94.55035725, 11.55536523, 40.54757405]) CAM02-LCD, CAM02-SCD, and CAM02-UCS Colourspaces - Luo, Cui and Li (2006) @@ -776,18 +965,27 @@ CAM02-LCD, CAM02-SCD, and CAM02-UCS Colourspaces - Luo, Cui and Li (2006) .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> XYZ_w = [95.05, 100.00, 108.88] - >>> L_A = 318.31 - >>> Y_b = 20.0 - >>> surround = colour.VIEWING_CONDITIONS_CIECAM02["Average"] - >>> specification = colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround) - >>> JMh = (specification.J, specification.M, specification.h) - >>> colour.JMh_CIECAM02_to_CAM02UCS(JMh) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + XYZ_w = [95.05, 100.00, 108.88] + L_A = 318.31 + Y_b = 20.0 + surround = colour.VIEWING_CONDITIONS_CIECAM02["Average"] + specification = colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround) + JMh = (specification.J, specification.M, specification.h) + colour.JMh_CIECAM02_to_CAM02UCS(JMh) + +.. code-block:: text + array([ 47.16899898, 38.72623785, 15.8663383 ]) - >>> XYZ = [0.20654008, 0.12197225, 0.05136952] - >>> XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] - >>> colour.XYZ_to_CAM02UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + +.. code-block:: python + + XYZ = [0.20654008, 0.12197225, 0.05136952] + XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] + colour.XYZ_to_CAM02UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + +.. code-block:: text + array([ 47.16899898, 38.72623785, 15.8663383 ]) CAM16-LCD, CAM16-SCD, and CAM16-UCS Colourspaces - Li et al. (2017) @@ -795,18 +993,27 @@ CAM16-LCD, CAM16-SCD, and CAM16-UCS Colourspaces - Li et al. (2017) .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> XYZ_w = [95.05, 100.00, 108.88] - >>> L_A = 318.31 - >>> Y_b = 20.0 - >>> surround = colour.VIEWING_CONDITIONS_CAM16["Average"] - >>> specification = colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround) - >>> JMh = (specification.J, specification.M, specification.h) - >>> colour.JMh_CAM16_to_CAM16UCS(JMh) - array([ 46.55542238, 40.22460974, 14.25288392] - >>> XYZ = [0.20654008, 0.12197225, 0.05136952] - >>> XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] - >>> colour.XYZ_to_CAM16UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + XYZ_w = [95.05, 100.00, 108.88] + L_A = 318.31 + Y_b = 20.0 + surround = colour.VIEWING_CONDITIONS_CAM16["Average"] + specification = colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround) + JMh = (specification.J, specification.M, specification.h) + colour.JMh_CAM16_to_CAM16UCS(JMh) + +.. code-block:: text + + array([ 46.55542238, 40.22460974, 14.25288392]) + +.. code-block:: python + + XYZ = [0.20654008, 0.12197225, 0.05136952] + XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] + colour.XYZ_to_CAM16UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + +.. code-block:: text + array([ 46.55542238, 40.22460974, 14.25288392]) DIN99 Colourspace and DIN99b, DIN99c, DIN99d Refined Formulas @@ -814,8 +1021,11 @@ DIN99 Colourspace and DIN99b, DIN99c, DIN99d Refined Formulas .. code-block:: python - >>> Lab = [41.52787529, 52.63858304, 26.92317922] - >>> colour.Lab_to_DIN99(Lab) + Lab = [41.52787529, 52.63858304, 26.92317922] + colour.Lab_to_DIN99(Lab) + +.. code-block:: text + array([ 53.22821988, 28.41634656, 3.89839552]) ICaCb Colourspace @@ -823,7 +1033,10 @@ ICaCb Colourspace .. code-block:: python - >>> XYZ_to_ICaCb(np.array([0.20654008, 0.12197225, 0.05136952])) + XYZ_to_ICaCb(np.array([0.20654008, 0.12197225, 0.05136952])) + +.. code-block:: text + array([ 0.06875297, 0.05753352, 0.02081548]) IgPgTg Colourspace @@ -831,7 +1044,10 @@ IgPgTg Colourspace .. code-block:: python - >>> colour.XYZ_to_IgPgTg([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_IgPgTg([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.42421258, 0.18632491, 0.10689223]) IPT Colourspace @@ -839,7 +1055,10 @@ IPT Colourspace .. code-block:: python - >>> colour.XYZ_to_IPT([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_IPT([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.38426191, 0.38487306, 0.18886838]) Jzazbz Colourspace @@ -847,7 +1066,10 @@ Jzazbz Colourspace .. code-block:: python - >>> colour.XYZ_to_Jzazbz([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Jzazbz([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.00535048, 0.00924302, 0.00526007]) hdr-CIELAB Colourspace @@ -855,7 +1077,10 @@ hdr-CIELAB Colourspace .. code-block:: python - >>> colour.XYZ_to_hdr_CIELab([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_hdr_CIELab([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 51.87002062, 60.4763385 , 32.14551912]) hdr-IPT Colourspace @@ -863,7 +1088,10 @@ hdr-IPT Colourspace .. code-block:: python - >>> colour.XYZ_to_hdr_IPT([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_hdr_IPT([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 25.18261761, -22.62111297, 3.18511729]) Hunter L,a,b Colour Scale @@ -871,8 +1099,11 @@ Hunter L,a,b Colour Scale .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_Hunter_Lab(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_Hunter_Lab(XYZ) + +.. code-block:: text + array([ 34.92452577, 47.06189858, 14.38615107]) Hunter Rd,a,b Colour Scale @@ -880,8 +1111,11 @@ Hunter Rd,a,b Colour Scale .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_Hunter_Rdab(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_Hunter_Rdab(XYZ) + +.. code-block:: text + array([ 12.197225 , 57.12537874, 17.46241341]) Oklab Colourspace @@ -889,7 +1123,10 @@ Oklab Colourspace .. code-block:: python - >>> colour.XYZ_to_Oklab([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Oklab([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.51634019, 0.154695 , 0.06289579]) OSA UCS Colourspace @@ -897,8 +1134,11 @@ OSA UCS Colourspace .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_OSA_UCS(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_OSA_UCS(XYZ) + +.. code-block:: text + array([-3.0049979 , 2.99713697, -9.66784231]) ProLab Colourspace @@ -906,7 +1146,10 @@ ProLab Colourspace .. code-block:: python - >>> colour.XYZ_to_ProLab([0.51634019, 0.15469500, 0.06289579]) + colour.XYZ_to_ProLab([0.51634019, 0.15469500, 0.06289579]) + +.. code-block:: text + array([1.24610688, 2.39525236, 0.41902126]) Ragoo and Farup (2021) Optimised IPT Colourspace @@ -914,7 +1157,10 @@ Ragoo and Farup (2021) Optimised IPT Colourspace .. code-block:: python - >>> colour.XYZ_to_IPT_Ragoo2021([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_IPT_Ragoo2021([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.42248243, 0.2910514 , 0.20410663]) Yrg Colourspace - Kirk (2019) @@ -922,7 +1168,10 @@ Yrg Colourspace - Kirk (2019) .. code-block:: python - >>> colour.XYZ_to_Yrg([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Yrg([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.13137801, 0.49037645, 0.37777388]) Y'CbCr Colour Encoding @@ -930,7 +1179,10 @@ Y'CbCr Colour Encoding .. code-block:: python - >>> colour.RGB_to_YCbCr([1.0, 1.0, 1.0]) + colour.RGB_to_YCbCr([1.0, 1.0, 1.0]) + +.. code-block:: text + array([ 0.92156863, 0.50196078, 0.50196078]) YCoCg Colour Encoding @@ -938,7 +1190,10 @@ YCoCg Colour Encoding .. code-block:: python - >>> colour.RGB_to_YCoCg([0.75, 0.75, 0.0]) + colour.RGB_to_YCoCg([0.75, 0.75, 0.0]) + +.. code-block:: text + array([ 0.5625, 0.375 , 0.1875]) ICtCp Colour Encoding @@ -946,7 +1201,10 @@ ICtCp Colour Encoding .. code-block:: python - >>> colour.RGB_to_ICtCp([0.45620519, 0.03081071, 0.04091952]) + colour.RGB_to_ICtCp([0.45620519, 0.03081071, 0.04091952]) + +.. code-block:: text + array([ 0.07351364, 0.00475253, 0.09351596]) HSV Colourspace @@ -954,7 +1212,10 @@ HSV Colourspace .. code-block:: python - >>> colour.RGB_to_HSV([0.45620519, 0.03081071, 0.04091952]) + colour.RGB_to_HSV([0.45620519, 0.03081071, 0.04091952]) + +.. code-block:: text + array([ 0.99603944, 0.93246304, 0.45620519]) IHLS Colourspace @@ -962,7 +1223,10 @@ IHLS Colourspace .. code-block:: python - >>> colour.RGB_to_IHLS([0.45620519, 0.03081071, 0.04091952]) + colour.RGB_to_IHLS([0.45620519, 0.03081071, 0.04091952]) + +.. code-block:: text + array([ 6.26236117, 0.12197943, 0.42539448]) Prismatic Colourspace @@ -970,7 +1234,10 @@ Prismatic Colourspace .. code-block:: python - >>> colour.RGB_to_Prismatic([0.25, 0.50, 0.75]) + colour.RGB_to_Prismatic([0.25, 0.50, 0.75]) + +.. code-block:: text + array([ 0.75 , 0.16666667, 0.33333333, 0.5 ]) RGB Colourspace and Transformations @@ -978,22 +1245,25 @@ RGB Colourspace and Transformations .. code-block:: python - >>> XYZ = [0.21638819, 0.12570000, 0.03847493] - >>> illuminant_XYZ = [0.34570, 0.35850] - >>> illuminant_RGB = [0.31270, 0.32900] - >>> chromatic_adaptation_transform = "Bradford" - >>> matrix_XYZ_to_RGB = [ - ... [3.24062548, -1.53720797, -0.49862860], - ... [-0.96893071, 1.87575606, 0.04151752], - ... [0.05571012, -0.20402105, 1.05699594], - ... ] - >>> colour.XYZ_to_RGB( - ... XYZ, - ... illuminant_XYZ, - ... illuminant_RGB, - ... matrix_XYZ_to_RGB, - ... chromatic_adaptation_transform, - ... ) + XYZ = [0.21638819, 0.12570000, 0.03847493] + illuminant_XYZ = [0.34570, 0.35850] + illuminant_RGB = [0.31270, 0.32900] + chromatic_adaptation_transform = "Bradford" + matrix_XYZ_to_RGB = [ + [3.24062548, -1.53720797, -0.49862860], + [-0.96893071, 1.87575606, 0.04151752], + [0.05571012, -0.20402105, 1.05699594], + ] + colour.XYZ_to_RGB( + XYZ, + illuminant_XYZ, + illuminant_RGB, + matrix_XYZ_to_RGB, + chromatic_adaptation_transform, + ) + +.. code-block:: text + array([ 0.45595571, 0.03039702, 0.04087245]) RGB Colourspace Derivation @@ -1001,9 +1271,12 @@ RGB Colourspace Derivation .. code-block:: python - >>> p = [0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700] - >>> w = [0.32168, 0.33767] - >>> colour.normalised_primary_matrix(p, w) + p = [0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700] + w = [0.32168, 0.33767] + colour.normalised_primary_matrix(p, w) + +.. code-block:: text + array([[ 9.52552396e-01, 0.00000000e+00, 9.36786317e-05], [ 3.43966450e-01, 7.28166097e-01, -7.21325464e-02], [ 0.00000000e+00, 0.00000000e+00, 1.00882518e+00]]) @@ -1013,7 +1286,10 @@ RGB Colourspaces .. code-block:: python - >>> sorted(colour.RGB_COLOURSPACES) + sorted(colour.RGB_COLOURSPACES) + +.. code-block:: text + ['ACES2065-1', 'ACEScc', 'ACEScct', @@ -1089,7 +1365,10 @@ OETFs .. code-block:: python - >>> sorted(colour.OETFS) + sorted(colour.OETFS) + +.. code-block:: text + ['ARIB STD-B67', 'Blackmagic Film Generation 5', 'DaVinci Intermediate', @@ -1109,7 +1388,10 @@ EOTFs .. code-block:: python - >>> sorted(colour.EOTFS) + sorted(colour.EOTFS) + +.. code-block:: text + ['DCDM', 'DICOM GSDF', 'ITU-R BT.1886', @@ -1125,18 +1407,26 @@ OOTFs .. code-block:: python - >>> sorted(colour.OOTFS) + sorted(colour.OOTFS) + +.. code-block:: text + ['ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'] + Log Encoding / Decoding *********************** .. code-block:: python - >>> sorted(colour.LOG_ENCODINGS) + sorted(colour.LOG_ENCODINGS) + +.. code-block:: text + ['ACEScc', 'ACEScct', 'ACESproxy', + 'Apple Log Profile', 'ARRI LogC3', 'ARRI LogC4', 'Canon Log', @@ -1170,10 +1460,14 @@ CCTFs Encoding / Decoding .. code-block:: python - >>> sorted(colour.CCTF_ENCODINGS) + sorted(colour.CCTF_ENCODINGS) + +.. code-block:: text + ['ACEScc', 'ACEScct', 'ACESproxy', + 'Apple Log Profile', 'ARRI LogC3', 'ARRI LogC4', 'ARIB STD-B67', @@ -1223,10 +1517,18 @@ Recommendation ITU-T H.273 Code points for Video Signal Type Identification .. code-block:: python - >>> colour.COLOUR_PRIMARIES_ITUTH273.keys() + colour.COLOUR_PRIMARIES_ITUTH273.keys() + +.. code-block:: text + dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 22, 23]) - >>> colour.COLOUR_PRIMARIES_ITUTH273.keys() - >>> description = colour.models.describe_video_signal_colour_primaries(1) + +.. code-block:: python + + colour.models.describe_video_signal_colour_primaries(1) + +.. code-block:: text + =============================================================================== * * * Colour Primaries: 1 * @@ -1246,11 +1548,21 @@ Recommendation ITU-T H.273 Code points for Video Signal Type Identification * FFmpeg Constants : ['AVCOL_PRI_BT709', 'BT709'] * * * =============================================================================== - >>> colour.TRANSFER_CHARACTERISTICS_ITUTH273.keys() + +.. code-block:: python + + colour.TRANSFER_CHARACTERISTICS_ITUTH273.keys() + +.. code-block:: text + dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) - >>> description = ( - ... colour.models.describe_video_signal_transfer_characteristics(1) - ... ) + +.. code-block:: python + + colour.models.describe_video_signal_transfer_characteristics(1) + +.. code-block:: text + =============================================================================== * * * Transfer Characteristics: 1 * @@ -1260,11 +1572,21 @@ Recommendation ITU-T H.273 Code points for Video Signal Type Identification * FFmpeg Constants : ['AVCOL_TRC_BT709', 'BT709'] * * * =============================================================================== - >>> colour.MATRIX_COEFFICIENTS_ITUTH273.keys() + +.. code-block:: python + + colour.MATRIX_COEFFICIENTS_ITUTH273.keys() + +.. code-block:: text + dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) - >>> description = colour.models.describe_video_signal_matrix_coefficients( - ... 1 - ... ) + +.. code-block:: python + + colour.models.describe_video_signal_matrix_coefficients(1) + +.. code-block:: text + =============================================================================== * * * Matrix Coefficients: 1 * @@ -1283,9 +1605,18 @@ Munsell Value .. code-block:: python - >>> colour.munsell_value(12.23634268) + colour.munsell_value(12.23634268) + +.. code-block:: text + 4.0824437076525664 - >>> sorted(colour.MUNSELL_VALUE_METHODS) + +.. code-block:: python + + sorted(colour.MUNSELL_VALUE_METHODS) + +.. code-block:: text + ['ASTM D1535', 'Ladd 1955', 'McCamy 1987', @@ -1300,9 +1631,18 @@ Munsell Colour .. code-block:: python - >>> colour.xyY_to_munsell_colour([0.38736945, 0.35751656, 0.59362000]) + colour.xyY_to_munsell_colour([0.38736945, 0.35751656, 0.59362000]) + +.. code-block:: text + '4.2YR 8.1/5.3' - >>> colour.munsell_colour_to_xyY("4.2YR 8.1/5.3") + +.. code-block:: python + + colour.munsell_colour_to_xyY("4.2YR 8.1/5.3") + +.. code-block:: text + array([ 0.38736945, 0.35751656, 0.59362 ]) Optical Phenomena - ``colour.phenomena`` @@ -1310,7 +1650,10 @@ Optical Phenomena - ``colour.phenomena`` .. code-block:: python - >>> colour.rayleigh_scattering_sd() + colour.rayleigh_scattering_sd() + +.. code-block:: text + SpectralDistribution([[ 3.60000000e+02, 5.99101337e-01], [ 3.61000000e+02, 5.92170690e-01], [ 3.62000000e+02, 5.85341006e-01], @@ -1331,9 +1674,18 @@ Colour Fidelity Index .. code-block:: python - >>> colour.colour_fidelity_index(colour.SDS_ILLUMINANTS["FL2"]) + colour.colour_fidelity_index(colour.SDS_ILLUMINANTS["FL2"]) + +.. code-block:: text + 70.120825477833037 - >>> sorted(colour.COLOUR_FIDELITY_INDEX_METHODS) + +.. code-block:: python + + sorted(colour.COLOUR_FIDELITY_INDEX_METHODS) + +.. code-block:: text + ['ANSI/IES TM-30-18', 'CIE 2017'] Colour Quality Scale @@ -1341,9 +1693,18 @@ Colour Quality Scale .. code-block:: python - >>> colour.colour_quality_scale(colour.SDS_ILLUMINANTS["FL2"]) + colour.colour_quality_scale(colour.SDS_ILLUMINANTS["FL2"]) + +.. code-block:: text + 64.111703163816699 - >>> sorted(colour.COLOUR_QUALITY_SCALE_METHODS) + +.. code-block:: python + + sorted(colour.COLOUR_QUALITY_SCALE_METHODS) + +.. code-block:: text + ['NIST CQS 7.4', 'NIST CQS 9.0'] Colour Rendering Index @@ -1351,7 +1712,10 @@ Colour Rendering Index .. code-block:: python - >>> colour.colour_rendering_index(colour.SDS_ILLUMINANTS["FL2"]) + colour.colour_rendering_index(colour.SDS_ILLUMINANTS["FL2"]) + +.. code-block:: text + 64.233724121664807 Academy Spectral Similarity Index (SSI) @@ -1359,9 +1723,12 @@ Academy Spectral Similarity Index (SSI) .. code-block:: python - >>> colour.spectral_similarity_index( - ... colour.SDS_ILLUMINANTS["C"], colour.SDS_ILLUMINANTS["D65"] - ... ) + colour.spectral_similarity_index( + colour.SDS_ILLUMINANTS["C"], colour.SDS_ILLUMINANTS["D65"] + ) + +.. code-block:: text + 94.0 Spectral Up-Sampling & Recovery - ``colour.recovery`` @@ -1372,7 +1739,10 @@ Reflectance Recovery .. code-block:: python - >>> colour.XYZ_to_sd([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_sd([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + SpectralDistribution([[ 3.60000000e+02, 8.40144095e-02], [ 3.65000000e+02, 8.41264236e-02], [ 3.70000000e+02, 8.40057597e-02], @@ -1385,40 +1755,44 @@ Reflectance Recovery Extrapolator, {'method': 'Constant', 'left': None, 'right': None}) - >>> sorted(colour.REFLECTANCE_RECOVERY_METHODS) +.. code-block:: python + + sorted(colour.REFLECTANCE_RECOVERY_METHODS) + +.. code-block:: text + ['Jakob 2019', 'Mallett 2019', 'Meng 2015', 'Otsu 2018', 'Smits 1999'] Camera RGB Sensitivities Recovery ********************************* - >>> illuminant = colour.colorimetry.SDS_ILLUMINANTS["D65"] - >>> sensitivities = colour.characterisation.MSDS_CAMERA_SENSITIVITIES[ - ... "Nikon 5100 (NPL)" - ... ] - >>> reflectances = [ - ... sd.copy().align( - ... colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017 - ... ) - ... for sd in colour.characterisation.SDS_COLOURCHECKERS[ - ... "BabelColor Average" - ... ].values() - ... ] - >>> reflectances = colour.colorimetry.sds_and_msds_to_msds(reflectances) - >>> RGB = colour.colorimetry.msds_to_XYZ( - ... reflectances, - ... method="Integration", - ... cmfs=sensitivities, - ... illuminant=illuminant, - ... k=0.01, - ... shape=colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, - ... ) - >>> colour.recovery.RGB_to_msds_camera_sensitivities_Jiang2013( - ... RGB, - ... illuminant, - ... reflectances, - ... colour.recovery.BASIS_FUNCTIONS_DYER2017, - ... colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, - ... ) +.. code-block:: python + + illuminant = colour.colorimetry.SDS_ILLUMINANTS["D65"] + sensitivities = colour.characterisation.MSDS_CAMERA_SENSITIVITIES["Nikon 5100 (NPL)"] + reflectances = [ + sd.copy().align(colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017) + for sd in colour.characterisation.SDS_COLOURCHECKERS["BabelColor Average"].values() + ] + reflectances = colour.colorimetry.sds_and_msds_to_msds(reflectances) + RGB = colour.colorimetry.msds_to_XYZ( + reflectances, + method="Integration", + cmfs=sensitivities, + illuminant=illuminant, + k=0.01, + shape=colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, + ) + colour.recovery.RGB_to_msds_camera_sensitivities_Jiang2013( + RGB, + illuminant, + reflectances, + colour.recovery.BASIS_FUNCTIONS_DYER2017, + colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, + ) + +.. code-block:: text + RGB_CameraSensitivities([[ 4.00000000e+02, 7.22815777e-03, 9.22506480e-03, -9.88368972e-03], [ 4.10000000e+02, -8.50457609e-03, 1.12777480e-02, @@ -1443,11 +1817,26 @@ Correlated Colour Temperature Computation Methods - ``colour.temperature`` .. code-block:: python - >>> colour.uv_to_CCT([0.1978, 0.3122]) + colour.uv_to_CCT([0.1978, 0.3122]) + +.. code-block:: text + array([ 6.50751282e+03, 3.22335875e-03]) - >>> sorted(colour.UV_TO_CCT_METHODS) + +.. code-block:: python + + sorted(colour.UV_TO_CCT_METHODS) + +.. code-block:: text + ['Krystek 1985', 'Ohno 2013', 'Planck 1900', 'Robertson 1968', 'ohno2013', 'robertson1968'] - >>> sorted(colour.XY_TO_CCT_METHODS) + +.. code-block:: python + + sorted(colour.XY_TO_CCT_METHODS) + +.. code-block:: text + ['CIE Illuminant D Series', 'Hernandez 1999', 'Kang 2002', @@ -1462,9 +1851,10 @@ Colour Volume - ``colour.volume`` .. code-block:: python - >>> colour.RGB_colourspace_volume_MonteCarlo( - ... colour.RGB_COLOURSPACE_RGB["sRGB"] - ... ) + colour.RGB_colourspace_volume_MonteCarlo(colour.RGB_COLOURSPACE_RGB["sRGB"]) + +.. code-block:: text + 821958.30000000005 Geometry Primitives Generation - ``colour.geometry`` @@ -1472,8 +1862,11 @@ Geometry Primitives Generation - ``colour.geometry`` .. code-block:: python - >>> colour.primitive("Grid") - (array([ ([-0.5, 0.5, 0. ], [ 0., 1.], [ 0., 0., 1.], [ 0., 1., 0., 1.]), + colour.primitive("Grid") + +.. code-block:: text + + (array([ ([-0.5, 0.5, 0. ], [ 0., 1.], [ 0., 0., 1.], [ 0., 1., 0., 1.]), ([ 0.5, 0.5, 0. ], [ 1., 1.], [ 0., 0., 1.], [ 1., 1., 0., 1.]), ([-0.5, -0.5, 0. ], [ 0., 0.], [ 0., 0., 1.], [ 0., 0., 0., 1.]), ([ 0.5, -0.5, 0. ], [ 1., 0.], [ 0., 0., 1.], [ 1., 0., 0., 1.])], @@ -1482,14 +1875,26 @@ Geometry Primitives Generation - ``colour.geometry`` [2, 3], [3, 1], [1, 0]], dtype=uint32)) - >>> sorted(colour.PRIMITIVE_METHODS) + +.. code-block:: python + + sorted(colour.PRIMITIVE_METHODS) + +.. code-block:: text + ['Cube', 'Grid'] - >>> colour.primitive_vertices("Quad MPL") + +.. code-block:: python + + colour.primitive_vertices("Quad MPL") + +.. code-block:: text + array([[ 0., 0., 0.], [ 1., 0., 0.], [ 1., 1., 0.], [ 0., 1., 0.]]) - >>> sorted(colour.PRIMITIVE_VERTICES_METHODS) + sorted(colour.PRIMITIVE_VERTICES_METHODS) ['Cube MPL', 'Grid MPL', 'Quad MPL', 'Sphere'] Plotting - ``colour.plotting`` @@ -1499,15 +1904,16 @@ Most of the objects are available from the ``colour.plotting`` namespace: .. code-block:: python - >>> from colour.plotting import * - >>> colour_style() + from colour.plotting import * + + colour_style() Visible Spectrum **************** .. code-block:: python - >>> plot_visible_spectrum("CIE 1931 2 Degree Standard Observer") + plot_visible_spectrum("CIE 1931 2 Degree Standard Observer") .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Visible_Spectrum.png @@ -1516,7 +1922,7 @@ Spectral Distribution .. code-block:: python - >>> plot_single_illuminant_sd("FL1") + plot_single_illuminant_sd("FL1") .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Illuminant_F1_SD.png @@ -1525,17 +1931,17 @@ Blackbody .. code-block:: python - >>> blackbody_sds = [ - ... colour.sd_blackbody(i, colour.SpectralShape(0, 10000, 10)) - ... for i in range(1000, 15000, 1000) - ... ] - >>> plot_multi_sds( - ... blackbody_sds, - ... y_label="W / (sr m$^2$) / m", - ... plot_kwargs={"use_sd_colours": True, "normalise_sd_colours": True}, - ... legend_location="upper right", - ... bounding_box=(0, 1250, 0, 2.5e6), - ... ) + blackbody_sds = [ + colour.sd_blackbody(i, colour.SpectralShape(0, 10000, 10)) + for i in range(1000, 15000, 1000) + ] + plot_multi_sds( + blackbody_sds, + y_label="W / (sr m$^2$) / m", + plot_kwargs={"use_sd_colours": True, "normalise_sd_colours": True}, + legend_location="upper right", + bounding_box=(0, 1250, 0, 2.5e6), + ) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Blackbodies.png @@ -1544,11 +1950,11 @@ Colour Matching Functions .. code-block:: python - >>> plot_single_cmfs( - ... "Stockman & Sharpe 2 Degree Cone Fundamentals", - ... y_label="Sensitivity", - ... bounding_box=(390, 870, 0, 1.1), - ... ) + plot_single_cmfs( + "Stockman & Sharpe 2 Degree Cone Fundamentals", + y_label="Sensitivity", + bounding_box=(390, 870, 0, 1.1), + ) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Cone_Fundamentals.png @@ -1557,20 +1963,20 @@ Luminous Efficiency .. code-block:: python - >>> sd_mesopic_luminous_efficiency_function = ( - ... colour.sd_mesopic_luminous_efficiency_function(0.2) - ... ) - >>> plot_multi_sds( - ... ( - ... sd_mesopic_luminous_efficiency_function, - ... colour.PHOTOPIC_LEFS["CIE 1924 Photopic Standard Observer"], - ... colour.SCOTOPIC_LEFS["CIE 1951 Scotopic Standard Observer"], - ... ), - ... y_label="Luminous Efficiency", - ... legend_location="upper right", - ... y_tighten=True, - ... margins=(0, 0, 0, 0.1), - ... ) + sd_mesopic_luminous_efficiency_function = ( + colour.sd_mesopic_luminous_efficiency_function(0.2) + ) + plot_multi_sds( + ( + sd_mesopic_luminous_efficiency_function, + colour.PHOTOPIC_LEFS["CIE 1924 Photopic Standard Observer"], + colour.SCOTOPIC_LEFS["CIE 1951 Scotopic Standard Observer"], + ), + y_label="Luminous Efficiency", + legend_location="upper right", + y_tighten=True, + margins=(0, 0, 0, 0.1), + ) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Luminous_Efficiency.png @@ -1579,29 +1985,26 @@ Colour Checker .. code-block:: python - >>> from colour.characterisation.dataset.colour_checkers.sds import ( - ... COLOURCHECKER_INDEXES_TO_NAMES_MAPPING, - ... ) - >>> plot_multi_sds( - ... [ - ... colour.SDS_COLOURCHECKERS["BabelColor Average"][value] - ... for key, value in sorted( - ... COLOURCHECKER_INDEXES_TO_NAMES_MAPPING.items() - ... ) - ... ], - ... plot_kwargs={ - ... "use_sd_colours": True, - ... }, - ... title=("BabelColor Average - " "Spectral Distributions"), - ... ) + from colour.characterisation.dataset.colour_checkers.sds import ( + COLOURCHECKER_INDEXES_TO_NAMES_MAPPING, + ) + + plot_multi_sds( + [ + colour.SDS_COLOURCHECKERS["BabelColor Average"][value] + for key, value in sorted(COLOURCHECKER_INDEXES_TO_NAMES_MAPPING.items()) + ], + plot_kwargs={ + "use_sd_colours": True, + }, + title=("BabelColor Average - " "Spectral Distributions"), + ) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_BabelColor_Average.png .. code-block:: python - >>> plot_single_colour_checker( - ... "ColorChecker 2005", text_kwargs={"visible": False} - ... ) + plot_single_colour_checker("ColorChecker 2005", text_kwargs={"visible": False}) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_ColorChecker_2005.png @@ -1610,9 +2013,7 @@ Chromaticities Prediction .. code-block:: python - >>> plot_corresponding_chromaticities_prediction( - ... 2, "Von Kries", "Bianco 2010" - ... ) + plot_corresponding_chromaticities_prediction(2, "Von Kries", "Bianco 2010") .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Chromaticities_Prediction.png @@ -1621,24 +2022,23 @@ Chromaticities .. code-block:: python - >>> import numpy as np - >>> RGB = np.random.random((32, 32, 3)) - >>> plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931( - ... RGB, - ... "ITU-R BT.709", - ... colourspaces=["ACEScg", "S-Gamut", "Pointer Gamut"], - ... ) + import numpy as np + + RGB = np.random.random((32, 32, 3)) + plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931( + RGB, + "ITU-R BT.709", + colourspaces=["ACEScg", "S-Gamut", "Pointer Gamut"], + ) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Chromaticities_CIE_1931_Chromaticity_Diagram.png -Colour Rendering Index -********************** +Colour Rendering Index Bars +*************************** .. code-block:: python - >>> plot_single_sd_colour_rendering_index_bars( - ... colour.SDS_ILLUMINANTS["FL2"] - ... ) + plot_single_sd_colour_rendering_index_bars(colour.SDS_ILLUMINANTS["FL2"]) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_CRI.png @@ -1647,7 +2047,7 @@ ANSI/IES TM-30-18 Colour Rendition Report .. code-block:: python - >>> plot_single_sd_colour_rendition_report(colour.SDS_ILLUMINANTS["FL2"]) + plot_single_sd_colour_rendition_report(colour.SDS_ILLUMINANTS["FL2"]) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Colour_Rendition_Report.png @@ -1656,17 +2056,13 @@ Gamut Section .. code-block:: python - >>> plot_visible_spectrum_section( - ... section_colours="RGB", section_opacity=0.15 - ... ) + plot_visible_spectrum_section(section_colours="RGB", section_opacity=0.15) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Plot_Visible_Spectrum_Section.png .. code-block:: python - >>> plot_RGB_colourspace_section( - ... "sRGB", section_colours="RGB", section_opacity=0.15 - ... ) + plot_RGB_colourspace_section("sRGB", section_colours="RGB", section_opacity=0.15) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_Plot_RGB_Colourspace_Section.png @@ -1675,9 +2071,7 @@ Colour Temperature .. code-block:: python - >>> plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS( - ... ["A", "B", "C"] - ... ) + plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS(["A", "B", "C"]) .. image:: https://colour.readthedocs.io/en/develop/_static/Examples_Plotting_CCT_CIE_1960_UCS_Chromaticity_Diagram.png @@ -1688,7 +2082,7 @@ Installation ~~~~~~~~~~~~ **Colour** and its primary dependencies can be easily installed from the -`Python Package Index `__ +`Python Package Index `__ by issuing this command in a shell: .. code-block:: bash @@ -1696,10 +2090,10 @@ by issuing this command in a shell: $ pip install --user colour-science The detailed installation procedure for the secondary dependencies is -described in the `Installation Guide `__. +described in the `Installation Guide `__. **Colour** is also available for `Anaconda `__ -from *Continuum Analytics* via `conda-forge `__: +from *Continuum Analytics* via `conda-forge `__: .. code-block:: bash @@ -1723,7 +2117,7 @@ Contributing ~~~~~~~~~~~~ If you would like to contribute to **Colour**, please refer to the following -`Contributing `__ guide. +`Contributing `__ guide. Changes ~~~~~~~ @@ -1733,7 +2127,7 @@ The changes are viewable on the `Releases `__ page. +The bibliography is available on the `Bibliography `__ page. It is also viewable directly from the repository in `BibTeX `__ @@ -1756,12 +2150,12 @@ Software **Python** - `ColorPy `__ by Kness, M. -- `Colorspacious `__ by Smith, N. J., et al. -- `python-colormath `__ by Taylor, G., et al. +- `Colorspacious `__ by Smith, N. J., et al. +- `python-colormath `__ by Taylor, G., et al. **Go** -- `go-colorful `__ by Beyer, L., et al. +- `go-colorful `__ by Beyer, L., et al. **.NET** @@ -1774,16 +2168,14 @@ Software **Matlab & Octave** - `COLORLAB `__ by Malo, J., et al. -- `Psychtoolbox `__ by Brainard, D., et al. +- `Psychtoolbox `__ by Brainard, D., et al. - `The Munsell and Kubelka-Munk Toolbox `__ by Centore, P. Code of Conduct --------------- The *Code of Conduct*, adapted from the `Contributor Covenant 1.4 `__, -is available on the `Code of Conduct `__ page. - -.. begin-trim-long-description +is available on the `Code of Conduct `__ page. Contact & Social ---------------- @@ -1796,6 +2188,8 @@ The *Colour Developers* can be reached via different means: - `Gitter `__ - `Twitter `__ +.. begin-trim-long-description + Thank You! ---------- diff --git a/SPONSORS.rst b/SPONSORS.rst index 5c2a415369..4f10955dc2 100644 --- a/SPONSORS.rst +++ b/SPONSORS.rst @@ -4,7 +4,7 @@ `Colour `__ is an independent `BSD-3-Clause `__ Open Source -affiliated project of `NumFOCUS `__, a 501(c)(3) +affiliated project of `NumFOCUS `__, a 501(c)(3) nonprofit in the United States. We are grateful 💖 for the support of our diff --git a/TODO.rst b/TODO.rst index d6cfb52a8c..cd5cac176b 100644 --- a/TODO.rst +++ b/TODO.rst @@ -6,64 +6,64 @@ TODO - colour/__init__.py - - Line 897 : # TODO: Remove legacy printing support when deemed appropriate. + - Line 878 : # TODO: Remove legacy printing support when deemed appropriate. - colour/colorimetry/spectrum.py - - Line 1189 : # TODO: Provide support for fractional interval like 0.1, etc... + - Line 1190 : # TODO: Provide support for fractional interval like 0.1, etc... - colour/colorimetry/tristimulus_values.py - - Line 1064 : # TODO: Investigate code vectorisation. + - Line 1071 : # TODO: Investigate code vectorisation. - colour/appearance/ciecam02.py - - Line 376 : # TODO: Compute hue composition. + - Line 377 : # TODO: Compute hue composition. - colour/appearance/ciecam16.py - - Line 324 : # TODO: Compute hue composition. + - Line 325 : # TODO: Compute hue composition. - colour/appearance/cam16.py - - Line 312 : # TODO: Compute hue composition. + - Line 313 : # TODO: Compute hue composition. - colour/appearance/hellwig2022.py - - Line 354 : # TODO: Compute hue composition. + - Line 355 : # TODO: Compute hue composition. - colour/appearance/hunt.py - - Line 486 : # TODO: Implement hue quadrature & composition computation. - - Line 517 : # TODO: Implement whiteness-blackness :math:`Q_{wb}` computation. + - Line 487 : # TODO: Implement hue quadrature & composition computation. + - Line 518 : # TODO: Implement whiteness-blackness :math:`Q_{wb}` computation. - colour/appearance/rlab.py - - Line 286 : # TODO: Implement hue composition computation. + - Line 287 : # TODO: Implement hue composition computation. - colour/appearance/nayatani95.py - - Line 310 : # TODO: Implement hue quadrature & composition computation. - - Line 323 : # TODO: Investigate components usage. M_RG, M_YB = tsplit(colourfulness_components(C_RG, C_YB, brightness_ideal_white)) + - Line 311 : # TODO: Implement hue quadrature & composition computation. + - Line 324 : # TODO: Investigate components usage. M_RG, M_YB = tsplit(colourfulness_components(C_RG, C_YB, brightness_ideal_white)) - colour/appearance/llab.py - - Line 395 : # TODO: Implement hue composition computation. + - Line 396 : # TODO: Implement hue composition computation. - colour/recovery/tests/test_jiang2013.py - - Line 61 : # TODO: Last eigen value seems to be very sensitive and produce differences on ARM. + - Line 63 : # TODO: Last eigen value seems to be very sensitive and produce differences on ARM. - colour/io/ocio.py @@ -73,55 +73,55 @@ TODO - colour/io/ctl.py - - Line 63 : # TODO: Reinstate coverage when "ctlrender" is trivially available cross-platform. + - Line 64 : # TODO: Reinstate coverage when "ctlrender" is trivially available cross-platform. - colour/io/tests/test_ocio.py - - Line 37 : # TODO: Remove when "Pypi" wheel compatible with "ARM" on "macOS" is released. + - Line 39 : # TODO: Remove when "Pypi" wheel compatible with "ARM" on "macOS" is released. - colour/io/tests/test_ctl.py - - Line 39 : # TODO: Reinstate coverage when "ctlrender" is tivially available cross-platform. + - Line 41 : # TODO: Reinstate coverage when "ctlrender" is tivially available cross-platform. - colour/io/tests/test_image.py - - Line 307 : # TODO: Investigate "OIIO" behaviour here: 1.0 != 15360.0 image = read_image_OpenImageIO( os.path.join(ROOT_RESOURCES, 'Colour_Logo.png'), 'float16') self.assertIs(image.dtype, np.dtype('float16')) self.assertEqual(np.min(image), 0.0) self.assertEqual(np.max(image), 1.0) + - Line 314 : # TODO: Investigate "OIIO" behaviour here: 1.0 != 15360.0 image = read_image_OpenImageIO( os.path.join(ROOT_RESOURCES, 'Colour_Logo.png'), 'float16') self.assertIs(image.dtype, np.dtype('float16')) self.assertEqual(np.min(image), 0.0) self.assertEqual(np.max(image), 1.0) - colour/models/rgb/derivation.py - - Line 239 : # TODO: Investigate if we return an ndarray here with primaries and whitepoint stacked together. + - Line 231 : # TODO: Investigate if we return an ndarray here with primaries and whitepoint stacked together. - colour/models/rgb/tests/test_rgb_colourspace.py - - Line 346 : # TODO: Remove tests when dropping deprecated signature support. - - Line 549 : # TODO: Remove tests when dropping deprecated signature support. + - Line 348 : # TODO: Remove tests when dropping deprecated signature support. + - Line 551 : # TODO: Remove tests when dropping deprecated signature support. - colour/models/rgb/tests/test_derivation.py - - Line 325 : # TODO: Simplify that monster. + - Line 339 : # TODO: Simplify that monster. - colour/utilities/verbose.py - - Line 627 : # TODO: Implement support for "pyproject.toml" file whenever "TOML" is supported in the standard library. + - Line 669 : # TODO: Implement support for "pyproject.toml" file whenever "TOML" is supported in the standard library. NOTE: A few clauses are not reached and a few packages are not available during continuous integration and are thus ignored for coverage. - colour/utilities/array.py - - Line 575 : # TODO: Remove when https://github.com/numpy/numpy/issues/5718 is addressed. - - Line 863 : # TODO: Investigate behaviour on Windows. - - Line 920 : # TODO: Annotate with "Union[Literal['ignore', 'reference', '1', '100'], str]" when Python 3.7 is dropped. + - Line 577 : # TODO: Remove when https://github.com/numpy/numpy/issues/5718 is addressed. + - Line 865 : # TODO: Investigate behaviour on Windows. + - Line 922 : # TODO: Annotate with "Union[Literal['ignore', 'reference', '1', '100'], str]" when Python 3.7 is dropped. - colour/plotting/models.py - - Line 1997 : # TODO: Filter appropriate colour models. NOTE: "dtype=object" is required for ragged array support in "Numpy" 1.24.0. + - Line 1939 : # TODO: Filter appropriate colour models. NOTE: "dtype=object" is required for ragged array support in "Numpy" 1.24.0. - colour/plotting/graph.py @@ -131,13 +131,13 @@ TODO - colour/plotting/common.py - - Line 799 : # TODO: Reassess according to https://github.com/matplotlib/matplotlib/issues/1077 - - Line 918 : # TODO: Consider using "MutableMapping" here. + - Line 870 : # TODO: Reassess according to https://github.com/matplotlib/matplotlib/issues/1077 + - Line 989 : # TODO: Consider using "MutableMapping" here. - colour/characterisation/aces_it.py - - Line 409 : # TODO: Remove when removing the "colour.sd_blackbody" definition warning. + - Line 397 : # TODO: Remove when removing the "colour.sd_blackbody" definition warning. - colour/characterisation/correction.py @@ -147,23 +147,23 @@ TODO - colour/notation/munsell.py - - Line 1247 : # TODO: Consider refactoring implementation. + - Line 1251 : # TODO: Consider refactoring implementation. - colour/continuous/signal.py - - Line 423 : # TODO: Check for interpolator compatibility. - - Line 483 : # TODO: Check for extrapolator compatibility. + - Line 424 : # TODO: Check for interpolator compatibility. + - Line 484 : # TODO: Check for extrapolator compatibility. - colour/hints/__init__.py - - Line 117 : # TODO: Revisit to use Protocol. + - Line 135 : # TODO: Revisit to use Protocol. - colour/algebra/tests/test_interpolation.py - - Line 1174 : # TODO: Revisit if the interpolator can be applied on non-uniform "x" independent variable. + - Line 1176 : # TODO: Revisit if the interpolator can be applied on non-uniform "x" independent variable. About ----- diff --git a/colour/__init__.py b/colour/__init__.py index e31a5c1bd2..e2767b1654 100644 --- a/colour/__init__.py +++ b/colour/__init__.py @@ -3,14 +3,14 @@ ====== `Colour `__ is an open-source -`Python `__ package providing a comprehensive number +`Python `__ package providing a comprehensive number of algorithms and datasets for colour science. It is freely available under the `BSD-3-Clause `__ terms. `Colour `__ is an affiliated project -of `NumFOCUS `__, a 501(c)(3) nonprofit in the United +of `NumFOCUS `__, a 501(c)(3) nonprofit in the United States. Sub-packages @@ -45,19 +45,12 @@ """ import contextlib -import numpy as np +import os import sys -from .utilities.deprecation import ModuleAPI, build_API_changes -from .utilities.documentation import is_documentation_building - -from .utilities.array import ( - domain_range_scale, - get_domain_range_scale, - set_domain_range_scale, -) +import numpy as np -from .hints import Any +from colour import plotting # noqa: F401 from .adaptation import ( CHROMATIC_ADAPTATION_METHODS, @@ -66,22 +59,91 @@ chromatic_adaptation, ) from .algebra import ( + TABLE_INTERPOLATION_METHODS, CubicSplineInterpolator, Extrapolator, KernelInterpolator, - NearestNeighbourInterpolator, LinearInterpolator, + NearestNeighbourInterpolator, NullInterpolator, PchipInterpolator, SpragueInterpolator, - TABLE_INTERPOLATION_METHODS, kernel_cardinal_spline, kernel_lanczos, kernel_linear, kernel_nearest_neighbour, kernel_sinc, - table_interpolation, lagrange_coefficients, + table_interpolation, +) +from .appearance import ( + HKE_NAYATANI1997_METHODS, + MEDIA_PARAMETERS_KIM2009, + VIEWING_CONDITIONS_CAM16, + VIEWING_CONDITIONS_CIECAM02, + VIEWING_CONDITIONS_CIECAM16, + VIEWING_CONDITIONS_HELLWIG2022, + VIEWING_CONDITIONS_HUNT, + VIEWING_CONDITIONS_KIM2009, + VIEWING_CONDITIONS_LLAB, + VIEWING_CONDITIONS_RLAB, + VIEWING_CONDITIONS_ZCAM, + CAM16_to_XYZ, + CAM_Specification_ATD95, + CAM_Specification_CAM16, + CAM_Specification_CIECAM02, + CAM_Specification_CIECAM16, + CAM_Specification_Hellwig2022, + CAM_Specification_Hunt, + CAM_Specification_Kim2009, + CAM_Specification_LLAB, + CAM_Specification_Nayatani95, + CAM_Specification_RLAB, + CAM_Specification_ZCAM, + CIECAM02_to_XYZ, + CIECAM16_to_XYZ, + Hellwig2022_to_XYZ, + HelmholtzKohlrausch_effect_luminous_Nayatani1997, + HelmholtzKohlrausch_effect_object_Nayatani1997, + Kim2009_to_XYZ, + XYZ_to_ATD95, + XYZ_to_CAM16, + XYZ_to_CIECAM02, + XYZ_to_CIECAM16, + XYZ_to_Hellwig2022, + XYZ_to_Hunt, + XYZ_to_Kim2009, + XYZ_to_LLAB, + XYZ_to_Nayatani95, + XYZ_to_RLAB, + XYZ_to_ZCAM, + ZCAM_to_XYZ, +) +from .blindness import ( + CVD_MATRICES_MACHADO2010, + matrix_anomalous_trichromacy_Machado2009, + matrix_cvd_Machado2009, + msds_cmfs_anomalous_trichromacy_Machado2009, +) +from .characterisation import ( + APPLY_MATRIX_COLOUR_CORRECTION_METHODS, + CCS_COLOURCHECKERS, + COLOUR_CORRECTION_METHODS, + MATRIX_COLOUR_CORRECTION_METHODS, + MSDS_CAMERA_SENSITIVITIES, + MSDS_DISPLAY_PRIMARIES, + POLYNOMIAL_EXPANSION_METHODS, + SDS_COLOURCHECKERS, + SDS_FILTERS, + SDS_LENSES, + apply_matrix_colour_correction, + camera_RGB_to_ACES2065_1, + colour_correction, + matrix_colour_correction, + matrix_idt, + polynomial_expansion, + sd_to_ACES2065_1, + sd_to_aces_relative_exposure_values, ) from .colorimetry import ( BANDPASS_CORRECTION_METHODS, @@ -91,22 +153,22 @@ LUMINANCE_METHODS, MSDS_CMFS, MSDS_TO_XYZ_METHODS, - MultiSpectralDistributions, - SDS_ILLUMINANTS, - SDS_LEFS, - SDS_LIGHT_SOURCES, SD_GAUSSIAN_METHODS, SD_MULTI_LEDS_METHODS, SD_SINGLE_LED_METHODS, SD_TO_XYZ_METHODS, + SDS_ILLUMINANTS, + SDS_LEFS, + SDS_LIGHT_SOURCES, SPECTRAL_SHAPE_ASTME308, SPECTRAL_SHAPE_DEFAULT, - SpectralDistribution, - SpectralShape, TVS_ILLUMINANTS, TVS_ILLUMINANTS_HUNTERLAB, WHITENESS_METHODS, YELLOWNESS_METHODS, + MultiSpectralDistributions, + SpectralDistribution, + SpectralShape, bandpass_correction, colorimetric_purity, complementary_wavelength, @@ -119,11 +181,11 @@ luminous_flux, msds_constant, msds_ones, - msds_zeros, msds_to_XYZ, + msds_zeros, + sd_blackbody, sd_CIE_illuminant_D_series, sd_CIE_standard_illuminant_A, - sd_blackbody, sd_constant, sd_gaussian, sd_mesopic_luminous_efficiency_function, @@ -138,117 +200,92 @@ whiteness, yellowness, ) -from .blindness import ( - CVD_MATRICES_MACHADO2010, - matrix_anomalous_trichromacy_Machado2009, - matrix_cvd_Machado2009, - msds_cmfs_anomalous_trichromacy_Machado2009, +from .contrast import ( + CONTRAST_SENSITIVITY_METHODS, + contrast_sensitivity_function, ) -from .appearance import ( - CAM_Specification_ATD95, - CAM_Specification_CAM16, - CAM_Specification_CIECAM02, - CAM_Specification_CIECAM16, - CAM_Specification_Hellwig2022, - CAM_Specification_Hunt, - CAM_Specification_Kim2009, - CAM_Specification_LLAB, - CAM_Specification_Nayatani95, - CAM_Specification_RLAB, - CAM_Specification_ZCAM, - CAM16_to_XYZ, - CIECAM02_to_XYZ, - CIECAM16_to_XYZ, - HKE_NAYATANI1997_METHODS, - Hellwig2022_to_XYZ, - HelmholtzKohlrausch_effect_object_Nayatani1997, - HelmholtzKohlrausch_effect_luminous_Nayatani1997, - Kim2009_to_XYZ, - MEDIA_PARAMETERS_KIM2009, - VIEWING_CONDITIONS_CAM16, - VIEWING_CONDITIONS_CIECAM02, - VIEWING_CONDITIONS_CIECAM16, - VIEWING_CONDITIONS_HELLWIG2022, - VIEWING_CONDITIONS_HUNT, - VIEWING_CONDITIONS_KIM2009, - VIEWING_CONDITIONS_LLAB, - VIEWING_CONDITIONS_RLAB, - VIEWING_CONDITIONS_ZCAM, - XYZ_to_ATD95, - XYZ_to_CAM16, - XYZ_to_CIECAM02, - XYZ_to_CIECAM16, - XYZ_to_Kim2009, - XYZ_to_Hellwig2022, - XYZ_to_Hunt, - XYZ_to_LLAB, - XYZ_to_Nayatani95, - XYZ_to_RLAB, - XYZ_to_ZCAM, - ZCAM_to_XYZ, +from .corresponding import ( + BRENEMAN_EXPERIMENT_PRIMARIES_CHROMATICITIES, + BRENEMAN_EXPERIMENTS, + CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS, + CorrespondingChromaticitiesPrediction, + CorrespondingColourDataset, + corresponding_chromaticities_prediction, ) from .difference import ( DELTA_E_METHODS, - delta_E, INDEX_STRESS_METHODS, + delta_E, index_stress, ) from .geometry import ( PRIMITIVE_METHODS, - primitive, PRIMITIVE_VERTICES_METHODS, + primitive, primitive_vertices, ) +from .graph import convert, describe_conversion_path +from .hints import Any from .io import ( - Header_IESTM2714, LUT1D, - LUT3x1D, LUT3D, + READ_IMAGE_METHODS, + WRITE_IMAGE_METHODS, + Header_IESTM2714, + LUT3x1D, LUTOperatorMatrix, LUTSequence, - READ_IMAGE_METHODS, SpectralDistribution_IESTM2714, - WRITE_IMAGE_METHODS, + SpectralDistribution_Sekonic, + SpectralDistribution_UPRTek, read_image, read_LUT, read_sds_from_csv_file, read_sds_from_xrite_file, read_spectral_data_from_csv_file, - SpectralDistribution_Sekonic, - SpectralDistribution_UPRTek, write_image, write_LUT, write_sds_to_csv_file, ) from .models import ( + CCTF_DECODINGS, + CCTF_ENCODINGS, + COLOUR_PRIMARIES_ITUTH273, + COLOURSPACE_MODELS, + DATA_MACADAM_1942_ELLIPSES, + EOTF_INVERSES, + EOTFS, + HDR_CIELAB_METHODS, + HDR_IPT_METHODS, + LOG_DECODINGS, + LOG_ENCODINGS, + MATRIX_COEFFICIENTS_ITUTH273, + OETF_INVERSES, + OETFS, + OOTF_INVERSES, + OOTFS, + RGB_COLOURSPACES, + TRANSFER_CHARACTERISTICS_ITUTH273, + WEIGHTS_YCBCR, CAM02LCD_to_JMh_CIECAM02, - CAM02SCD_to_JMh_CIECAM02, - CAM02UCS_to_JMh_CIECAM02, CAM02LCD_to_XYZ, + CAM02SCD_to_JMh_CIECAM02, CAM02SCD_to_XYZ, + CAM02UCS_to_JMh_CIECAM02, CAM02UCS_to_XYZ, CAM16LCD_to_JMh_CAM16, - CAM16SCD_to_JMh_CAM16, - CAM16UCS_to_JMh_CAM16, CAM16LCD_to_XYZ, + CAM16SCD_to_JMh_CAM16, CAM16SCD_to_XYZ, + CAM16UCS_to_JMh_CAM16, CAM16UCS_to_XYZ, - CCTF_DECODINGS, - CCTF_ENCODINGS, - CMYK_to_CMY, CMY_to_CMYK, CMY_to_RGB, - COLOURSPACE_MODELS, - COLOUR_PRIMARIES_ITUTH273, + CMYK_to_CMY, CV_range, - DATA_MACADAM_1942_ELLIPSES, DIN99_to_Lab, DIN99_to_XYZ, - EOTFS, - EOTF_INVERSES, HCL_to_RGB, - HDR_CIELAB_METHODS, - HDR_IPT_METHODS, HSL_to_RGB, HSV_to_RGB, Hunter_Lab_to_XYZ, @@ -256,11 +293,11 @@ ICaCb_to_XYZ, ICtCp_to_RGB, ICtCp_to_XYZ, - IHLS_to_RGB, IgPgTg_to_XYZ, + IHLS_to_RGB, IPT_hue_angle, - IPT_to_XYZ, IPT_Ragoo2021_to_XYZ, + IPT_to_XYZ, JMh_CAM16_to_CAM16LCD, JMh_CAM16_to_CAM16SCD, JMh_CAM16_to_CAM16UCS, @@ -268,27 +305,19 @@ JMh_CIECAM02_to_CAM02SCD, JMh_CIECAM02_to_CAM02UCS, Jzazbz_to_XYZ, - LCHab_to_Lab, - LCHuv_to_Luv, - LOG_DECODINGS, - LOG_ENCODINGS, Lab_to_DIN99, Lab_to_LCHab, Lab_to_XYZ, + LCHab_to_Lab, + LCHuv_to_Luv, Luv_to_LCHuv, - Luv_to_XYZ, Luv_to_uv, + Luv_to_XYZ, Luv_uv_to_xy, - MATRIX_COEFFICIENTS_ITUTH273, - OETFS, - OETF_INVERSES, - OOTFS, - OOTF_INVERSES, - OSA_UCS_to_XYZ, Oklab_to_XYZ, + OSA_UCS_to_XYZ, Prismatic_to_RGB, ProLab_to_XYZ, - RGB_COLOURSPACES, RGB_Colourspace, RGB_luminance, RGB_luminance_equation, @@ -302,14 +331,12 @@ RGB_to_RGB, RGB_to_XYZ, RGB_to_YCbCr, - RGB_to_YCoCg, RGB_to_YcCbcCrc, - TRANSFER_CHARACTERISTICS_ITUTH273, - UCS_to_XYZ, + RGB_to_YCoCg, UCS_to_uv, + UCS_to_XYZ, UCS_uv_to_xy, UVW_to_XYZ, - WEIGHTS_YCBCR, XYZ_to_CAM02LCD, XYZ_to_CAM02SCD, XYZ_to_CAM02UCS, @@ -317,6 +344,8 @@ XYZ_to_CAM16SCD, XYZ_to_CAM16UCS, XYZ_to_DIN99, + XYZ_to_hdr_CIELab, + XYZ_to_hdr_IPT, XYZ_to_Hunter_Lab, XYZ_to_Hunter_Rdab, XYZ_to_ICaCb, @@ -328,21 +357,19 @@ XYZ_to_K_ab_HunterLab1966, XYZ_to_Lab, XYZ_to_Luv, - XYZ_to_OSA_UCS, XYZ_to_Oklab, + XYZ_to_OSA_UCS, XYZ_to_ProLab, XYZ_to_RGB, + XYZ_to_sRGB, XYZ_to_UCS, XYZ_to_UVW, - XYZ_to_hdr_CIELab, - XYZ_to_hdr_IPT, - XYZ_to_sRGB, XYZ_to_xy, XYZ_to_xyY, XYZ_to_Yrg, YCbCr_to_RGB, - YCoCg_to_RGB, YcCbcCrc_to_RGB, + YCoCg_to_RGB, Yrg_to_XYZ, cctf_decoding, cctf_encoding, @@ -369,29 +396,12 @@ sRGB_to_XYZ, uv_to_Luv, uv_to_UCS, - xyY_to_XYZ, - xyY_to_xy, xy_to_Luv_uv, xy_to_UCS_uv, - xy_to_XYZ, xy_to_xyY, -) -from .corresponding import ( - BRENEMAN_EXPERIMENTS, - BRENEMAN_EXPERIMENT_PRIMARIES_CHROMATICITIES, - CORRESPONDING_CHROMATICITIES_PREDICTION_MODELS, - CorrespondingColourDataset, - CorrespondingChromaticitiesPrediction, - corresponding_chromaticities_prediction, -) -from .contrast import ( - CONTRAST_SENSITIVITY_METHODS, - contrast_sensitivity_function, -) -from .phenomena import ( - rayleigh_scattering, - scattering_cross_section, - sd_rayleigh_scattering, + xy_to_XYZ, + xyY_to_xy, + xyY_to_XYZ, ) from .notation import ( MUNSELL_COLOURS, @@ -400,6 +410,11 @@ munsell_value, xyY_to_munsell_colour, ) +from .phenomena import ( + rayleigh_scattering, + scattering_cross_section, + sd_rayleigh_scattering, +) from .quality import ( COLOUR_FIDELITY_INDEX_METHODS, COLOUR_QUALITY_SCALE_METHODS, @@ -412,66 +427,32 @@ from .temperature import ( CCT_TO_UV_METHODS, CCT_TO_XY_METHODS, - CCT_to_uv, - CCT_to_xy, UV_TO_CCT_METHODS, XY_TO_CCT_METHODS, + CCT_to_uv, + CCT_to_xy, uv_to_CCT, xy_to_CCT, ) -from .characterisation import ( - APPLY_MATRIX_COLOUR_CORRECTION_METHODS, - CCS_COLOURCHECKERS, - MATRIX_COLOUR_CORRECTION_METHODS, - COLOUR_CORRECTION_METHODS, - MSDS_CAMERA_SENSITIVITIES, - MSDS_DISPLAY_PRIMARIES, - POLYNOMIAL_EXPANSION_METHODS, - SDS_COLOURCHECKERS, - SDS_FILTERS, - SDS_LENSES, - apply_matrix_colour_correction, - camera_RGB_to_ACES2065_1, - colour_correction, - matrix_colour_correction, - matrix_idt, - polynomial_expansion, - sd_to_ACES2065_1, - sd_to_aces_relative_exposure_values, +from .utilities.array import ( + domain_range_scale, + get_domain_range_scale, + set_domain_range_scale, ) +from .utilities.deprecation import ModuleAPI, build_API_changes +from .utilities.documentation import is_documentation_building from .volume import ( OPTIMAL_COLOUR_STIMULI_ILLUMINANTS, RGB_colourspace_limits, RGB_colourspace_pointer_gamut_coverage_MonteCarlo, RGB_colourspace_visible_spectrum_coverage_MonteCarlo, - RGB_colourspace_volume_MonteCarlo, RGB_colourspace_volume_coverage_MonteCarlo, + RGB_colourspace_volume_MonteCarlo, is_within_macadam_limits, is_within_mesh_volume, is_within_pointer_gamut, is_within_visible_spectrum, ) -from .graph import describe_conversion_path, convert - -from colour.utilities import is_matplotlib_installed - -# Exposing "colour.plotting" sub-package if "Matplotlib" is available. -if is_matplotlib_installed(): - import colour.plotting as plotting # noqa: F401, PLR0402 -else: - - class MockPlotting: # pragma: no cover - """ - Mock object for :mod:`colour.plotting` sub-package raising an exception - if the sub-package is accessed but *Matplotlib* is not installed. - """ - - def __getattr__(self, attribute) -> Any: - """Return the value from the attribute with given name.""" - - is_matplotlib_installed(raise_exception=True) - - globals()["plotting"] = MockPlotting() # pragma: no cover __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -889,7 +870,7 @@ def __getattr__(self, attribute) -> Any: __major_version__ = "0" __minor_version__ = "4" -__change_version__ = "3" +__change_version__ = "4" __version__ = ".".join( (__major_version__, __minor_version__, __change_version__) ) @@ -968,7 +949,7 @@ def __getattr__(self, attribute) -> Any: sys.modules["colour"], build_API_changes(API_CHANGES) ) - del ModuleAPI, is_documentation_building, build_API_changes, sys + del ModuleAPI, is_documentation_building, build_API_changes colour.__disable_lazy_load__ = True # pyright: ignore __disable_lazy_load__ = colour.__disable_lazy_load__ # pyright: ignore @@ -976,3 +957,77 @@ def __getattr__(self, attribute) -> Any: Ensures that the lazy loaded datasets are not transformed during import. See :class:`colour.utilities.LazyCanonicalMapping` for more information. """ + +# NOTE: We are solving the clash with https://github.com/vaab/colour by loading +# a known subset of the objects given by vaab/colour-0.1.5 into our namespace +# if the *COLOUR_SCIENCE__COLOUR__IMPORT_VAAB_COLOUR=True* environment variable +# is defined. +# +# See the following issues for more information: +# - https://github.com/colour-science/colour/issues/958 +# - https://github.com/colour-science/colour/issues/1221 +# - https://github.com/vaab/colour/issues/62 +for _path in sys.path: + _module_path = os.path.join(_path, "colour.py") + if os.path.exists(_module_path): + import colour # pyright: ignore + + if not os.environ.get("COLOUR_SCIENCE__COLOUR__IMPORT_VAAB_COLOUR"): + colour.utilities.warning( # pyright: ignore + '"vaab/colour" was detected in "sys.path", please define a ' + '"COLOUR_SCIENCE__COLOUR__IMPORT_VAAB_COLOUR=True" environment ' + 'variable to import its objects into "colour" namespace!' + ) + break + + import importlib.machinery + + _module = importlib.machinery.SourceFileLoader( + "__vaab_colour__", _module_path + ).load_module() + + for name in [ + "COLOR_NAME_TO_RGB", + "C_HEX", + "C_HSL", + "C_RGB", + "Color", + "HEX", + "HSL", + "HSL_equivalence", + "LONG_HEX_COLOR", + "RGB", + "RGB_TO_COLOR_NAMES", + "RGB_color_picker", + "RGB_equivalence", + "SHORT_HEX_COLOR", + "color_scale", + "hash_or_str", + "hex2hsl", + "hex2rgb", + "hex2web", + "hsl2hex", + "hsl2rgb", + "hsl2web", + "make_color_factory", + "rgb2hex", + "rgb2hsl", + "rgb2web", + "web2hex", + "web2hsl", + "web2rgb", + ]: + if name in dir(_module): + colour.utilities.warning( # pyright: ignore + f'Importing "vaab/colour" "{name}" object into ' + f'"Colour"\'s namespace!' + ) + setattr(sys.modules["colour"], name, getattr(_module, name)) + + del importlib, _module + + break + + del _module_path, _path + +del os, sys diff --git a/colour/adaptation/cie1994.py b/colour/adaptation/cie1994.py index e4f1332474..442a3ebc96 100644 --- a/colour/adaptation/cie1994.py +++ b/colour/adaptation/cie1994.py @@ -18,8 +18,8 @@ import numpy as np -from colour.algebra import sdiv, sdiv_mode, spow, vector_dot from colour.adaptation import CAT_VON_KRIES +from colour.algebra import sdiv, sdiv_mode, spow, vector_dot from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( as_float_array, diff --git a/colour/adaptation/cmccat2000.py b/colour/adaptation/cmccat2000.py index 2b6ccda68a..9167f44cd2 100644 --- a/colour/adaptation/cmccat2000.py +++ b/colour/adaptation/cmccat2000.py @@ -22,9 +22,10 @@ from __future__ import annotations -import numpy as np from typing import NamedTuple +import numpy as np + from colour.adaptation import CAT_CMCCAT2000 from colour.algebra import vector_dot from colour.hints import ArrayLike, Literal, NDArrayFloat diff --git a/colour/adaptation/fairchild1990.py b/colour/adaptation/fairchild1990.py index 95f3e1f4e4..ba5afce035 100644 --- a/colour/adaptation/fairchild1990.py +++ b/colour/adaptation/fairchild1990.py @@ -19,8 +19,8 @@ import numpy as np -from colour.algebra import sdiv, sdiv_mode, spow, vector_dot from colour.adaptation import CAT_VON_KRIES +from colour.algebra import sdiv, sdiv_mode, spow, vector_dot from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( as_float_array, diff --git a/colour/adaptation/tests/test__init__.py b/colour/adaptation/tests/test__init__.py index 3e603180aa..dc2cf044cd 100644 --- a/colour/adaptation/tests/test__init__.py +++ b/colour/adaptation/tests/test__init__.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.adaptation` module.""" -import numpy as np import unittest +import numpy as np + from colour.adaptation import chromatic_adaptation +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale __author__ = "Colour Developers" @@ -31,15 +33,15 @@ def test_chromatic_adaptation(self): XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) XYZ_w = np.array([0.95045593, 1.00000000, 1.08905775]) XYZ_wr = np.array([0.96429568, 1.00000000, 0.82510460]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation(XYZ, XYZ_w, XYZ_wr), np.array([0.21638819, 0.12570000, 0.03847494]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_o = 0.2 E_o = 1000 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation( XYZ, XYZ_w, @@ -50,25 +52,25 @@ def test_chromatic_adaptation(self): E_o2=E_o, ), np.array([0.21347453, 0.12252986, 0.03347887]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) L_A = 200 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation( XYZ, XYZ_w, XYZ_wr, method="CMCCAT2000", L_A1=L_A, L_A2=L_A ), np.array([0.21498829, 0.12474711, 0.03910138]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_n = 200 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation( XYZ, XYZ_w, XYZ_wr, method="Fairchild 1990", Y_n=Y_n ), np.array([0.21394049, 0.12262315, 0.03891917]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation(self): @@ -106,7 +108,7 @@ def test_domain_range_scale_chromatic_adaptation(self): for method, value in zip(m, v): for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation( XYZ * factor, XYZ_w * factor, @@ -120,7 +122,7 @@ def test_domain_range_scale_chromatic_adaptation(self): Y_n=Y_n, ), value * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/adaptation/tests/test_cie1994.py b/colour/adaptation/tests/test_cie1994.py index f7a45c7191..4e052e921e 100644 --- a/colour/adaptation/tests/test_cie1994.py +++ b/colour/adaptation/tests/test_cie1994.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.adaptation.cie1994` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.adaptation import chromatic_adaptation_CIE1994 +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -32,7 +34,7 @@ def test_chromatic_adaptation_CIE1994(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_CIE1994( XYZ_1=np.array([28.00, 21.26, 5.27]), xy_o1=np.array([0.44760, 0.40740]), @@ -42,10 +44,10 @@ def test_chromatic_adaptation_CIE1994(self): E_o2=1000, ), np.array([24.03379521, 21.15621214, 17.64301199]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_CIE1994( XYZ_1=np.array([21.77, 19.18, 16.73]), xy_o1=np.array([0.31270, 0.32900]), @@ -55,10 +57,10 @@ def test_chromatic_adaptation_CIE1994(self): E_o2=1000, ), np.array([21.12891746, 19.42980532, 19.49577765]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_CIE1994( XYZ_1=np.array([0.07818780, 0.06157201, 0.28099326]) * 100, xy_o1=np.array([0.31270, 0.32900]), @@ -68,7 +70,7 @@ def test_chromatic_adaptation_CIE1994(self): E_o2=1000, ), np.array([9.14287406, 9.35843355, 15.95753504]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_chromatic_adaptation_CIE1994(self): @@ -89,10 +91,10 @@ def test_n_dimensional_chromatic_adaptation_CIE1994(self): XYZ_1 = np.tile(XYZ_1, (6, 1)) XYZ_2 = np.tile(XYZ_2, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2), XYZ_2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) xy_o1 = np.tile(xy_o1, (6, 1)) @@ -100,10 +102,10 @@ def test_n_dimensional_chromatic_adaptation_CIE1994(self): Y_o = np.tile(Y_o, 6) E_o1 = np.tile(E_o1, 6) E_o2 = np.tile(E_o2, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2), XYZ_2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_1 = np.reshape(XYZ_1, (2, 3, 3)) @@ -113,10 +115,10 @@ def test_n_dimensional_chromatic_adaptation_CIE1994(self): E_o1 = np.reshape(E_o1, (2, 3)) E_o2 = np.reshape(E_o2, (2, 3)) XYZ_2 = np.reshape(XYZ_2, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2), XYZ_2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation_CIE1994(self): @@ -138,12 +140,12 @@ def test_domain_range_scale_chromatic_adaptation_CIE1994(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_CIE1994( XYZ_1 * factor, xy_o1, xy_o2, Y_o * factor, E_o1, E_o2 ), XYZ_2 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/adaptation/tests/test_cmccat2000.py b/colour/adaptation/tests/test_cmccat2000.py index 4765dfecb1..dbebf4d2e0 100644 --- a/colour/adaptation/tests/test_cmccat2000.py +++ b/colour/adaptation/tests/test_cmccat2000.py @@ -1,15 +1,16 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.adaptation.cmccat2000.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.adaptation.cmccat2000 import ( chromatic_adaptation_forward_CMCCAT2000, chromatic_adaptation_inverse_CMCCAT2000, ) - +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -37,7 +38,7 @@ def test_chromatic_adaptation_forward_CMCCAT2000(self): chromatic_adaptation_forward_CMCCAT2000` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_forward_CMCCAT2000( np.array([22.48, 22.74, 8.54]), np.array([111.15, 100.00, 35.20]), @@ -46,10 +47,10 @@ def test_chromatic_adaptation_forward_CMCCAT2000(self): 200, ), np.array([19.52698326, 23.06833960, 24.97175229]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_forward_CMCCAT2000( np.array([0.14222010, 0.23042768, 0.10495772]) * 100, np.array([0.95045593, 1.00000000, 1.08905775]) * 100, @@ -58,10 +59,10 @@ def test_chromatic_adaptation_forward_CMCCAT2000(self): 100, ), np.array([17.90511171, 22.75299363, 3.79837384]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_forward_CMCCAT2000( np.array([0.07818780, 0.06157201, 0.28099326]) * 100, np.array([0.95045593, 1.00000000, 1.08905775]) * 100, @@ -70,7 +71,7 @@ def test_chromatic_adaptation_forward_CMCCAT2000(self): 100, ), np.array([6.76564344, 5.86585763, 18.40577315]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_chromatic_adaptation_forward_CMCCAT2000(self): @@ -91,24 +92,24 @@ def test_n_dimensional_chromatic_adaptation_forward_CMCCAT2000(self): XYZ = np.tile(XYZ, (6, 1)) XYZ_c = np.tile(XYZ_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_forward_CMCCAT2000( XYZ, XYZ_w, XYZ_wr, L_A1, L_A2 ), XYZ_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) XYZ_wr = np.tile(XYZ_wr, (6, 1)) L_A1 = np.tile(L_A1, 6) L_A2 = np.tile(L_A2, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_forward_CMCCAT2000( XYZ, XYZ_w, XYZ_wr, L_A1, L_A2 ), XYZ_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) @@ -117,12 +118,12 @@ def test_n_dimensional_chromatic_adaptation_forward_CMCCAT2000(self): L_A1 = np.reshape(L_A1, (2, 3)) L_A2 = np.reshape(L_A2, (2, 3)) XYZ_c = np.reshape(XYZ_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_forward_CMCCAT2000( XYZ, XYZ_w, XYZ_wr, L_A1, L_A2 ), XYZ_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self): @@ -144,7 +145,7 @@ def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_forward_CMCCAT2000( XYZ * factor, XYZ_w * factor, @@ -153,7 +154,7 @@ def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self): L_A2, ), XYZ_c * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -182,7 +183,7 @@ def test_chromatic_adaptation_inverse_CMCCAT2000(self): chromatic_adaptation_inverse_CMCCAT2000` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_inverse_CMCCAT2000( np.array([19.52698326, 23.06833960, 24.97175229]), np.array([111.15, 100.00, 35.20]), @@ -191,10 +192,10 @@ def test_chromatic_adaptation_inverse_CMCCAT2000(self): 200, ), np.array([22.48, 22.74, 8.54]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_inverse_CMCCAT2000( np.array([17.90511171, 22.75299363, 3.79837384]), np.array([0.95045593, 1.00000000, 1.08905775]) * 100, @@ -203,10 +204,10 @@ def test_chromatic_adaptation_inverse_CMCCAT2000(self): 100, ), np.array([0.14222010, 0.23042768, 0.10495772]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_inverse_CMCCAT2000( np.array([6.76564344, 5.86585763, 18.40577315]), np.array([0.95045593, 1.00000000, 1.08905775]) * 100, @@ -215,7 +216,7 @@ def test_chromatic_adaptation_inverse_CMCCAT2000(self): 100, ), np.array([0.07818780, 0.06157201, 0.28099326]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_chromatic_adaptation_inverse_CMCCAT2000(self): @@ -236,24 +237,24 @@ def test_n_dimensional_chromatic_adaptation_inverse_CMCCAT2000(self): XYZ_c = np.tile(XYZ_c, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_inverse_CMCCAT2000( XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2 ), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) XYZ_wr = np.tile(XYZ_wr, (6, 1)) L_A1 = np.tile(L_A1, 6) L_A2 = np.tile(L_A2, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_inverse_CMCCAT2000( XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2 ), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_c = np.reshape(XYZ_c, (2, 3, 3)) @@ -262,12 +263,12 @@ def test_n_dimensional_chromatic_adaptation_inverse_CMCCAT2000(self): L_A1 = np.reshape(L_A1, (2, 3)) L_A2 = np.reshape(L_A2, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_inverse_CMCCAT2000( XYZ_c, XYZ_w, XYZ_wr, L_A1, L_A2 ), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self): @@ -289,7 +290,7 @@ def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_inverse_CMCCAT2000( XYZ_c * factor, XYZ_w * factor, @@ -298,7 +299,7 @@ def test_domain_range_scale_chromatic_adaptation_CMCCAT2000(self): L_A2, ), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/adaptation/tests/test_fairchild1990.py b/colour/adaptation/tests/test_fairchild1990.py index 123a6bc22e..17a8cd7962 100644 --- a/colour/adaptation/tests/test_fairchild1990.py +++ b/colour/adaptation/tests/test_fairchild1990.py @@ -2,12 +2,14 @@ """Define the unit tests for the :mod:`colour.adaptation.fairchild1990` module.""" import contextlib -import numpy as np import unittest from itertools import product + +import numpy as np from numpy.linalg import LinAlgError from colour.adaptation import chromatic_adaptation_Fairchild1990 +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -34,7 +36,7 @@ def test_chromatic_adaptation_Fairchild1990(self): chromatic_adaptation_Fairchild1990` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Fairchild1990( np.array([19.53, 23.07, 24.97]), np.array([111.15, 100.00, 35.20]), @@ -42,10 +44,10 @@ def test_chromatic_adaptation_Fairchild1990(self): 200, ), np.array([23.32526349, 23.32455819, 76.11593750]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Fairchild1990( np.array([0.14222010, 0.23042768, 0.10495772]) * 100, np.array([0.95045593, 1.00000000, 1.08905775]) * 100, @@ -53,10 +55,10 @@ def test_chromatic_adaptation_Fairchild1990(self): 200, ), np.array([19.28089326, 22.91583715, 3.42923503]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Fairchild1990( np.array([0.07818780, 0.06157201, 0.28099326]) * 100, np.array([0.95045593, 1.00000000, 1.08905775]) * 100, @@ -64,7 +66,7 @@ def test_chromatic_adaptation_Fairchild1990(self): 200, ), np.array([6.35093475, 6.13061347, 17.36852430]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_chromatic_adaptation_Fairchild1990(self): @@ -81,19 +83,19 @@ def test_n_dimensional_chromatic_adaptation_Fairchild1990(self): XYZ_1 = np.tile(XYZ_1, (6, 1)) XYZ_c = np.tile(XYZ_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Fairchild1990(XYZ_1, XYZ_n, XYZ_r, Y_n), XYZ_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_n = np.tile(XYZ_n, (6, 1)) XYZ_r = np.tile(XYZ_r, (6, 1)) Y_n = np.tile(Y_n, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Fairchild1990(XYZ_1, XYZ_n, XYZ_r, Y_n), XYZ_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_1 = np.reshape(XYZ_1, (2, 3, 3)) @@ -101,10 +103,10 @@ def test_n_dimensional_chromatic_adaptation_Fairchild1990(self): XYZ_r = np.reshape(XYZ_r, (2, 3, 3)) Y_n = np.reshape(Y_n, (2, 3)) XYZ_c = np.reshape(XYZ_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Fairchild1990(XYZ_1, XYZ_n, XYZ_r, Y_n), XYZ_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation_Fairchild1990(self): @@ -122,12 +124,12 @@ def test_domain_range_scale_chromatic_adaptation_Fairchild1990(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Fairchild1990( XYZ_1 * factor, XYZ_n * factor, XYZ_r * factor, Y_n ), XYZ_c * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/adaptation/tests/test_vonkries.py b/colour/adaptation/tests/test_vonkries.py index 67fc0096f0..79b5c95677 100644 --- a/colour/adaptation/tests/test_vonkries.py +++ b/colour/adaptation/tests/test_vonkries.py @@ -1,14 +1,16 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.adaptation.vonkries` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.adaptation import ( - matrix_chromatic_adaptation_VonKries, chromatic_adaptation_VonKries, + matrix_chromatic_adaptation_VonKries, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -36,7 +38,7 @@ def test_matrix_chromatic_adaptation_VonKries(self): matrix_chromatic_adaptation_VonKries` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_chromatic_adaptation_VonKries( np.array([0.95045593, 1.00000000, 1.08905775]), np.array([0.96429568, 1.00000000, 0.82510460]), @@ -48,10 +50,10 @@ def test_matrix_chromatic_adaptation_VonKries(self): [-0.00116488, -0.00342053, 0.76178907], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_chromatic_adaptation_VonKries( np.array([0.95045593, 1.00000000, 1.08905775]), np.array([1.09846607, 1.00000000, 0.35582280]), @@ -63,10 +65,10 @@ def test_matrix_chromatic_adaptation_VonKries(self): [-0.00413024, -0.00912739, 0.33871096], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_chromatic_adaptation_VonKries( np.array([0.95045593, 1.00000000, 1.08905775]), np.array([0.99144661, 1.00000000, 0.67315942]), @@ -77,10 +79,10 @@ def test_matrix_chromatic_adaptation_VonKries(self): np.array([0.95045593, 1.00000000, 1.08905775]), ) ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_chromatic_adaptation_VonKries( np.array([0.95045593, 1.00000000, 1.08905775]), np.array([0.96429568, 1.00000000, 0.82510460]), @@ -93,10 +95,10 @@ def test_matrix_chromatic_adaptation_VonKries(self): [0.00000000, 0.00000000, 0.75763163], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_chromatic_adaptation_VonKries( np.array([0.95045593, 1.00000000, 1.08905775]), np.array([0.96429568, 1.00000000, 0.82510460]), @@ -109,10 +111,10 @@ def test_matrix_chromatic_adaptation_VonKries(self): [-0.00924304, 0.01505519, 0.75187428], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_chromatic_adaptation_VonKries( np.array([0.95045593, 1.00000000, 1.08905775]), np.array([0.96429568, 1.00000000, 0.82510460]), @@ -125,7 +127,7 @@ def test_matrix_chromatic_adaptation_VonKries(self): [0.00000000, 0.00000000, 0.75763163], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_matrix_chromatic_adaptation_VonKries(self): @@ -141,15 +143,19 @@ def test_n_dimensional_matrix_chromatic_adaptation_VonKries(self): XYZ_w = np.tile(XYZ_w, (6, 1)) XYZ_wr = np.tile(XYZ_wr, (6, 1)) M = np.reshape(np.tile(M, (6, 1)), (6, 3, 3)) - np.testing.assert_array_almost_equal( - matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr), M, decimal=7 + np.testing.assert_allclose( + matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr), + M, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ_wr = np.reshape(XYZ_wr, (2, 3, 3)) M = np.reshape(M, (2, 3, 3, 3)) - np.testing.assert_array_almost_equal( - matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr), M, decimal=7 + np.testing.assert_allclose( + matrix_chromatic_adaptation_VonKries(XYZ_w, XYZ_wr), + M, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation_VonKries(self): @@ -166,12 +172,12 @@ def test_domain_range_scale_chromatic_adaptation_VonKries(self): d_r = (("reference", 1), ("1", 1), ("100", 0.01)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_chromatic_adaptation_VonKries( XYZ_w * factor, XYZ_wr * factor ), M, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -198,37 +204,37 @@ def test_chromatic_adaptation_VonKries(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_VonKries( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.95045593, 1.00000000, 1.08905775]), np.array([0.96429568, 1.00000000, 0.82510460]), ), np.array([0.21638819, 0.12570000, 0.03847494]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_VonKries( np.array([0.14222010, 0.23042768, 0.10495772]), np.array([0.95045593, 1.00000000, 1.08905775]), np.array([1.09846607, 1.00000000, 0.35582280]), ), np.array([0.18673833, 0.23111171, 0.03285972]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_VonKries( np.array([0.07818780, 0.06157201, 0.28099326]), np.array([0.95045593, 1.00000000, 1.08905775]), np.array([0.99144661, 1.00000000, 0.67315942]), ), np.array([0.06385467, 0.05509729, 0.17506386]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_VonKries( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.95045593, 1.00000000, 1.08905775]), @@ -236,10 +242,10 @@ def test_chromatic_adaptation_VonKries(self): transform="XYZ Scaling", ), np.array([0.20954755, 0.12197225, 0.03891917]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_VonKries( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.95045593, 1.00000000, 1.08905775]), @@ -247,10 +253,10 @@ def test_chromatic_adaptation_VonKries(self): transform="Bradford", ), np.array([0.21666003, 0.12604777, 0.03855068]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_VonKries( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.95045593, 1.00000000, 1.08905775]), @@ -258,7 +264,7 @@ def test_chromatic_adaptation_VonKries(self): transform="Von Kries", ), np.array([0.21394049, 0.12262315, 0.03891917]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_chromatic_adaptation_VonKries(self): @@ -276,16 +282,20 @@ def test_n_dimensional_chromatic_adaptation_VonKries(self): XYZ_w = np.tile(XYZ_w, (6, 1)) XYZ_wr = np.tile(XYZ_wr, (6, 1)) XYZ_a = np.tile(XYZ_a, (6, 1)) - np.testing.assert_array_almost_equal( - chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr), XYZ_a, decimal=7 + np.testing.assert_allclose( + chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr), + XYZ_a, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ_wr = np.reshape(XYZ_wr, (2, 3, 3)) XYZ_a = np.reshape(XYZ_a, (2, 3, 3)) - np.testing.assert_array_almost_equal( - chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr), XYZ_a, decimal=7 + np.testing.assert_allclose( + chromatic_adaptation_VonKries(XYZ, XYZ_w, XYZ_wr), + XYZ_a, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation_VonKries(self): @@ -302,12 +312,12 @@ def test_domain_range_scale_chromatic_adaptation_VonKries(self): d_r = (("reference", 1), ("1", 1), ("100", 0.01)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_VonKries( XYZ * factor, XYZ_w * factor, XYZ_wr * factor ), XYZ_a * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/adaptation/tests/test_zhai2018.py b/colour/adaptation/tests/test_zhai2018.py index 48dfaa0078..3260eb0bc6 100644 --- a/colour/adaptation/tests/test_zhai2018.py +++ b/colour/adaptation/tests/test_zhai2018.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.adaptation.zhai2018` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.adaptation import chromatic_adaptation_Zhai2018 +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -32,7 +34,7 @@ def test_chromatic_adaptation_Zhai2018(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018( XYZ_b=np.array([48.900, 43.620, 6.250]), XYZ_wb=np.array([109.850, 100, 35.585]), @@ -42,10 +44,10 @@ def test_chromatic_adaptation_Zhai2018(self): XYZ_wo=np.array([100, 100, 100]), ), np.array([39.18561644, 42.15461798, 19.23672036]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018( XYZ_b=np.array([48.900, 43.620, 6.250]), XYZ_wb=np.array([109.850, 100, 35.585]), @@ -56,10 +58,10 @@ def test_chromatic_adaptation_Zhai2018(self): transform="CAT16", ), np.array([40.37398343, 43.69426311, 20.51733764]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018( XYZ_b=np.array([52.034, 58.824, 23.703]), XYZ_wb=np.array([92.288, 100, 38.775]), @@ -69,10 +71,10 @@ def test_chromatic_adaptation_Zhai2018(self): XYZ_wo=np.array([97.079, 100, 141.798]), ), np.array([57.03242915, 58.93434364, 64.76261333]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018( XYZ_b=np.array([52.034, 58.824, 23.703]), XYZ_wb=np.array([92.288, 100, 38.775]), @@ -83,17 +85,17 @@ def test_chromatic_adaptation_Zhai2018(self): transform="CAT16", ), np.array([56.77130011, 58.81317888, 64.66922808]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018( XYZ_b=np.array([48.900, 43.620, 6.250]), XYZ_wb=np.array([109.850, 100, 35.585]), XYZ_wd=np.array([95.047, 100, 108.883]), ), np.array([38.72444735, 42.09232891, 20.05297620]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_chromatic_adaptation_Zhai2018(self): @@ -111,20 +113,20 @@ def test_n_dimensional_chromatic_adaptation_Zhai2018(self): XYZ_b = np.tile(XYZ_b, (6, 1)) XYZ_d = np.tile(XYZ_d, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018(XYZ_b, XYZ_wb, XYZ_wd, D_b, D_d), XYZ_d, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_wb = np.tile(XYZ_wb, (6, 1)) XYZ_wd = np.tile(XYZ_wd, (6, 1)) D_b = np.tile(D_b, (6, 1)) D_d = np.tile(D_d, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018(XYZ_b, XYZ_wb, XYZ_wd, D_b, D_d), XYZ_d, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_b = np.reshape(XYZ_b, (2, 3, 3)) @@ -133,10 +135,10 @@ def test_n_dimensional_chromatic_adaptation_Zhai2018(self): D_b = np.reshape(D_b, (2, 3, 1)) D_d = np.reshape(D_d, (2, 3, 1)) XYZ_d = np.reshape(XYZ_d, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018(XYZ_b, XYZ_wb, XYZ_wd, D_b, D_d), XYZ_d, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_chromatic_adaptation_Zhai2018(self): @@ -153,12 +155,12 @@ def test_domain_range_scale_chromatic_adaptation_Zhai2018(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatic_adaptation_Zhai2018( XYZ_b * factor, XYZ_wb * factor, XYZ_wd * factor ), XYZ_d * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/adaptation/vonkries.py b/colour/adaptation/vonkries.py index 1a9c0d25d5..040d378dbc 100644 --- a/colour/adaptation/vonkries.py +++ b/colour/adaptation/vonkries.py @@ -19,8 +19,12 @@ import numpy as np from colour.adaptation import CHROMATIC_ADAPTATION_TRANSFORMS -from colour.algebra import matrix_dot, vector_dot, sdiv, sdiv_mode -from colour.hints import ArrayLike, Literal, NDArrayFloat +from colour.algebra import matrix_dot, sdiv, sdiv_mode, vector_dot +from colour.hints import ( + ArrayLike, + LiteralChromaticAdaptationTransform, + NDArrayFloat, +) from colour.utilities import ( from_range_1, row_as_diagonal, @@ -44,21 +48,7 @@ def matrix_chromatic_adaptation_VonKries( XYZ_w: ArrayLike, XYZ_wr: ArrayLike, - transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] - | str = "CAT02", + transform: LiteralChromaticAdaptationTransform | str = "CAT02", ) -> NDArrayFloat: """ Compute the *chromatic adaptation* matrix from test viewing conditions @@ -145,21 +135,7 @@ def chromatic_adaptation_VonKries( XYZ: ArrayLike, XYZ_w: ArrayLike, XYZ_wr: ArrayLike, - transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] - | str = "CAT02", + transform: LiteralChromaticAdaptationTransform | str = "CAT02", ) -> NDArrayFloat: """ Adapt given stimulus from test viewing conditions to reference viewing diff --git a/colour/adaptation/zhai2018.py b/colour/adaptation/zhai2018.py index 6755ee1fab..a77b70adc6 100644 --- a/colour/adaptation/zhai2018.py +++ b/colour/adaptation/zhai2018.py @@ -15,8 +15,8 @@ import numpy as np -from colour.algebra import vector_dot from colour.adaptation import CHROMATIC_ADAPTATION_TRANSFORMS +from colour.algebra import vector_dot from colour.hints import ArrayLike, Literal, NDArrayFloat, Union from colour.utilities import ( as_float_array, diff --git a/colour/algebra/common.py b/colour/algebra/common.py index 2762b49d4b..93905ba75c 100644 --- a/colour/algebra/common.py +++ b/colour/algebra/common.py @@ -9,6 +9,7 @@ from __future__ import annotations import functools + import numpy as np from colour.hints import ( @@ -21,8 +22,8 @@ cast, ) from colour.utilities import ( - as_float_array, as_float, + as_float_array, optional, tsplit, validate_method, diff --git a/colour/algebra/coordinates/tests/test_transformations.py b/colour/algebra/coordinates/tests/test_transformations.py index 6ff66a3c03..182674c691 100644 --- a/colour/algebra/coordinates/tests/test_transformations.py +++ b/colour/algebra/coordinates/tests/test_transformations.py @@ -3,18 +3,20 @@ :mod:`colour.algebra.coordinates.transformations` module. """ -import numpy as np import unittest from itertools import product +import numpy as np + from colour.algebra import ( - cartesian_to_spherical, - spherical_to_cartesian, - cartesian_to_polar, - polar_to_cartesian, cartesian_to_cylindrical, + cartesian_to_polar, + cartesian_to_spherical, cylindrical_to_cartesian, + polar_to_cartesian, + spherical_to_cartesian, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -46,22 +48,22 @@ def test_cartesian_to_spherical(self): cartesian_to_spherical` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_spherical(np.array([3, 1, 6])), np.array([6.78232998, 0.48504979, 0.32175055]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_spherical(np.array([-1, 9, 16])), np.array([18.38477631, 0.51501513, 1.68145355]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_spherical(np.array([6.3434, -0.9345, 18.5675])), np.array([19.64342307, 0.33250603, -0.14626640]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_cartesian_to_spherical(self): @@ -75,14 +77,14 @@ def test_n_dimensional_cartesian_to_spherical(self): a_i = np.tile(a_i, (6, 1)) a_o = np.tile(a_o, (6, 1)) - np.testing.assert_array_almost_equal( - cartesian_to_spherical(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cartesian_to_spherical(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) a_i = np.reshape(a_i, (2, 3, 3)) a_o = np.reshape(a_o, (2, 3, 3)) - np.testing.assert_array_almost_equal( - cartesian_to_spherical(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cartesian_to_spherical(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -109,28 +111,28 @@ def test_spherical_to_cartesian(self): spherical_to_cartesian` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( spherical_to_cartesian( np.array([6.78232998, 0.48504979, 0.32175055]) ), np.array([3.00000000, 0.99999999, 6.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( spherical_to_cartesian( np.array([18.38477631, 0.51501513, 1.68145355]) ), np.array([-1.00000003, 9.00000007, 15.99999996]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( spherical_to_cartesian( np.array([19.64342307, 0.33250603, -0.14626640]) ), np.array([6.34339996, -0.93449999, 18.56750001]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_spherical_to_cartesian(self): @@ -144,14 +146,14 @@ def test_n_dimensional_spherical_to_cartesian(self): a_i = np.tile(a_i, (6, 1)) a_o = np.tile(a_o, (6, 1)) - np.testing.assert_array_almost_equal( - spherical_to_cartesian(a_i), a_o, decimal=7 + np.testing.assert_allclose( + spherical_to_cartesian(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) a_i = np.reshape(a_i, (2, 3, 3)) a_o = np.reshape(a_o, (2, 3, 3)) - np.testing.assert_array_almost_equal( - spherical_to_cartesian(a_i), a_o, decimal=7 + np.testing.assert_allclose( + spherical_to_cartesian(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -178,22 +180,22 @@ def test_cartesian_to_polar(self): cartesian_to_polar` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_polar(np.array([3, 1])), np.array([3.16227766, 0.32175055]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_polar(np.array([-1, 9])), np.array([9.05538514, 1.68145355]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_polar(np.array([6.3434, -0.9345])), np.array([6.41186508, -0.14626640]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_cartesian_to_polar(self): @@ -207,14 +209,14 @@ def test_n_dimensional_cartesian_to_polar(self): a_i = np.tile(a_i, (6, 1)) a_o = np.tile(a_o, (6, 1)) - np.testing.assert_array_almost_equal( - cartesian_to_polar(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cartesian_to_polar(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) a_i = np.reshape(a_i, (2, 3, 2)) a_o = np.reshape(a_o, (2, 3, 2)) - np.testing.assert_array_almost_equal( - cartesian_to_polar(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cartesian_to_polar(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -241,22 +243,22 @@ def test_polar_to_cartesian(self): polar_to_cartesian` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( polar_to_cartesian(np.array([0.32175055, 1.08574654])), np.array([0.15001697, 0.28463718]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( polar_to_cartesian(np.array([1.68145355, 1.05578119])), np.array([0.82819662, 1.46334425]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( polar_to_cartesian(np.array([-0.14626640, 1.23829030])), np.array([-0.04774323, -0.13825500]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_polar_to_cartesian(self): @@ -270,14 +272,14 @@ def test_n_dimensional_polar_to_cartesian(self): a_i = np.tile(a_i, (6, 1)) a_o = np.tile(a_o, (6, 1)) - np.testing.assert_array_almost_equal( - polar_to_cartesian(a_i), a_o, decimal=7 + np.testing.assert_allclose( + polar_to_cartesian(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) a_i = np.reshape(a_i, (2, 3, 2)) a_o = np.reshape(a_o, (2, 3, 2)) - np.testing.assert_array_almost_equal( - polar_to_cartesian(a_i), a_o, decimal=7 + np.testing.assert_allclose( + polar_to_cartesian(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -304,22 +306,22 @@ def test_cartesian_to_cylindrical(self): cartesian_to_cylindrical` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_cylindrical(np.array([3, 1, 6])), np.array([3.16227766, 0.32175055, 6.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_cylindrical(np.array([-1, 9, 16])), np.array([9.05538514, 1.68145355, 16.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cartesian_to_cylindrical(np.array([6.3434, -0.9345, 18.5675])), np.array([6.41186508, -0.14626640, 18.56750000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_cartesian_to_cylindrical(self): @@ -333,14 +335,14 @@ def test_n_dimensional_cartesian_to_cylindrical(self): a_i = np.tile(a_i, (6, 1)) a_o = np.tile(a_o, (6, 1)) - np.testing.assert_array_almost_equal( - cartesian_to_cylindrical(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cartesian_to_cylindrical(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) a_i = np.reshape(a_i, (2, 3, 3)) a_o = np.reshape(a_o, (2, 3, 3)) - np.testing.assert_array_almost_equal( - cartesian_to_cylindrical(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cartesian_to_cylindrical(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -367,28 +369,28 @@ def test_cylindrical_to_cartesian(self): cylindrical_to_cartesian` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cylindrical_to_cartesian( np.array([0.32175055, 1.08574654, 6.78232998]) ), np.array([0.15001697, 0.28463718, 6.78232998]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cylindrical_to_cartesian( np.array([1.68145355, 1.05578119, 18.38477631]) ), np.array([0.82819662, 1.46334425, 18.38477631]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( cylindrical_to_cartesian( np.array([-0.14626640, 1.23829030, 19.64342307]) ), np.array([-0.04774323, -0.13825500, 19.64342307]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_cylindrical_to_cartesian(self): @@ -402,14 +404,14 @@ def test_n_dimensional_cylindrical_to_cartesian(self): a_i = np.tile(a_i, (6, 1)) a_o = np.tile(a_o, (6, 1)) - np.testing.assert_array_almost_equal( - cylindrical_to_cartesian(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cylindrical_to_cartesian(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) a_i = np.reshape(a_i, (2, 3, 3)) a_o = np.reshape(a_o, (2, 3, 3)) - np.testing.assert_array_almost_equal( - cylindrical_to_cartesian(a_i), a_o, decimal=7 + np.testing.assert_allclose( + cylindrical_to_cartesian(a_i), a_o, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/algebra/extrapolation.py b/colour/algebra/extrapolation.py index 8c564b7fbf..7ca33eecdd 100644 --- a/colour/algebra/extrapolation.py +++ b/colour/algebra/extrapolation.py @@ -21,7 +21,7 @@ import numpy as np from colour.algebra import NullInterpolator, sdiv, sdiv_mode -from colour.constants import DEFAULT_FLOAT_DTYPE +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.hints import ( Any, ArrayLike, @@ -33,8 +33,8 @@ Type, ) from colour.utilities import ( - as_float_array, as_float, + as_float_array, attest, is_numeric, is_string, @@ -144,7 +144,7 @@ def __init__( *args: Any, # noqa: ARG002 **kwargs: Any, # noqa: ARG002 ) -> None: - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) self._interpolator: ProtocolInterpolator = NullInterpolator( np.array([-np.inf, np.inf]), np.array([-np.inf, np.inf]) diff --git a/colour/algebra/interpolation.py b/colour/algebra/interpolation.py index a20849da9c..d5752a710a 100644 --- a/colour/algebra/interpolation.py +++ b/colour/algebra/interpolation.py @@ -60,13 +60,18 @@ from __future__ import annotations import itertools -import numpy as np -import scipy.interpolate from collections.abc import Mapping from functools import reduce +import numpy as np +import scipy.interpolate + from colour.algebra import sdiv, sdiv_mode -from colour.constants import DEFAULT_FLOAT_DTYPE +from colour.constants import ( + DTYPE_FLOAT_DEFAULT, + TOLERANCE_ABSOLUTE_DEFAULT, + TOLERANCE_RELATIVE_DEFAULT, +) from colour.hints import ( Any, ArrayLike, @@ -81,9 +86,9 @@ from colour.utilities import ( CanonicalMapping, as_array, + as_float, as_float_array, as_float_scalar, - as_float, as_int_array, attest, closest_indexes, @@ -406,7 +411,7 @@ def __init__( *args: Any, # noqa: ARG002 **kwargs: Any, # noqa: ARG002 ) -> None: - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) self._x_p: NDArrayFloat = np.array([]) self._y_p: NDArrayFloat = np.array([]) @@ -814,7 +819,7 @@ def __init__( *args: Any, # noqa: ARG002 **kwargs: Any, # noqa: ARG002 ) -> None: - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) self._x: NDArrayFloat = np.array([]) self._y: NDArrayFloat = np.array([]) @@ -1036,7 +1041,7 @@ def __init__( *args: Any, # noqa: ARG002 **kwargs: Any, # noqa: ARG002 ) -> None: - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) self._xp: NDArrayFloat = np.array([]) self._yp: NDArrayFloat = np.array([]) @@ -1417,19 +1422,19 @@ def __init__( self, x: ArrayLike, y: ArrayLike, - absolute_tolerance: float = 10e-7, - relative_tolerance: float = 10e-7, + absolute_tolerance: float = TOLERANCE_ABSOLUTE_DEFAULT, + relative_tolerance: float = TOLERANCE_RELATIVE_DEFAULT, default: float = np.nan, dtype: Type[DTypeReal] | None = None, *args: Any, # noqa: ARG002 **kwargs: Any, # noqa: ARG002 ) -> None: - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) self._x: NDArrayFloat = np.array([]) self._y: NDArrayFloat = np.array([]) - self._absolute_tolerance: float = 10e-7 - self._relative_tolerance: float = 10e-7 + self._absolute_tolerance: float = TOLERANCE_ABSOLUTE_DEFAULT + self._relative_tolerance: float = TOLERANCE_RELATIVE_DEFAULT self._default: float = np.nan self._dtype: Type[DTypeReal] = dtype diff --git a/colour/algebra/tests/test_common.py b/colour/algebra/tests/test_common.py index ff9f291622..d542a401d7 100644 --- a/colour/algebra/tests/test_common.py +++ b/colour/algebra/tests/test_common.py @@ -1,31 +1,33 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.algebra.common` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.algebra import ( + eigen_decomposition, + euclidean_distance, get_sdiv_mode, - set_sdiv_mode, - sdiv_mode, - sdiv, + is_identity, is_spow_enabled, + linear_conversion, + linstep_function, + manhattan_distance, + matrix_dot, + normalise_maximum, + normalise_vector, + sdiv, + sdiv_mode, + set_sdiv_mode, set_spow_enable, - spow_enable, - spow, smoothstep_function, - normalise_vector, - normalise_maximum, + spow, + spow_enable, vector_dot, - matrix_dot, - euclidean_distance, - manhattan_distance, - linear_conversion, - linstep_function, - is_identity, - eigen_decomposition, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -282,15 +284,15 @@ def test_spow(self): self.assertEqual(spow(-2, 2), -4.0) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( spow([2, -2, -2, 0], [2, 2, 0.15, 0]), np.array([4.00000000, -4.00000000, -1.10956947, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) with spow_enable(True): - np.testing.assert_array_almost_equal( - spow(-2, 0.15), -1.10956947, decimal=7 + np.testing.assert_allclose( + spow(-2, 0.15), -1.10956947, atol=TOLERANCE_ABSOLUTE_TESTS ) with spow_enable(False): @@ -306,22 +308,22 @@ class TestNormaliseVector(unittest.TestCase): def test_normalise_vector(self): """Test :func:`colour.algebra.common.normalise_vector` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_vector(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.84197033, 0.49722560, 0.20941026]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_vector(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.48971705, 0.79344877, 0.36140872]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_vector(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([0.26229003, 0.20655044, 0.94262445]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -334,13 +336,13 @@ class TestNormaliseMaximum(unittest.TestCase): def test_normalise_maximum(self): """Test :func:`colour.algebra.common.normalise_maximum` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_maximum(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([1.00000000, 0.59055003, 0.24871454]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_maximum( np.array( [ @@ -357,10 +359,10 @@ def test_normalise_maximum(self): [0.27825507, 0.21912273, 1.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_maximum( np.array( [ @@ -378,31 +380,31 @@ def test_normalise_maximum(self): [0.27825507, 0.21912273, 1.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_maximum( np.array([0.20654008, 0.12197225, 0.05136952]), factor=10 ), np.array([10.00000000, 5.90550028, 2.48714535]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_maximum( np.array([-0.11518475, -0.10080000, 0.05089373]) ), np.array([0.00000000, 0.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_maximum( np.array([-0.20654008, -0.12197225, 0.05136952]), clip=False ), np.array([-4.02067374, -2.37440899, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -427,7 +429,7 @@ def test_vector_dot(self): v = np.array([0.20654008, 0.12197225, 0.05136952]) v = np.tile(v, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vector_dot(m, v), np.array( [ @@ -439,7 +441,7 @@ def test_vector_dot(self): [0.19540944, 0.06203965, 0.05279523], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -463,7 +465,7 @@ def test_matrix_dot(self): b = a - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_dot(a, b), np.array( [ @@ -499,7 +501,7 @@ def test_matrix_dot(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -512,31 +514,31 @@ class TestEuclideanDistance(unittest.TestCase): def test_euclidean_distance(self): """Test :func:`colour.algebra.common.euclidean_distance` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( euclidean_distance( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 426.67945353, 72.39590835]), ), 451.71330197, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( euclidean_distance( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 74.05216981, 276.45318193]), ), 52.64986116, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( euclidean_distance( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 8.32281957, -73.58297716]), ), 346.06489172, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_euclidean_distance(self): @@ -552,15 +554,15 @@ def test_n_dimensional_euclidean_distance(self): a = np.tile(a, (6, 1)) b = np.tile(b, (6, 1)) distance = np.tile(distance, 6) - np.testing.assert_array_almost_equal( - euclidean_distance(a, b), distance, decimal=7 + np.testing.assert_allclose( + euclidean_distance(a, b), distance, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3, 3)) b = np.reshape(b, (2, 3, 3)) distance = np.reshape(distance, (2, 3)) - np.testing.assert_array_almost_equal( - euclidean_distance(a, b), distance, decimal=7 + np.testing.assert_allclose( + euclidean_distance(a, b), distance, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -584,31 +586,31 @@ class TestManhattanDistance(unittest.TestCase): def test_manhattan_distance(self): """Test :func:`colour.algebra.common.manhattan_distance` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( manhattan_distance( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 426.67945353, 72.39590835]), ), 604.93963510999993, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( manhattan_distance( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 74.05216981, 276.45318193]), ), 56.705054670000052, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( manhattan_distance( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 8.32281957, -73.58297716]), ), 359.06045465999995, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_manhattan_distance(self): @@ -624,15 +626,15 @@ def test_n_dimensional_manhattan_distance(self): a = np.tile(a, (6, 1)) b = np.tile(b, (6, 1)) distance = np.tile(distance, 6) - np.testing.assert_array_almost_equal( - manhattan_distance(a, b), distance, decimal=7 + np.testing.assert_allclose( + manhattan_distance(a, b), distance, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3, 3)) b = np.reshape(b, (2, 3, 3)) distance = np.reshape(distance, (2, 3)) - np.testing.assert_array_almost_equal( - manhattan_distance(a, b), distance, decimal=7 + np.testing.assert_allclose( + manhattan_distance(a, b), distance, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -656,7 +658,7 @@ class TestLinearConversion(unittest.TestCase): def test_linear_conversion(self): """Test :func:`colour.algebra.common.linear_conversion` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( linear_conversion( np.linspace(0, 1, 10), np.array([0, 1]), np.array([1, np.pi]) ), @@ -674,7 +676,7 @@ def test_linear_conversion(self): 3.14159265, ] ), - decimal=8, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -687,7 +689,7 @@ class TestLinstepFunction(unittest.TestCase): def test_linstep_function(self): """Test :func:`colour.algebra.common.linstep_function` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( linstep_function( np.linspace(0, 1, 10), np.linspace(0, 1, 10), @@ -707,10 +709,10 @@ def test_linstep_function(self): 2.00000000, ] ), - decimal=8, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( linstep_function( np.linspace(0, 2, 10), np.linspace(0.25, 0.5, 10), @@ -731,7 +733,7 @@ def test_linstep_function(self): 0.75000000, ] ), - decimal=8, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -749,13 +751,15 @@ def test_smoothstep_function(self): self.assertEqual(smoothstep_function(0.75), 0.84375) x = np.linspace(-2, 2, 5) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( smoothstep_function(x), np.array([28.00000, 5.00000, 0.00000, 1.00000, -4.00000]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( smoothstep_function(x, -2, 2, clip=True), np.array([0.00000, 0.15625, 0.50000, 0.84375, 1.00000]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/algebra/tests/test_extrapolation.py b/colour/algebra/tests/test_extrapolation.py index a2a2a7614a..32f086a92c 100644 --- a/colour/algebra/tests/test_extrapolation.py +++ b/colour/algebra/tests/test_extrapolation.py @@ -1,16 +1,18 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.algebra.extrapolation` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.algebra import ( + CubicSplineInterpolator, Extrapolator, LinearInterpolator, - CubicSplineInterpolator, PchipInterpolator, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -108,14 +110,14 @@ def test__call__(self): extrapolator = Extrapolator( LinearInterpolator(np.array([5, 6, 7]), np.array([5, 6, 7])) ) - np.testing.assert_array_almost_equal(extrapolator((4, 8)), (4, 8)) + np.testing.assert_array_equal(extrapolator((4, 8)), (4, 8)) self.assertEqual(extrapolator(4), 4) extrapolator = Extrapolator( LinearInterpolator(np.array([3, 4, 5]), np.array([1, 2, 3])), method="Constant", ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( extrapolator((0.1, 0.2, 8, 9)), (1, 1, 3, 3) ) self.assertEqual(extrapolator(0.1), 1.0) @@ -125,7 +127,7 @@ def test__call__(self): method="Constant", left=0, ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( extrapolator((0.1, 0.2, 8, 9)), (0, 0, 3, 3) ) self.assertEqual(extrapolator(0.1), 0) @@ -135,7 +137,7 @@ def test__call__(self): method="Constant", right=0, ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( extrapolator((0.1, 0.2, 8, 9)), (1, 1, 0, 0) ) self.assertEqual(extrapolator(9), 0) @@ -145,16 +147,20 @@ def test__call__(self): np.array([3, 4, 5, 6]), np.array([1, 2, 3, 4]) ) ) - np.testing.assert_array_almost_equal( - extrapolator((0.1, 0.2, 8.0, 9.0)), (-1.9, -1.8, 6.0, 7.0) + np.testing.assert_allclose( + extrapolator((0.1, 0.2, 8.0, 9.0)), + (-1.9, -1.8, 6.0, 7.0), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(extrapolator(9), 7) extrapolator = Extrapolator( PchipInterpolator(np.array([3, 4, 5]), np.array([1, 2, 3])) ) - np.testing.assert_array_almost_equal( - extrapolator((0.1, 0.2, 8.0, 9.0)), (-1.9, -1.8, 6.0, 7.0) + np.testing.assert_allclose( + extrapolator((0.1, 0.2, 8.0, 9.0)), + (-1.9, -1.8, 6.0, 7.0), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(extrapolator(9), 7.0) diff --git a/colour/algebra/tests/test_interpolation.py b/colour/algebra/tests/test_interpolation.py index bc21d303e8..37ab8c5b7e 100644 --- a/colour/algebra/tests/test_interpolation.py +++ b/colour/algebra/tests/test_interpolation.py @@ -10,31 +10,33 @@ from __future__ import annotations -import numpy as np import os import unittest from itertools import product -from colour.algebra.interpolation import vertices_and_relative_coordinates -from colour.hints import NDArrayFloat, cast +import numpy as np + from colour.algebra import ( - kernel_nearest_neighbour, - kernel_linear, - kernel_sinc, - kernel_lanczos, - kernel_cardinal_spline, + CubicSplineInterpolator, KernelInterpolator, - NearestNeighbourInterpolator, LinearInterpolator, - SpragueInterpolator, - CubicSplineInterpolator, - PchipInterpolator, + NearestNeighbourInterpolator, NullInterpolator, + PchipInterpolator, + SpragueInterpolator, + kernel_cardinal_spline, + kernel_lanczos, + kernel_linear, + kernel_nearest_neighbour, + kernel_sinc, lagrange_coefficients, - table_interpolation_trilinear, + random_triplet_generator, table_interpolation_tetrahedral, + table_interpolation_trilinear, ) -from colour.algebra import random_triplet_generator +from colour.algebra.interpolation import vertices_and_relative_coordinates +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.hints import NDArrayFloat, cast from colour.io import LUT3D, read_LUT from colour.utilities import ignore_numpy_errors @@ -510,7 +512,7 @@ def test_kernel_nearest(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_nearest_neighbour(np.linspace(-5, 5, 25)), np.array( [ @@ -541,7 +543,7 @@ def test_kernel_nearest(self): 0, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -554,7 +556,7 @@ class TestKernelLinear(unittest.TestCase): def test_kernel_linear(self): """Test :func:`colour.algebra.interpolation.kernel_linear` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_linear(np.linspace(-5, 5, 25)), np.array( [ @@ -585,7 +587,7 @@ def test_kernel_linear(self): 0.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -598,7 +600,7 @@ class TestKernelSinc(unittest.TestCase): def test_kernel_sinc(self): """Test :func:`colour.algebra.interpolation.kernel_sinc` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_sinc(np.linspace(-5, 5, 25)), np.array( [ @@ -629,10 +631,10 @@ def test_kernel_sinc(self): 0.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_sinc(np.linspace(-5, 5, 25), 1), np.array( [ @@ -663,7 +665,7 @@ def test_kernel_sinc(self): 0.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -676,7 +678,7 @@ class TestKernelLanczos(unittest.TestCase): def test_kernel_lanczos(self): """Test :func:`colour.algebra.interpolation.kernel_lanczos` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_lanczos(np.linspace(-5, 5, 25)), np.array( [ @@ -707,10 +709,10 @@ def test_kernel_lanczos(self): 0.00000000e00, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_lanczos(np.linspace(-5, 5, 25), 1), np.array( [ @@ -741,7 +743,7 @@ def test_kernel_lanczos(self): 0.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -757,7 +759,7 @@ def test_kernel_cardinal_spline(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_cardinal_spline(np.linspace(-5, 5, 25)), np.array( [ @@ -788,10 +790,10 @@ def test_kernel_cardinal_spline(self): 0.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_cardinal_spline(np.linspace(-5, 5, 25), 0, 1), np.array( [ @@ -822,7 +824,7 @@ def test_kernel_cardinal_spline(self): 0.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -953,7 +955,7 @@ def test__call__(self): x_i = np.linspace(11, 25, 25) kernel_interpolator = KernelInterpolator(x, y) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_interpolator(x_i), np.array( [ @@ -984,11 +986,11 @@ def test__call__(self): 3.14159265, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) kernel_interpolator = KernelInterpolator(x, y, kernel=kernel_sinc) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_interpolator(x_i), np.array( [ @@ -1019,11 +1021,11 @@ def test__call__(self): 3.14159265, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) kernel_interpolator = KernelInterpolator(x, y, window=1) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_interpolator(x_i), np.array( [ @@ -1054,13 +1056,13 @@ def test__call__(self): 3.14159265, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) kernel_interpolator = KernelInterpolator( x, y, window=1, kernel_kwargs={"a": 1} ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_interpolator(x_i), np.array( [ @@ -1091,13 +1093,13 @@ def test__call__(self): 3.14159265, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) kernel_interpolator = KernelInterpolator( x, y, padding_kwargs={"pad_width": (3, 3), "mode": "mean"} ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( kernel_interpolator(x_i), np.array( [ @@ -1128,7 +1130,7 @@ def test__call__(self): 3.14159265, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) x_1 = np.arange(1, 10, 1) @@ -1137,16 +1139,16 @@ def test__call__(self): y = np.sin(x_1 / len(x_1) * np.pi * 6) / (x_1 / len(x_1)) x_i = np.linspace(1, 9, 25) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( KernelInterpolator(x_1, y)(x_i), KernelInterpolator(x_2, y)(x_i * 10), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( KernelInterpolator(x_1, y)(x_i), KernelInterpolator(x_3, y)(x_i / 10), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception___call__(self): @@ -1255,17 +1257,18 @@ def test__call__(self): for i, value in enumerate( np.arange(0, len(DATA_POINTS_A) - 1 + interval, interval) ): - self.assertAlmostEqual( + np.testing.assert_allclose( DATA_POINTS_A_LINEAR_INTERPOLATED_10_SAMPLES[i], linear_interpolator(value), - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( linear_interpolator( np.arange(0, len(DATA_POINTS_A) - 1 + interval, interval) ), DATA_POINTS_A_LINEAR_INTERPOLATED_10_SAMPLES, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception___call__(self): @@ -1342,17 +1345,18 @@ def test__call__(self): for i, value in enumerate( np.arange(0, len(DATA_POINTS_A) - 1 + interval, interval) ): - self.assertAlmostEqual( + np.testing.assert_allclose( DATA_POINTS_A_SPRAGUE_INTERPOLATED_10_SAMPLES[i], sprague_interpolator(value), - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sprague_interpolator( np.arange(0, len(DATA_POINTS_A) - 1 + interval, interval) ), DATA_POINTS_A_SPRAGUE_INTERPOLATED_10_SAMPLES, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception___call__(self): @@ -1402,11 +1406,12 @@ def test__call__(self): and is assumed to be unit tested thoroughly. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CubicSplineInterpolator( np.linspace(0, 1, len(DATA_POINTS_A)), DATA_POINTS_A )(np.linspace(0, 1, len(DATA_POINTS_A) * 2)), DATA_POINTS_A_CUBIC_SPLINE_INTERPOLATED_X2_SAMPLES, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1527,15 +1532,17 @@ def test__call__(self): x = np.arange(len(DATA_POINTS_A)) null_interpolator = NullInterpolator(x, DATA_POINTS_A) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( null_interpolator(np.array([0.75, 2.0, 3.0, 4.75])), np.array([np.nan, 12.46, 9.51, np.nan]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) null_interpolator = NullInterpolator(x, DATA_POINTS_A, 0.25, 0.25) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( null_interpolator(np.array([0.75, 2.0, 3.0, 4.75])), np.array([12.32, 12.46, 9.51, 4.33]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception___call__(self): @@ -1590,13 +1597,13 @@ def test_lagrange_coefficients(self): """ lc = [lagrange_coefficients(i, 3) for i in np.linspace(0.05, 0.95, 19)] - np.testing.assert_array_almost_equal( - lc, LAGRANGE_COEFFICIENTS_A, decimal=7 + np.testing.assert_allclose( + lc, LAGRANGE_COEFFICIENTS_A, atol=TOLERANCE_ABSOLUTE_TESTS ) lc = [lagrange_coefficients(i, 4) for i in np.linspace(1.05, 1.95, 19)] - np.testing.assert_array_almost_equal( - lc, LAGRANGE_COEFFICIENTS_B, decimal=7 + np.testing.assert_allclose( + lc, LAGRANGE_COEFFICIENTS_B, atol=TOLERANCE_ABSOLUTE_TESTS ) @@ -1617,7 +1624,7 @@ def test_vertices_and_relative_coordinates(self): V_xyz = random_triplet_generator(4, random_state=prng) vertices, V_xyzr = vertices_and_relative_coordinates(V_xyz, LUT_TABLE) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices, np.array( [ @@ -1671,8 +1678,10 @@ def test_vertices_and_relative_coordinates(self): ], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + + np.testing.assert_allclose( V_xyzr, np.array( [ @@ -1682,6 +1691,7 @@ def test_vertices_and_relative_coordinates(self): [0.14444798, 0.01869077, 0.59305522], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1701,7 +1711,7 @@ def test_interpolation_trilinear(self): V_xyz = random_triplet_generator(16, random_state=prng) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( table_interpolation_trilinear(V_xyz, LUT_TABLE), np.array( [ @@ -1723,6 +1733,7 @@ def test_interpolation_trilinear(self): [0.59220355, 0.93136492, 0.30063692], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1742,7 +1753,7 @@ def test_interpolation_tetrahedral(self): V_xyz = random_triplet_generator(16, random_state=prng) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( table_interpolation_tetrahedral(V_xyz, LUT_TABLE), np.array( [ @@ -1764,6 +1775,7 @@ def test_interpolation_tetrahedral(self): [0.61272658, 0.92799297, 0.29650424], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/algebra/tests/test_prng.py b/colour/algebra/tests/test_prng.py index 2bbaea5475..a4d326ca06 100644 --- a/colour/algebra/tests/test_prng.py +++ b/colour/algebra/tests/test_prng.py @@ -12,10 +12,12 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + from colour.algebra import random_triplet_generator +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import NDArrayFloat __author__ = "Colour Developers" @@ -66,10 +68,10 @@ def test_random_triplet_generator(self): """ prng = np.random.RandomState(4) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RANDOM_TRIPLETS, random_triplet_generator(10, random_state=prng), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/algebra/tests/test_regression.py b/colour/algebra/tests/test_regression.py index 6ce5fdf435..edf425575a 100644 --- a/colour/algebra/tests/test_regression.py +++ b/colour/algebra/tests/test_regression.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.algebra.regression` module.""" -import numpy as np import unittest +import numpy as np + from colour.algebra import least_square_mapping_MoorePenrose +from colour.constants import TOLERANCE_ABSOLUTE_TESTS __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -34,7 +36,7 @@ def test_least_square_mapping_MoorePenrose(self): y = prng.random_sample((24, 3)) x = y + (prng.random_sample((24, 3)) - 0.5) * 0.5 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( least_square_mapping_MoorePenrose(y, x), np.array( [ @@ -43,12 +45,12 @@ def test_least_square_mapping_MoorePenrose(self): [0.05725508, -0.20526336, 1.10151945], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) y = prng.random_sample((4, 3, 2)) x = y + (prng.random_sample((4, 3, 2)) - 0.5) * 0.5 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( least_square_mapping_MoorePenrose(y, x), np.array( [ @@ -82,7 +84,7 @@ def test_least_square_mapping_MoorePenrose(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/appearance/atd95.py b/colour/appearance/atd95.py index 92df9842fc..ec1086fa9d 100644 --- a/colour/appearance/atd95.py +++ b/colour/appearance/atd95.py @@ -26,9 +26,10 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass, field +import numpy as np + from colour.algebra import spow, vector_dot from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( diff --git a/colour/appearance/cam16.py b/colour/appearance/cam16.py index 63442d4802..c120b0dd7f 100644 --- a/colour/appearance/cam16.py +++ b/colour/appearance/cam16.py @@ -20,15 +20,16 @@ from __future__ import annotations -import numpy as np from collections import namedtuple from dataclasses import astuple, dataclass, field -from colour.algebra import spow, vector_dot +import numpy as np + from colour.adaptation import CAT_CAT16 +from colour.algebra import spow, vector_dot from colour.appearance.ciecam02 import ( - InductionFactors_CIECAM02, VIEWING_CONDITIONS_CIECAM02, + InductionFactors_CIECAM02, P, achromatic_response_forward, achromatic_response_inverse, @@ -40,11 +41,11 @@ hue_angle, hue_quadrature, lightness_correlate, + matrix_post_adaptation_non_linear_response_compression, opponent_colour_dimensions_forward, opponent_colour_dimensions_inverse, post_adaptation_non_linear_response_compression_forward, post_adaptation_non_linear_response_compression_inverse, - matrix_post_adaptation_non_linear_response_compression, saturation_correlate, temporary_magnitude_quantity_inverse, viewing_conditions_dependent_parameters, diff --git a/colour/appearance/ciecam02.py b/colour/appearance/ciecam02.py index 4c99d896e7..fa7a03b574 100644 --- a/colour/appearance/ciecam02.py +++ b/colour/appearance/ciecam02.py @@ -32,12 +32,13 @@ from __future__ import annotations -import numpy as np from collections import namedtuple from dataclasses import astuple, dataclass, field -from colour.algebra import matrix_dot, sdiv, sdiv_mode, spow, vector_dot +import numpy as np + from colour.adaptation import CAT_CAT02 +from colour.algebra import matrix_dot, sdiv, sdiv_mode, spow, vector_dot from colour.appearance.hunt import ( MATRIX_HPE_TO_XYZ, MATRIX_XYZ_TO_HPE, @@ -53,8 +54,8 @@ as_float, as_float_array, as_int_array, - from_range_degrees, from_range_100, + from_range_degrees, has_only_nan, ones, to_domain_100, @@ -791,7 +792,7 @@ def full_chromatic_adaptation_forward( Y_w[..., None] * sdiv(D[..., None], RGB_w) + 1 - D[..., None] ) * RGB - return RGB_c + return cast(NDArrayFloat, RGB_c) def full_chromatic_adaptation_inverse( diff --git a/colour/appearance/ciecam16.py b/colour/appearance/ciecam16.py index f9e0759686..cbc3163277 100644 --- a/colour/appearance/ciecam16.py +++ b/colour/appearance/ciecam16.py @@ -20,15 +20,16 @@ from __future__ import annotations -import numpy as np from collections import namedtuple from dataclasses import astuple, dataclass, field +import numpy as np + from colour.algebra import spow, vector_dot from colour.appearance.cam16 import MATRIX_16, MATRIX_INVERSE_16 from colour.appearance.ciecam02 import ( - InductionFactors_CIECAM02, VIEWING_CONDITIONS_CIECAM02, + InductionFactors_CIECAM02, P, achromatic_response_forward, achromatic_response_inverse, @@ -40,10 +41,10 @@ hue_angle, hue_quadrature, lightness_correlate, + matrix_post_adaptation_non_linear_response_compression, opponent_colour_dimensions_forward, opponent_colour_dimensions_inverse, post_adaptation_non_linear_response_compression_forward, - matrix_post_adaptation_non_linear_response_compression, saturation_correlate, temporary_magnitude_quantity_inverse, viewing_conditions_dependent_parameters, diff --git a/colour/appearance/hellwig2022.py b/colour/appearance/hellwig2022.py index 9d0028c35f..8903672b37 100644 --- a/colour/appearance/hellwig2022.py +++ b/colour/appearance/hellwig2022.py @@ -24,28 +24,29 @@ from __future__ import annotations -import numpy as np from collections import namedtuple from dataclasses import astuple, dataclass, field +import numpy as np + from colour.algebra import sdiv, sdiv_mode, spow, vector_dot from colour.appearance.cam16 import ( MATRIX_16, MATRIX_INVERSE_16, ) from colour.appearance.ciecam02 import ( - InductionFactors_CIECAM02, VIEWING_CONDITIONS_CIECAM02, + InductionFactors_CIECAM02, achromatic_response_inverse, base_exponential_non_linearity, degree_of_adaptation, hue_angle, hue_quadrature, lightness_correlate, + matrix_post_adaptation_non_linear_response_compression, opponent_colour_dimensions_forward, post_adaptation_non_linear_response_compression_forward, post_adaptation_non_linear_response_compression_inverse, - matrix_post_adaptation_non_linear_response_compression, ) from colour.appearance.hunt import luminance_level_adaptation_factor from colour.hints import ArrayLike, NDArrayFloat, Tuple diff --git a/colour/appearance/hke.py b/colour/appearance/hke.py index 66db1371c1..48d5fecc98 100644 --- a/colour/appearance/hke.py +++ b/colour/appearance/hke.py @@ -28,7 +28,7 @@ import numpy as np from colour.algebra import spow -from colour.hints import ArrayLike, NDArrayFloat, Literal +from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, as_float_array, diff --git a/colour/appearance/hunt.py b/colour/appearance/hunt.py index 498219eba8..726b0a0f12 100644 --- a/colour/appearance/hunt.py +++ b/colour/appearance/hunt.py @@ -19,10 +19,11 @@ from __future__ import annotations -import numpy as np from collections import namedtuple from dataclasses import dataclass, field +import numpy as np + from colour.algebra import spow, vector_dot from colour.hints import ArrayLike, NDArrayFloat, cast from colour.utilities import ( diff --git a/colour/appearance/kim2009.py b/colour/appearance/kim2009.py index 973060fe2a..ab0cbaec91 100644 --- a/colour/appearance/kim2009.py +++ b/colour/appearance/kim2009.py @@ -21,14 +21,16 @@ from __future__ import annotations -import numpy as np from collections import namedtuple from dataclasses import astuple, dataclass, field +import numpy as np + from colour.adaptation import CAT_CAT02 +from colour.algebra import spow, vector_dot from colour.appearance.ciecam02 import ( - VIEWING_CONDITIONS_CIECAM02, CAT_INVERSE_CAT02, + VIEWING_CONDITIONS_CIECAM02, RGB_to_rgb, degree_of_adaptation, full_chromatic_adaptation_forward, @@ -36,7 +38,6 @@ hue_quadrature, rgb_to_RGB, ) -from colour.algebra import vector_dot, spow from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import ( CanonicalMapping, diff --git a/colour/appearance/llab.py b/colour/appearance/llab.py index 13ba3e1ab8..6c9ff8f8b6 100644 --- a/colour/appearance/llab.py +++ b/colour/appearance/llab.py @@ -25,10 +25,11 @@ Colour_Appearance_and_Gamut_Mapping """ -import numpy as np from collections import namedtuple from dataclasses import dataclass, field +import numpy as np + from colour.algebra import ( polar_to_cartesian, sdiv, diff --git a/colour/appearance/nayatani95.py b/colour/appearance/nayatani95.py index 1871c03dc3..b286b32213 100644 --- a/colour/appearance/nayatani95.py +++ b/colour/appearance/nayatani95.py @@ -20,16 +20,17 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass, field -from colour.algebra import spow, vector_dot +import numpy as np + from colour.adaptation.cie1994 import ( MATRIX_XYZ_TO_RGB_CIE1994, beta_1, exponential_factors, intermediate_values, ) +from colour.algebra import spow, vector_dot from colour.hints import ArrayLike, NDArrayFloat, cast from colour.models import XYZ_to_xy from colour.utilities import ( diff --git a/colour/appearance/rlab.py b/colour/appearance/rlab.py index 9977418fc9..3b2a5e29a4 100644 --- a/colour/appearance/rlab.py +++ b/colour/appearance/rlab.py @@ -20,9 +20,10 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass, field +import numpy as np + from colour.algebra import matrix_dot, sdiv, sdiv_mode, spow, vector_dot from colour.appearance.hunt import MATRIX_XYZ_TO_HPE, XYZ_to_rgb from colour.hints import ArrayLike, NDArrayFloat diff --git a/colour/appearance/tests/test_atd95.py b/colour/appearance/tests/test_atd95.py index 72fa1b731c..7edafe3a9f 100644 --- a/colour/appearance/tests/test_atd95.py +++ b/colour/appearance/tests/test_atd95.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.appearance.atd95` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import XYZ_to_ATD95 +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -62,7 +64,6 @@ def test_XYZ_to_ATD95(self): 0.0108, ] ), - rtol=0.01, atol=0.01, ) @@ -83,7 +84,6 @@ def test_XYZ_to_ATD95(self): 0.0005, ] ), - rtol=0.01, atol=0.01, ) @@ -105,7 +105,6 @@ def test_XYZ_to_ATD95(self): 0.0044, ] ), - rtol=0.01, atol=0.01, ) @@ -126,7 +125,6 @@ def test_XYZ_to_ATD95(self): 0.013, ] ), - rtol=0.01, atol=0.01, ) @@ -146,26 +144,26 @@ def test_n_dimensional_XYZ_to_ATD95(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ATD95(XYZ, XYZ_0, Y_02, K_1, K_2, sigma), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_0 = np.tile(XYZ_0, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ATD95(XYZ, XYZ_0, Y_02, K_1, K_2, sigma), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_0 = np.reshape(XYZ_0, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 9)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ATD95(XYZ, XYZ_0, Y_02, K_1, K_2, sigma), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -189,12 +187,12 @@ def test_domain_range_scale_XYZ_to_ATD95(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ATD95( XYZ * factor_a, XYZ_0 * factor_a, Y_0, k_1, k_2 ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_cam16.py b/colour/appearance/tests/test_cam16.py index 7eba6781c6..c6fc2dad32 100644 --- a/colour/appearance/tests/test_cam16.py +++ b/colour/appearance/tests/test_cam16.py @@ -1,17 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.appearance.cam16` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import ( VIEWING_CONDITIONS_CAM16, - InductionFactors_CAM16, + CAM16_to_XYZ, CAM_Specification_CAM16, + InductionFactors_CAM16, XYZ_to_CAM16, - CAM16_to_XYZ, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -46,7 +48,7 @@ def test_XYZ_to_CAM16(self): L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_CAM16["Average"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -60,12 +62,12 @@ def test_XYZ_to_CAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([57.06, 43.06, 31.96]) L_A = 31.83 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -79,13 +81,13 @@ def test_XYZ_to_CAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([3.53, 6.56, 2.14]) XYZ_w = np.array([109.85, 100, 35.58]) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -99,12 +101,12 @@ def test_XYZ_to_CAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([19.01, 20.00, 21.78]) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -118,13 +120,13 @@ def test_XYZ_to_CAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([61.45276998, 7.00421901, 82.2406738]) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 4.074366543152521 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -138,7 +140,7 @@ def test_XYZ_to_CAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_CAM16(self): @@ -156,26 +158,26 @@ def test_n_dimensional_XYZ_to_CAM16(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 8)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -218,12 +220,12 @@ def test_domain_range_scale_XYZ_to_CAM16(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CAM16( XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b, surround ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -257,20 +259,20 @@ def test_CAM16_to_XYZ(self): L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_CAM16["Average"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CAM16( 65.42828069, 49.67956420, 17.48659243 ) L_A = 31.83 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([57.06, 43.06, 31.96]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CAM16( @@ -278,20 +280,20 @@ def test_CAM16_to_XYZ(self): ) XYZ_w = np.array([109.85, 100, 35.58]) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([3.53, 6.56, 2.14]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CAM16( 41.36326063, 52.81154022, 258.88676291 ) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CAM16( @@ -299,10 +301,10 @@ def test_CAM16_to_XYZ(self): ) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 4.074366543152521 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([61.45276998, 7.00421901, 82.2406738]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CAM16_to_XYZ(self): @@ -323,17 +325,17 @@ def test_n_dimensional_CAM16_to_XYZ(self): *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist() ) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CAM16( @@ -341,10 +343,10 @@ def test_n_dimensional_CAM16_to_XYZ(self): ) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -388,7 +390,7 @@ def test_domain_range_scale_CAM16_to_XYZ(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CAM16_to_XYZ( specification * factor_a, XYZ_w * factor_b, @@ -397,7 +399,7 @@ def test_domain_range_scale_CAM16_to_XYZ(self): surround, ), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_ciecam02.py b/colour/appearance/tests/test_ciecam02.py index cf63030092..f848b95b05 100644 --- a/colour/appearance/tests/test_ciecam02.py +++ b/colour/appearance/tests/test_ciecam02.py @@ -1,17 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.appearance.ciecam02` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import ( VIEWING_CONDITIONS_CIECAM02, - InductionFactors_CIECAM02, CAM_Specification_CIECAM02, - XYZ_to_CIECAM02, CIECAM02_to_XYZ, + InductionFactors_CIECAM02, + XYZ_to_CIECAM02, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -57,8 +59,7 @@ def test_XYZ_to_CIECAM02(self): np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), np.array([41.73, 0.1, 219, 2.36, 195.37, 0.11, 278.1, np.nan]), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([57.06, 43.06, 31.96]) @@ -68,8 +69,7 @@ def test_XYZ_to_CIECAM02(self): np.array( [65.96, 48.57, 19.6, 52.25, 152.67, 41.67, 399.6, np.nan] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([3.53, 6.56, 2.14]) @@ -80,8 +80,7 @@ def test_XYZ_to_CIECAM02(self): np.array( [21.79, 46.94, 177.1, 58.79, 141.17, 48.8, 220.4, np.nan] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([19.01, 20.00, 21.78]) @@ -91,8 +90,7 @@ def test_XYZ_to_CIECAM02(self): np.array( [42.53, 51.92, 248.9, 60.22, 122.83, 44.54, 305.8, np.nan] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([61.45276998, 7.00421901, 82.24067384]) @@ -112,8 +110,7 @@ def test_XYZ_to_CIECAM02(self): np.nan, ] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) def test_n_dimensional_XYZ_to_CIECAM02(self): @@ -131,26 +128,26 @@ def test_n_dimensional_XYZ_to_CIECAM02(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 8)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -193,12 +190,12 @@ def test_domain_range_scale_XYZ_to_CIECAM02(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM02( XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b, surround ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -235,8 +232,7 @@ def test_CIECAM02_to_XYZ(self): np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - rtol=0.01, - atol=0.01, + atol=0.05, ) specification = CAM_Specification_CIECAM02( @@ -246,8 +242,7 @@ def test_CIECAM02_to_XYZ(self): np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([57.06, 43.06, 31.96]), - rtol=0.01, - atol=0.01, + atol=0.05, ) specification = CAM_Specification_CIECAM02( @@ -258,8 +253,7 @@ def test_CIECAM02_to_XYZ(self): np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([3.53, 6.56, 2.14]), - rtol=0.01, - atol=0.01, + atol=0.05, ) specification = CAM_Specification_CIECAM02( @@ -269,8 +263,7 @@ def test_CIECAM02_to_XYZ(self): np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - rtol=0.01, - atol=0.01, + atol=0.05, ) specification = CAM_Specification_CIECAM02( @@ -288,8 +281,7 @@ def test_CIECAM02_to_XYZ(self): np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([61.45276998, 7.00421901, 82.24067384]), - rtol=0.01, - atol=0.01, + atol=0.05, ) def test_n_dimensional_CIECAM02_to_XYZ(self): @@ -310,17 +302,17 @@ def test_n_dimensional_CIECAM02_to_XYZ(self): *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist() ) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CIECAM02( @@ -328,10 +320,10 @@ def test_n_dimensional_CIECAM02_to_XYZ(self): ) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM02_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -375,7 +367,7 @@ def test_domain_range_scale_CIECAM02_to_XYZ(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM02_to_XYZ( specification * factor_a, XYZ_w * factor_b, @@ -384,7 +376,7 @@ def test_domain_range_scale_CIECAM02_to_XYZ(self): surround, ), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_ciecam16.py b/colour/appearance/tests/test_ciecam16.py index 7efab8cbfc..c7ad6522b6 100644 --- a/colour/appearance/tests/test_ciecam16.py +++ b/colour/appearance/tests/test_ciecam16.py @@ -1,17 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.appearance.ciecam16` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import ( VIEWING_CONDITIONS_CIECAM16, - InductionFactors_CIECAM16, CAM_Specification_CIECAM16, - XYZ_to_CIECAM16, CIECAM16_to_XYZ, + InductionFactors_CIECAM16, + XYZ_to_CIECAM16, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -48,7 +50,7 @@ def test_XYZ_to_CIECAM16(self): L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_CIECAM16["Average"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -62,12 +64,12 @@ def test_XYZ_to_CIECAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([57.06, 43.06, 31.96]) L_A = 31.83 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -81,13 +83,13 @@ def test_XYZ_to_CIECAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([3.53, 6.56, 2.14]) XYZ_w = np.array([109.85, 100, 35.58]) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -101,12 +103,12 @@ def test_XYZ_to_CIECAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([19.01, 20.00, 21.78]) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -120,13 +122,13 @@ def test_XYZ_to_CIECAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([61.45276998, 7.00421901, 82.2406738]) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 4.074366543152521 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -140,14 +142,14 @@ def test_XYZ_to_CIECAM16(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([60.70, 49.60, 10.29]) XYZ_w = np.array([96.46, 100.00, 108.62]) L_A = 40 Y_b = 16 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), np.array( [ @@ -161,7 +163,7 @@ def test_XYZ_to_CIECAM16(self): np.nan, ] ), - decimal=4, + atol=5e-5, ) def test_n_dimensional_XYZ_to_CIECAM16(self): @@ -179,26 +181,26 @@ def test_n_dimensional_XYZ_to_CIECAM16(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 8)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -241,12 +243,12 @@ def test_domain_range_scale_XYZ_to_CIECAM16(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CIECAM16( XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b, surround ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -282,20 +284,20 @@ def test_CIECAM16_to_XYZ(self): L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_CIECAM16["Average"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CIECAM16( 65.42828069, 49.67956420, 17.48659243 ) L_A = 31.83 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([57.06, 43.06, 31.96]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CIECAM16( @@ -303,20 +305,20 @@ def test_CIECAM16_to_XYZ(self): ) XYZ_w = np.array([109.85, 100, 35.58]) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([3.53, 6.56, 2.14]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CIECAM16( 41.36326063, 52.81154022, 258.88676291 ) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CIECAM16( @@ -324,20 +326,20 @@ def test_CIECAM16_to_XYZ(self): ) XYZ_w = np.array([95.05, 100.00, 108.88]) L_A = 4.074366543152521 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([61.45276998, 7.00421901, 82.2406738]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CIECAM16(70.4406, 58.6035, 57.9145) XYZ_w = np.array([96.46, 100.00, 108.62]) L_A = 40 Y_b = 16 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([60.70, 49.60, 10.29]), - decimal=2, + atol=1e-4, ) def test_n_dimensional_CIECAM16_to_XYZ(self): @@ -358,17 +360,17 @@ def test_n_dimensional_CIECAM16_to_XYZ(self): *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist() ) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_CIECAM16( @@ -376,10 +378,10 @@ def test_n_dimensional_CIECAM16_to_XYZ(self): ) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -423,7 +425,7 @@ def test_domain_range_scale_CIECAM16_to_XYZ(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CIECAM16_to_XYZ( specification * factor_a, XYZ_w * factor_b, @@ -432,7 +434,7 @@ def test_domain_range_scale_CIECAM16_to_XYZ(self): surround, ), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_hellwig2022.py b/colour/appearance/tests/test_hellwig2022.py index 15fa3b6f2f..d9d6f69967 100644 --- a/colour/appearance/tests/test_hellwig2022.py +++ b/colour/appearance/tests/test_hellwig2022.py @@ -8,17 +8,19 @@ Discussion with Mansencal, T. """ -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import ( VIEWING_CONDITIONS_HELLWIG2022, - InductionFactors_Hellwig2022, CAM_Specification_Hellwig2022, - XYZ_to_Hellwig2022, Hellwig2022_to_XYZ, + InductionFactors_Hellwig2022, + XYZ_to_Hellwig2022, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -72,7 +74,6 @@ def test_XYZ_to_Hellwig2022(self): 56.05183586, ] ), - rtol=0.01, atol=0.01, ) @@ -94,7 +95,6 @@ def test_XYZ_to_Hellwig2022(self): 69.04574688, ] ), - rtol=0.01, atol=0.01, ) @@ -117,7 +117,6 @@ def test_XYZ_to_Hellwig2022(self): 39.28664523, ] ), - rtol=0.01, atol=0.01, ) @@ -140,7 +139,6 @@ def test_XYZ_to_Hellwig2022(self): 48.627748198047854, ] ), - rtol=0.01, atol=0.01, ) @@ -159,26 +157,26 @@ def test_n_dimensional_XYZ_to_Hellwig2022(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hellwig2022(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hellwig2022(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 10)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hellwig2022(XYZ, XYZ_w, L_A, Y_b, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -223,12 +221,12 @@ def test_domain_range_scale_XYZ_to_Hellwig2022(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hellwig2022( XYZ * factor_a, XYZ_w * factor_a, L_A, Y_b, surround ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -267,20 +265,20 @@ def test_Hellwig2022_to_XYZ(self): L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_HELLWIG2022["Average"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_Hellwig2022( 65.428280687118473, 31.330032520870901, 17.486592427576902 ) L_A = 31.83 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([57.06, 43.06, 31.96]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_Hellwig2022( @@ -288,20 +286,20 @@ def test_Hellwig2022_to_XYZ(self): ) XYZ_w = np.array([109.85, 100, 35.58]) L_A = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([3.53, 6.56, 2.14]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_Hellwig2022( 41.064050542871215, 31.939561618552826, 259.03405661643671 ) L_A = 31.38 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_Hellwig2022( @@ -311,10 +309,10 @@ def test_Hellwig2022_to_XYZ(self): L_A = 318.31 Y_b = 20 surround = VIEWING_CONDITIONS_HELLWIG2022["Average"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), np.array([19.01, 20.00, 21.78]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Hellwig2022_to_XYZ(self): @@ -335,17 +333,17 @@ def test_n_dimensional_Hellwig2022_to_XYZ(self): *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist() ) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_Hellwig2022( @@ -353,10 +351,10 @@ def test_n_dimensional_Hellwig2022_to_XYZ(self): ) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ(specification, XYZ_w, L_A, Y_b, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -402,7 +400,7 @@ def test_domain_range_scale_Hellwig2022_to_XYZ(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hellwig2022_to_XYZ( specification * factor_a, XYZ_w * factor_b, @@ -411,7 +409,7 @@ def test_domain_range_scale_Hellwig2022_to_XYZ(self): surround, ), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_hke.py b/colour/appearance/tests/test_hke.py index cd7ceee75a..ca6b2157c4 100644 --- a/colour/appearance/tests/test_hke.py +++ b/colour/appearance/tests/test_hke.py @@ -1,16 +1,18 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.appearance.hke` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance.hke import ( - HelmholtzKohlrausch_effect_object_Nayatani1997, HelmholtzKohlrausch_effect_luminous_Nayatani1997, + HelmholtzKohlrausch_effect_object_Nayatani1997, coefficient_K_Br_Nayatani1997, coefficient_q_Nayatani1997, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Ilia Sibiryakov" @@ -40,7 +42,7 @@ def test_HelmholtzKohlrausch_effect_object_Nayatani1997(self): HelmholtzKohlrausch_effect_object_Nayatani1997` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_object_Nayatani1997( np.array([0.40351010, 0.53933673]), np.array([0.19783001, 0.46831999]), @@ -48,10 +50,10 @@ def test_HelmholtzKohlrausch_effect_object_Nayatani1997(self): method="VCC", ), 1.344152435497761, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_object_Nayatani1997( np.array([0.40351010, 0.53933673]), np.array([0.19783001, 0.46831999]), @@ -59,7 +61,7 @@ def test_HelmholtzKohlrausch_effect_object_Nayatani1997(self): method="VAC", ), 1.261777232837009, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_HelmholtzKohlrausch_effect_object_Nayatani1997( @@ -87,20 +89,20 @@ def test_n_dimensional_HelmholtzKohlrausch_effect_object_Nayatani1997( result_vcc = np.tile(result_vcc, 6) result_vac = np.tile(result_vac, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_object_Nayatani1997( uv, uv_d65, L_a, method="VCC" ), result_vcc, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_object_Nayatani1997( uv, uv_d65, L_a, method="VAC" ), result_vac, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) uv_d65 = np.reshape(uv_d65, (2, 3, 2)) @@ -108,20 +110,20 @@ def test_n_dimensional_HelmholtzKohlrausch_effect_object_Nayatani1997( result_vcc = np.reshape(result_vcc, (2, 3)) result_vac = np.reshape(result_vac, (2, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_object_Nayatani1997( uv, uv_d65, L_a, method="VCC" ), result_vcc, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_object_Nayatani1997( uv, uv_d65, L_a, method="VAC" ), result_vac, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -150,7 +152,7 @@ def test_HelmholtzKohlrausch_effect_luminous_Nayatani1997(self): HelmholtzKohlrausch_effect_luminous_Nayatani1997` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_luminous_Nayatani1997( np.array([0.40351010, 0.53933673]), np.array([0.19783001, 0.46831999]), @@ -158,10 +160,10 @@ def test_HelmholtzKohlrausch_effect_luminous_Nayatani1997(self): method="VCC", ), 2.014433723774654, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_luminous_Nayatani1997( np.array([0.40351010, 0.53933673]), np.array([0.19783001, 0.46831999]), @@ -169,7 +171,7 @@ def test_HelmholtzKohlrausch_effect_luminous_Nayatani1997(self): method="VAC", ), 1.727991241148628, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_HelmholtzKohlrausch_effect_luminous_Nayatani1997( @@ -197,20 +199,20 @@ def test_n_dimensional_HelmholtzKohlrausch_effect_luminous_Nayatani1997( result_vcc = np.tile(result_vcc, 6) result_vac = np.tile(result_vac, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_luminous_Nayatani1997( uv, uv_d65, L_a, method="VCC" ), result_vcc, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_luminous_Nayatani1997( uv, uv_d65, L_a, method="VAC" ), result_vac, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) uv_d65 = np.reshape(uv_d65, (2, 3, 2)) @@ -218,20 +220,20 @@ def test_n_dimensional_HelmholtzKohlrausch_effect_luminous_Nayatani1997( result_vcc = np.reshape(result_vcc, (2, 3)) result_vac = np.reshape(result_vac, (2, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_luminous_Nayatani1997( uv, uv_d65, L_a, method="VCC" ), result_vcc, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HelmholtzKohlrausch_effect_luminous_Nayatani1997( uv, uv_d65, L_a, method="VAC" ), result_vac, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -261,28 +263,28 @@ def test_coefficient_K_Br_Nayatani1997(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( coefficient_K_Br_Nayatani1997(10.00000000), 0.71344817765758839, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( coefficient_K_Br_Nayatani1997(63.66000000), 1.000128455584031, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( coefficient_K_Br_Nayatani1997(1000.00000000), 1.401080840298197, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( coefficient_K_Br_Nayatani1997(10000.00000000), 1.592511806930447, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_coefficient_K_Br_Nayatani1997(self): @@ -296,20 +298,26 @@ def test_n_dimensional_coefficient_K_Br_Nayatani1997(self): L_a = np.tile(L_a, 6) K_Br = np.tile(K_Br, 6) - np.testing.assert_array_almost_equal( - coefficient_K_Br_Nayatani1997(L_a), K_Br, decimal=7 + np.testing.assert_allclose( + coefficient_K_Br_Nayatani1997(L_a), + K_Br, + atol=TOLERANCE_ABSOLUTE_TESTS, ) L_a = np.reshape(L_a, (2, 3)) K_Br = np.reshape(K_Br, (2, 3)) - np.testing.assert_array_almost_equal( - coefficient_K_Br_Nayatani1997(L_a), K_Br, decimal=7 + np.testing.assert_allclose( + coefficient_K_Br_Nayatani1997(L_a), + K_Br, + atol=TOLERANCE_ABSOLUTE_TESTS, ) L_a = np.reshape(L_a, (2, 3, 1)) K_Br = np.reshape(K_Br, (2, 3, 1)) - np.testing.assert_array_almost_equal( - coefficient_K_Br_Nayatani1997(L_a), K_Br, decimal=7 + np.testing.assert_allclose( + coefficient_K_Br_Nayatani1997(L_a), + K_Br, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -335,22 +343,28 @@ def test_coefficient_q_Nayatani1997(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( coefficient_q_Nayatani1997(0.00000000), -0.121200000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - coefficient_q_Nayatani1997(0.78539816), 0.125211117768464, places=7 + np.testing.assert_allclose( + coefficient_q_Nayatani1997(0.78539816), + 0.125211117768464, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - coefficient_q_Nayatani1997(1.57079633), 0.191679999416415, places=7 + np.testing.assert_allclose( + coefficient_q_Nayatani1997(1.57079633), + 0.191679999416415, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - coefficient_q_Nayatani1997(2.35619449), 0.028480866426611, places=7 + np.testing.assert_allclose( + coefficient_q_Nayatani1997(2.35619449), + 0.028480866426611, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_coefficient_q_Nayatani1997(self): @@ -364,20 +378,20 @@ def test_n_dimensional_coefficient_q_Nayatani1997(self): L_a = np.tile(L_a, 6) q = np.tile(q, 6) - np.testing.assert_array_almost_equal( - coefficient_q_Nayatani1997(L_a), q, decimal=7 + np.testing.assert_allclose( + coefficient_q_Nayatani1997(L_a), q, atol=TOLERANCE_ABSOLUTE_TESTS ) L_a = np.reshape(L_a, (2, 3)) q = np.reshape(q, (2, 3)) - np.testing.assert_array_almost_equal( - coefficient_q_Nayatani1997(L_a), q, decimal=7 + np.testing.assert_allclose( + coefficient_q_Nayatani1997(L_a), q, atol=TOLERANCE_ABSOLUTE_TESTS ) L_a = np.reshape(L_a, (2, 3, 1)) q = np.reshape(q, (2, 3, 1)) - np.testing.assert_array_almost_equal( - coefficient_q_Nayatani1997(L_a), q, decimal=7 + np.testing.assert_allclose( + coefficient_q_Nayatani1997(L_a), q, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_hunt.py b/colour/appearance/tests/test_hunt.py index 05d70fb8b9..1ada17da5f 100644 --- a/colour/appearance/tests/test_hunt.py +++ b/colour/appearance/tests/test_hunt.py @@ -2,15 +2,17 @@ """Define the unit tests for the :mod:`colour.appearance.hunt` module.""" import contextlib -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import ( VIEWING_CONDITIONS_HUNT, InductionFactors_Hunt, XYZ_to_Hunt, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -55,8 +57,7 @@ def test_XYZ_to_Hunt(self): np.testing.assert_allclose( XYZ_to_Hunt(XYZ, XYZ_w, XYZ_b, L_A, surround, CCT_w=CCT_w), np.array([42.12, 0.16, 269.3, 0.03, 31.92, 0.16, np.nan, np.nan]), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([57.06, 43.06, 31.96]) @@ -66,8 +67,7 @@ def test_XYZ_to_Hunt(self): np.array( [66.76, 63.89, 18.6, 153.36, 31.22, 58.28, np.nan, np.nan] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([3.53, 6.56, 2.14]) @@ -79,8 +79,7 @@ def test_XYZ_to_Hunt(self): np.array( [19.56, 74.58, 178.3, 245.4, 18.9, 76.33, np.nan, np.nan] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([19.01, 20.00, 21.78]) @@ -90,8 +89,7 @@ def test_XYZ_to_Hunt(self): np.array( [40.27, 73.84, 262.8, 209.29, 22.15, 67.35, np.nan, np.nan] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) def test_n_dimensional_XYZ_to_Hunt(self): @@ -112,28 +110,28 @@ def test_n_dimensional_XYZ_to_Hunt(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunt(XYZ, XYZ_w, XYZ_b, L_A, surround, CCT_w=CCT_w), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) XYZ_b = np.tile(XYZ_b, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunt(XYZ, XYZ_w, XYZ_b, L_A, surround, CCT_w=CCT_w), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ_b = np.reshape(XYZ_b, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 8)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunt(XYZ, XYZ_w, XYZ_b, L_A, surround, CCT_w=CCT_w), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_Hunt(self): @@ -159,7 +157,7 @@ def test_domain_range_scale_XYZ_to_Hunt(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunt( XYZ * factor_a, XYZ_w * factor_a, @@ -169,7 +167,7 @@ def test_domain_range_scale_XYZ_to_Hunt(self): CCT_w=CCT_w, ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -210,7 +208,7 @@ def test_XYZ_p_XYZ_to_Hunt(self): surround = VIEWING_CONDITIONS_HUNT["Normal Scenes"] CCT_w = 6504.0 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunt( XYZ, XYZ_w, @@ -232,7 +230,7 @@ def test_XYZ_p_XYZ_to_Hunt(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_kim2009.py b/colour/appearance/tests/test_kim2009.py index 36a9cf8f66..ccc9c9a38b 100644 --- a/colour/appearance/tests/test_kim2009.py +++ b/colour/appearance/tests/test_kim2009.py @@ -1,19 +1,21 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.appearance.kim2009` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import ( MEDIA_PARAMETERS_KIM2009, VIEWING_CONDITIONS_KIM2009, - InductionFactors_Kim2009, CAM_Specification_Kim2009, + InductionFactors_Kim2009, + Kim2009_to_XYZ, MediaParameters_Kim2009, XYZ_to_Kim2009, - Kim2009_to_XYZ, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -48,7 +50,7 @@ def test_XYZ_to_Kim2009(self): L_a = 318.31 media = MEDIA_PARAMETERS_KIM2009["CRT Displays"] surround = VIEWING_CONDITIONS_KIM2009["Average"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), np.array( [ @@ -62,12 +64,12 @@ def test_XYZ_to_Kim2009(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([57.06, 43.06, 31.96]) L_a = 31.83 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), np.array( [ @@ -81,13 +83,13 @@ def test_XYZ_to_Kim2009(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([3.53, 6.56, 2.14]) XYZ_w = np.array([109.85, 100.00, 35.58]) L_a = 318.31 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), np.array( [ @@ -101,12 +103,12 @@ def test_XYZ_to_Kim2009(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.array([19.01, 20.00, 21.78]) L_a = 31.83 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), np.array( [ @@ -120,7 +122,7 @@ def test_XYZ_to_Kim2009(self): np.nan, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Kim2009(self): @@ -138,26 +140,26 @@ def test_n_dimensional_XYZ_to_Kim2009(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 8)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -200,12 +202,12 @@ def test_domain_range_scale_XYZ_to_Kim2009(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Kim2009( XYZ * factor_a, XYZ_w * factor_a, L_a, media, surround ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -251,7 +253,6 @@ def test_Kim2009_to_XYZ(self): Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), np.array([19.01, 20.00, 21.78]), atol=0.01, - rtol=0.01, ) specification = CAM_Specification_Kim2009( @@ -269,7 +270,6 @@ def test_Kim2009_to_XYZ(self): Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), np.array([57.06, 43.06, 31.96]), atol=0.01, - rtol=0.01, ) specification = CAM_Specification_Kim2009( @@ -288,7 +288,6 @@ def test_Kim2009_to_XYZ(self): Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), np.array([3.53, 6.56, 2.14]), atol=0.01, - rtol=0.01, ) specification = CAM_Specification_Kim2009( @@ -306,7 +305,6 @@ def test_Kim2009_to_XYZ(self): Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), np.array([19.01, 20.00, 21.78]), atol=0.01, - rtol=0.01, ) def test_n_dimensional_Kim2009_to_XYZ(self): @@ -327,17 +325,17 @@ def test_n_dimensional_Kim2009_to_XYZ(self): *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist() ) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = CAM_Specification_Kim2009( @@ -345,10 +343,10 @@ def test_n_dimensional_Kim2009_to_XYZ(self): ) XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -392,7 +390,7 @@ def test_domain_range_scale_Kim2009_to_XYZ(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Kim2009_to_XYZ( specification * factor_a, XYZ_w * factor_b, @@ -401,7 +399,7 @@ def test_domain_range_scale_Kim2009_to_XYZ(self): surround, ), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_llab.py b/colour/appearance/tests/test_llab.py index c7cc5649a0..ccc9c9a38b 100644 --- a/colour/appearance/tests/test_llab.py +++ b/colour/appearance/tests/test_llab.py @@ -1,21 +1,26 @@ # !/usr/bin/env python -"""Define the unit tests for the :mod:`colour.appearance.llab` module.""" +"""Define the unit tests for the :mod:`colour.appearance.kim2009` module.""" -import numpy as np import unittest -from unittest import mock from itertools import product +import numpy as np + from colour.appearance import ( - VIEWING_CONDITIONS_LLAB, - InductionFactors_LLAB, - XYZ_to_LLAB, - llab, + MEDIA_PARAMETERS_KIM2009, + VIEWING_CONDITIONS_KIM2009, + CAM_Specification_Kim2009, + InductionFactors_Kim2009, + Kim2009_to_XYZ, + MediaParameters_Kim2009, + XYZ_to_Kim2009, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, ignore_numpy_errors, + tsplit, ) __author__ = "Colour Developers" @@ -26,167 +31,420 @@ __status__ = "Production" __all__ = [ - "TestXYZ_to_LLAB", + "TestXYZ_to_Kim2009", + "TestKim2009_to_XYZ", ] -class TestXYZ_to_LLAB(unittest.TestCase): +class TestXYZ_to_Kim2009(unittest.TestCase): """ - Define :func:`colour.appearance.llab.XYZ_to_LLAB` definition unit + Define :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition unit tests methods. """ - def test_XYZ_to_LLAB(self): - """ - Test :func:`colour.appearance.llab.XYZ_to_LLAB` definition. + def test_XYZ_to_Kim2009(self): + """Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition.""" - Notes - ----- - - The test values have been generated from data of the following file - by *Fairchild (2013)*: - http://rit-mcsl.org/fairchild//files/AppModEx.xls - """ + XYZ = np.array([19.01, 20.00, 21.78]) + XYZ_w = np.array([95.05, 100.00, 108.88]) + L_a = 318.31 + media = MEDIA_PARAMETERS_KIM2009["CRT Displays"] + surround = VIEWING_CONDITIONS_KIM2009["Average"] + np.testing.assert_allclose( + XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), + np.array( + [ + 28.86190898, + 0.55924559, + 219.04806678, + 9.38377973, + 52.71388839, + 0.46417384, + 278.06028246, + np.nan, + ] + ), + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - with mock.patch( - "colour.appearance.llab.MATRIX_RGB_TO_XYZ_LLAB", - np.around(np.linalg.inv(llab.MATRIX_XYZ_TO_RGB_LLAB), decimals=4), - ): - XYZ = np.array([19.01, 20.00, 21.78]) - XYZ_0 = np.array([95.05, 100.00, 108.88]) - Y_b = 20 - L = 318.31 - surround = VIEWING_CONDITIONS_LLAB[ - "Reference Samples & Images, Average Surround, Subtending < 4" - ] - np.testing.assert_allclose( - XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround), - np.array([37.37, 0.01, 229.5, 0, 0.02, np.nan, -0.01, -0.01]), - rtol=0.01, - atol=0.01, - ) - - XYZ = np.array([57.06, 43.06, 31.96]) - L = 31.83 - np.testing.assert_allclose( - XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround), - np.array( - [61.26, 30.51, 22.3, 0.5, 56.55, np.nan, 52.33, 21.43] - ), - rtol=0.01, - atol=0.01, - ) - - XYZ = np.array([3.53, 6.56, 2.14]) - XYZ_0 = np.array([109.85, 100.00, 35.58]) - L = 318.31 - np.testing.assert_allclose( - XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround), - np.array( - [16.25, 30.43, 173.8, 1.87, 53.83, np.nan, -53.51, 5.83] - ), - rtol=0.01, - atol=0.01, - ) - - XYZ = np.array([19.01, 20.00, 21.78]) - L = 31.83 - np.testing.assert_allclose( - XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround), - np.array( - [39.82, 29.34, 271.9, 0.74, 54.59, np.nan, 1.76, -54.56] - ), - rtol=0.01, - atol=0.01, - ) + XYZ = np.array([57.06, 43.06, 31.96]) + L_a = 31.83 + np.testing.assert_allclose( + XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), + np.array( + [ + 70.15940419, + 57.89295872, + 21.27017200, + 61.23630434, + 128.14034598, + 48.05115573, + 1.41841443, + np.nan, + ] + ), + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - def test_n_dimensional_XYZ_to_LLAB(self): + XYZ = np.array([3.53, 6.56, 2.14]) + XYZ_w = np.array([109.85, 100.00, 35.58]) + L_a = 318.31 + np.testing.assert_allclose( + XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), + np.array( + [ + -4.83430022, + 37.42013921, + 177.12166057, + np.nan, + -8.82944930, + 31.05871555, + 220.36270343, + np.nan, + ] + ), + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + XYZ = np.array([19.01, 20.00, 21.78]) + L_a = 31.83 + np.testing.assert_allclose( + XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), + np.array( + [ + 47.20460719, + 56.35723637, + 241.04877377, + 73.65830083, + 86.21530880, + 46.77650619, + 301.77516676, + np.nan, + ] + ), + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + def test_n_dimensional_XYZ_to_Kim2009(self): """ - Test :func:`colour.appearance.llab.XYZ_to_LLAB` definition + Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition n-dimensional support. """ XYZ = np.array([19.01, 20.00, 21.78]) - XYZ_0 = np.array([95.05, 100.00, 108.88]) - Y_b = 20 - L = 318.31 - surround = VIEWING_CONDITIONS_LLAB[ - "Reference Samples & Images, Average Surround, Subtending < 4" - ] - specification = XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround) + XYZ_w = np.array([95.05, 100.00, 108.88]) + L_a = 318.31 + media = MEDIA_PARAMETERS_KIM2009["CRT Displays"] + surround = VIEWING_CONDITIONS_KIM2009["Average"] + specification = XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround) XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround), specification, decimal=7 + np.testing.assert_allclose( + XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - XYZ_0 = np.tile(XYZ_0, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround), specification, decimal=7 + XYZ_w = np.tile(XYZ_w, (6, 1)) + np.testing.assert_allclose( + XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) - XYZ_0 = np.reshape(XYZ_0, (2, 3, 3)) + XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 8)) - np.testing.assert_array_almost_equal( - XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround), specification, decimal=7 + np.testing.assert_allclose( + XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - def test_colourspace_conversion_matrices_precision(self): + @ignore_numpy_errors + def test_domain_range_scale_XYZ_to_Kim2009(self): """ - Test for loss of precision in conversion between - *LLAB(l:c)* colour appearance model *CIE XYZ* tristimulus values and - normalised cone responses matrix. + Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition + domain and range scale support. """ - start = np.array([1, 1, 1]) - result = np.array(start) - for _ in range(100000): - result = llab.MATRIX_RGB_TO_XYZ_LLAB.dot(result) - result = llab.MATRIX_XYZ_TO_RGB_LLAB.dot(result) - np.testing.assert_array_almost_equal(start, result, decimal=7) + XYZ = np.array([19.01, 20.00, 21.78]) + XYZ_w = np.array([95.05, 100.00, 108.88]) + L_a = 318.31 + media = MEDIA_PARAMETERS_KIM2009["CRT Displays"] + surround = VIEWING_CONDITIONS_KIM2009["Average"] + specification = XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround) + + d_r = ( + ("reference", 1, 1), + ( + "1", + 0.01, + np.array( + [ + 1 / 100, + 1 / 100, + 1 / 360, + 1 / 100, + 1 / 100, + 1 / 100, + 1 / 400, + np.nan, + ] + ), + ), + ( + "100", + 1, + np.array([1, 1, 100 / 360, 1, 1, 1, 100 / 400, np.nan]), + ), + ) + for scale, factor_a, factor_b in d_r: + with domain_range_scale(scale): + np.testing.assert_allclose( + XYZ_to_Kim2009( + XYZ * factor_a, XYZ_w * factor_a, L_a, media, surround + ), + as_float_array(specification) * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + @ignore_numpy_errors + def test_nan_XYZ_to_Kim2009(self): + """ + Test :func:`colour.appearance.kim2009.XYZ_to_Kim2009` definition + nan support. + """ + + cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] + cases = np.array(list(set(product(cases, repeat=3)))) + media = MediaParameters_Kim2009(cases[0, 0]) + surround = InductionFactors_Kim2009( + cases[0, 0], cases[0, 0], cases[0, 0] + ) + XYZ_to_Kim2009(cases, cases, cases[0, 0], media, surround) + + +class TestKim2009_to_XYZ(unittest.TestCase): + """ + Define :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition unit + tests methods. + """ + + def test_Kim2009_to_XYZ(self): + """Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition.""" + + specification = CAM_Specification_Kim2009( + 28.86190898, + 0.55924559, + 219.04806678, + 9.38377973, + 52.71388839, + 0.46417384, + 278.06028246, + np.nan, + ) + XYZ_w = np.array([95.05, 100.00, 108.88]) + L_a = 318.31 + media = MEDIA_PARAMETERS_KIM2009["CRT Displays"] + surround = VIEWING_CONDITIONS_KIM2009["Average"] + np.testing.assert_allclose( + Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), + np.array([19.01, 20.00, 21.78]), + atol=0.01, + ) + + specification = CAM_Specification_Kim2009( + 70.15940419, + 57.89295872, + 21.27017200, + 61.23630434, + 128.14034598, + 48.05115573, + 1.41841443, + np.nan, + ) + L_a = 31.83 + np.testing.assert_allclose( + Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), + np.array([57.06, 43.06, 31.96]), + atol=0.01, + ) + + specification = CAM_Specification_Kim2009( + -4.83430022, + 37.42013921, + 177.12166057, + np.nan, + -8.82944930, + 31.05871555, + 220.36270343, + np.nan, + ) + XYZ_w = np.array([109.85, 100.00, 35.58]) + L_a = 318.31 + np.testing.assert_allclose( + Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), + np.array([3.53, 6.56, 2.14]), + atol=0.01, + ) + + specification = CAM_Specification_Kim2009( + 47.20460719, + 56.35723637, + 241.04877377, + 73.65830083, + 86.21530880, + 46.77650619, + 301.77516676, + np.nan, + ) + L_a = 31.83 + np.testing.assert_allclose( + Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), + np.array([19.01, 20.00, 21.78]), + atol=0.01, + ) - def test_domain_range_scale_XYZ_to_LLAB(self): + def test_n_dimensional_Kim2009_to_XYZ(self): """ - Test :func:`colour.appearance.llab.XYZ_to_LLAB` definition domain - and range scale support. + Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition + n-dimensional support. """ XYZ = np.array([19.01, 20.00, 21.78]) - XYZ_0 = np.array([95.05, 100.00, 108.88]) - Y_b = 20 - L = 318.31 - surround = VIEWING_CONDITIONS_LLAB["ref_average_4_minus"] - specification = XYZ_to_LLAB(XYZ, XYZ_0, Y_b, L, surround) + XYZ_w = np.array([95.05, 100.00, 108.88]) + L_a = 318.31 + media = MEDIA_PARAMETERS_KIM2009["CRT Displays"] + surround = VIEWING_CONDITIONS_KIM2009["Average"] + specification = XYZ_to_Kim2009(XYZ, XYZ_w, L_a, media, surround) + XYZ = Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround) + + specification = CAM_Specification_Kim2009( + *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist() + ) + XYZ = np.tile(XYZ, (6, 1)) + np.testing.assert_allclose( + Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + XYZ_w = np.tile(XYZ_w, (6, 1)) + np.testing.assert_allclose( + Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + specification = CAM_Specification_Kim2009( + *tsplit(np.reshape(specification, (2, 3, 8))).tolist() + ) + XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) + XYZ = np.reshape(XYZ, (2, 3, 3)) + np.testing.assert_allclose( + Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + @ignore_numpy_errors + def test_domain_range_scale_Kim2009_to_XYZ(self): + """ + Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition + domain and range scale support. + """ + + XYZ_i = np.array([19.01, 20.00, 21.78]) + XYZ_w = np.array([95.05, 100.00, 108.88]) + L_a = 318.31 + media = MEDIA_PARAMETERS_KIM2009["CRT Displays"] + surround = VIEWING_CONDITIONS_KIM2009["Average"] + specification = XYZ_to_Kim2009(XYZ_i, XYZ_w, L_a, media, surround) + XYZ = Kim2009_to_XYZ(specification, XYZ_w, L_a, media, surround) d_r = ( ("reference", 1, 1), - ("1", 0.01, np.array([1, 1, 1 / 360, 1, 1, np.nan, 1, 1])), - ("100", 1, np.array([1, 1, 100 / 360, 1, 1, np.nan, 1, 1])), + ( + "1", + np.array( + [ + 1 / 100, + 1 / 100, + 1 / 360, + 1 / 100, + 1 / 100, + 1 / 100, + 1 / 400, + np.nan, + ] + ), + 0.01, + ), + ( + "100", + np.array([1, 1, 100 / 360, 1, 1, 1, 100 / 400, np.nan]), + 1, + ), ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_LLAB( - XYZ * factor_a, XYZ_0 * factor_a, Y_b, L, surround + np.testing.assert_allclose( + Kim2009_to_XYZ( + specification * factor_a, + XYZ_w * factor_b, + L_a, + media, + surround, ), - as_float_array(specification) * factor_b, - decimal=7, + XYZ * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors - def test_nan_XYZ_to_LLAB(self): + def test_raise_exception_Kim2009_to_XYZ(self): """ - Test :func:`colour.appearance.llab.XYZ_to_LLAB` definition - nan support. + Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition + raised exception. + """ + + self.assertRaises( + ValueError, + Kim2009_to_XYZ, + CAM_Specification_Kim2009( + 41.731091132513917, + None, + 219.04843265831178, + ), + np.array([95.05, 100.00, 108.88]), + 318.31, + 20.0, + VIEWING_CONDITIONS_KIM2009["Average"], + ) + + @ignore_numpy_errors + def test_nan_Kim2009_to_XYZ(self): + """ + Test :func:`colour.appearance.kim2009.Kim2009_to_XYZ` definition nan + support. """ cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] cases = np.array(list(set(product(cases, repeat=3)))) - surround = InductionFactors_LLAB( - 1, cases[0, 0], cases[0, 0], cases[0, 0] + media = MediaParameters_Kim2009(cases[0, 0]) + surround = InductionFactors_Kim2009( + cases[0, 0], cases[0, 0], cases[0, 0] + ) + Kim2009_to_XYZ( + CAM_Specification_Kim2009( + cases[..., 0], cases[..., 0], cases[..., 0], M=50 + ), + cases, + cases[0, 0], + media, + surround, ) - XYZ_to_LLAB(cases, cases, cases[..., 0], cases[..., 0], surround) if __name__ == "__main__": diff --git a/colour/appearance/tests/test_nayatani95.py b/colour/appearance/tests/test_nayatani95.py index ef8be901ed..758108cdfd 100644 --- a/colour/appearance/tests/test_nayatani95.py +++ b/colour/appearance/tests/test_nayatani95.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.appearance.nayatani95` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import XYZ_to_Nayatani95 +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -50,8 +52,7 @@ def test_XYZ_to_Nayatani95(self): np.testing.assert_allclose( XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), np.array([50, 0.01, 257.5, 0.01, 62.6, 0.02, np.nan, np.nan, 50]), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([57.06, 43.06, 31.96]) @@ -59,8 +60,7 @@ def test_XYZ_to_Nayatani95(self): np.testing.assert_allclose( XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), np.array([73, 48.3, 21.6, 37.1, 67.3, 42.9, np.nan, np.nan, 75.9]), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([3.53, 6.56, 2.14]) @@ -71,8 +71,7 @@ def test_XYZ_to_Nayatani95(self): np.array( [24.5, 49.3, 190.6, 81.3, 37.5, 62.1, np.nan, np.nan, 29.7] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) XYZ = np.array([19.01, 20.00, 21.78]) @@ -82,8 +81,7 @@ def test_XYZ_to_Nayatani95(self): np.array( [49.4, 39.9, 236.3, 40.2, 44.2, 35.8, np.nan, np.nan, 49.4] ), - rtol=0.01, - atol=0.01, + atol=0.05, ) def test_n_dimensional_XYZ_to_Nayatani95(self): @@ -101,26 +99,26 @@ def test_n_dimensional_XYZ_to_Nayatani95(self): XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_n = np.tile(XYZ_n, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 9)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_Nayatani95(self): @@ -147,12 +145,12 @@ def test_domain_range_scale_XYZ_to_Nayatani95(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Nayatani95( XYZ * factor_a, XYZ_n * factor_a, Y_o, E_o, E_or ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/appearance/tests/test_rlab.py b/colour/appearance/tests/test_rlab.py index b8190b183c..758108cdfd 100644 --- a/colour/appearance/tests/test_rlab.py +++ b/colour/appearance/tests/test_rlab.py @@ -1,15 +1,13 @@ # !/usr/bin/env python -"""Define the unit tests for the :mod:`colour.appearance.rlab` module.""" +"""Define the unit tests for the :mod:`colour.appearance.nayatani95` module.""" -import numpy as np import unittest from itertools import product -from colour.appearance import ( - D_FACTOR_RLAB, - VIEWING_CONDITIONS_RLAB, - XYZ_to_RLAB, -) +import numpy as np + +from colour.appearance import XYZ_to_Nayatani95 +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, @@ -24,19 +22,20 @@ __status__ = "Production" __all__ = [ - "TestXYZ_to_RLAB", + "TestXYZ_to_Nayatani95", ] -class TestXYZ_to_RLAB(unittest.TestCase): +class TestXYZ_to_Nayatani95(unittest.TestCase): """ - Define :func:`colour.appearance.rlab.XYZ_to_RLAB` definition unit - tests methods. + Define :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition + unit tests methods. """ - def test_XYZ_to_RLAB(self): + def test_XYZ_to_Nayatani95(self): """ - Test :func:`colour.appearance.rlab.XYZ_to_RLAB` definition. + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` + definition. Notes ----- @@ -47,111 +46,125 @@ def test_XYZ_to_RLAB(self): XYZ = np.array([19.01, 20.00, 21.78]) XYZ_n = np.array([95.05, 100.00, 108.88]) - Y_n = 318.31 - sigma = 0.4347 + Y_o = 20 + E_o = 5000 + E_or = 1000 np.testing.assert_allclose( - XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma), - np.array([49.67, 0.01, 270, 0, np.nan, 0, -0.01]), - rtol=0.01, - atol=0.01, + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + np.array([50, 0.01, 257.5, 0.01, 62.6, 0.02, np.nan, np.nan, 50]), + atol=0.05, ) XYZ = np.array([57.06, 43.06, 31.96]) - Y_n = 31.83 + E_o = 500 np.testing.assert_allclose( - XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma), - np.array([69.33, 49.74, 21.3, 0.72, np.nan, 46.33, 18.09]), - rtol=0.01, - atol=0.01, + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + np.array([73, 48.3, 21.6, 37.1, 67.3, 42.9, np.nan, np.nan, 75.9]), + atol=0.05, ) XYZ = np.array([3.53, 6.56, 2.14]) XYZ_n = np.array([109.85, 100.00, 35.58]) - Y_n = 318.31 + E_o = 5000 np.testing.assert_allclose( - XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma), - np.array([30.78, 41.02, 176.9, 1.33, np.nan, -40.96, 2.25]), - rtol=0.01, - atol=0.01, + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + np.array( + [24.5, 49.3, 190.6, 81.3, 37.5, 62.1, np.nan, np.nan, 29.7] + ), + atol=0.05, ) XYZ = np.array([19.01, 20.00, 21.78]) - Y_n = 31.83 + E_o = 500 np.testing.assert_allclose( - XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma), - np.array([49.83, 54.87, 286.5, 1.1, np.nan, 15.57, -52.61]), - rtol=0.01, - atol=0.01, + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + np.array( + [49.4, 39.9, 236.3, 40.2, 44.2, 35.8, np.nan, np.nan, 49.4] + ), + atol=0.05, ) - def test_n_dimensional_XYZ_to_RLAB(self): + def test_n_dimensional_XYZ_to_Nayatani95(self): """ - Test :func:`colour.appearance.rlab.XYZ_to_RLAB` definition + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition n-dimensional support. """ XYZ = np.array([19.01, 20.00, 21.78]) XYZ_n = np.array([95.05, 100.00, 108.88]) - Y_n = 318.31 - sigma = 0.4347 - specification = XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma) + Y_o = 20 + E_o = 5000 + E_or = 1000 + specification = XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or) XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma), specification, decimal=7 + np.testing.assert_allclose( + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_n = np.tile(XYZ_n, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma), specification, decimal=7 + np.testing.assert_allclose( + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) - specification = np.reshape(specification, (2, 3, 7)) - np.testing.assert_array_almost_equal( - XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma), specification, decimal=7 + specification = np.reshape(specification, (2, 3, 9)) + np.testing.assert_allclose( + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - def test_domain_range_scale_XYZ_to_RLAB(self): + def test_domain_range_scale_XYZ_to_Nayatani95(self): """ - Test :func:`colour.appearance.rlab.XYZ_to_RLAB` definition domain and - range scale support. + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition + domain and range scale support. """ XYZ = np.array([19.01, 20.00, 21.78]) - XYZ_n = np.array([109.85, 100, 35.58]) - Y_n = 31.83 - sigma = VIEWING_CONDITIONS_RLAB["Average"] - D = D_FACTOR_RLAB["Hard Copy Images"] - specification = XYZ_to_RLAB(XYZ, XYZ_n, Y_n, sigma, D) + XYZ_n = np.array([95.05, 100.00, 108.88]) + Y_o = 20.0 + E_o = 5000.0 + E_or = 1000.0 + specification = XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or) d_r = ( ("reference", 1, 1), - ("1", 0.01, np.array([1, 1, 1 / 360, 1, np.nan, 1, 1])), - ("100", 1, np.array([1, 1, 100 / 360, 1, np.nan, 1, 1])), + ("1", 0.01, np.array([1, 1, 1 / 360, 1, 1, 1, np.nan, np.nan, 1])), + ( + "100", + 1, + np.array([1, 1, 100 / 360, 1, 1, 1, np.nan, np.nan, 1]), + ), ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_RLAB( - XYZ * factor_a, XYZ_n * factor_a, Y_n, sigma, D + np.testing.assert_allclose( + XYZ_to_Nayatani95( + XYZ * factor_a, XYZ_n * factor_a, Y_o, E_o, E_or ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors - def test_nan_XYZ_to_RLAB(self): + def test_nan_XYZ_to_Nayatani95(self): """ - Test :func:`colour.appearance.rlab.XYZ_to_RLAB` definition nan - support. + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition + nan support. """ cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] cases = np.array(list(set(product(cases, repeat=3)))) - XYZ_to_RLAB(cases, cases, cases[..., 0], cases[..., 0], cases[..., 0]) + XYZ_to_Nayatani95( + cases, cases, cases[..., 0], cases[..., 0], cases[..., 0] + ) if __name__ == "__main__": diff --git a/colour/appearance/tests/test_zcam.py b/colour/appearance/tests/test_zcam.py index 12e763df2e..758108cdfd 100644 --- a/colour/appearance/tests/test_zcam.py +++ b/colour/appearance/tests/test_zcam.py @@ -1,22 +1,17 @@ # !/usr/bin/env python -"""Define the unit tests for the :mod:`colour.appearance.zcam` module.""" +"""Define the unit tests for the :mod:`colour.appearance.nayatani95` module.""" -import numpy as np import unittest from itertools import product -from colour.appearance import ( - VIEWING_CONDITIONS_ZCAM, - InductionFactors_ZCAM, - CAM_Specification_ZCAM, - XYZ_to_ZCAM, - ZCAM_to_XYZ, -) +import numpy as np + +from colour.appearance import XYZ_to_Nayatani95 +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ( as_float_array, domain_range_scale, ignore_numpy_errors, - tsplit, ) __author__ = "Colour Developers" @@ -27,506 +22,148 @@ __status__ = "Production" __all__ = [ - "TestXYZ_to_ZCAM", - "TestZCAM_to_XYZ", + "TestXYZ_to_Nayatani95", ] -class TestXYZ_to_ZCAM(unittest.TestCase): +class TestXYZ_to_Nayatani95(unittest.TestCase): """ - Define :func:`colour.appearance.zcam.XYZ_to_ZCAM` definition unit tests - methods. + Define :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition + unit tests methods. """ - def test_XYZ_to_ZCAM(self): - """Test :func:`colour.appearance.zcam.XYZ_to_ZCAM` definition.""" + def test_XYZ_to_Nayatani95(self): + """ + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` + definition. + + Notes + ----- + - The test values have been generated from data of the following file + by *Fairchild (2013)*: + http://rit-mcsl.org/fairchild//files/AppModEx.xls + """ - XYZ = np.array([185, 206, 163]) - XYZ_w = np.array([256, 264, 202]) - L_a = 264 - Y_b = 100 - surround = VIEWING_CONDITIONS_ZCAM["Average"] + XYZ = np.array([19.01, 20.00, 21.78]) + XYZ_n = np.array([95.05, 100.00, 108.88]) + Y_o = 20 + E_o = 5000 + E_or = 1000 np.testing.assert_allclose( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), - np.array( - [ - 92.2520, - 3.0216, - 196.3524, - 19.1314, - 321.3464, - 10.5252, - 237.6401, - np.nan, - 34.7022, - 25.2994, - 91.6837, - ] - ), - rtol=0.025, - atol=0.025, + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + np.array([50, 0.01, 257.5, 0.01, 62.6, 0.02, np.nan, np.nan, 50]), + atol=0.05, ) - XYZ = np.array([89, 96, 120]) + XYZ = np.array([57.06, 43.06, 31.96]) + E_o = 500 np.testing.assert_allclose( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), - np.array( - [ - 71.2071, - 6.8539, - 250.6422, - 32.7963, - 248.0394, - 23.8744, - 307.0595, - np.nan, - 18.2796, - 40.4621, - 70.4026, - ] - ), - rtol=0.025, - atol=0.025, + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), + np.array([73, 48.3, 21.6, 37.1, 67.3, 42.9, np.nan, np.nan, 75.9]), + atol=0.05, ) - # NOTE: Hue quadrature :math:`H_z` is significantly different for this - # test, i.e. 47.748252 vs 43.8258. - # NOTE: :math:`F_L` as reported in the supplemental document has the - # same value as for :math:`L_a` = 264 instead of 150. The values seem - # to be computed for :math:`L_a` = 264 and :math:`Y_b` = 100. - XYZ = np.array([79, 81, 62]) - # L_a = 150 - # Y_b = 60 - surround = VIEWING_CONDITIONS_ZCAM["Dim"] + XYZ = np.array([3.53, 6.56, 2.14]) + XYZ_n = np.array([109.85, 100.00, 35.58]) + E_o = 5000 np.testing.assert_allclose( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), np.array( - [ - 68.8890, - 0.9774, - 58.7532, - 12.5916, - 196.7686, - 2.7918, - 43.8258, - np.nan, - 11.0371, - 44.4143, - 68.8737, - ] + [24.5, 49.3, 190.6, 81.3, 37.5, 62.1, np.nan, np.nan, 29.7] ), - rtol=0.025, - atol=4, + atol=0.05, ) - XYZ = np.array([910, 1114, 500]) - XYZ_w = np.array([2103, 2259, 1401]) - L_a = 359 - Y_b = 16 - surround = VIEWING_CONDITIONS_ZCAM["Dark"] + XYZ = np.array([19.01, 20.00, 21.78]) + E_o = 500 np.testing.assert_allclose( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), np.array( - [ - 82.6445, - 13.0838, - 123.9464, - 44.7277, - 114.7431, - 18.1655, - 178.6422, - np.nan, - 34.4874, - 26.8778, - 78.2653, - ] + [49.4, 39.9, 236.3, 40.2, 44.2, 35.8, np.nan, np.nan, 49.4] ), - rtol=0.025, - atol=0.025, + atol=0.05, ) - XYZ = np.array([96, 67, 28]) - np.testing.assert_allclose( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), - np.array( - [ - 33.0139, - 19.4070, - 389.7720 % 360, - 86.1882, - 45.8363, - 26.9446, - 397.3301, - np.nan, - 43.6447, - 47.9942, - 30.2593, - ] - ), - rtol=0.025, - atol=0.025, - ) - - def test_n_dimensional_XYZ_to_ZCAM(self): + def test_n_dimensional_XYZ_to_Nayatani95(self): """ - Test :func:`colour.appearance.zcam.XYZ_to_ZCAM` definition + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition n-dimensional support. """ - XYZ = np.array([185, 206, 163]) - XYZ_w = np.array([256, 264, 202]) - L_a = 264 - Y_b = 100 - surround = VIEWING_CONDITIONS_ZCAM["Average"] - specification = XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround) + XYZ = np.array([19.01, 20.00, 21.78]) + XYZ_n = np.array([95.05, 100.00, 108.88]) + Y_o = 20 + E_o = 5000 + E_or = 1000 + specification = XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or) XYZ = np.tile(XYZ, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), + np.testing.assert_allclose( + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), + XYZ_n = np.tile(XYZ_n, (6, 1)) + np.testing.assert_allclose( + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) - XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) - specification = np.reshape(specification, (2, 3, 11)) - np.testing.assert_array_almost_equal( - XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround), + XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) + specification = np.reshape(specification, (2, 3, 9)) + np.testing.assert_allclose( + XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or), specification, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - @ignore_numpy_errors - def test_domain_range_scale_XYZ_to_ZCAM(self): + def test_domain_range_scale_XYZ_to_Nayatani95(self): """ - Test :func:`colour.appearance.zcam.XYZ_to_ZCAM` definition + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition domain and range scale support. """ - XYZ = np.array([185, 206, 163]) - XYZ_w = np.array([256, 264, 202]) - L_a = 264 - Y_b = 100 - surround = VIEWING_CONDITIONS_ZCAM["Average"] - specification = XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround) + XYZ = np.array([19.01, 20.00, 21.78]) + XYZ_n = np.array([95.05, 100.00, 108.88]) + Y_o = 20.0 + E_o = 5000.0 + E_or = 1000.0 + specification = XYZ_to_Nayatani95(XYZ, XYZ_n, Y_o, E_o, E_or) d_r = ( ("reference", 1, 1), - ( - "1", - 1, - np.array([1, 1, 1 / 360, 1, 1, 1, 1 / 400, np.nan, 1, 1, 1]), - ), + ("1", 0.01, np.array([1, 1, 1 / 360, 1, 1, 1, np.nan, np.nan, 1])), ( "100", - 100, - np.array( - [ - 100, - 100, - 100 / 360, - 100, - 100, - 100, - 100 / 400, - np.nan, - 100, - 100, - 100, - ] - ), + 1, + np.array([1, 1, 100 / 360, 1, 1, 1, np.nan, np.nan, 1]), ), ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_ZCAM( - XYZ * factor_a, XYZ_w * factor_a, L_a, Y_b, surround + np.testing.assert_allclose( + XYZ_to_Nayatani95( + XYZ * factor_a, XYZ_n * factor_a, Y_o, E_o, E_or ), as_float_array(specification) * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors - def test_nan_XYZ_to_ZCAM(self): + def test_nan_XYZ_to_Nayatani95(self): """ - Test :func:`colour.appearance.zcam.XYZ_to_ZCAM` definition + Test :func:`colour.appearance.nayatani95.XYZ_to_Nayatani95` definition nan support. """ cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] cases = np.array(list(set(product(cases, repeat=3)))) - surround = InductionFactors_ZCAM( - cases[0, 0], cases[0, 0], cases[0, 0], cases[0, 0] - ) - XYZ_to_ZCAM(cases, cases, cases[0, 0], cases[0, 0], surround) - - -class TestZCAM_to_XYZ(unittest.TestCase): - """ - Define :func:`colour.appearance.zcam.ZCAM_to_XYZ` definition unit - tests methods. - """ - - def test_ZCAM_to_XYZ(self): - """Test :func:`colour.appearance.zcam.ZCAM_to_XYZ` definition.""" - - specification = CAM_Specification_ZCAM( - 92.2520, - 3.0216, - 196.3524, - 19.1314, - 321.3464, - 10.5252, - 237.6401, - np.nan, - 34.7022, - 25.2994, - 91.6837, - ) - XYZ_w = np.array([256, 264, 202]) - L_a = 264 - Y_b = 100 - surround = VIEWING_CONDITIONS_ZCAM["Average"] - np.testing.assert_allclose( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - np.array([185, 206, 163]), - atol=0.01, - rtol=0.01, - ) - - specification = CAM_Specification_ZCAM( - 71.2071, - 6.8539, - 250.6422, - 32.7963, - 248.0394, - 23.8744, - 307.0595, - np.nan, - 18.2796, - 40.4621, - 70.4026, - ) - np.testing.assert_allclose( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - np.array([89, 96, 120]), - atol=0.01, - rtol=0.01, - ) - - specification = CAM_Specification_ZCAM( - 68.8890, - 0.9774, - 58.7532, - 12.5916, - 196.7686, - 2.7918, - 43.8258, - np.nan, - 11.0371, - 44.4143, - 68.8737, - ) - surround = VIEWING_CONDITIONS_ZCAM["Dim"] - np.testing.assert_allclose( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - np.array([79, 81, 62]), - atol=0.01, - rtol=0.01, - ) - - specification = CAM_Specification_ZCAM( - 82.6445, - 13.0838, - 123.9464, - 44.7277, - 114.7431, - 18.1655, - 178.6422, - np.nan, - 34.4874, - 26.8778, - 78.2653, - ) - XYZ_w = np.array([2103, 2259, 1401]) - L_a = 359 - Y_b = 16 - surround = VIEWING_CONDITIONS_ZCAM["Dark"] - np.testing.assert_allclose( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - np.array([910, 1114, 500]), - atol=0.01, - rtol=0.01, - ) - - specification = CAM_Specification_ZCAM( - 33.0139, - 19.4070, - 389.7720 % 360, - 86.1882, - 45.8363, - 26.9446, - 397.3301, - np.nan, - 43.6447, - 47.9942, - 30.2593, - ) - np.testing.assert_allclose( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - np.array([96, 67, 28]), - atol=0.01, - rtol=0.01, - ) - - def test_n_dimensional_ZCAM_to_XYZ(self): - """ - Test :func:`colour.appearance.zcam.ZCAM_to_XYZ` definition - n-dimensional support. - """ - - XYZ = np.array([185, 206, 163]) - XYZ_w = np.array([256, 264, 202]) - L_a = 264 - Y_b = 100 - surround = VIEWING_CONDITIONS_ZCAM["Average"] - specification = XYZ_to_ZCAM(XYZ, XYZ_w, L_a, Y_b, surround) - XYZ = ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround) - - specification = CAM_Specification_ZCAM( - *np.transpose(np.tile(tsplit(specification), (6, 1))).tolist() - ) - XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - XYZ, - decimal=7, - ) - - XYZ_w = np.tile(XYZ_w, (6, 1)) - np.testing.assert_array_almost_equal( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - XYZ, - decimal=7, - ) - - specification = CAM_Specification_ZCAM( - *tsplit(np.reshape(specification, (2, 3, 11))).tolist() - ) - XYZ_w = np.reshape(XYZ_w, (2, 3, 3)) - XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround), - XYZ, - decimal=7, - ) - - @ignore_numpy_errors - def test_domain_range_scale_ZCAM_to_XYZ(self): - """ - Test :func:`colour.appearance.zcam.ZCAM_to_XYZ` definition - domain and range scale support. - """ - - XYZ_i = np.array([185, 206, 163]) - XYZ_w = np.array([256, 264, 202]) - L_a = 264 - Y_b = 100 - surround = VIEWING_CONDITIONS_ZCAM["Average"] - specification = XYZ_to_ZCAM(XYZ_i, XYZ_w, L_a, Y_b, surround) - XYZ = ZCAM_to_XYZ(specification, XYZ_w, L_a, Y_b, surround) - - d_r = ( - ("reference", 1, 1), - ( - "1", - np.array([1, 1, 1 / 360, 1, 1, 1, 1 / 400, np.nan, 1, 1, 1]), - 1, - ), - ( - "100", - np.array( - [ - 100, - 100, - 100 / 360, - 100, - 100, - 100, - 100 / 400, - np.nan, - 100, - 100, - 100, - ] - ), - 100, - ), - ) - for scale, factor_a, factor_b in d_r: - with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ZCAM_to_XYZ( - specification * factor_a, - XYZ_w * factor_b, - L_a, - Y_b, - surround, - ), - XYZ * factor_b, - decimal=7, - ) - - @ignore_numpy_errors - def test_raise_exception_ZCAM_to_XYZ(self): - """ - Test :func:`colour.appearance.zcam.ZCAM_to_XYZ` definition - raised exception. - """ - - self.assertRaises( - ValueError, - ZCAM_to_XYZ, - CAM_Specification_ZCAM( - 41.731091132513917, - None, - 219.04843265831178, - ), - np.array([256, 264, 202]), - 318.31, - 20.0, - VIEWING_CONDITIONS_ZCAM["Average"], - ) - - @ignore_numpy_errors - def test_nan_ZCAM_to_XYZ(self): - """ - Test :func:`colour.appearance.zcam.ZCAM_to_XYZ` definition nan - support. - """ - - cases = [-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan] - cases = np.array(list(set(product(cases, repeat=3)))) - surround = InductionFactors_ZCAM( - cases[0, 0], cases[0, 0], cases[0, 0], cases[0, 0] - ) - ZCAM_to_XYZ( - CAM_Specification_ZCAM( - cases[..., 0], cases[..., 0], cases[..., 0], M=50 - ), - cases, - cases[0, 0], - cases[0, 0], - surround, + XYZ_to_Nayatani95( + cases, cases, cases[..., 0], cases[..., 0], cases[..., 0] ) diff --git a/colour/appearance/zcam.py b/colour/appearance/zcam.py index 56746023ba..79f8299a91 100644 --- a/colour/appearance/zcam.py +++ b/colour/appearance/zcam.py @@ -26,17 +26,18 @@ from __future__ import annotations -import numpy as np from collections import namedtuple from dataclasses import astuple, dataclass, field +import numpy as np + from colour.adaptation import chromatic_adaptation_Zhai2018 +from colour.algebra import sdiv, sdiv_mode, spow from colour.appearance.ciecam02 import ( VIEWING_CONDITIONS_CIECAM02, degree_of_adaptation, hue_angle, ) -from colour.algebra import sdiv, sdiv_mode, spow from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import ArrayLike, NDArrayFloat from colour.models import Izazbz_to_XYZ, XYZ_to_Izazbz, xy_to_XYZ @@ -573,7 +574,7 @@ def ZCAM_to_XYZ( - *Safdar, Hardeberg and Luo (2021)* does not specify how the chromatic adaptation to *CIE Standard Illuminant D65* in *Step 0* should be performed. A one-step *Von Kries* chromatic adaptation transform is not - symetrical or transitive when a degree of adptation is involved. + symmetrical or transitive when a degree of adptation is involved. *Safdar, Hardeberg and Luo (2018)* uses *Zhai and Luo (2018)* two-steps chromatic adaptation transform, thus it seems sensible to adopt this transform for the *ZCAM* colour appearance model until more information diff --git a/colour/biochemistry/michaelis_menten.py b/colour/biochemistry/michaelis_menten.py index e5f91b1175..7cec5251c8 100644 --- a/colour/biochemistry/michaelis_menten.py +++ b/colour/biochemistry/michaelis_menten.py @@ -27,7 +27,7 @@ from __future__ import annotations -from colour.hints import Any, ArrayLike, NDArrayFloat, Literal +from colour.hints import Any, ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, as_float, diff --git a/colour/biochemistry/tests/test_michaelis_menten.py b/colour/biochemistry/tests/test_michaelis_menten.py index fba2a0cd1d..7add626d9d 100644 --- a/colour/biochemistry/tests/test_michaelis_menten.py +++ b/colour/biochemistry/tests/test_michaelis_menten.py @@ -3,16 +3,18 @@ module. """ -import numpy as np import unittest from itertools import product +import numpy as np + from colour.biochemistry import ( - reaction_rate_MichaelisMenten_Michaelis1913, - substrate_concentration_MichaelisMenten_Michaelis1913, reaction_rate_MichaelisMenten_Abebe2017, + reaction_rate_MichaelisMenten_Michaelis1913, substrate_concentration_MichaelisMenten_Abebe2017, + substrate_concentration_MichaelisMenten_Michaelis1913, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -42,22 +44,22 @@ def test_reaction_rate_MichaelisMenten_Michaelis1913(self): reaction_rate_MichaelisMenten_Michaelis1913` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Michaelis1913(0.25, 0.5, 0.25), 0.250000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Michaelis1913(0.5, 0.5, 0.25), 0.333333333333333, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Michaelis1913(0.65, 0.75, 0.35), 0.487500000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_reaction_rate_MichaelisMenten_Michaelis1913(self): @@ -74,28 +76,28 @@ def test_n_dimensional_reaction_rate_MichaelisMenten_Michaelis1913(self): v = np.tile(v, (6, 1)) S = np.tile(S, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Michaelis1913(v, V_max, K_m), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V_max = np.tile(V_max, (6, 1)) K_m = np.tile(K_m, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Michaelis1913(v, V_max, K_m), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) v = np.reshape(v, (2, 3, 1)) V_max = np.reshape(V_max, (2, 3, 1)) K_m = np.reshape(K_m, (2, 3, 1)) S = np.reshape(S, (2, 3, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Michaelis1913(v, V_max, K_m), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -124,31 +126,31 @@ def test_substrate_concentration_MichaelisMenten_Michaelis1913(self): substrate_concentration_MichaelisMenten_Michaelis1913` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Michaelis1913( 0.25, 0.5, 0.25 ), 0.250000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Michaelis1913( 1 / 3, 0.5, 0.25 ), 0.500000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Michaelis1913( 0.4875, 0.75, 0.35 ), 0.650000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - def test_n_dimensional_substrate_concentration_MichaelisMenten_Michaelis1913( # noqa: E501 + def test_n_dimensional_substrate_concentration_MichaelisMenten_Michaelis1913( self, ): """ @@ -166,34 +168,34 @@ def test_n_dimensional_substrate_concentration_MichaelisMenten_Michaelis1913( # S = np.tile(S, (6, 1)) v = np.tile(v, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Michaelis1913( S, V_max, K_m ), v, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V_max = np.tile(V_max, (6, 1)) K_m = np.tile(K_m, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Michaelis1913( S, V_max, K_m ), v, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) S = np.reshape(S, (2, 3, 1)) V_max = np.reshape(V_max, (2, 3, 1)) K_m = np.reshape(K_m, (2, 3, 1)) v = np.reshape(v, (2, 3, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Michaelis1913( S, V_max, K_m ), v, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -222,22 +224,22 @@ def test_reaction_rate_MichaelisMenten_Abebe2017(self): reaction_rate_MichaelisMenten_Abebe2017` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Abebe2017(0.25, 0.5, 0.25, 0.25), 0.400000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Abebe2017(0.5, 0.5, 0.25, 0.25), 0.666666666666666, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Abebe2017(0.65, 0.75, 0.35, 0.25), 0.951219512195122, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_reaction_rate_MichaelisMenten_Abebe2017(self): @@ -255,19 +257,19 @@ def test_n_dimensional_reaction_rate_MichaelisMenten_Abebe2017(self): v = np.tile(v, (6, 1)) S = np.tile(S, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Abebe2017(v, V_max, K_m, b_m), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V_max = np.tile(V_max, (6, 1)) K_m = np.tile(K_m, (6, 1)) b_m = np.tile(b_m, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Abebe2017(v, V_max, K_m, b_m), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) v = np.reshape(v, (2, 3, 1)) @@ -275,10 +277,10 @@ def test_n_dimensional_reaction_rate_MichaelisMenten_Abebe2017(self): K_m = np.reshape(K_m, (2, 3, 1)) b_m = np.reshape(b_m, (2, 3, 1)) S = np.reshape(S, (2, 3, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( reaction_rate_MichaelisMenten_Abebe2017(v, V_max, K_m, b_m), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -305,28 +307,28 @@ def test_substrate_concentration_MichaelisMenten_Abebe2017(self): substrate_concentration_MichaelisMenten_Abebe2017` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Abebe2017( 0.400000000000000, 0.5, 0.25, 0.25 ), 0.250000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Abebe2017( 0.666666666666666, 0.5, 0.25, 0.25 ), 0.500000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Abebe2017( 0.951219512195122, 0.75, 0.35, 0.25 ), 0.650000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_substrate_concentration_MichaelisMenten_Abebe2017( @@ -348,23 +350,23 @@ def test_n_dimensional_substrate_concentration_MichaelisMenten_Abebe2017( S = np.tile(S, (6, 1)) v = np.tile(v, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Abebe2017( S, V_max, K_m, b_m ), v, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V_max = np.tile(V_max, (6, 1)) K_m = np.tile(K_m, (6, 1)) b_m = np.tile(b_m, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Abebe2017( S, V_max, K_m, b_m ), v, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) S = np.reshape(S, (2, 3, 1)) @@ -372,12 +374,12 @@ def test_n_dimensional_substrate_concentration_MichaelisMenten_Abebe2017( K_m = np.reshape(K_m, (2, 3, 1)) b_m = np.reshape(b_m, (2, 3, 1)) v = np.reshape(v, (2, 3, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( substrate_concentration_MichaelisMenten_Abebe2017( S, V_max, K_m, b_m ), v, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/blindness/machado2009.py b/colour/blindness/machado2009.py index 728e39ff19..c1d5b1d5e9 100644 --- a/colour/blindness/machado2009.py +++ b/colour/blindness/machado2009.py @@ -140,11 +140,7 @@ def matrix_RGB_to_WSYBRG( ] ) - PWS = 1 / (WS_R + WS_G + WS_B) - PYB = 1 / (YB_R + YB_G + YB_B) - PRG = 1 / (RG_R + RG_G + RG_B) - - M_G *= np.array([PWS, PYB, PRG])[:, None] + M_G /= np.sum(M_G, axis=-1)[:, None] return M_G diff --git a/colour/blindness/tests/test_machado2009.py b/colour/blindness/tests/test_machado2009.py index 446d9de24c..fd419c88bd 100644 --- a/colour/blindness/tests/test_machado2009.py +++ b/colour/blindness/tests/test_machado2009.py @@ -1,17 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.blindness.machado2009` module.""" -import numpy as np import unittest +import numpy as np + from colour.blindness import ( CVD_MATRICES_MACHADO2010, + matrix_anomalous_trichromacy_Machado2009, matrix_cvd_Machado2009, msds_cmfs_anomalous_trichromacy_Machado2009, - matrix_anomalous_trichromacy_Machado2009, ) from colour.characterisation import MSDS_DISPLAY_PRIMARIES from colour.colorimetry import MSDS_CMFS_LMS +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -41,7 +43,7 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): """ cmfs = MSDS_CMFS_LMS.get("Smith & Pokorny 1975 Normal Trichromats") - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_cmfs_anomalous_trichromacy_Machado2009( cmfs, np.array( @@ -49,10 +51,10 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): ), )[450], cmfs[450], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_cmfs_anomalous_trichromacy_Machado2009( cmfs, np.array( @@ -60,10 +62,10 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): ), )[450], np.array([0.03631700, 0.06350000, 0.91000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_cmfs_anomalous_trichromacy_Machado2009( cmfs, np.array( @@ -71,10 +73,10 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): ), )[450], np.array([0.03430000, 0.06178404, 0.91000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_cmfs_anomalous_trichromacy_Machado2009( cmfs, np.array( @@ -82,10 +84,10 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): ), )[450], np.array([0.03430000, 0.06350000, 0.92270240]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_cmfs_anomalous_trichromacy_Machado2009( cmfs, np.array( @@ -93,10 +95,10 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): ), )[450], np.array([0.05447001, 0.06350000, 0.91000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_cmfs_anomalous_trichromacy_Machado2009( cmfs, np.array( @@ -104,10 +106,10 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): ), )[450], np.array([0.03430000, 0.04634036, 0.91000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_cmfs_anomalous_trichromacy_Machado2009( cmfs, np.array( @@ -115,7 +117,7 @@ def test_msds_cmfs_anomalous_trichromacy_Machado2009(self): ), )[450], np.array([0.03430000, 0.06350000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -133,12 +135,12 @@ def test_matrix_anomalous_trichromacy_Machado2009(self): cmfs = MSDS_CMFS_LMS.get("Smith & Pokorny 1975 Normal Trichromats") primaries = MSDS_DISPLAY_PRIMARIES["Typical CRT Brainard 1997"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_anomalous_trichromacy_Machado2009( cmfs, primaries, np.array([0, 0, 0]) ), np.identity(3), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -146,7 +148,14 @@ def test_matrix_anomalous_trichromacy_Machado2009(self): cmfs, primaries, np.array([2, 0, 0]) ), CVD_MATRICES_MACHADO2010.get("Protanomaly").get(0.1), - rtol=0.0001, + atol=0.0001, + ) + + np.testing.assert_allclose( + matrix_anomalous_trichromacy_Machado2009( + cmfs, primaries, np.array([10, 0, 0]) + ), + CVD_MATRICES_MACHADO2010.get("Protanomaly").get(0.5), atol=0.0001, ) @@ -155,7 +164,6 @@ def test_matrix_anomalous_trichromacy_Machado2009(self): cmfs, primaries, np.array([20, 0, 0]) ), CVD_MATRICES_MACHADO2010.get("Protanomaly").get(1.0), - rtol=0.0001, atol=0.0001, ) @@ -164,7 +172,14 @@ def test_matrix_anomalous_trichromacy_Machado2009(self): cmfs, primaries, np.array([0, 2, 0]) ), CVD_MATRICES_MACHADO2010.get("Deuteranomaly").get(0.1), - rtol=0.0001, + atol=0.0001, + ) + + np.testing.assert_allclose( + matrix_anomalous_trichromacy_Machado2009( + cmfs, primaries, np.array([0, 10, 0]) + ), + CVD_MATRICES_MACHADO2010.get("Deuteranomaly").get(0.5), atol=0.0001, ) @@ -173,7 +188,6 @@ def test_matrix_anomalous_trichromacy_Machado2009(self): cmfs, primaries, np.array([0, 20, 0]) ), CVD_MATRICES_MACHADO2010.get("Deuteranomaly").get(1.0), - rtol=0.0001, atol=0.0001, ) @@ -182,7 +196,14 @@ def test_matrix_anomalous_trichromacy_Machado2009(self): cmfs, primaries, np.array([0, 0, 5.00056688094503]) ), CVD_MATRICES_MACHADO2010.get("Tritanomaly").get(0.1), - rtol=0.0001, + atol=0.0001, + ) + + np.testing.assert_allclose( + matrix_anomalous_trichromacy_Machado2009( + cmfs, primaries, np.array([0, 0, 29.002939088780934]) + ), + CVD_MATRICES_MACHADO2010.get("Tritanomaly").get(0.5), atol=0.0001, ) @@ -191,7 +212,6 @@ def test_matrix_anomalous_trichromacy_Machado2009(self): cmfs, primaries, np.array([0, 0, 59.00590434857581]) ), CVD_MATRICES_MACHADO2010.get("Tritanomaly").get(1.0), - rtol=0.001, atol=0.001, ) @@ -208,7 +228,7 @@ def test_matrix_cvd_Machado2009(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_cvd_Machado2009("Protanomaly", 0.0), np.array( [ @@ -217,10 +237,10 @@ def test_matrix_cvd_Machado2009(self): [0, 0, 1], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_cvd_Machado2009("Deuteranomaly", 0.1), np.array( [ @@ -229,10 +249,10 @@ def test_matrix_cvd_Machado2009(self): [-0.00345300, 0.00723300, 0.99622000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_cvd_Machado2009("Tritanomaly", 1.0), np.array( [ @@ -241,10 +261,10 @@ def test_matrix_cvd_Machado2009(self): [0.00473300, 0.69136700, 0.30390000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_cvd_Machado2009("Tritanomaly", 0.55), np.array( [ @@ -253,7 +273,7 @@ def test_matrix_cvd_Machado2009(self): [0.00317700, 0.27513700, 0.72168600], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/characterisation/aces_it.py b/colour/characterisation/aces_it.py index a8c4582353..34f6e7c47c 100644 --- a/colour/characterisation/aces_it.py +++ b/colour/characterisation/aces_it.py @@ -55,8 +55,9 @@ from __future__ import annotations -import numpy as np import os + +import numpy as np from scipy.optimize import minimize from colour.adaptation import matrix_chromatic_adaptation_VonKries @@ -64,29 +65,29 @@ euclidean_distance, vector_dot, ) +from colour.characterisation import ( + MSDS_ACES_RICD, + RGB_CameraSensitivities, + polynomial_expansion_Finlayson2015, +) from colour.colorimetry import ( - MultiSpectralDistributions, SDS_ILLUMINANTS, + MultiSpectralDistributions, SpectralDistribution, SpectralShape, handle_spectral_arguments, reshape_msds, reshape_sd, - sds_and_msds_to_msds, - sd_CIE_illuminant_D_series, sd_blackbody, + sd_CIE_illuminant_D_series, sd_to_XYZ, -) -from colour.characterisation import ( - MSDS_ACES_RICD, - RGB_CameraSensitivities, - polynomial_expansion_Finlayson2015, + sds_and_msds_to_msds, ) from colour.hints import ( ArrayLike, Callable, DTypeFloat, - Literal, + LiteralChromaticAdaptationTransform, Mapping, NDArrayFloat, Tuple, @@ -101,8 +102,8 @@ xy_to_XYZ, ) from colour.models.rgb import ( - RGB_Colourspace, RGB_COLOURSPACE_ACES2065_1, + RGB_Colourspace, RGB_to_XYZ, XYZ_to_RGB, ) @@ -160,20 +161,7 @@ def sd_to_aces_relative_exposure_values( sd: SpectralDistribution, illuminant: SpectralDistribution | None = None, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", **kwargs, @@ -541,7 +529,7 @@ def normalise_illuminant( Normalise given illuminant with given camera *RGB* spectral sensitivities. The multiplicative inverse scaling factor :math:`k` is computed by - multiplying the illuminant by the sensitivies channel with the maximum + multiplying the illuminant by the sensitivities channel with the maximum value. Parameters @@ -665,20 +653,7 @@ def training_data_sds_to_XYZ( training_data: MultiSpectralDistributions, cmfs: MultiSpectralDistributions, illuminant: SpectralDistribution, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", ) -> NDArrayFloat: @@ -1022,20 +997,7 @@ def matrix_idt( cmfs: MultiSpectralDistributions | None = None, optimisation_factory: Callable = optimisation_factory_rawtoaces_v1, optimisation_kwargs: dict | None = None, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", additional_data: bool = False, @@ -1104,7 +1066,7 @@ def matrix_idt( array([ 2.3414154..., 1. , 1.5163375...]) The *RAW to ACES* v1 matrix for the same camera and optimized by - `Ceres Solver `__ is as follows:: + `Ceres Solver `__ is as follows:: 0.864994 -0.026302 0.161308 0.056527 1.122997 -0.179524 diff --git a/colour/characterisation/cameras.py b/colour/characterisation/cameras.py index d5d4cddc98..5687082965 100644 --- a/colour/characterisation/cameras.py +++ b/colour/characterisation/cameras.py @@ -18,10 +18,10 @@ ) from colour.continuous import MultiSignals, Signal from colour.hints import ( - ArrayLike, + TYPE_CHECKING, Any, + ArrayLike, Sequence, - TYPE_CHECKING, ) from colour.utilities import is_pandas_installed diff --git a/colour/characterisation/correction.py b/colour/characterisation/correction.py index 291a341ee4..2f8b46aba6 100644 --- a/colour/characterisation/correction.py +++ b/colour/characterisation/correction.py @@ -71,7 +71,7 @@ import numpy as np from colour.algebra import least_square_mapping_MoorePenrose, spow -from colour.hints import ArrayLike, Any, Literal, NDArrayFloat +from colour.hints import Any, ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, as_float, diff --git a/colour/characterisation/datasets/colour_checkers/chromaticity_coordinates.py b/colour/characterisation/datasets/colour_checkers/chromaticity_coordinates.py index 2d3faf736a..c3e2eb4d83 100644 --- a/colour/characterisation/datasets/colour_checkers/chromaticity_coordinates.py +++ b/colour/characterisation/datasets/colour_checkers/chromaticity_coordinates.py @@ -50,9 +50,10 @@ from __future__ import annotations -import numpy as np from collections import namedtuple +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models import Lab_to_XYZ, XYZ_to_xyY diff --git a/colour/characterisation/datasets/colour_checkers/sds.py b/colour/characterisation/datasets/colour_checkers/sds.py index 9452916421..c45ba674c4 100644 --- a/colour/characterisation/datasets/colour_checkers/sds.py +++ b/colour/characterisation/datasets/colour_checkers/sds.py @@ -16,8 +16,6 @@ of 30 *ColorChecker Classic* charts. - :attr:`colour.characterisation.datasets.colour_checkers.sds.\ SDS_COLORCHECKER_N_OHTA`: Measured by Ohta (1997). -- :attr:`colour.characterisation.datasets.colour_checkers.sds.\ -SDS_ISO17321_1`: Reflectance values for spectral curves of a set of 24 patches. Notes ----- diff --git a/colour/characterisation/displays.py b/colour/characterisation/displays.py index 056dfc50b7..5b891fa968 100644 --- a/colour/characterisation/displays.py +++ b/colour/characterisation/displays.py @@ -19,10 +19,10 @@ ) from colour.continuous import MultiSignals, Signal from colour.hints import ( - ArrayLike, + TYPE_CHECKING, Any, + ArrayLike, Sequence, - TYPE_CHECKING, ) from colour.utilities import is_pandas_installed diff --git a/colour/characterisation/tests/test_aces_it.py b/colour/characterisation/tests/test_aces_it.py index 98d9469014..93ec2b4255 100644 --- a/colour/characterisation/tests/test_aces_it.py +++ b/colour/characterisation/tests/test_aces_it.py @@ -5,41 +5,43 @@ from __future__ import annotations -import numpy as np import os import unittest +import numpy as np + from colour.characterisation import ( MSDS_ACES_RICD, MSDS_CAMERA_SENSITIVITIES, SDS_COLOURCHECKERS, - sd_to_aces_relative_exposure_values, - read_training_data_rawtoaces_v1, - generate_illuminants_rawtoaces_v1, - white_balance_multipliers, best_illuminant, + camera_RGB_to_ACES2065_1, + generate_illuminants_rawtoaces_v1, + matrix_idt, normalise_illuminant, + optimisation_factory_Jzazbz, + optimisation_factory_Oklab_15, + optimisation_factory_rawtoaces_v1, + read_training_data_rawtoaces_v1, + sd_to_aces_relative_exposure_values, training_data_sds_to_RGB, training_data_sds_to_XYZ, + white_balance_multipliers, whitepoint_preserving_matrix, - optimisation_factory_rawtoaces_v1, - optimisation_factory_Jzazbz, - optimisation_factory_Oklab_15, - matrix_idt, - camera_RGB_to_ACES2065_1, ) from colour.characterisation.aces_it import ROOT_RESOURCES_RAWTOACES from colour.colorimetry import ( MSDS_CMFS, - MultiSpectralDistributions, SDS_ILLUMINANTS, + MultiSpectralDistributions, SpectralDistribution, SpectralShape, reshape_msds, - sds_and_msds_to_msds, sd_constant, sd_ones, + sds_and_msds_to_msds, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import read_sds_from_csv_file from colour.utilities import domain_range_scale @@ -101,50 +103,52 @@ def test_sd_to_aces_relative_exposure_values(self): shape = MSDS_ACES_RICD.shape grey_reflector = sd_constant(0.18, shape) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_aces_relative_exposure_values(grey_reflector), np.array([0.18, 0.18, 0.18]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) perfect_reflector = sd_ones(shape) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_aces_relative_exposure_values(perfect_reflector), np.array([0.97783784, 0.97783784, 0.97783784]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) + # NOTE: Reduced precision for random unit tests failure. dark_skin = SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_aces_relative_exposure_values(dark_skin), np.array([0.11807796, 0.08690312, 0.05891252]), - decimal=7, + atol=1e-5, ) + # NOTE: Reduced precision for random unit tests failure. dark_skin = SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_aces_relative_exposure_values( dark_skin, SDS_ILLUMINANTS["A"] ), np.array([0.12937082, 0.09120875, 0.06110636]), - decimal=7, + atol=1e-4, ) dark_skin = SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_aces_relative_exposure_values(dark_skin), np.array([0.11807796, 0.08690312, 0.05891252]), - decimal=7, + atol=1e-5, ) dark_skin = SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_aces_relative_exposure_values( dark_skin, chromatic_adaptation_transform="Bradford", ), np.array([0.11805993, 0.08689013, 0.05900396]), - decimal=7, + atol=1e-5, ) def test_domain_range_scale_spectral_to_aces_relative_exposure_values( @@ -163,10 +167,10 @@ def test_domain_range_scale_spectral_to_aces_relative_exposure_values( d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_aces_relative_exposure_values(grey_reflector), RGB * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -266,21 +270,21 @@ def test_white_balance_multipliers(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( white_balance_multipliers( MSDS_CANON_EOS_5DMARK_II, SDS_ILLUMINANTS["D55"] ), np.array([2.34141541, 1.00000000, 1.51633759]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( white_balance_multipliers( MSDS_CANON_EOS_5DMARK_II, SDS_ILLUMINANTS["ISO 7589 Studio Tungsten"], ), np.array([1.57095278, 1.00000000, 2.43560477]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -331,14 +335,14 @@ def test_normalise_illuminant(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( np.sum( normalise_illuminant( SDS_ILLUMINANTS["D55"], MSDS_CANON_EOS_5DMARK_II ).values ), 3.439037388220850, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -359,7 +363,7 @@ def test_training_data_sds_to_RGB(self): MSDS_CANON_EOS_5DMARK_II, SDS_ILLUMINANTS["D55"], ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB, np.array( [ @@ -555,11 +559,13 @@ def test_training_data_sds_to_RGB(self): [909.87331348, 498.83253656, 750.09672276], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - RGB_w, np.array([2.34141541, 1.00000000, 1.51633759]), decimal=7 + np.testing.assert_allclose( + RGB_w, + np.array([2.34141541, 1.00000000, 1.51633759]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) training_data = sds_and_msds_to_msds( @@ -568,7 +574,7 @@ def test_training_data_sds_to_RGB(self): RGB, RGB_w = training_data_sds_to_RGB( training_data, MSDS_CANON_EOS_5DMARK_II, SDS_ILLUMINANTS["D55"] ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB, np.array( [ @@ -598,11 +604,13 @@ def test_training_data_sds_to_RGB(self): [64.77754952, 64.80020759, 65.45515287], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - RGB_w, np.array([2.34141541, 1.00000000, 1.51633759]), decimal=7 + np.testing.assert_allclose( + RGB_w, + np.array([2.34141541, 1.00000000, 1.51633759]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -618,7 +626,7 @@ def test_training_data_sds_to_XYZ(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( training_data_sds_to_XYZ( read_training_data_rawtoaces_v1(), MSDS_CMFS["CIE 1931 2 Degree Standard Observer"], @@ -818,14 +826,15 @@ def test_training_data_sds_to_XYZ(self): [0.41991006, 0.29457037, 0.40780639], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) training_data = sds_and_msds_to_msds( SDS_COLOURCHECKERS["BabelColor Average"].values() ) - np.testing.assert_array_almost_equal( + # NOTE: Reduced precision for random unit tests failure. + np.testing.assert_allclose( training_data_sds_to_XYZ( training_data, MSDS_CMFS["CIE 1931 2 Degree Standard Observer"], @@ -859,10 +868,11 @@ def test_training_data_sds_to_XYZ(self): [0.03058273, 0.03200953, 0.03277947], ] ), - decimal=7, + atol=1e-6, ) - np.testing.assert_array_almost_equal( + # NOTE: Reduced precision for random unit tests failure. + np.testing.assert_allclose( training_data_sds_to_XYZ( training_data, MSDS_CMFS["CIE 1931 2 Degree Standard Observer"], @@ -897,7 +907,7 @@ def test_training_data_sds_to_XYZ(self): [0.03058222, 0.03200864, 0.03278183], ] ), - decimal=7, + atol=1e-6, ) @@ -988,7 +998,7 @@ def test_matrix_idt(self): """ # The *RAW to ACES* v1 matrix for the same camera and optimized by - # `Ceres Solver `__ is as follows: + # `Ceres Solver `__ is as follows: # # 0.864994 -0.026302 0.161308 # 0.056527 1.122997 -0.179524 @@ -1002,12 +1012,11 @@ def test_matrix_idt(self): [0.02369089, -0.20253026, 1.17883937], ] ), - rtol=0.0001, atol=0.0001, ) # The *RAW to ACES* v1 matrix for the same camera and optimized by - # `Ceres Solver `__ is as follows: + # `Ceres Solver `__ is as follows: # # 0.888492 -0.077505 0.189014 # 0.021805 1.066614 -0.088418 @@ -1023,7 +1032,6 @@ def test_matrix_idt(self): [-0.01971799, -0.20666347, 1.22638146], ] ), - rtol=0.0001, atol=0.0001, ) @@ -1041,13 +1049,11 @@ def test_matrix_idt(self): [0.02327675, -0.22372411, 1.20044737], ] ), - rtol=0.0001, atol=0.0001, ) np.testing.assert_allclose( RGB_w, np.array([2.34141541, 1.00000000, 1.51633759]), - rtol=0.0001, atol=0.0001, ) M, RGB_w = matrix_idt( @@ -1085,13 +1091,11 @@ def test_matrix_idt(self): ], ] ), - rtol=0.0001, atol=0.0001, ) np.testing.assert_allclose( RGB_w, np.array([2.34141541, 1.00000000, 1.51633759]), - rtol=0.0001, atol=0.0001, ) @@ -1109,13 +1113,11 @@ def test_matrix_idt(self): [0.015048, -0.150215, 1.135168], ] ), - rtol=0.0001, atol=0.0001, ) np.testing.assert_allclose( RGB_w, np.array([2.34141541, 1.00000000, 1.51633759]), - rtol=0.0001, atol=0.0001, ) @@ -1139,7 +1141,6 @@ def test_matrix_idt(self): [0.06964389, -0.31098445, 1.24134056], ] ), - rtol=0.0001, atol=0.0001, ) @@ -1156,7 +1157,6 @@ def test_matrix_idt(self): [0.02450723, -0.20931423, 1.18480700], ] ), - rtol=0.0001, atol=0.0001, ) @@ -1166,11 +1166,11 @@ def test_matrix_idt(self): additional_data=True, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_w, np.array([2.34141541, 1.00000000, 1.51633759]) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ[:5, ...], np.array( [ @@ -1181,9 +1181,10 @@ def test_matrix_idt(self): [0.56264334, 0.59145486, 0.58950505], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB[:5, ...], np.array( [ @@ -1194,6 +1195,7 @@ def test_matrix_idt(self): [0.58984787, 0.59040152, 0.58510766], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1210,19 +1212,22 @@ def test_camera_RGB_to_ACES2065_1(self): """ B, b = matrix_idt(MSDS_CANON_EOS_5DMARK_II, SDS_ILLUMINANTS["D55"]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( camera_RGB_to_ACES2065_1(np.array([0.1, 0.2, 0.3]), B, b), np.array([0.27064400, 0.15614871, 0.50129650]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( camera_RGB_to_ACES2065_1(np.array([1.5, 1.5, 1.5]), B, b), np.array([3.36538176, 1.47467189, 2.46068761]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( camera_RGB_to_ACES2065_1(np.array([1.0, 1.0, 1.0]), B, b, True), np.array([2.24358784, 0.98311459, 1.64045840]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/characterisation/tests/test_correction.py b/colour/characterisation/tests/test_correction.py index 39b8bb2e36..b6ef999b6a 100644 --- a/colour/characterisation/tests/test_correction.py +++ b/colour/characterisation/tests/test_correction.py @@ -6,26 +6,28 @@ from __future__ import annotations import contextlib -import numpy as np import platform import unittest from itertools import product + +import numpy as np from numpy.linalg import LinAlgError from colour.characterisation.correction import ( - matrix_augmented_Cheung2004, - polynomial_expansion_Finlayson2015, - polynomial_expansion_Vandermonde, - matrix_colour_correction_Cheung2004, - matrix_colour_correction_Finlayson2015, - matrix_colour_correction_Vandermonde, apply_matrix_colour_correction_Cheung2004, apply_matrix_colour_correction_Finlayson2015, apply_matrix_colour_correction_Vandermonde, colour_correction_Cheung2004, colour_correction_Finlayson2015, colour_correction_Vandermonde, + matrix_augmented_Cheung2004, + matrix_colour_correction_Cheung2004, + matrix_colour_correction_Finlayson2015, + matrix_colour_correction_Vandermonde, + polynomial_expansion_Finlayson2015, + polynomial_expansion_Vandermonde, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import NDArrayFloat from colour.utilities import ignore_numpy_errors @@ -360,10 +362,10 @@ def test_matrix_augmented_Cheung2004(self): for i, terms in enumerate( [3, 4, 5, 7, 8, 10, 11, 14, 16, 17, 19, 20, 22, 35] ): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_augmented_Cheung2004(RGB, terms), polynomials[i], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_matrix_augmented_Cheung2004(self): @@ -546,15 +548,15 @@ def test_polynomial_expansion_Finlayson2015(self): ] for i in range(4): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( polynomial_expansion_Finlayson2015(RGB, i + 1, False), polynomials[i][0], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( polynomial_expansion_Finlayson2015(RGB, i + 1, True), polynomials[i][1], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_polynomial_expansion_Finlayson2015(self): @@ -643,10 +645,10 @@ def test_polynomial_expansion_Vandermonde(self): ] for i in range(4): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( polynomial_expansion_Vandermonde(RGB, i + 1), polynomials[i], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -673,7 +675,7 @@ def test_matrix_colour_correction_Cheung2004(self): matrix_colour_correction_Cheung2004` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_colour_correction_Cheung2004(MATRIX_TEST, MATRIX_REFERENCE), np.array( [ @@ -682,10 +684,10 @@ def test_matrix_colour_correction_Cheung2004(self): [-0.06314956, 0.09212471, 0.97134152], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_colour_correction_Cheung2004( MATRIX_TEST, MATRIX_REFERENCE, terms=7 ), @@ -720,7 +722,7 @@ def test_matrix_colour_correction_Cheung2004(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -756,7 +758,7 @@ def test_matrix_colour_correction_Finlayson2015(self): matrix_colour_correction_Finlayson2015` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_colour_correction_Finlayson2015( MATRIX_TEST, MATRIX_REFERENCE ), @@ -767,10 +769,10 @@ def test_matrix_colour_correction_Finlayson2015(self): [-0.06314956, 0.09212471, 0.97134152], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_colour_correction_Finlayson2015( MATRIX_TEST, MATRIX_REFERENCE, degree=3 ), @@ -823,7 +825,7 @@ def test_matrix_colour_correction_Finlayson2015(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -861,7 +863,7 @@ def test_matrix_colour_correction_Vandermonde(self): matrix_colour_correction_Vandermonde` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_colour_correction_Vandermonde( MATRIX_TEST, MATRIX_REFERENCE ), @@ -872,10 +874,10 @@ def test_matrix_colour_correction_Vandermonde(self): [-0.14502258, 0.07716975, 0.87841836, 0.06666049], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_colour_correction_Vandermonde( MATRIX_TEST, MATRIX_REFERENCE, degree=3 ), @@ -919,7 +921,7 @@ def test_matrix_colour_correction_Vandermonde(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -959,7 +961,7 @@ def test_apply_matrix_colour_correction_Cheung2004(self): RGB = np.array([0.17224810, 0.09170660, 0.06416938]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Cheung2004( RGB, np.array( @@ -971,7 +973,7 @@ def test_apply_matrix_colour_correction_Cheung2004(self): ), ), np.array([0.13348722, 0.08439216, 0.05990144]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_apply_matrix_colour_correction_Cheung2004(self): @@ -992,18 +994,18 @@ def test_n_dimensional_apply_matrix_colour_correction_Cheung2004(self): RGB = np.tile(RGB, (6, 1)) RGB_c = np.tile(RGB_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Cheung2004(RGB, CCM), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB = np.reshape(RGB, (2, 3, 3)) RGB_c = np.reshape(RGB_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Cheung2004(RGB, CCM), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1043,7 +1045,7 @@ def test_apply_matrix_colour_correction_Finlayson2015(self): RGB = np.array([0.17224810, 0.09170660, 0.06416938]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Finlayson2015( RGB, np.array( @@ -1055,7 +1057,7 @@ def test_apply_matrix_colour_correction_Finlayson2015(self): ), ), np.array([0.13348722, 0.08439216, 0.05990144]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_apply_matrix_colour_correction_Finlayson2015(self): @@ -1076,18 +1078,18 @@ def test_n_dimensional_apply_matrix_colour_correction_Finlayson2015(self): RGB = np.tile(RGB, (6, 1)) RGB_c = np.tile(RGB_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Finlayson2015(RGB, CCM), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB = np.reshape(RGB, (2, 3, 3)) RGB_c = np.reshape(RGB_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Finlayson2015(RGB, CCM), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1127,7 +1129,7 @@ def test_apply_matrix_colour_correction_Vandermonde(self): RGB = np.array([0.17224810, 0.09170660, 0.06416938]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Vandermonde( RGB, np.array( @@ -1139,7 +1141,7 @@ def test_apply_matrix_colour_correction_Vandermonde(self): ), ), np.array([0.15034881, 0.10503956, 0.10512517]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_apply_matrix_colour_correction_Vandermonde(self): @@ -1160,18 +1162,18 @@ def test_n_dimensional_apply_matrix_colour_correction_Vandermonde(self): RGB = np.tile(RGB, (6, 1)) RGB_c = np.tile(RGB_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Vandermonde(RGB, CCM), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB = np.reshape(RGB, (2, 3, 3)) RGB_c = np.reshape(RGB_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( apply_matrix_colour_correction_Vandermonde(RGB, CCM), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1211,18 +1213,18 @@ def test_colour_correction_Cheung2004(self): RGB = np.array([0.17224810, 0.09170660, 0.06416938]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Cheung2004(RGB, MATRIX_TEST, MATRIX_REFERENCE), np.array([0.13348722, 0.08439216, 0.05990144]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Cheung2004( RGB, MATRIX_TEST, MATRIX_REFERENCE, terms=7 ), np.array([0.15850295, 0.09871628, 0.08105752]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_colour_correction_Cheung2004(self): @@ -1238,18 +1240,18 @@ def test_n_dimensional_colour_correction_Cheung2004(self): RGB = np.tile(RGB, (6, 1)) RGB_c = np.tile(RGB_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Cheung2004(RGB, MATRIX_TEST, MATRIX_REFERENCE), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB = np.reshape(RGB, (2, 3, 3)) RGB_c = np.reshape(RGB_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Cheung2004(RGB, MATRIX_TEST, MATRIX_REFERENCE), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1288,20 +1290,20 @@ def test_colour_correction_Finlayson2015(self): RGB = np.array([0.17224810, 0.09170660, 0.06416938]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Finlayson2015( RGB, MATRIX_TEST, MATRIX_REFERENCE ), np.array([0.13348722, 0.08439216, 0.05990144]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Finlayson2015( RGB, MATRIX_TEST, MATRIX_REFERENCE, degree=3 ), np.array([0.13914542, 0.08602124, 0.06422973]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_colour_correction_Finlayson2015(self): @@ -1317,22 +1319,22 @@ def test_n_dimensional_colour_correction_Finlayson2015(self): RGB = np.tile(RGB, (6, 1)) RGB_c = np.tile(RGB_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Finlayson2015( RGB, MATRIX_TEST, MATRIX_REFERENCE ), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB = np.reshape(RGB, (2, 3, 3)) RGB_c = np.reshape(RGB_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Finlayson2015( RGB, MATRIX_TEST, MATRIX_REFERENCE ), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1371,18 +1373,18 @@ def test_colour_correction_Vandermonde(self): RGB = np.array([0.17224810, 0.09170660, 0.06416938]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Vandermonde(RGB, MATRIX_TEST, MATRIX_REFERENCE), np.array([0.15034881, 0.10503956, 0.10512517]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Vandermonde( RGB, MATRIX_TEST, MATRIX_REFERENCE, degree=3 ), np.array([0.15747814, 0.10035799, 0.06616709]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_colour_correction_Vandermonde(self): @@ -1398,18 +1400,18 @@ def test_n_dimensional_colour_correction_Vandermonde(self): RGB = np.tile(RGB, (6, 1)) RGB_c = np.tile(RGB_c, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Vandermonde(RGB, MATRIX_TEST, MATRIX_REFERENCE), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB = np.reshape(RGB, (2, 3, 3)) RGB_c = np.reshape(RGB_c, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colour_correction_Vandermonde(RGB, MATRIX_TEST, MATRIX_REFERENCE), RGB_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/colorimetry/cmfs.py b/colour/colorimetry/cmfs.py index 83eb31fe9e..2fd654c40c 100644 --- a/colour/colorimetry/cmfs.py +++ b/colour/colorimetry/cmfs.py @@ -23,10 +23,10 @@ ) from colour.continuous import MultiSignals, Signal from colour.hints import ( - ArrayLike, + TYPE_CHECKING, Any, + ArrayLike, Sequence, - TYPE_CHECKING, ) from colour.utilities import is_pandas_installed diff --git a/colour/colorimetry/datasets/illuminants/chromaticity_coordinates.py b/colour/colorimetry/datasets/illuminants/chromaticity_coordinates.py index ccaad3da55..263d6f298a 100644 --- a/colour/colorimetry/datasets/illuminants/chromaticity_coordinates.py +++ b/colour/colorimetry/datasets/illuminants/chromaticity_coordinates.py @@ -424,7 +424,7 @@ - *CIE Illuminant D Series D50* illuminant and *CIE Standard Illuminant D Series D65* chromaticity coordinates are rounded - to 4 decimals as given in the typical RGB colourspaces litterature. Their + to 4 decimals as given in the typical RGB colourspaces literature. Their chromaticity coordinates as given in :cite:`CIETC1-482004h` are (0.34567, 0.35851) and (0.31272, 0.32903) respectively. - *CIE* illuminants with chromaticity coordinates not defined in the diff --git a/colour/colorimetry/datasets/illuminants/hunterlab.py b/colour/colorimetry/datasets/illuminants/hunterlab.py index 3899f86287..9beea9ac88 100644 --- a/colour/colorimetry/datasets/illuminants/hunterlab.py +++ b/colour/colorimetry/datasets/illuminants/hunterlab.py @@ -22,9 +22,10 @@ from __future__ import annotations -import numpy as np from collections import namedtuple +import numpy as np + from colour.utilities import CanonicalMapping __author__ = "Colour Developers" diff --git a/colour/colorimetry/dominant.py b/colour/colorimetry/dominant.py index 7f5f7ee9e1..34abac7527 100644 --- a/colour/colorimetry/dominant.py +++ b/colour/colorimetry/dominant.py @@ -39,7 +39,7 @@ extend_line_segment, intersect_line_segments, ) -from colour.hints import ArrayLike, NDArrayFloat, Tuple +from colour.hints import ArrayLike, NDArrayFloat, NDArrayInt, Tuple from colour.models import XYZ_to_xy from colour.utilities import as_float_array @@ -61,7 +61,7 @@ def closest_spectral_locus_wavelength( xy: ArrayLike, xy_n: ArrayLike, xy_s: ArrayLike, inverse: bool = False -) -> Tuple[NDArrayFloat, NDArrayFloat]: +) -> Tuple[NDArrayInt, NDArrayFloat]: """ Return the coordinates and closest spectral locus wavelength index to the point where the line defined by the given achromatic stimulus :math:`xy_n` diff --git a/colour/colorimetry/illuminants.py b/colour/colorimetry/illuminants.py index fa0cdef291..ff5743147d 100644 --- a/colour/colorimetry/illuminants.py +++ b/colour/colorimetry/illuminants.py @@ -30,14 +30,14 @@ from colour.algebra import LinearInterpolator from colour.colorimetry import ( - SPECTRAL_SHAPE_DEFAULT, SDS_BASIS_FUNCTIONS_CIE_ILLUMINANT_D_SERIES, + SPECTRAL_SHAPE_DEFAULT, SpectralDistribution, SpectralShape, reshape_sd, ) from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float, tsplit +from colour.utilities import as_float, as_float_array, tsplit __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/colorimetry/lefs.py b/colour/colorimetry/lefs.py index 7b5ffd2cba..00547b9ef1 100644 --- a/colour/colorimetry/lefs.py +++ b/colour/colorimetry/lefs.py @@ -20,7 +20,7 @@ SpectralShape, ) from colour.colorimetry.datasets.lefs import DATA_MESOPIC_X -from colour.hints import ArrayLike, NDArrayFloat, Literal +from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import closest, optional, validate_method __author__ = "Colour Developers" @@ -101,7 +101,7 @@ def mesopic_weighting_function( mesopic_x_luminance_values = sorted(DATA_MESOPIC_X.keys()) index = mesopic_x_luminance_values.index( - closest(mesopic_x_luminance_values, L_p) # pyright: ignore + closest(mesopic_x_luminance_values, L_p) ) x = DATA_MESOPIC_X[mesopic_x_luminance_values[index]][source][method] diff --git a/colour/colorimetry/lightness.py b/colour/colorimetry/lightness.py index beb7c59b7b..a2bbf50bc9 100644 --- a/colour/colorimetry/lightness.py +++ b/colour/colorimetry/lightness.py @@ -66,10 +66,10 @@ from colour.algebra import spow from colour.biochemistry import ( - reaction_rate_MichaelisMenten_Michaelis1913, reaction_rate_MichaelisMenten_Abebe2017, + reaction_rate_MichaelisMenten_Michaelis1913, ) -from colour.hints import Any, ArrayLike, NDArrayFloat, Literal +from colour.hints import Any, ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, as_float, diff --git a/colour/colorimetry/luminance.py b/colour/colorimetry/luminance.py index 9d5ef962a5..84d165ce68 100644 --- a/colour/colorimetry/luminance.py +++ b/colour/colorimetry/luminance.py @@ -67,10 +67,10 @@ from colour.algebra import spow from colour.biochemistry import ( - substrate_concentration_MichaelisMenten_Michaelis1913, substrate_concentration_MichaelisMenten_Abebe2017, + substrate_concentration_MichaelisMenten_Michaelis1913, ) -from colour.hints import Any, ArrayLike, NDArrayFloat, Literal +from colour.hints import Any, ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, as_float, diff --git a/colour/colorimetry/spectrum.py b/colour/colorimetry/spectrum.py index efaea7451a..4a77b92fb9 100644 --- a/colour/colorimetry/spectrum.py +++ b/colour/colorimetry/spectrum.py @@ -27,21 +27,23 @@ from __future__ import annotations -import numpy as np from collections.abc import Mapping +import numpy as np + from colour.algebra import ( - Extrapolator, CubicSplineInterpolator, + Extrapolator, SpragueInterpolator, sdiv, sdiv_mode, ) -from colour.constants import DEFAULT_FLOAT_DTYPE -from colour.continuous import Signal, MultiSignals +from colour.constants import DTYPE_FLOAT_DEFAULT +from colour.continuous import MultiSignals, Signal from colour.hints import ( - ArrayLike, + TYPE_CHECKING, Any, + ArrayLike, DTypeFloat, Generator, List, @@ -50,9 +52,8 @@ ProtocolExtrapolator, ProtocolInterpolator, Real, - Sequence, Self, - TYPE_CHECKING, + Sequence, Type, TypeVar, cast, @@ -64,12 +65,13 @@ attest, filter_kwargs, first_item, + interval, + is_caching_enabled, is_iterable, is_numeric, is_pandas_installed, is_string, is_uniform, - interval, optional, runtime_warning, tstack, @@ -397,7 +399,7 @@ def __contains__(self, wavelength: ArrayLike) -> bool: False """ - decimals = np.finfo(cast(Any, DEFAULT_FLOAT_DTYPE)).precision + decimals = np.finfo(cast(Any, DTYPE_FLOAT_DEFAULT)).precision return bool( np.all( @@ -515,10 +517,10 @@ def range( # noqa: A003 9.9, 10. ]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) hash_key = hash((self, dtype)) - if hash_key in _CACHE_SHAPE_RANGE: + if is_caching_enabled() and hash_key in _CACHE_SHAPE_RANGE: return _CACHE_SHAPE_RANGE[hash_key].copy() start, end, interval = ( @@ -715,19 +717,18 @@ def __init__( self._shape: SpectralShape | None = None - def _on_domain_changed( - self, name: str, value: NDArrayFloat - ) -> NDArrayFloat: - """Invalidate *self._shape* when *self._domain* is changed.""" - if name == "_domain": - self._shape = None - - return value - self.register_callback( - "_domain", "on_domain_changed", _on_domain_changed + "_domain", "on_domain_changed", self._on_domain_changed ) + @staticmethod + def _on_domain_changed(sd, name: str, value: NDArrayFloat) -> NDArrayFloat: + """Invalidate *sd._shape* when *sd._domain* is changed.""" + if name == "_domain": + sd._shape = None + + return value + @property def display_name(self) -> str: """ @@ -2839,7 +2840,7 @@ def reshape_sd( hash_key = hash((sd, shape, method, tuple(kwargs_items))) - if hash_key in _CACHE_RESHAPED_SDS_AND_MSDS: + if is_caching_enabled() and hash_key in _CACHE_RESHAPED_SDS_AND_MSDS: reshaped_sd = _CACHE_RESHAPED_SDS_AND_MSDS[hash_key] return reshaped_sd.copy() if copy else reshaped_sd diff --git a/colour/colorimetry/tests/test_blackbody.py b/colour/colorimetry/tests/test_blackbody.py index 916a381226..afb9e34c3b 100644 --- a/colour/colorimetry/tests/test_blackbody.py +++ b/colour/colorimetry/tests/test_blackbody.py @@ -3,17 +3,19 @@ from __future__ import annotations -import numpy as np import unittest from itertools import product +import numpy as np + from colour.colorimetry import ( SpectralShape, planck_law, - sd_blackbody, rayleigh_jeans_law, + sd_blackbody, sd_rayleigh_jeans, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import NDArrayFloat from colour.utilities import ignore_numpy_errors @@ -1209,9 +1211,7 @@ def test_planck_law(self): np.testing.assert_allclose( planck_law(wavelengths, temperature), radiance, - rtol=0.0000001, - atol=0.0000001, - verbose=False, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_planck_law(self): @@ -1225,26 +1225,40 @@ def test_n_dimensional_planck_law(self): wl = np.tile(wl, 6) p = np.tile(p, 6) - np.testing.assert_array_almost_equal(planck_law(wl, 5500), p) + np.testing.assert_allclose( + planck_law(wl, 5500), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) wl = np.reshape(wl, (2, 3)) # The "colour.colorimetry.planck_law" definition behaviour with # n-dimensional arrays is unusual. # p = np.np.reshape(p, (2, 3)) - np.testing.assert_array_almost_equal(planck_law(wl, 5500), p) + np.testing.assert_allclose( + planck_law(wl, 5500), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) wl = np.reshape(wl, (2, 3, 1)) # The "colour.colorimetry.planck_law" definition behaviour with # n-dimensional arrays is unusual. # p = np.reshape(p, (2, 3, 1)) - np.testing.assert_array_almost_equal(planck_law(wl, 5500), p) + np.testing.assert_allclose( + planck_law(wl, 5500), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) # The "colour.colorimetry.planck_law" definition behaviour with # n-dimensional arrays is unusual. p = planck_law(500 * 1e-9, [5000, 5500, 6000]) p = np.tile(p, (6, 1)) - np.testing.assert_array_almost_equal( - planck_law(wl, [5000, 5500, 6000]), p + np.testing.assert_allclose( + planck_law(wl, [5000, 5500, 6000]), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_planck_law(self): @@ -1281,8 +1295,7 @@ def test_sd_blackbody(self): np.testing.assert_allclose( sd_blackbody(5000, SpectralShape(360, 830, 1)).values, DATA_BLACKBODY, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1303,9 +1316,7 @@ def test_rayleigh_jeans_law(self): np.testing.assert_allclose( rayleigh_jeans_law(wavelengths, temperature), radiance, - rtol=0.0000001, - atol=0.0000001, - verbose=False, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_rayleigh_jeans_law(self): @@ -1319,26 +1330,40 @@ def test_n_dimensional_rayleigh_jeans_law(self): wl = np.tile(wl, 6) p = np.tile(p, 6) - np.testing.assert_array_almost_equal(rayleigh_jeans_law(wl, 5500), p) + np.testing.assert_allclose( + rayleigh_jeans_law(wl, 5500), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) wl = np.reshape(wl, (2, 3)) # The "colour.colorimetry.rayleigh_jeans_law" definition behaviour with # n-dimensional arrays is unusual. # p = np.np.reshape(p, (2, 3)) - np.testing.assert_array_almost_equal(rayleigh_jeans_law(wl, 5500), p) + np.testing.assert_allclose( + rayleigh_jeans_law(wl, 5500), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) wl = np.reshape(wl, (2, 3, 1)) # The "colour.colorimetry.rayleigh_jeans_law" definition behaviour with # n-dimensional arrays is unusual. # p = np.reshape(p, (2, 3, 1)) - np.testing.assert_array_almost_equal(rayleigh_jeans_law(wl, 5500), p) + np.testing.assert_allclose( + rayleigh_jeans_law(wl, 5500), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) # The "colour.colorimetry.rayleigh_jeans_law" definition behaviour with # n-dimensional arrays is unusual. p = rayleigh_jeans_law(500 * 1e-9, [5000, 5500, 6000]) p = np.tile(p, (6, 1)) - np.testing.assert_array_almost_equal( - rayleigh_jeans_law(wl, [5000, 5500, 6000]), p + np.testing.assert_allclose( + rayleigh_jeans_law(wl, [5000, 5500, 6000]), + p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1368,8 +1393,7 @@ def test_sd_rayleigh_jeans(self): np.testing.assert_allclose( sd_rayleigh_jeans(5000, SpectralShape(360, 830, 1)).values, DATA_RAYLEIGH_JEANS, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_correction.py b/colour/colorimetry/tests/test_correction.py index a2f623dc35..9956d308f4 100644 --- a/colour/colorimetry/tests/test_correction.py +++ b/colour/colorimetry/tests/test_correction.py @@ -1,13 +1,15 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.correction` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( SpectralDistribution, bandpass_correction_Stearns1988, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -82,8 +84,10 @@ def test_bandpass_correction_Stearns1988(self): ) ) - np.testing.assert_array_almost_equal( - bandpass_correction_Stearns1988(sd).values, DATA_BANDPASS_CORRECTED + np.testing.assert_allclose( + bandpass_correction_Stearns1988(sd).values, + DATA_BANDPASS_CORRECTED, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_dominant.py b/colour/colorimetry/tests/test_dominant.py index 1adabe0a73..55456f8a58 100644 --- a/colour/colorimetry/tests/test_dominant.py +++ b/colour/colorimetry/tests/test_dominant.py @@ -1,21 +1,23 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.dominant` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.colorimetry import ( - MSDS_CMFS, CCS_ILLUMINANTS, - dominant_wavelength, + MSDS_CMFS, + colorimetric_purity, complementary_wavelength, + dominant_wavelength, excitation_purity, - colorimetric_purity, ) from colour.colorimetry.dominant import ( closest_spectral_locus_wavelength, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import XYZ_to_xy from colour.utilities import ignore_numpy_errors @@ -63,16 +65,20 @@ def test_closest_spectral_locus_wavelength(self): i_wl, xy_wl = closest_spectral_locus_wavelength(xy, xy_n, self._xy_s) self.assertEqual(i_wl, np.array(256)) - np.testing.assert_array_almost_equal( - xy_wl, np.array([0.68354746, 0.31628409]), decimal=7 + np.testing.assert_allclose( + xy_wl, + np.array([0.68354746, 0.31628409]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) xy = np.array([0.37605506, 0.24452225]) i_wl, xy_wl = closest_spectral_locus_wavelength(xy, xy_n, self._xy_s) self.assertEqual(i_wl, np.array(248)) - np.testing.assert_array_almost_equal( - xy_wl, np.array([0.45723147, 0.13628148]), decimal=7 + np.testing.assert_allclose( + xy_wl, + np.array([0.45723147, 0.13628148]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_closest_spectral_locus_wavelength(self): @@ -85,24 +91,30 @@ def test_n_dimensional_closest_spectral_locus_wavelength(self): xy_n = self._xy_D65 i_wl, xy_wl = closest_spectral_locus_wavelength(xy, xy_n, self._xy_s) i_wl_r, xy_wl_r = np.array(256), np.array([0.68354746, 0.31628409]) - np.testing.assert_array_almost_equal(i_wl, i_wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) + np.testing.assert_allclose(i_wl, i_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.tile(xy, (6, 1)) xy_n = np.tile(xy_n, (6, 1)) i_wl, xy_wl = closest_spectral_locus_wavelength(xy, xy_n, self._xy_s) i_wl_r = np.tile(i_wl_r, 6) xy_wl_r = np.tile(xy_wl_r, (6, 1)) - np.testing.assert_array_almost_equal(i_wl, i_wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) + np.testing.assert_allclose(i_wl, i_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) xy_n = np.reshape(xy_n, (2, 3, 2)) i_wl, xy_wl = closest_spectral_locus_wavelength(xy, xy_n, self._xy_s) i_wl_r = np.reshape(i_wl_r, (2, 3)) xy_wl_r = np.reshape(xy_wl_r, (2, 3, 2)) - np.testing.assert_array_almost_equal(i_wl, i_wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) + np.testing.assert_allclose(i_wl, i_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_closest_spectral_locus_wavelength(self): @@ -141,22 +153,30 @@ def test_dominant_wavelength(self): wl, xy_wl, xy_cwl = dominant_wavelength(xy, xy_n) self.assertEqual(wl, np.array(616.0)) - np.testing.assert_array_almost_equal( - xy_wl, np.array([0.68354746, 0.31628409]), decimal=7 + np.testing.assert_allclose( + xy_wl, + np.array([0.68354746, 0.31628409]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - xy_cwl, np.array([0.68354746, 0.31628409]), decimal=7 + np.testing.assert_allclose( + xy_cwl, + np.array([0.68354746, 0.31628409]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) xy = np.array([0.37605506, 0.24452225]) i_wl, xy_wl, xy_cwl = dominant_wavelength(xy, xy_n) self.assertEqual(i_wl, np.array(-509.0)) - np.testing.assert_array_almost_equal( - xy_wl, np.array([0.45723147, 0.13628148]), decimal=7 + np.testing.assert_allclose( + xy_wl, + np.array([0.45723147, 0.13628148]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - xy_cwl, np.array([0.01040962, 0.73207453]), decimal=7 + np.testing.assert_allclose( + xy_cwl, + np.array([0.01040962, 0.73207453]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_dominant_wavelength(self): @@ -173,9 +193,13 @@ def test_n_dimensional_dominant_wavelength(self): np.array([0.68354746, 0.31628409]), np.array([0.68354746, 0.31628409]), ) - np.testing.assert_array_almost_equal(wl, wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) - np.testing.assert_array_almost_equal(xy_cwl, xy_cwl_r, decimal=7) + np.testing.assert_allclose(wl, wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + xy_cwl, xy_cwl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.tile(xy, (6, 1)) xy_n = np.tile(xy_n, (6, 1)) @@ -183,9 +207,13 @@ def test_n_dimensional_dominant_wavelength(self): wl_r = np.tile(wl_r, 6) xy_wl_r = np.tile(xy_wl_r, (6, 1)) xy_cwl_r = np.tile(xy_cwl_r, (6, 1)) - np.testing.assert_array_almost_equal(wl, wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) - np.testing.assert_array_almost_equal(xy_cwl, xy_cwl_r, decimal=7) + np.testing.assert_allclose(wl, wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + xy_cwl, xy_cwl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) xy_n = np.reshape(xy_n, (2, 3, 2)) @@ -193,9 +221,13 @@ def test_n_dimensional_dominant_wavelength(self): wl_r = np.reshape(wl_r, (2, 3)) xy_wl_r = np.reshape(xy_wl_r, (2, 3, 2)) xy_cwl_r = np.reshape(xy_cwl_r, (2, 3, 2)) - np.testing.assert_array_almost_equal(wl, wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) - np.testing.assert_array_almost_equal(xy_cwl, xy_cwl_r, decimal=7) + np.testing.assert_allclose(wl, wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + xy_cwl, xy_cwl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_dominant_wavelength(self): @@ -234,22 +266,30 @@ def test_complementary_wavelength(self): wl, xy_wl, xy_cwl = complementary_wavelength(xy, xy_n) self.assertEqual(wl, np.array(492.0)) - np.testing.assert_array_almost_equal( - xy_wl, np.array([0.03647950, 0.33847127]), decimal=7 + np.testing.assert_allclose( + xy_wl, + np.array([0.03647950, 0.33847127]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - xy_cwl, np.array([0.03647950, 0.33847127]), decimal=7 + np.testing.assert_allclose( + xy_cwl, + np.array([0.03647950, 0.33847127]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) xy = np.array([0.37605506, 0.24452225]) i_wl, xy_wl, xy_cwl = complementary_wavelength(xy, xy_n) self.assertEqual(i_wl, np.array(509.0)) - np.testing.assert_array_almost_equal( - xy_wl, np.array([0.01040962, 0.73207453]), decimal=7 + np.testing.assert_allclose( + xy_wl, + np.array([0.01040962, 0.73207453]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - xy_cwl, np.array([0.01040962, 0.73207453]), decimal=7 + np.testing.assert_allclose( + xy_cwl, + np.array([0.01040962, 0.73207453]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_complementary_wavelength(self): @@ -266,9 +306,13 @@ def test_n_dimensional_complementary_wavelength(self): np.array([0.03647950, 0.33847127]), np.array([0.03647950, 0.33847127]), ) - np.testing.assert_array_almost_equal(wl, wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) - np.testing.assert_array_almost_equal(xy_cwl, xy_cwl_r, decimal=7) + np.testing.assert_allclose(wl, wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + xy_cwl, xy_cwl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.tile(xy, (6, 1)) xy_n = np.tile(xy_n, (6, 1)) @@ -276,9 +320,13 @@ def test_n_dimensional_complementary_wavelength(self): wl_r = np.tile(wl_r, 6) xy_wl_r = np.tile(xy_wl_r, (6, 1)) xy_cwl_r = np.tile(xy_cwl_r, (6, 1)) - np.testing.assert_array_almost_equal(wl, wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) - np.testing.assert_array_almost_equal(xy_cwl, xy_cwl_r, decimal=7) + np.testing.assert_allclose(wl, wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + xy_cwl, xy_cwl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) xy_n = np.reshape(xy_n, (2, 3, 2)) @@ -286,9 +334,13 @@ def test_n_dimensional_complementary_wavelength(self): wl_r = np.reshape(wl_r, (2, 3)) xy_wl_r = np.reshape(xy_wl_r, (2, 3, 2)) xy_cwl_r = np.reshape(xy_cwl_r, (2, 3, 2)) - np.testing.assert_array_almost_equal(wl, wl_r) - np.testing.assert_array_almost_equal(xy_wl, xy_wl_r, decimal=7) - np.testing.assert_array_almost_equal(xy_cwl, xy_cwl_r, decimal=7) + np.testing.assert_allclose(wl, wl_r, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose( + xy_wl, xy_wl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + xy_cwl, xy_cwl_r, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_complementary_wavelength(self): @@ -322,13 +374,17 @@ def test_excitation_purity(self): xy = np.array([0.54369557, 0.32107944]) xy_n = self._xy_D65 - self.assertAlmostEqual( - excitation_purity(xy, xy_n), 0.622885671878446, places=7 + np.testing.assert_allclose( + excitation_purity(xy, xy_n), + 0.622885671878446, + atol=TOLERANCE_ABSOLUTE_TESTS, ) xy = np.array([0.37605506, 0.24452225]) - self.assertAlmostEqual( - excitation_purity(xy, xy_n), 0.438347859215887, places=7 + np.testing.assert_allclose( + excitation_purity(xy, xy_n), + 0.438347859215887, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_excitation_purity(self): @@ -344,15 +400,15 @@ def test_n_dimensional_excitation_purity(self): xy = np.tile(xy, (6, 1)) xy_n = np.tile(xy_n, (6, 1)) P_e = np.tile(P_e, 6) - np.testing.assert_array_almost_equal( - excitation_purity(xy, xy_n), P_e, decimal=7 + np.testing.assert_allclose( + excitation_purity(xy, xy_n), P_e, atol=TOLERANCE_ABSOLUTE_TESTS ) xy = np.reshape(xy, (2, 3, 2)) xy_n = np.reshape(xy_n, (2, 3, 2)) P_e = np.reshape(P_e, (2, 3)) - np.testing.assert_array_almost_equal( - excitation_purity(xy, xy_n), P_e, decimal=7 + np.testing.assert_allclose( + excitation_purity(xy, xy_n), P_e, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -390,13 +446,17 @@ def test_colorimetric_purity(self): xy = np.array([0.54369557, 0.32107944]) xy_n = self._xy_D65 - self.assertAlmostEqual( - colorimetric_purity(xy, xy_n), 0.613582813175483, places=7 + np.testing.assert_allclose( + colorimetric_purity(xy, xy_n), + 0.613582813175483, + atol=TOLERANCE_ABSOLUTE_TESTS, ) xy = np.array([0.37605506, 0.24452225]) - self.assertAlmostEqual( - colorimetric_purity(xy, xy_n), 0.244307811178847, places=7 + np.testing.assert_allclose( + colorimetric_purity(xy, xy_n), + 0.244307811178847, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_colorimetric_purity(self): @@ -412,15 +472,15 @@ def test_n_dimensional_colorimetric_purity(self): xy = np.tile(xy, (6, 1)) xy_n = np.tile(xy_n, (6, 1)) P_e = np.tile(P_e, 6) - np.testing.assert_array_almost_equal( - colorimetric_purity(xy, xy_n), P_e, decimal=7 + np.testing.assert_allclose( + colorimetric_purity(xy, xy_n), P_e, atol=TOLERANCE_ABSOLUTE_TESTS ) xy = np.reshape(xy, (2, 3, 2)) xy_n = np.reshape(xy_n, (2, 3, 2)) P_e = np.reshape(P_e, (2, 3)) - np.testing.assert_array_almost_equal( - colorimetric_purity(xy, xy_n), P_e, decimal=7 + np.testing.assert_allclose( + colorimetric_purity(xy, xy_n), P_e, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/colorimetry/tests/test_generation.py b/colour/colorimetry/tests/test_generation.py index ae78c0fd4c..0f2dc00d3e 100644 --- a/colour/colorimetry/tests/test_generation.py +++ b/colour/colorimetry/tests/test_generation.py @@ -1,21 +1,23 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.generation` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry.generation import ( - sd_constant, - sd_zeros, - sd_ones, msds_constant, - msds_zeros, msds_ones, - sd_gaussian_normal, + msds_zeros, + sd_constant, sd_gaussian_fwhm, - sd_single_led_Ohno2005, + sd_gaussian_normal, sd_multi_leds_Ohno2005, + sd_ones, + sd_single_led_Ohno2005, + sd_zeros, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -49,11 +51,17 @@ def test_sd_constant(self): sd = sd_constant(np.pi) - self.assertAlmostEqual(sd[360], np.pi, places=7) + np.testing.assert_allclose( + sd[360], np.pi, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[555], np.pi, places=7) + np.testing.assert_allclose( + sd[555], np.pi, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[780], np.pi, places=7) + np.testing.assert_allclose( + sd[780], np.pi, atol=TOLERANCE_ABSOLUTE_TESTS + ) class TestSdZeros(unittest.TestCase): @@ -106,16 +114,22 @@ def test_msds_constant(self): msds = msds_constant(np.pi, labels=["a", "b", "c"]) - np.testing.assert_array_almost_equal( - msds[360], np.array([np.pi, np.pi, np.pi]), decimal=7 + np.testing.assert_allclose( + msds[360], + np.array([np.pi, np.pi, np.pi]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - msds[555], np.array([np.pi, np.pi, np.pi]), decimal=7 + np.testing.assert_allclose( + msds[555], + np.array([np.pi, np.pi, np.pi]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - msds[780], np.array([np.pi, np.pi, np.pi]), decimal=7 + np.testing.assert_allclose( + msds[780], + np.array([np.pi, np.pi, np.pi]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -172,11 +186,15 @@ def test_sd_gaussian_normal(self): sd = sd_gaussian_normal(555, 25) - self.assertAlmostEqual(sd[530], 0.606530659712633, places=7) + np.testing.assert_allclose( + sd[530], 0.606530659712633, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[555], 1, places=7) + np.testing.assert_allclose(sd[555], 1, atol=TOLERANCE_ABSOLUTE_TESTS) - self.assertAlmostEqual(sd[580], 0.606530659712633, places=7) + np.testing.assert_allclose( + sd[580], 0.606530659712633, atol=TOLERANCE_ABSOLUTE_TESTS + ) class TestSdGaussianFwhm(unittest.TestCase): @@ -192,13 +210,19 @@ def test_sd_gaussian_fwhm(self): sd = sd_gaussian_fwhm(555, 25) - self.assertAlmostEqual(sd[530], 0.0625, places=7) + np.testing.assert_allclose( + sd[530], 0.0625, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[555], 1, places=7) + np.testing.assert_allclose(sd[555], 1, atol=TOLERANCE_ABSOLUTE_TESTS) - self.assertAlmostEqual(sd[580], 0.062499999999999, places=7) + np.testing.assert_allclose( + sd[580], 0.062499999999999, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[555 - 25 / 2], 0.5, places=7) + np.testing.assert_allclose( + sd[555 - 25 / 2], 0.5, atol=TOLERANCE_ABSOLUTE_TESTS + ) class TestSdSingleLedOhno2005(unittest.TestCase): @@ -215,11 +239,15 @@ def test_sd_single_led_Ohno2005(self): sd = sd_single_led_Ohno2005(555, 25) - self.assertAlmostEqual(sd[530], 0.127118445056538, places=7) + np.testing.assert_allclose( + sd[530], 0.127118445056538, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[555], 1, places=7) + np.testing.assert_allclose(sd[555], 1, atol=TOLERANCE_ABSOLUTE_TESTS) - self.assertAlmostEqual(sd[580], 0.127118445056538, places=7) + np.testing.assert_allclose( + sd[580], 0.127118445056538, atol=TOLERANCE_ABSOLUTE_TESTS + ) class TestSdMultiLedsOhno2005(unittest.TestCase): @@ -240,22 +268,34 @@ def test_sd_multi_leds_Ohno2005(self): np.array([0.731, 1.000, 1.660]), ) - self.assertAlmostEqual(sd[500], 0.129513248576116, places=7) + np.testing.assert_allclose( + sd[500], 0.129513248576116, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[570], 0.059932156222703, places=7) + np.testing.assert_allclose( + sd[570], 0.059932156222703, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[640], 0.116433257970624, places=7) + np.testing.assert_allclose( + sd[640], 0.116433257970624, atol=TOLERANCE_ABSOLUTE_TESTS + ) sd = sd_multi_leds_Ohno2005( np.array([457, 530, 615]), np.array([20, 30, 20]), ) - self.assertAlmostEqual(sd[500], 0.130394510062799, places=7) + np.testing.assert_allclose( + sd[500], 0.130394510062799, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[570], 0.058539618824187, places=7) + np.testing.assert_allclose( + sd[570], 0.058539618824187, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(sd[640], 0.070140708922879, places=7) + np.testing.assert_allclose( + sd[640], 0.070140708922879, atol=TOLERANCE_ABSOLUTE_TESTS + ) if __name__ == "__main__": diff --git a/colour/colorimetry/tests/test_illuminants.py b/colour/colorimetry/tests/test_illuminants.py index 943ffc386c..254bc527ea 100644 --- a/colour/colorimetry/tests/test_illuminants.py +++ b/colour/colorimetry/tests/test_illuminants.py @@ -3,16 +3,18 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( SDS_ILLUMINANTS, SpectralShape, - sd_CIE_standard_illuminant_A, - sd_CIE_illuminant_D_series, daylight_locus_function, + sd_CIE_illuminant_D_series, + sd_CIE_standard_illuminant_A, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import NDArrayFloat from colour.temperature import CCT_to_xy_CIE_D from colour.utilities import ignore_numpy_errors @@ -144,10 +146,10 @@ def test_sd_CIE_standard_illuminant_A(self): sd_CIE_standard_illuminant_A` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_CIE_standard_illuminant_A(SpectralShape(360, 830, 5)).values, DATA_A, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -166,8 +168,8 @@ def test_sd_CIE_illuminant_D_series(self): for name, CCT, tolerance in ( ("D50", 5000, 0.001), ("D55", 5500, 0.001), - ("D65", 6500, 0.00001), - ("D75", 7500, 0.0001), + ("D65", 6500, 0.001), + ("D75", 7500, 0.001), ): CCT *= 1.4388 / 1.4380 # noqa: PLW2901 xy = CCT_to_xy_CIE_D(CCT) @@ -177,7 +179,6 @@ def test_sd_CIE_illuminant_D_series(self): np.testing.assert_allclose( sd_r.values, sd_t[sd_r.wavelengths], - rtol=tolerance, atol=tolerance, ) @@ -194,16 +195,22 @@ def test_daylight_locus_function(self): definition. """ - self.assertAlmostEqual( - daylight_locus_function(0.31270), 0.329105129999999, places=7 + np.testing.assert_allclose( + daylight_locus_function(0.31270), + 0.329105129999999, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - daylight_locus_function(0.34570), 0.358633529999999, places=7 + np.testing.assert_allclose( + daylight_locus_function(0.34570), + 0.358633529999999, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - daylight_locus_function(0.44758), 0.408571030799999, places=7 + np.testing.assert_allclose( + daylight_locus_function(0.44758), + 0.408571030799999, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_daylight_locus_function(self): @@ -217,14 +224,14 @@ def test_n_dimensional_daylight_locus_function(self): x_D = np.tile(x_D, (6, 1)) y_D = np.tile(y_D, (6, 1)) - np.testing.assert_array_almost_equal( - daylight_locus_function(x_D), y_D, decimal=7 + np.testing.assert_allclose( + daylight_locus_function(x_D), y_D, atol=TOLERANCE_ABSOLUTE_TESTS ) x_D = np.reshape(x_D, (2, 3, 1)) y_D = np.reshape(y_D, (2, 3, 1)) - np.testing.assert_array_almost_equal( - daylight_locus_function(x_D), y_D, decimal=7 + np.testing.assert_allclose( + daylight_locus_function(x_D), y_D, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/colorimetry/tests/test_lefs.py b/colour/colorimetry/tests/test_lefs.py index 763e1a6e81..c9ca33aa61 100644 --- a/colour/colorimetry/tests/test_lefs.py +++ b/colour/colorimetry/tests/test_lefs.py @@ -1,13 +1,15 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.lefs` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( mesopic_weighting_function, sd_mesopic_luminous_efficiency_function, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -440,24 +442,26 @@ def test_mesopic_weighting_function(self): definition. """ - self.assertAlmostEqual( - mesopic_weighting_function(500, 0.2), 0.70522000, places=7 + np.testing.assert_allclose( + mesopic_weighting_function(500, 0.2), + 0.70522000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( mesopic_weighting_function( 500, 0.2, source="Red Heavy", method="LRC" ), 0.90951000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( mesopic_weighting_function( 700, 10, source="Red Heavy", method="LRC" ), 0.00410200, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_mesopic_weighting_function(self): @@ -471,20 +475,26 @@ def test_n_dimensional_mesopic_weighting_function(self): wl = np.tile(wl, 6) Vm = np.tile(Vm, 6) - np.testing.assert_array_almost_equal( - mesopic_weighting_function(wl, 0.2), Vm + np.testing.assert_allclose( + mesopic_weighting_function(wl, 0.2), + Vm, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) Vm = np.reshape(Vm, (2, 3)) - np.testing.assert_array_almost_equal( - mesopic_weighting_function(wl, 0.2), Vm + np.testing.assert_allclose( + mesopic_weighting_function(wl, 0.2), + Vm, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) Vm = np.reshape(Vm, (2, 3, 1)) - np.testing.assert_array_almost_equal( - mesopic_weighting_function(wl, 0.2), Vm + np.testing.assert_allclose( + mesopic_weighting_function(wl, 0.2), + Vm, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -511,10 +521,10 @@ def test_sd_mesopic_luminous_efficiency_function(self): sd_mesopic_luminous_efficiency_function` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_mesopic_luminous_efficiency_function(0.2).values, DATA_MESOPIC_LEF, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_lightness.py b/colour/colorimetry/tests/test_lightness.py index 062c55ddbf..91e2648893 100644 --- a/colour/colorimetry/tests/test_lightness.py +++ b/colour/colorimetry/tests/test_lightness.py @@ -1,19 +1,21 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.lightness` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( - lightness_Glasser1958, - lightness_Wyszecki1963, intermediate_lightness_function_CIE1976, + lightness_Abebe2017, lightness_CIE1976, lightness_Fairchild2010, lightness_Fairchild2011, - lightness_Abebe2017, + lightness_Glasser1958, + lightness_Wyszecki1963, ) from colour.colorimetry.lightness import lightness +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -47,16 +49,22 @@ def test_lightness_Glasser1958(self): definition. """ - self.assertAlmostEqual( - lightness_Glasser1958(12.19722535), 39.83512646492521, places=7 + np.testing.assert_allclose( + lightness_Glasser1958(12.19722535), + 39.83512646492521, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Glasser1958(23.04276781), 53.585946877480623, places=7 + np.testing.assert_allclose( + lightness_Glasser1958(23.04276781), + 53.585946877480623, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Glasser1958(6.15720079), 27.972867038082629, places=7 + np.testing.assert_allclose( + lightness_Glasser1958(6.15720079), + 27.972867038082629, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_lightness_Glasser1958(self): @@ -70,20 +78,20 @@ def test_n_dimensional_lightness_Glasser1958(self): Y = np.tile(Y, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal( - lightness_Glasser1958(Y), L, decimal=7 + np.testing.assert_allclose( + lightness_Glasser1958(Y), L, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal( - lightness_Glasser1958(Y), L, decimal=7 + np.testing.assert_allclose( + lightness_Glasser1958(Y), L, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal( - lightness_Glasser1958(Y), L, decimal=7 + np.testing.assert_allclose( + lightness_Glasser1958(Y), L, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_lightness_Glasser1958(self): @@ -97,10 +105,10 @@ def test_domain_range_scale_lightness_Glasser1958(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lightness_Glasser1958(12.19722535 * factor), L * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -127,16 +135,22 @@ def test_lightness_Wyszecki1963(self): definition. """ - self.assertAlmostEqual( - lightness_Wyszecki1963(12.19722535), 40.547574599570197, places=7 + np.testing.assert_allclose( + lightness_Wyszecki1963(12.19722535), + 40.547574599570197, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Wyszecki1963(23.04276781), 54.140714588256841, places=7 + np.testing.assert_allclose( + lightness_Wyszecki1963(23.04276781), + 54.140714588256841, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Wyszecki1963(6.15720079), 28.821339499883976, places=7 + np.testing.assert_allclose( + lightness_Wyszecki1963(6.15720079), + 28.821339499883976, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_lightness_Wyszecki1963(self): @@ -150,20 +164,20 @@ def test_n_dimensional_lightness_Wyszecki1963(self): Y = np.tile(Y, 6) W = np.tile(W, 6) - np.testing.assert_array_almost_equal( - lightness_Wyszecki1963(Y), W, decimal=7 + np.testing.assert_allclose( + lightness_Wyszecki1963(Y), W, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3)) W = np.reshape(W, (2, 3)) - np.testing.assert_array_almost_equal( - lightness_Wyszecki1963(Y), W, decimal=7 + np.testing.assert_allclose( + lightness_Wyszecki1963(Y), W, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3, 1)) W = np.reshape(W, (2, 3, 1)) - np.testing.assert_array_almost_equal( - lightness_Wyszecki1963(Y), W, decimal=7 + np.testing.assert_allclose( + lightness_Wyszecki1963(Y), W, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_lightness_Wyszecki1963(self): @@ -177,10 +191,10 @@ def test_domain_range_scale_lightness_Wyszecki1963(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lightness_Wyszecki1963(12.19722535 * factor), W * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -207,22 +221,22 @@ def test_intermediate_lightness_function_CIE1976(self): intermediate_lightness_function_CIE1976` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( intermediate_lightness_function_CIE1976(12.19722535), 0.495929964178047, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( intermediate_lightness_function_CIE1976(23.04276781), 0.613072093530391, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( intermediate_lightness_function_CIE1976(6.15720079), 0.394876333449113, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_intermediate_lightness_function_CIE1976(self): @@ -237,20 +251,26 @@ def test_n_dimensional_intermediate_lightness_function_CIE1976(self): Y = np.tile(Y, 6) f_Y_Y_n = np.tile(f_Y_Y_n, 6) - np.testing.assert_array_almost_equal( - intermediate_lightness_function_CIE1976(Y), f_Y_Y_n, decimal=7 + np.testing.assert_allclose( + intermediate_lightness_function_CIE1976(Y), + f_Y_Y_n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y = np.reshape(Y, (2, 3)) f_Y_Y_n = np.reshape(f_Y_Y_n, (2, 3)) - np.testing.assert_array_almost_equal( - intermediate_lightness_function_CIE1976(Y), f_Y_Y_n, decimal=7 + np.testing.assert_allclose( + intermediate_lightness_function_CIE1976(Y), + f_Y_Y_n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y = np.reshape(Y, (2, 3, 1)) f_Y_Y_n = np.reshape(f_Y_Y_n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - intermediate_lightness_function_CIE1976(Y), f_Y_Y_n, decimal=7 + np.testing.assert_allclose( + intermediate_lightness_function_CIE1976(Y), + f_Y_Y_n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_intermediate_lightness_function_CIE1976(self): @@ -264,10 +284,10 @@ def test_domain_range_scale_intermediate_lightness_function_CIE1976(self): for scale in ("reference", "1", "100"): with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( intermediate_lightness_function_CIE1976(12.19722535, 100), f_Y_Y_n, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -294,28 +314,40 @@ def test_lightness_CIE1976(self): definition. """ - self.assertAlmostEqual( - lightness_CIE1976(12.19722535), 41.527875844653451, places=7 + np.testing.assert_allclose( + lightness_CIE1976(12.19722535), + 41.527875844653451, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_CIE1976(23.04276781), 55.116362849525402, places=7 + np.testing.assert_allclose( + lightness_CIE1976(23.04276781), + 55.116362849525402, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_CIE1976(6.15720079), 29.805654680097106, places=7 + np.testing.assert_allclose( + lightness_CIE1976(6.15720079), + 29.805654680097106, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_CIE1976(12.19722535, 50), 56.480581732417676, places=7 + np.testing.assert_allclose( + lightness_CIE1976(12.19722535, 50), + 56.480581732417676, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_CIE1976(12.19722535, 75), 47.317620274162735, places=7 + np.testing.assert_allclose( + lightness_CIE1976(12.19722535, 75), + 47.317620274162735, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_CIE1976(12.19722535, 95), 42.519930728120940, places=7 + np.testing.assert_allclose( + lightness_CIE1976(12.19722535, 95), + 42.519930728120940, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_lightness_CIE1976(self): @@ -329,20 +361,20 @@ def test_n_dimensional_lightness_CIE1976(self): Y = np.tile(Y, 6) L_star = np.tile(L_star, 6) - np.testing.assert_array_almost_equal( - lightness_CIE1976(Y), L_star, decimal=7 + np.testing.assert_allclose( + lightness_CIE1976(Y), L_star, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3)) L_star = np.reshape(L_star, (2, 3)) - np.testing.assert_array_almost_equal( - lightness_CIE1976(Y), L_star, decimal=7 + np.testing.assert_allclose( + lightness_CIE1976(Y), L_star, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3, 1)) L_star = np.reshape(L_star, (2, 3, 1)) - np.testing.assert_array_almost_equal( - lightness_CIE1976(Y), L_star, decimal=7 + np.testing.assert_allclose( + lightness_CIE1976(Y), L_star, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_lightness_CIE1976(self): @@ -356,10 +388,10 @@ def test_domain_range_scale_lightness_CIE1976(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lightness_CIE1976(12.19722535 * factor, 100), L_star * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -384,36 +416,40 @@ def test_lightness_Fairchild2010(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2010(12.19722535 / 100), 31.996390226262736, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2010(23.04276781 / 100), 60.203153682783302, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2010(6.15720079 / 100), 11.836517240976489, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2010(12.19722535 / 100, 2.75), 24.424283249379986, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Fairchild2010(1008), 100.019986327374240, places=7 + np.testing.assert_allclose( + lightness_Fairchild2010(1008), + 100.019986327374240, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Fairchild2010(100800), 100.019999997090270, places=7 + np.testing.assert_allclose( + lightness_Fairchild2010(100800), + 100.019999997090270, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_lightness_Fairchild2010(self): @@ -427,20 +463,20 @@ def test_n_dimensional_lightness_Fairchild2010(self): Y = np.tile(Y, 6) L_hdr = np.tile(L_hdr, 6) - np.testing.assert_array_almost_equal( - lightness_Fairchild2010(Y), L_hdr, decimal=7 + np.testing.assert_allclose( + lightness_Fairchild2010(Y), L_hdr, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3)) L_hdr = np.reshape(L_hdr, (2, 3)) - np.testing.assert_array_almost_equal( - lightness_Fairchild2010(Y), L_hdr, decimal=7 + np.testing.assert_allclose( + lightness_Fairchild2010(Y), L_hdr, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3, 1)) L_hdr = np.reshape(L_hdr, (2, 3, 1)) - np.testing.assert_array_almost_equal( - lightness_Fairchild2010(Y), L_hdr, decimal=7 + np.testing.assert_allclose( + lightness_Fairchild2010(Y), L_hdr, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_lightness_Fairchild2010(self): @@ -454,10 +490,10 @@ def test_domain_range_scale_lightness_Fairchild2010(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lightness_Fairchild2010(12.19722535 / 100 * factor_a), L_hdr * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -484,36 +520,40 @@ def test_lightness_Fairchild2011(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2011(12.19722535 / 100), 51.852958445912506, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2011(23.04276781 / 100), 65.275207956353853, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2011(6.15720079 / 100), 39.818935510715917, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Fairchild2011(12.19722535 / 100, 2.75), 0.13268968410139345, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Fairchild2011(1008), 234.72925682, places=7 + np.testing.assert_allclose( + lightness_Fairchild2011(1008), + 234.72925682, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Fairchild2011(100800), 245.5705978, places=7 + np.testing.assert_allclose( + lightness_Fairchild2011(100800), + 245.5705978, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_lightness_Fairchild2011(self): @@ -527,20 +567,20 @@ def test_n_dimensional_lightness_Fairchild2011(self): Y = np.tile(Y, 6) L_hdr = np.tile(L_hdr, 6) - np.testing.assert_array_almost_equal( - lightness_Fairchild2011(Y), L_hdr, decimal=7 + np.testing.assert_allclose( + lightness_Fairchild2011(Y), L_hdr, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3)) L_hdr = np.reshape(L_hdr, (2, 3)) - np.testing.assert_array_almost_equal( - lightness_Fairchild2011(Y), L_hdr, decimal=7 + np.testing.assert_allclose( + lightness_Fairchild2011(Y), L_hdr, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3, 1)) L_hdr = np.reshape(L_hdr, (2, 3, 1)) - np.testing.assert_array_almost_equal( - lightness_Fairchild2011(Y), L_hdr, decimal=7 + np.testing.assert_allclose( + lightness_Fairchild2011(Y), L_hdr, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_lightness_Fairchild2011(self): @@ -554,10 +594,10 @@ def test_domain_range_scale_lightness_Fairchild2011(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lightness_Fairchild2011(12.19722535 / 100 * factor_a), L_hdr * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -584,28 +624,34 @@ def test_lightness_Abebe2017(self): definition. """ - self.assertAlmostEqual( - lightness_Abebe2017(12.19722535), 0.486955571109229, places=7 + np.testing.assert_allclose( + lightness_Abebe2017(12.19722535), + 0.486955571109229, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Abebe2017(12.19722535, method="Stevens"), 0.474544792145434, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Abebe2017(12.19722535, 1000), 0.286847428534793, places=7 + np.testing.assert_allclose( + lightness_Abebe2017(12.19722535, 1000), + 0.286847428534793, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - lightness_Abebe2017(12.19722535, 4000), 0.192145492588158, places=7 + np.testing.assert_allclose( + lightness_Abebe2017(12.19722535, 4000), + 0.192145492588158, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( lightness_Abebe2017(12.19722535, 4000, method="Stevens"), 0.170365211220992, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_lightness_Abebe2017(self): @@ -619,20 +665,20 @@ def test_n_dimensional_lightness_Abebe2017(self): Y = np.tile(Y, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal( - lightness_Abebe2017(Y), L, decimal=7 + np.testing.assert_allclose( + lightness_Abebe2017(Y), L, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal( - lightness_Abebe2017(Y), L, decimal=7 + np.testing.assert_allclose( + lightness_Abebe2017(Y), L, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.reshape(Y, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal( - lightness_Abebe2017(Y), L, decimal=7 + np.testing.assert_allclose( + lightness_Abebe2017(Y), L, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_lightness_Abebe2017(self): @@ -646,10 +692,10 @@ def test_domain_range_scale_lightness_Abebe2017(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lightness_Abebe2017(12.19722535 * factor, 100 * factor), L * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -690,10 +736,10 @@ def test_domain_range_scale_lightness(self): for method, value in zip(m, v): for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lightness(12.19722535 * factor, method, Y_n=100), value * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_luminance.py b/colour/colorimetry/tests/test_luminance.py index 8bb897e085..b9c1f058b4 100644 --- a/colour/colorimetry/tests/test_luminance.py +++ b/colour/colorimetry/tests/test_luminance.py @@ -1,19 +1,21 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.luminance` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( - luminance_Newhall1943, intermediate_luminance_function_CIE1976, - luminance_CIE1976, + luminance_Abebe2017, luminance_ASTMD1535, + luminance_CIE1976, luminance_Fairchild2010, luminance_Fairchild2011, - luminance_Abebe2017, + luminance_Newhall1943, ) from colour.colorimetry.luminance import luminance +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -47,16 +49,22 @@ def test_luminance_Newhall1943(self): definition. """ - self.assertAlmostEqual( - luminance_Newhall1943(4.08244375), 12.550078816731881, places=7 + np.testing.assert_allclose( + luminance_Newhall1943(4.08244375), + 12.550078816731881, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - luminance_Newhall1943(5.39132685), 23.481252371310738, places=7 + np.testing.assert_allclose( + luminance_Newhall1943(5.39132685), + 23.481252371310738, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - luminance_Newhall1943(2.97619312), 6.4514266875601924, places=7 + np.testing.assert_allclose( + luminance_Newhall1943(2.97619312), + 6.4514266875601924, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_luminance_Newhall1943(self): @@ -70,20 +78,20 @@ def test_n_dimensional_luminance_Newhall1943(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - luminance_Newhall1943(V), Y, decimal=7 + np.testing.assert_allclose( + luminance_Newhall1943(V), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - luminance_Newhall1943(V), Y, decimal=7 + np.testing.assert_allclose( + luminance_Newhall1943(V), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - luminance_Newhall1943(V), Y, decimal=7 + np.testing.assert_allclose( + luminance_Newhall1943(V), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_luminance_Newhall1943(self): @@ -97,10 +105,10 @@ def test_domain_range_scale_luminance_Newhall1943(self): d_r = (("reference", 1, 1), ("1", 0.1, 0.01), ("100", 10, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( luminance_Newhall1943(4.08244375 * factor_a), Y * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -127,16 +135,22 @@ def test_luminance_ASTMD1535(self): definition. """ - self.assertAlmostEqual( - luminance_ASTMD1535(4.08244375), 12.236342675366036, places=7 + np.testing.assert_allclose( + luminance_ASTMD1535(4.08244375), + 12.236342675366036, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - luminance_ASTMD1535(5.39132685), 22.893999867280378, places=7 + np.testing.assert_allclose( + luminance_ASTMD1535(5.39132685), + 22.893999867280378, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - luminance_ASTMD1535(2.97619312), 6.2902253509053132, places=7 + np.testing.assert_allclose( + luminance_ASTMD1535(2.97619312), + 6.2902253509053132, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_luminance_ASTMD1535(self): @@ -150,20 +164,20 @@ def test_n_dimensional_luminance_ASTMD1535(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - luminance_ASTMD1535(V), Y, decimal=7 + np.testing.assert_allclose( + luminance_ASTMD1535(V), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - luminance_ASTMD1535(V), Y, decimal=7 + np.testing.assert_allclose( + luminance_ASTMD1535(V), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - luminance_ASTMD1535(V), Y, decimal=7 + np.testing.assert_allclose( + luminance_ASTMD1535(V), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_luminance_ASTMD1535(self): @@ -177,10 +191,10 @@ def test_domain_range_scale_luminance_ASTMD1535(self): d_r = (("reference", 1, 1), ("1", 0.1, 0.01), ("100", 10, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( luminance_ASTMD1535(4.08244375 * factor_a), Y * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -207,22 +221,22 @@ def test_intermediate_luminance_function_CIE1976(self): intermediate_luminance_function_CIE1976` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( intermediate_luminance_function_CIE1976(0.495929964178047), 12.197225350000002, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( intermediate_luminance_function_CIE1976(0.613072093530391), 23.042767810000004, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( intermediate_luminance_function_CIE1976(0.394876333449113), 6.157200790000001, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_intermediate_luminance_function_CIE1976(self): @@ -237,20 +251,26 @@ def test_n_dimensional_intermediate_luminance_function_CIE1976(self): f_Y_Y_n = np.tile(f_Y_Y_n, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - intermediate_luminance_function_CIE1976(f_Y_Y_n), Y, decimal=7 + np.testing.assert_allclose( + intermediate_luminance_function_CIE1976(f_Y_Y_n), + Y, + atol=TOLERANCE_ABSOLUTE_TESTS, ) f_Y_Y_n = np.reshape(f_Y_Y_n, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - intermediate_luminance_function_CIE1976(f_Y_Y_n), Y, decimal=7 + np.testing.assert_allclose( + intermediate_luminance_function_CIE1976(f_Y_Y_n), + Y, + atol=TOLERANCE_ABSOLUTE_TESTS, ) f_Y_Y_n = np.reshape(f_Y_Y_n, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - intermediate_luminance_function_CIE1976(f_Y_Y_n), Y, decimal=7 + np.testing.assert_allclose( + intermediate_luminance_function_CIE1976(f_Y_Y_n), + Y, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_intermediate_luminance_function_CIE1976(self): @@ -264,12 +284,12 @@ def test_domain_range_scale_intermediate_luminance_function_CIE1976(self): for scale in ("reference", "1", "100"): with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( intermediate_luminance_function_CIE1976( 41.527875844653451, 100 ), Y, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -296,34 +316,40 @@ def test_luminance_CIE1976(self): definition. """ - self.assertAlmostEqual( - luminance_CIE1976(41.527875844653451), 12.197225350000002, places=7 + np.testing.assert_allclose( + luminance_CIE1976(41.527875844653451), + 12.197225350000002, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - luminance_CIE1976(55.116362849525402), 23.042767810000004, places=7 + np.testing.assert_allclose( + luminance_CIE1976(55.116362849525402), + 23.042767810000004, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - luminance_CIE1976(29.805654680097106), 6.157200790000001, places=7 + np.testing.assert_allclose( + luminance_CIE1976(29.805654680097106), + 6.157200790000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_CIE1976(56.480581732417676, 50), 12.197225349999998, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_CIE1976(47.317620274162735, 75), 12.197225350000002, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_CIE1976(42.519930728120940, 95), 12.197225350000005, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_luminance_CIE1976(self): @@ -337,20 +363,20 @@ def test_n_dimensional_luminance_CIE1976(self): L_star = np.tile(L_star, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - luminance_CIE1976(L_star), Y, decimal=7 + np.testing.assert_allclose( + luminance_CIE1976(L_star), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L_star = np.reshape(L_star, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - luminance_CIE1976(L_star), Y, decimal=7 + np.testing.assert_allclose( + luminance_CIE1976(L_star), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L_star = np.reshape(L_star, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - luminance_CIE1976(L_star), Y, decimal=7 + np.testing.assert_allclose( + luminance_CIE1976(L_star), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_luminance_CIE1976(self): @@ -364,10 +390,10 @@ def test_domain_range_scale_luminance_CIE1976(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( luminance_CIE1976(41.527875844653451 * factor, 100), Y * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -392,40 +418,40 @@ def test_luminance_Fairchild2010(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2010(31.996390226262736), 0.12197225350000002, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2010(60.203153682783302), 0.23042767809999998, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2010(11.836517240976489), 0.06157200790000001, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2010(24.424283249379986, 2.75), 0.12197225350000002, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2010(100.019986327374240), 1008.00000024, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2010(100.019999997090270), 100799.92312466, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_luminance_Fairchild2010(self): @@ -439,20 +465,20 @@ def test_n_dimensional_luminance_Fairchild2010(self): L_hdr = np.tile(L_hdr, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - luminance_Fairchild2010(L_hdr), Y, decimal=7 + np.testing.assert_allclose( + luminance_Fairchild2010(L_hdr), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L_hdr = np.reshape(L_hdr, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - luminance_Fairchild2010(L_hdr), Y, decimal=7 + np.testing.assert_allclose( + luminance_Fairchild2010(L_hdr), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L_hdr = np.reshape(L_hdr, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - luminance_Fairchild2010(L_hdr), Y, decimal=7 + np.testing.assert_allclose( + luminance_Fairchild2010(L_hdr), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_luminance_Fairchild2010(self): @@ -466,10 +492,10 @@ def test_domain_range_scale_luminance_Fairchild2010(self): d_r = (("reference", 1, 1), ("1", 0.01, 1), ("100", 1, 100)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( luminance_Fairchild2010(31.996390226262736 * factor_a), Y * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -496,40 +522,40 @@ def test_luminance_Fairchild2011(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2011(51.852958445912506), 0.12197225350000007, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2011(65.275207956353853), 0.23042767809999998, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2011(39.818935510715917), 0.061572007900000038, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2011(0.13268968410139345, 2.75), 0.12197225350000002, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2011(234.72925681957565), 1008.00000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Fairchild2011(245.57059778237573), 100800.00000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_luminance_Fairchild2011(self): @@ -543,20 +569,20 @@ def test_n_dimensional_luminance_Fairchild2011(self): L_hdr = np.tile(L_hdr, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - luminance_Fairchild2011(L_hdr), Y, decimal=7 + np.testing.assert_allclose( + luminance_Fairchild2011(L_hdr), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L_hdr = np.reshape(L_hdr, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - luminance_Fairchild2011(L_hdr), Y, decimal=7 + np.testing.assert_allclose( + luminance_Fairchild2011(L_hdr), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L_hdr = np.reshape(L_hdr, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - luminance_Fairchild2011(L_hdr), Y, decimal=7 + np.testing.assert_allclose( + luminance_Fairchild2011(L_hdr), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_luminance_Fairchild2011(self): @@ -570,10 +596,10 @@ def test_domain_range_scale_luminance_Fairchild2011(self): d_r = (("reference", 1, 1), ("1", 0.01, 1), ("100", 1, 100)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( luminance_Fairchild2011(26.459509817572265 * factor_a), Y * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -600,34 +626,34 @@ def test_luminance_Abebe2017(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Abebe2017(0.486955571109229), 12.197225350000004, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Abebe2017(0.474544792145434, method="Stevens"), 12.197225350000025, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Abebe2017(0.286847428534793, 1000), 12.197225350000046, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Abebe2017(0.192145492588158, 4000), 12.197225350000121, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminance_Abebe2017(0.170365211220992, 4000, method="Stevens"), 12.197225349999933, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_luminance_Abebe2017(self): @@ -641,20 +667,20 @@ def test_n_dimensional_luminance_Abebe2017(self): L = np.tile(L, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - luminance_Abebe2017(L), Y, decimal=7 + np.testing.assert_allclose( + luminance_Abebe2017(L), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - luminance_Abebe2017(L), Y, decimal=7 + np.testing.assert_allclose( + luminance_Abebe2017(L), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - luminance_Abebe2017(L), Y, decimal=7 + np.testing.assert_allclose( + luminance_Abebe2017(L), Y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_luminance_Abebe2017(self): @@ -668,12 +694,12 @@ def test_domain_range_scale_luminance_Abebe2017(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( luminance_Abebe2017( 0.486955571109229 * factor, 100 * factor ), L * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -714,12 +740,12 @@ def test_domain_range_scale_luminance(self): for method, value in zip(m, v): for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( luminance( 41.527875844653451 * factor, method, Y_n=100 ), value * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_photometry.py b/colour/colorimetry/tests/test_photometry.py index d274b10f73..5185f8b878 100644 --- a/colour/colorimetry/tests/test_photometry.py +++ b/colour/colorimetry/tests/test_photometry.py @@ -3,14 +3,17 @@ import unittest +import numpy as np + from colour.colorimetry import ( SDS_ILLUMINANTS, SDS_LIGHT_SOURCES, - luminous_flux, - luminous_efficiency, luminous_efficacy, + luminous_efficiency, + luminous_flux, sd_zeros, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -35,22 +38,22 @@ class TestLuminousFlux(unittest.TestCase): def test_luminous_flux(self): """Test :func:`colour.colorimetry.photometry.luminous_flux` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_flux(SDS_ILLUMINANTS["FL2"].copy().normalise()), 28588.73612977, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_flux(SDS_LIGHT_SOURCES["Neodimium Incandescent"]), 23807.65552737, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_flux(SDS_LIGHT_SOURCES["F32T8/TL841 (Triphosphor)"]), 13090.06759053, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -66,24 +69,24 @@ def test_luminous_efficiency(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_efficiency(SDS_ILLUMINANTS["FL2"].copy().normalise()), 0.49317624, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_efficiency(SDS_LIGHT_SOURCES["Neodimium Incandescent"]), 0.19943936, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_efficiency( SDS_LIGHT_SOURCES["F32T8/TL841 (Triphosphor)"] ), 0.51080919, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -99,27 +102,29 @@ def test_luminous_efficacy(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_efficacy(SDS_ILLUMINANTS["FL2"].copy().normalise()), 336.83937176, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_efficacy(SDS_LIGHT_SOURCES["Neodimium Incandescent"]), 136.21708032, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( luminous_efficacy(SDS_LIGHT_SOURCES["F32T8/TL841 (Triphosphor)"]), 348.88267549, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) sd = sd_zeros() sd[555] = 1 - self.assertAlmostEqual(luminous_efficacy(sd), 683.00000000, places=7) + np.testing.assert_allclose( + luminous_efficacy(sd), 683.00000000, atol=TOLERANCE_ABSOLUTE_TESTS + ) if __name__ == "__main__": diff --git a/colour/colorimetry/tests/test_spectrum.py b/colour/colorimetry/tests/test_spectrum.py index d64ae53939..b677844e05 100644 --- a/colour/colorimetry/tests/test_spectrum.py +++ b/colour/colorimetry/tests/test_spectrum.py @@ -1,22 +1,25 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.spectrum` module.""" -import colour -import numpy as np +import pickle import unittest +import numpy as np + +import colour from colour.algebra import CubicSplineInterpolator -from colour.colorimetry.spectrum import SPECTRAL_SHAPE_DEFAULT from colour.colorimetry.spectrum import ( - SpectralShape, - SpectralDistribution, + SPECTRAL_SHAPE_DEFAULT, MultiSpectralDistributions, - reshape_sd, + SpectralDistribution, + SpectralShape, reshape_msds, - sds_and_msds_to_sds, + reshape_sd, sds_and_msds_to_msds, + sds_and_msds_to_sds, ) -from colour.utilities import tstack +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.utilities import is_caching_enabled, tstack __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -1284,6 +1287,17 @@ def test_required_methods(self): for method in required_methods: self.assertIn(method, dir(SpectralShape)) + def test_pickling(self): + """ + Test whether the :class:`colour.colorimetry.spectrum.SpectralShape` + class can be pickled. + """ + + shape = SpectralShape(360, 830, 1) + data = pickle.dumps(shape) + data = pickle.loads(data) # noqa: S301 + self.assertEqual(shape, data) + def test_start(self): """ Test :attr:`colour.colorimetry.spectrum.SpectralShape.start` @@ -1331,7 +1345,7 @@ def test_wavelengths(self): property. """ - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( SpectralShape(0, 10, 0.1).wavelengths, np.arange(0, 10 + 0.1, 0.1), ) @@ -1350,7 +1364,7 @@ def test__iter__(self): method. """ - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( list(SpectralShape(0, 10, 0.1)), np.arange(0, 10 + 0.1, 0.1), ) @@ -1399,7 +1413,7 @@ def test__ne__(self): def test_range(self): """Test :func:`colour.colorimetry.spectrum.SpectralShape.range` method.""" - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( list(SpectralShape(0, 10, 0.1)), np.arange(0, 10 + 0.1, 0.1), ) @@ -1452,6 +1466,16 @@ def test_required_methods(self): for method in required_methods: self.assertIn(method, dir(SpectralDistribution)) + def test_pickling(self): + """ + Test whether the :class:`colour.colorimetry.spectrum.\ +SpectralDistribution` class can be pickled. + """ + + data = pickle.dumps(self._sd) + data = pickle.loads(data) # noqa: S301 + self.assertEqual(self._sd, data) + def test_display_name(self): """ Test :attr:`colour.colorimetry.spectrum.SpectralDistribution.display_name` @@ -1501,12 +1525,13 @@ def test__init__(self): method. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( SpectralDistribution(DATA_SAMPLE).wavelengths, SpectralDistribution( DATA_SAMPLE.values(), SpectralShape(340, 820, 20), ).wavelengths, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_interpolate(self): @@ -1517,10 +1542,8 @@ def test_interpolate(self): shape = SpectralShape(self._sd.shape.start, self._sd.shape.end, 1) sd = reshape_sd(self._sd, shape, "Interpolate") - np.testing.assert_array_almost_equal( - sd.values, - DATA_SAMPLE_INTERPOLATED, - decimal=7, + np.testing.assert_allclose( + sd.values, DATA_SAMPLE_INTERPOLATED, atol=TOLERANCE_ABSOLUTE_TESTS ) self.assertEqual(sd.shape, shape) @@ -1533,8 +1556,7 @@ def test_interpolate(self): np.testing.assert_allclose( sd.values, DATA_SAMPLE_INTERPOLATED_NON_UNIFORM, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual( sd.shape, @@ -1555,8 +1577,8 @@ def test_extrapolate(self): sd = SpectralDistribution(data) sd.extrapolate(SpectralShape(10, 50, 5)) - self.assertAlmostEqual(sd[10], 0, places=7) - self.assertAlmostEqual(sd[50], 1, places=7) + np.testing.assert_allclose(sd[10], 0, atol=TOLERANCE_ABSOLUTE_TESTS) + np.testing.assert_allclose(sd[50], 1, atol=TOLERANCE_ABSOLUTE_TESTS) sd = SpectralDistribution( np.linspace(0, 1, 10), np.linspace(25, 35, 10) @@ -1571,8 +1593,12 @@ def test_extrapolate(self): }, ) - self.assertAlmostEqual(sd[10], -1.5000000000000004, places=7) - self.assertAlmostEqual(sd[50], 2.4999999999999964, places=7) + np.testing.assert_allclose( + sd[10], -1.5000000000000004, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + sd[50], 2.4999999999999964, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_align(self): """ @@ -1604,8 +1630,10 @@ def test_normalise(self): SpectralDistribution.normalise` method. """ - np.testing.assert_array_almost_equal( - self._sd.copy().normalise(100).values, DATA_SAMPLE_NORMALISED + np.testing.assert_allclose( + self._sd.copy().normalise(100).values, + DATA_SAMPLE_NORMALISED, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_callback_on_domain_changed(self): @@ -1696,6 +1724,16 @@ def test_required_methods(self): for method in required_methods: self.assertIn(method, dir(MultiSpectralDistributions)) + def test_pickling(self): + """ + Test whether the :class:`colour.colorimetry.spectrum.\ +MultiSpectralDistributions` class can be pickled. + """ + + data = pickle.dumps(self._msds) + data = pickle.loads(data) # noqa: S301 + self.assertEqual(self._msds, data) + def test_display_name(self): """ Test :attr:`colour.colorimetry.spectrum.MultiSpectralDistributions.display_name` @@ -1762,12 +1800,13 @@ def test__init__(self): MultiSpectralDistributions.__init__` method. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( MultiSpectralDistributions(DATA_CMFS).wavelengths, MultiSpectralDistributions( DATA_CMFS.values(), SpectralShape(380, 780, 5), ).wavelengths, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_interpolate(self): @@ -1781,8 +1820,10 @@ def test_interpolate(self): ) msds = reshape_msds(self._sample_msds, shape, "Interpolate") for signal in msds.signals.values(): - np.testing.assert_array_almost_equal( - signal.values, DATA_SAMPLE_INTERPOLATED, decimal=7 + np.testing.assert_allclose( + signal.values, + DATA_SAMPLE_INTERPOLATED, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(msds.shape, shape) @@ -1800,8 +1841,7 @@ def test_interpolate(self): np.testing.assert_allclose( signal.values, DATA_SAMPLE_INTERPOLATED_NON_UNIFORM, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual( msds.shape, @@ -1822,11 +1862,11 @@ def test_extrapolate(self): msds = MultiSpectralDistributions(data) msds.extrapolate(SpectralShape(10, 50, 5)) - np.testing.assert_array_almost_equal( - msds[10], np.array([0.0, 0.0, 0.0]), decimal=7 + np.testing.assert_allclose( + msds[10], np.array([0.0, 0.0, 0.0]), atol=TOLERANCE_ABSOLUTE_TESTS ) - np.testing.assert_array_almost_equal( - msds[50], np.array([1.0, 1.0, 1.0]), decimal=7 + np.testing.assert_allclose( + msds[50], np.array([1.0, 1.0, 1.0]), atol=TOLERANCE_ABSOLUTE_TESTS ) msds = MultiSpectralDistributions( @@ -1840,11 +1880,13 @@ def test_extrapolate(self): "right": None, }, ) - np.testing.assert_array_almost_equal( - msds[10], np.array([-1.5, -1.5, -1.5]), decimal=7 + np.testing.assert_allclose( + msds[10], + np.array([-1.5, -1.5, -1.5]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - msds[50], np.array([2.5, 2.5, 2.5]), decimal=7 + np.testing.assert_allclose( + msds[50], np.array([2.5, 2.5, 2.5]), atol=TOLERANCE_ABSOLUTE_TESTS ) def test_align(self): @@ -1879,9 +1921,10 @@ def test_normalise(self): MultiSpectralDistributions.normalise` method. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._sample_msds.copy().normalise(100).values, tstack([DATA_SAMPLE_NORMALISED] * 3), + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_to_sds(self): @@ -1966,9 +2009,10 @@ def test_reshape_sd(self): sd_reshaped = reshape_sd(sd, shape, method="Trim") self.assertEqual(sd_reshaped, sd.copy().trim(shape)) - self.assertIs( - reshape_sd(sd, shape, method="Trim", copy=False), sd_reshaped - ) + if is_caching_enabled(): + self.assertIs( + reshape_sd(sd, shape, method="Trim", copy=False), sd_reshaped + ) class TestSdsAndMdsToSds(unittest.TestCase): @@ -2037,15 +2081,15 @@ def test_sds_and_msds_to_msds(self): shape, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sds_and_msds_to_msds( [sd_1, sd_2, multi_sds_1, multi_sds_2] ).wavelengths, shape.wavelengths, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sds_and_msds_to_msds( [sd_1, sd_2, multi_sds_1, multi_sds_2] ).values, @@ -2060,7 +2104,7 @@ def test_sds_and_msds_to_msds(self): for sd in sds_and_msds_to_sds(multi_sds_2.align(shape)) ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_transformations.py b/colour/colorimetry/tests/test_transformations.py index 2767ffd3d1..29b88ea0c3 100644 --- a/colour/colorimetry/tests/test_transformations.py +++ b/colour/colorimetry/tests/test_transformations.py @@ -3,17 +3,19 @@ module. """ -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( MSDS_CMFS, - RGB_10_degree_cmfs_to_LMS_10_degree_cmfs, - RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs, - RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs, LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs, LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs, + RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs, + RGB_10_degree_cmfs_to_LMS_10_degree_cmfs, + RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -69,20 +71,26 @@ def test_n_dimensional_RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(self): wl = np.tile(wl, 6) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) XYZ = np.reshape(XYZ, (2, 3, 1, 3)) - np.testing.assert_array_almost_equal( - RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + RGB_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -140,20 +148,26 @@ def test_n_dimensional_RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(self): wl = np.tile(wl, 6) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) XYZ = np.reshape(XYZ, (2, 3, 1, 3)) - np.testing.assert_array_almost_equal( - RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + RGB_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -211,20 +225,26 @@ def test_n_dimensional_RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(self): wl = np.tile(wl, 6) LMS = np.tile(LMS, (6, 1)) - np.testing.assert_array_almost_equal( - RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wl), LMS + np.testing.assert_allclose( + RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wl), + LMS, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) LMS = np.reshape(LMS, (2, 3, 3)) - np.testing.assert_array_almost_equal( - RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wl), LMS + np.testing.assert_allclose( + RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wl), + LMS, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) LMS = np.reshape(LMS, (2, 3, 1, 3)) - np.testing.assert_array_almost_equal( - RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wl), LMS + np.testing.assert_allclose( + RGB_10_degree_cmfs_to_LMS_10_degree_cmfs(wl), + LMS, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -282,20 +302,26 @@ def test_n_dimensional_LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(self): wl = np.tile(wl, 6) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) XYZ = np.reshape(XYZ, (2, 3, 1, 3)) - np.testing.assert_array_almost_equal( - LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + LMS_2_degree_cmfs_to_XYZ_2_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -353,20 +379,26 @@ def test_n_dimensional_LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(self): wl = np.tile(wl, 6) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) XYZ = np.reshape(XYZ, (2, 3, 1, 3)) - np.testing.assert_array_almost_equal( - LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), XYZ + np.testing.assert_allclose( + LMS_10_degree_cmfs_to_XYZ_10_degree_cmfs(wl), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/colorimetry/tests/test_tristimulus_values.py b/colour/colorimetry/tests/test_tristimulus_values.py index 85b1370fc4..4533db9857 100644 --- a/colour/colorimetry/tests/test_tristimulus_values.py +++ b/colour/colorimetry/tests/test_tristimulus_values.py @@ -11,9 +11,10 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + from colour.algebra import LinearInterpolator, SpragueInterpolator from colour.colorimetry import ( MSDS_CMFS, @@ -21,26 +22,25 @@ MultiSpectralDistributions, SpectralDistribution, SpectralShape, + adjust_tristimulus_weighting_factors_ASTME308, + handle_spectral_arguments, + lagrange_coefficients_ASTME2022, + msds_to_XYZ, + msds_to_XYZ_ASTME308, + msds_to_XYZ_integration, reshape_msds, reshape_sd, sd_CIE_standard_illuminant_A, sd_ones, - msds_to_XYZ, - sd_zeros, -) -from colour.colorimetry import ( - handle_spectral_arguments, - lagrange_coefficients_ASTME2022, - tristimulus_weighting_factors_ASTME2022, - adjust_tristimulus_weighting_factors_ASTME308, + sd_to_XYZ, + sd_to_XYZ_ASTME308, sd_to_XYZ_integration, sd_to_XYZ_tristimulus_weighting_factors_ASTME308, - sd_to_XYZ_ASTME308, - sd_to_XYZ, - msds_to_XYZ_integration, - msds_to_XYZ_ASTME308, + sd_zeros, + tristimulus_weighting_factors_ASTME2022, wavelength_to_XYZ, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import NDArrayFloat from colour.utilities import domain_range_scale @@ -629,31 +629,33 @@ def test_lagrange_coefficients_ASTME2022(self): lagrange_coefficients_ASTME2022` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lagrange_coefficients_ASTME2022(10, "inner"), LAGRANGE_COEFFICIENTS_A, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lagrange_coefficients_ASTME2022(10, "boundary"), LAGRANGE_COEFFICIENTS_B, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) # Testing that the cache returns a copy of the data. lagrange_coefficients = lagrange_coefficients_ASTME2022(10) - np.testing.assert_array_almost_equal( - lagrange_coefficients, LAGRANGE_COEFFICIENTS_A, decimal=7 + np.testing.assert_allclose( + lagrange_coefficients, + LAGRANGE_COEFFICIENTS_A, + atol=TOLERANCE_ABSOLUTE_TESTS, ) lagrange_coefficients *= 10 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( lagrange_coefficients_ASTME2022(10), LAGRANGE_COEFFICIENTS_A, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -685,15 +687,15 @@ def test_tristimulus_weighting_factors_ASTME2022(self): twf = tristimulus_weighting_factors_ASTME2022( cmfs, A, SpectralShape(360, 830, 10) ) - np.testing.assert_array_almost_equal( - np.round(twf, 3), TWF_A_CIE_1964_10_10, decimal=3 + np.testing.assert_allclose( + np.round(twf, 3), TWF_A_CIE_1964_10_10, atol=1e-5 ) twf = tristimulus_weighting_factors_ASTME2022( cmfs, A, SpectralShape(360, 830, 20) ) - np.testing.assert_array_almost_equal( - np.round(twf, 3), TWF_A_CIE_1964_10_20, decimal=3 + np.testing.assert_allclose( + np.round(twf, 3), TWF_A_CIE_1964_10_20, atol=1e-5 ) cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] @@ -703,15 +705,17 @@ def test_tristimulus_weighting_factors_ASTME2022(self): twf = tristimulus_weighting_factors_ASTME2022( cmfs, D65, SpectralShape(360, 830, 20) ) - np.testing.assert_array_almost_equal( - np.round(twf, 3), TWF_D65_CIE_1931_2_20, decimal=3 + np.testing.assert_allclose( + np.round(twf, 3), + TWF_D65_CIE_1931_2_20, + atol=TOLERANCE_ABSOLUTE_TESTS, ) twf = tristimulus_weighting_factors_ASTME2022( cmfs, D65, SpectralShape(360, 830, 20), k=1 ) - np.testing.assert_array_almost_equal( - twf, TWF_D65_CIE_1931_2_20_K1, decimal=7 + np.testing.assert_allclose( + twf, TWF_D65_CIE_1931_2_20_K1, atol=TOLERANCE_ABSOLUTE_TESTS ) # Testing that the cache returns a copy of the data. @@ -719,11 +723,13 @@ def test_tristimulus_weighting_factors_ASTME2022(self): twf = tristimulus_weighting_factors_ASTME2022( cmfs, A, SpectralShape(360, 830, 10) ) - np.testing.assert_array_almost_equal( - np.round(twf, 3), TWF_A_CIE_1964_10_10, decimal=3 + np.testing.assert_allclose( + np.round(twf, 3), + TWF_A_CIE_1964_10_10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.round( tristimulus_weighting_factors_ASTME2022( cmfs, A, SpectralShape(360, 830, 10) @@ -731,7 +737,7 @@ def test_tristimulus_weighting_factors_ASTME2022(self): 3, ), TWF_A_CIE_1964_10_10, - decimal=3, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_tristimulus_weighting_factors_ASTME2022(self): @@ -775,14 +781,14 @@ def test_adjust_tristimulus_weighting_factors_ASTME308(self): adjust_tristimulus_weighting_factors_ASTME308` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( adjust_tristimulus_weighting_factors_ASTME308( TWF_D65_CIE_1931_2_20, SpectralShape(360, 830, 20), SpectralShape(400, 700, 20), ), TWF_D65_CIE_1931_2_20_A, - decimal=3, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -799,13 +805,13 @@ def test_sd_to_XYZ_integration(self): """ cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration(SD_SAMPLE, cmfs, SDS_ILLUMINANTS["A"]), np.array([14.46341147, 10.85819624, 2.04695585]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( SD_SAMPLE.values, cmfs, @@ -813,28 +819,28 @@ def test_sd_to_XYZ_integration(self): shape=SD_SAMPLE.shape, ), np.array([14.46365947, 10.85828084, 2.04663993]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) cmfs = MSDS_CMFS["CIE 1964 10 Degree Standard Observer"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration(SD_SAMPLE, cmfs, SDS_ILLUMINANTS["C"]), np.array([10.77002699, 9.44876636, 6.62415290]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration(SD_SAMPLE, cmfs, SDS_ILLUMINANTS["FL2"]), np.array([11.57540576, 9.98608874, 3.95242590]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( SD_SAMPLE, cmfs, SDS_ILLUMINANTS["FL2"], k=683 ), np.array([1223.7509261493, 1055.7284645912, 417.8501342332]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_sd_to_XYZ_integration(self): @@ -849,12 +855,12 @@ def test_domain_range_scale_sd_to_XYZ_integration(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( SD_SAMPLE, cmfs, SDS_ILLUMINANTS["A"] ), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -873,42 +879,42 @@ def test_sd_to_XYZ_tristimulus_weighting_factors_ASTME308(self): """ cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( SD_SAMPLE, cmfs, SDS_ILLUMINANTS["A"] ), np.array([14.46341867, 10.85820227, 2.04697034]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) cmfs = MSDS_CMFS["CIE 1964 10 Degree Standard Observer"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( SD_SAMPLE, cmfs, SDS_ILLUMINANTS["C"] ), np.array([10.77005571, 9.44877491, 6.62428210]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( SD_SAMPLE, cmfs, SDS_ILLUMINANTS["FL2"] ), np.array([11.57542759, 9.98605604, 3.95273304]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( reshape_sd(SD_SAMPLE, SpectralShape(400, 700, 5), "Trim"), cmfs, SDS_ILLUMINANTS["A"], ), np.array([14.38153638, 10.74503131, 2.01613844]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( reshape_sd( SD_SAMPLE, SpectralShape(400, 700, 10), "Interpolate" @@ -917,10 +923,10 @@ def test_sd_to_XYZ_tristimulus_weighting_factors_ASTME308(self): SDS_ILLUMINANTS["A"], ), np.array([14.38257202, 10.74568178, 2.01588427]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( reshape_sd( SD_SAMPLE, SpectralShape(400, 700, 20), "Interpolate" @@ -929,10 +935,10 @@ def test_sd_to_XYZ_tristimulus_weighting_factors_ASTME308(self): SDS_ILLUMINANTS["A"], ), np.array([14.38329645, 10.74603515, 2.01561113]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( reshape_sd( SD_SAMPLE, SpectralShape(400, 700, 20), "Interpolate" @@ -942,7 +948,7 @@ def test_sd_to_XYZ_tristimulus_weighting_factors_ASTME308(self): k=1, ), np.array([1636.74881983, 1222.84626486, 229.36669308]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_sd_to_XYZ_twf_ASTME308(self): @@ -960,12 +966,12 @@ def test_domain_range_scale_sd_to_XYZ_twf_ASTME308(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_tristimulus_weighting_factors_ASTME308( SD_SAMPLE, cmfs, SDS_ILLUMINANTS["A"] ), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -988,15 +994,15 @@ def test_sd_to_XYZ_ASTME308_mi_1nm(self): definition for 1 nm measurement intervals. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, self._cmfs.shape), self._cmfs, self._A ), np.array([14.46372680, 10.85832950, 2.04663200]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, self._cmfs.shape), self._cmfs, @@ -1004,20 +1010,20 @@ def test_sd_to_XYZ_ASTME308_mi_1nm(self): use_practice_range=False, ), np.array([14.46366018, 10.85827949, 2.04662258]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 1)), self._cmfs, self._A, ), np.array([14.54173397, 10.88628632, 2.04965822]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 1)), self._cmfs, @@ -1025,10 +1031,10 @@ def test_sd_to_XYZ_ASTME308_mi_1nm(self): use_practice_range=False, ), np.array([14.54203076, 10.88636754, 2.04964877]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 1)), self._cmfs, @@ -1036,7 +1042,7 @@ def test_sd_to_XYZ_ASTME308_mi_1nm(self): k=1, ), np.array([15.6898152997, 11.7457671769, 2.2114803420]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_sd_to_XYZ_ASTME308_mi_5nm(self): @@ -1045,17 +1051,17 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): definition for 5 nm measurement intervals. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 830, 5)), self._cmfs, self._A, ), np.array([14.46372173, 10.85832502, 2.04664734]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 830, 5)), self._cmfs, @@ -1063,10 +1069,10 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): use_practice_range=False, ), np.array([14.46366388, 10.85828159, 2.04663915]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 830, 5)), self._cmfs, @@ -1074,20 +1080,20 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): mi_5nm_omission_method=False, ), np.array([14.46373399, 10.85833553, 2.0466465]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 5)), self._cmfs, self._A, ), np.array([14.54025742, 10.88576251, 2.04950226]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 5)), self._cmfs, @@ -1095,10 +1101,10 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): use_practice_range=False, ), np.array([14.54051517, 10.88583304, 2.04949406]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 5)), self._cmfs, @@ -1106,10 +1112,10 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): mi_5nm_omission_method=False, ), np.array([14.54022093, 10.88575468, 2.04951057]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 830, 5)), self._cmfs, @@ -1118,10 +1124,10 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): mi_5nm_omission_method=False, ), np.array([14.46366737, 10.85828552, 2.04663707]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 5)), self._cmfs, @@ -1130,10 +1136,10 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): mi_5nm_omission_method=False, ), np.array([14.54051772, 10.88583590, 2.04950113]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 5)), self._cmfs, @@ -1141,7 +1147,7 @@ def test_sd_to_XYZ_ASTME308_mi_5nm(self): k=1, ), np.array([15.6882479013, 11.7452212708, 2.2113156963]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_sd_to_XYZ_ASTME308_mi_10nm(self): @@ -1150,17 +1156,17 @@ def test_sd_to_XYZ_ASTME308_mi_10nm(self): definition for 10 nm measurement intervals. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 830, 10)), self._cmfs, self._A, ), np.array([14.47779980, 10.86358645, 2.04751388]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 830, 10)), self._cmfs, @@ -1168,20 +1174,20 @@ def test_sd_to_XYZ_ASTME308_mi_10nm(self): use_practice_range=False, ), np.array([14.47773312, 10.86353641, 2.04750445]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 10)), self._cmfs, self._A, ), np.array([14.54137532, 10.88641727, 2.04931318]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 10)), self._cmfs, @@ -1189,10 +1195,10 @@ def test_sd_to_XYZ_ASTME308_mi_10nm(self): use_practice_range=False, ), np.array([14.54167211, 10.88649849, 2.04930374]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 10)), self._cmfs, @@ -1200,10 +1206,10 @@ def test_sd_to_XYZ_ASTME308_mi_10nm(self): k=1, ), np.array([15.6894283333, 11.7459084705, 2.2111080639]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(401, 701, 10)), self._cmfs, @@ -1211,7 +1217,7 @@ def test_sd_to_XYZ_ASTME308_mi_10nm(self): k=1, ), np.array([15.6713226093, 11.7392254489, 2.2117708792]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_sd_to_XYZ_ASTME308_mi_20nm(self): @@ -1220,17 +1226,17 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): definition for 20 nm measurement intervals. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 820, 20)), self._cmfs, self._A, ), np.array([14.50187464, 10.87217124, 2.04918305]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 820, 20)), self._cmfs, @@ -1238,10 +1244,10 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): use_practice_range=False, ), np.array([14.50180785, 10.87212116, 2.04917361]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 820, 20)), self._cmfs, @@ -1249,20 +1255,20 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): mi_20nm_interpolation_method=False, ), np.array([14.50216194, 10.87236873, 2.04977256]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 20)), self._cmfs, self._A, ), np.array([14.54114025, 10.88634755, 2.04916445]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 20)), self._cmfs, @@ -1270,10 +1276,10 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): use_practice_range=False, ), np.array([14.54143704, 10.88642877, 2.04915501]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 20)), self._cmfs, @@ -1281,10 +1287,10 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): mi_20nm_interpolation_method=False, ), np.array([14.54242562, 10.88694088, 2.04919645]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(360, 820, 20)), self._cmfs, @@ -1293,10 +1299,10 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): mi_20nm_interpolation_method=False, ), np.array([14.50209515, 10.87231865, 2.04976312]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 20)), self._cmfs, @@ -1305,10 +1311,10 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): mi_20nm_interpolation_method=False, ), np.array([14.54272240, 10.88702210, 2.04918701]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(400, 700, 20)), self._cmfs, @@ -1316,17 +1322,17 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self): k=1, ), np.array([15.6891747040, 11.7458332427, 2.2109475945]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_ASTME308( reshape_sd(self._sd, SpectralShape(401, 701, 20)), self._cmfs, self._A, ), np.array([14.5220164311, 10.8790959535, 2.0490905325]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_sd_to_XYZ_ASTME308(self): @@ -1364,16 +1370,18 @@ def test_sd_to_XYZ(self): # Testing that the cache returns a copy of the data. XYZ = sd_to_XYZ(self._sd, self._cmfs, self._A) - np.testing.assert_array_almost_equal( - XYZ, np.array([14.46372680, 10.85832950, 2.04663200]), decimal=7 + np.testing.assert_allclose( + XYZ, + np.array([14.46372680, 10.85832950, 2.04663200]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ *= 10 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ(self._sd, self._cmfs, self._A), np.array([14.46372680, 10.85832950, 2.04663200]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1390,13 +1398,13 @@ def test_msds_to_XYZ_integration(self): """ cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_to_XYZ_integration(MSDS_TWO, cmfs, SDS_ILLUMINANTS["D65"]), TVS_D65_INTEGRATION_MSDS, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_to_XYZ_integration( DATA_TWO, cmfs, @@ -1404,10 +1412,10 @@ def test_msds_to_XYZ_integration(self): shape=SpectralShape(400, 700, 60), ), TVS_D65_ARRAY_INTEGRATION, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_to_XYZ_integration( DATA_TWO, cmfs, @@ -1416,7 +1424,7 @@ def test_msds_to_XYZ_integration(self): shape=SpectralShape(400, 700, 60), ), TVS_D65_ARRAY_K1_INTEGRATION, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_msds_to_XYZ_integration(self): @@ -1429,7 +1437,7 @@ def test_domain_range_scale_msds_to_XYZ_integration(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_to_XYZ_integration( DATA_TWO, cmfs, @@ -1437,7 +1445,7 @@ def test_domain_range_scale_msds_to_XYZ_integration(self): shape=SpectralShape(400, 700, 60), ), TVS_D65_ARRAY_INTEGRATION * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1455,16 +1463,16 @@ def test_msds_to_XYZ_ASTME308(self): cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] msds = reshape_msds(MSDS_TWO, SpectralShape(400, 700, 20)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_to_XYZ_ASTME308(msds, cmfs, SDS_ILLUMINANTS["D65"]), TVS_D65_ASTME308_MSDS, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_to_XYZ_ASTME308(msds, cmfs, SDS_ILLUMINANTS["D65"], k=1), TVS_D65_ASTME308_K1_MSDS, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_msds_to_XYZ_ASTME308(self): @@ -1477,14 +1485,14 @@ def test_domain_range_scale_msds_to_XYZ_ASTME308(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( msds_to_XYZ_ASTME308( reshape_msds(MSDS_TWO, SpectralShape(400, 700, 20)), cmfs, SDS_ILLUMINANTS["D65"], ), TVS_D65_ASTME308_MSDS * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_msds_to_XYZ_ASTME308(self): @@ -1525,7 +1533,7 @@ def test_absolute_integration_to_TVS_1nm(self): for method in methods[0:3]: XYZ = method(sd, k=k) XYZ = XYZ.reshape(3) if len(XYZ.shape) > 1 else XYZ - self.assertAlmostEqual(XYZ[1], k, delta=5e-5), ( + np.testing.assert_allclose(XYZ[1], k, atol=5e-5), ( "1 watt @ 555nm should be approximately 683 candela." f" Failed method: {method}" ) @@ -1536,7 +1544,7 @@ def test_absolute_integration_to_TVS_1nm(self): XYZ: np.ndarray = method(msds, k=k) if len(XYZ.shape) > 1: XYZ = XYZ.reshape(3) - self.assertAlmostEqual(XYZ[1], k, delta=5e-5), ( + np.testing.assert_allclose(XYZ[1], k, atol=5e-5), ( "1 watt @ 555nm should be approximately 683 candela." f" Failed method: {method}" ) @@ -1570,7 +1578,7 @@ def test_absolute_integration_to_TVS_5nm(self): for method in methods[0:3]: XYZ: np.ndarray = method(sd, k=k) XYZ = XYZ.reshape(3) if len(XYZ.shape) > 1 else XYZ - self.assertAlmostEqual(XYZ[1], k, delta=5e-2), ( + np.testing.assert_allclose(XYZ[1], k, atol=5e-2), ( "1 watt @ 555nm should be approximately 683 candela. " f"Failed method: {method}" ) @@ -1581,7 +1589,7 @@ def test_absolute_integration_to_TVS_5nm(self): XYZ: np.ndarray = method(msds, k=k) if len(XYZ.shape) > 1: XYZ = XYZ.reshape(3) - self.assertAlmostEqual(XYZ[1], k, delta=5e-2), ( + np.testing.assert_allclose(XYZ[1], k, atol=5e-2), ( "1 watt @ 555nm should be approximately 683 candela." f"Failed method: {method}" ) @@ -1599,28 +1607,28 @@ def test_wavelength_to_XYZ(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( wavelength_to_XYZ( 480, MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] ), np.array([0.09564, 0.13902, 0.81295]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( wavelength_to_XYZ( 480, MSDS_CMFS["CIE 2015 2 Degree Standard Observer"] ), np.array([0.08182895, 0.17880480, 0.75523790]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( wavelength_to_XYZ( 641.5, MSDS_CMFS["CIE 2015 2 Degree Standard Observer"] ), np.array([0.44575583, 0.18184213, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_wavelength_to_XYZ(self): @@ -1645,20 +1653,20 @@ def test_n_dimensional_wavelength_to_XYZ(self): wl = np.tile(wl, 6) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - wavelength_to_XYZ(wl, cmfs), XYZ, decimal=7 + np.testing.assert_allclose( + wavelength_to_XYZ(wl, cmfs), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - wavelength_to_XYZ(wl, cmfs), XYZ, decimal=7 + np.testing.assert_allclose( + wavelength_to_XYZ(wl, cmfs), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3, 1)) XYZ = np.reshape(XYZ, (2, 3, 1, 3)) - np.testing.assert_array_almost_equal( - wavelength_to_XYZ(wl, cmfs), XYZ, decimal=7 + np.testing.assert_allclose( + wavelength_to_XYZ(wl, cmfs), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) diff --git a/colour/colorimetry/tests/test_uniformity.py b/colour/colorimetry/tests/test_uniformity.py index 0cc486942a..46958a2498 100644 --- a/colour/colorimetry/tests/test_uniformity.py +++ b/colour/colorimetry/tests/test_uniformity.py @@ -3,10 +3,12 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + from colour.colorimetry import spectral_uniformity +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import NDArrayFloat __author__ = "Colour Developers" @@ -236,18 +238,18 @@ def test_spectral_uniformity(self): from colour.quality.datasets import SDS_TCS - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( spectral_uniformity(SDS_TCS.values()), DATA_UNIFORMITY_FIRST_ORDER_DERIVATIVES, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( spectral_uniformity( SDS_TCS.values(), use_second_order_derivatives=True ), DATA_UNIFORMITY_SECOND_ORDER_DERIVATIVES, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_whiteness.py b/colour/colorimetry/tests/test_whiteness.py index b2ea8bc251..f71fe15051 100644 --- a/colour/colorimetry/tests/test_whiteness.py +++ b/colour/colorimetry/tests/test_whiteness.py @@ -1,19 +1,21 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.whiteness` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.colorimetry import ( - whiteness_Berger1959, - whiteness_Taube1960, - whiteness_Stensby1968, whiteness_ASTME313, - whiteness_Ganz1979, + whiteness_Berger1959, whiteness_CIE2004, + whiteness_Ganz1979, + whiteness_Stensby1968, + whiteness_Taube1960, ) from colour.colorimetry.whiteness import whiteness +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -46,31 +48,31 @@ def test_whiteness_Berger1959(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Berger1959( np.array([95.00000000, 100.00000000, 105.00000000]), np.array([94.80966767, 100.00000000, 107.30513595]), ), 30.36380179, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Berger1959( np.array([105.00000000, 100.00000000, 95.00000000]), np.array([94.80966767, 100.00000000, 107.30513595]), ), 5.530469280673941, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Berger1959( np.array([100.00000000, 100.00000000, 100.00000000]), np.array([100.00000000, 100.00000000, 100.00000000]), ), 33.300000000000011, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_whiteness_Berger1959(self): @@ -86,15 +88,15 @@ def test_n_dimensional_whiteness_Berger1959(self): XYZ = np.tile(XYZ, (6, 1)) XYZ_0 = np.tile(XYZ_0, (6, 1)) W = np.tile(W, 6) - np.testing.assert_array_almost_equal( - whiteness_Berger1959(XYZ, XYZ_0), W, decimal=7 + np.testing.assert_allclose( + whiteness_Berger1959(XYZ, XYZ_0), W, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_0 = np.reshape(XYZ_0, (2, 3, 3)) W = np.reshape(W, (2, 3)) - np.testing.assert_array_almost_equal( - whiteness_Berger1959(XYZ, XYZ_0), W, decimal=7 + np.testing.assert_allclose( + whiteness_Berger1959(XYZ, XYZ_0), W, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_whiteness_Berger1959(self): @@ -110,10 +112,10 @@ def test_domain_range_scale_whiteness_Berger1959(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_Berger1959(XYZ * factor, XYZ_0 * factor), W * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -140,31 +142,31 @@ def test_whiteness_Taube1960(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Taube1960( np.array([95.00000000, 100.00000000, 105.00000000]), np.array([94.80966767, 100.00000000, 107.30513595]), ), 91.407173833416152, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Taube1960( np.array([105.00000000, 100.00000000, 95.00000000]), np.array([94.80966767, 100.00000000, 107.30513595]), ), 54.130300134995593, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Taube1960( np.array([100.00000000, 100.00000000, 100.00000000]), np.array([100.00000000, 100.00000000, 100.00000000]), ), 100.0, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_whiteness_Taube1960(self): @@ -180,15 +182,15 @@ def test_n_dimensional_whiteness_Taube1960(self): XYZ = np.tile(XYZ, (6, 1)) XYZ_0 = np.tile(XYZ_0, (6, 1)) WI = np.tile(WI, 6) - np.testing.assert_array_almost_equal( - whiteness_Taube1960(XYZ, XYZ_0), WI, decimal=7 + np.testing.assert_allclose( + whiteness_Taube1960(XYZ, XYZ_0), WI, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_0 = np.reshape(XYZ_0, (2, 3, 3)) WI = np.reshape(WI, (2, 3)) - np.testing.assert_array_almost_equal( - whiteness_Taube1960(XYZ, XYZ_0), WI, decimal=7 + np.testing.assert_allclose( + whiteness_Taube1960(XYZ, XYZ_0), WI, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_whiteness_Taube1960(self): @@ -204,10 +206,10 @@ def test_domain_range_scale_whiteness_Taube1960(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_Taube1960(XYZ * factor, XYZ_0 * factor), WI * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -234,24 +236,26 @@ def test_whiteness_Stensby1968(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Stensby1968( np.array([100.00000000, -2.46875131, -16.72486654]) ), 142.76834569, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_Stensby1968( np.array([100.00000000, 14.40943727, -9.61394885]) ), 172.07015836, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - whiteness_Stensby1968(np.array([1, 1, 1])), 1.00000000, places=7 + np.testing.assert_allclose( + whiteness_Stensby1968(np.array([1, 1, 1])), + 1.00000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_whiteness_Stensby1968(self): @@ -265,14 +269,14 @@ def test_n_dimensional_whiteness_Stensby1968(self): Lab = np.tile(Lab, (6, 1)) WI = np.tile(WI, 6) - np.testing.assert_array_almost_equal( - whiteness_Stensby1968(Lab), WI, decimal=7 + np.testing.assert_allclose( + whiteness_Stensby1968(Lab), WI, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab = np.reshape(Lab, (2, 3, 3)) WI = np.reshape(WI, (2, 3)) - np.testing.assert_array_almost_equal( - whiteness_Stensby1968(Lab), WI, decimal=7 + np.testing.assert_allclose( + whiteness_Stensby1968(Lab), WI, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_whiteness_Stensby1968(self): @@ -287,8 +291,10 @@ def test_domain_range_scale_whiteness_Stensby1968(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - whiteness_Stensby1968(Lab * factor), WI * factor, decimal=7 + np.testing.assert_allclose( + whiteness_Stensby1968(Lab * factor), + WI * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -315,28 +321,28 @@ def test_whiteness_ASTME313(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_ASTME313( np.array([95.00000000, 100.00000000, 105.00000000]) ), 55.740000000000009, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_ASTME313( np.array([105.00000000, 100.00000000, 95.00000000]) ), 21.860000000000014, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( whiteness_ASTME313( np.array([100.00000000, 100.00000000, 100.00000000]) ), 38.800000000000011, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_whiteness_ASTME313(self): @@ -350,14 +356,14 @@ def test_n_dimensional_whiteness_ASTME313(self): XYZ = np.tile(XYZ, (6, 1)) WI = np.tile(WI, 6) - np.testing.assert_array_almost_equal( - whiteness_ASTME313(XYZ), WI, decimal=7 + np.testing.assert_allclose( + whiteness_ASTME313(XYZ), WI, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) WI = np.reshape(WI, (2, 3)) - np.testing.assert_array_almost_equal( - whiteness_ASTME313(XYZ), WI, decimal=7 + np.testing.assert_allclose( + whiteness_ASTME313(XYZ), WI, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_whiteness_ASTME313(self): @@ -372,8 +378,10 @@ def test_domain_range_scale_whiteness_ASTME313(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - whiteness_ASTME313(XYZ * factor), WI * factor, decimal=7 + np.testing.assert_allclose( + whiteness_ASTME313(XYZ * factor), + WI * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -400,22 +408,22 @@ def test_whiteness_Ganz1979(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_Ganz1979(np.array([0.3139, 0.3311]), 100), np.array([99.33176520, 1.76108290]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_Ganz1979(np.array([0.3500, 0.3334]), 100), np.array([23.38525400, -32.66182560]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_Ganz1979(np.array([0.3334, 0.3334]), 100), np.array([54.39939920, -16.04152380]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_whiteness_Ganz1979(self): @@ -430,20 +438,20 @@ def test_n_dimensional_whiteness_Ganz1979(self): xy = np.tile(xy, (6, 1)) WT = np.tile(WT, (6, 1)) - np.testing.assert_array_almost_equal( - whiteness_Ganz1979(xy, Y), WT, decimal=7 + np.testing.assert_allclose( + whiteness_Ganz1979(xy, Y), WT, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - whiteness_Ganz1979(xy, Y), WT, decimal=7 + np.testing.assert_allclose( + whiteness_Ganz1979(xy, Y), WT, atol=TOLERANCE_ABSOLUTE_TESTS ) xy = np.reshape(xy, (2, 3, 2)) Y = np.reshape(Y, (2, 3)) WT = np.reshape(WT, (2, 3, 2)) - np.testing.assert_array_almost_equal( - whiteness_Ganz1979(xy, Y), WT, decimal=7 + np.testing.assert_allclose( + whiteness_Ganz1979(xy, Y), WT, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_whiteness_Ganz1979(self): @@ -459,8 +467,10 @@ def test_domain_range_scale_whiteness_Ganz1979(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - whiteness_Ganz1979(xy, Y * factor), WT * factor, decimal=7 + np.testing.assert_allclose( + whiteness_Ganz1979(xy, Y * factor), + WT * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -487,28 +497,28 @@ def test_whiteness_CIE2004(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_CIE2004( np.array([0.3139, 0.3311]), 100, np.array([0.3139, 0.3311]) ), np.array([100.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_CIE2004( np.array([0.3500, 0.3334]), 100, np.array([0.3139, 0.3311]) ), np.array([67.21000000, -34.60500000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_CIE2004( np.array([0.3334, 0.3334]), 100, np.array([0.3139, 0.3311]) ), np.array([80.49000000, -18.00500000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_whiteness_CIE2004(self): @@ -524,22 +534,22 @@ def test_n_dimensional_whiteness_CIE2004(self): xy = np.tile(xy, (6, 1)) WT = np.tile(WT, (6, 1)) - np.testing.assert_array_almost_equal( - whiteness_CIE2004(xy, Y, xy_n), WT, decimal=7 + np.testing.assert_allclose( + whiteness_CIE2004(xy, Y, xy_n), WT, atol=TOLERANCE_ABSOLUTE_TESTS ) Y = np.tile(Y, 6) xy_n = np.tile(xy_n, (6, 1)) - np.testing.assert_array_almost_equal( - whiteness_CIE2004(xy, Y, xy_n), WT, decimal=7 + np.testing.assert_allclose( + whiteness_CIE2004(xy, Y, xy_n), WT, atol=TOLERANCE_ABSOLUTE_TESTS ) xy = np.reshape(xy, (2, 3, 2)) Y = np.reshape(Y, (2, 3)) xy_n = np.reshape(xy_n, (2, 3, 2)) WT = np.reshape(WT, (2, 3, 2)) - np.testing.assert_array_almost_equal( - whiteness_CIE2004(xy, Y, xy_n), WT, decimal=7 + np.testing.assert_allclose( + whiteness_CIE2004(xy, Y, xy_n), WT, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_whiteness_CIE2004(self): @@ -556,10 +566,10 @@ def test_domain_range_scale_whiteness_CIE2004(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness_CIE2004(xy, Y * factor, xy_n), WT * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -603,10 +613,10 @@ def test_domain_range_scale_whiteness(self): for method, value in zip(m, v): for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( whiteness(XYZ * factor, XYZ_0 * factor, method), value * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tests/test_yellowness.py b/colour/colorimetry/tests/test_yellowness.py index 44fddad034..ea1423f24d 100644 --- a/colour/colorimetry/tests/test_yellowness.py +++ b/colour/colorimetry/tests/test_yellowness.py @@ -1,17 +1,21 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.colorimetry.yellowness` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.colorimetry import ( yellowness_ASTMD1925, - yellowness_ASTME313_alternative, yellowness_ASTME313, + yellowness_ASTME313_alternative, +) +from colour.colorimetry.yellowness import ( + YELLOWNESS_COEFFICIENTS_ASTME313, + yellowness, ) -from colour.colorimetry.yellowness import YELLOWNESS_COEFFICIENTS_ASTME313 -from colour.colorimetry.yellowness import yellowness +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -41,28 +45,28 @@ def test_yellowness_ASTMD1925(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTMD1925( np.array([95.00000000, 100.00000000, 105.00000000]) ), 10.299999999999997, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTMD1925( np.array([105.00000000, 100.00000000, 95.00000000]) ), 33.700000000000003, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTMD1925( np.array([100.00000000, 100.00000000, 100.00000000]) ), 22.0, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_yellowness_ASTMD1925(self): @@ -76,14 +80,14 @@ def test_n_dimensional_yellowness_ASTMD1925(self): XYZ = np.tile(XYZ, (6, 1)) YI = np.tile(YI, 6) - np.testing.assert_array_almost_equal( - yellowness_ASTMD1925(XYZ), YI, decimal=7 + np.testing.assert_allclose( + yellowness_ASTMD1925(XYZ), YI, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) YI = np.reshape(YI, (2, 3)) - np.testing.assert_array_almost_equal( - yellowness_ASTMD1925(XYZ), YI, decimal=7 + np.testing.assert_allclose( + yellowness_ASTMD1925(XYZ), YI, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_yellowness_ASTMD1925(self): @@ -98,8 +102,10 @@ def test_domain_range_scale_yellowness_ASTMD1925(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - yellowness_ASTMD1925(XYZ * factor), YI * factor, decimal=7 + np.testing.assert_allclose( + yellowness_ASTMD1925(XYZ * factor), + YI * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -126,28 +132,28 @@ def test_yellowness_ASTME313_alternative(self): yellowness_ASTME313_alternative` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTME313_alternative( np.array([95.00000000, 100.00000000, 105.00000000]) ), 11.065000000000003, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTME313_alternative( np.array([105.00000000, 100.00000000, 95.00000000]) ), 19.534999999999989, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTME313_alternative( np.array([100.00000000, 100.00000000, 100.00000000]) ), 15.300000000000002, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_yellowness_ASTME313_alternative(self): @@ -161,14 +167,18 @@ def test_n_dimensional_yellowness_ASTME313_alternative(self): XYZ = np.tile(XYZ, (6, 1)) YI = np.tile(YI, 6) - np.testing.assert_array_almost_equal( - yellowness_ASTME313_alternative(XYZ), YI, decimal=7 + np.testing.assert_allclose( + yellowness_ASTME313_alternative(XYZ), + YI, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) YI = np.reshape(YI, (2, 3)) - np.testing.assert_array_almost_equal( - yellowness_ASTME313_alternative(XYZ), YI, decimal=7 + np.testing.assert_allclose( + yellowness_ASTME313_alternative(XYZ), + YI, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_yellowness_ASTME313_alternative(self): @@ -183,10 +193,10 @@ def test_domain_range_scale_yellowness_ASTME313_alternative(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( yellowness_ASTME313_alternative(XYZ * factor), YI * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -213,31 +223,31 @@ def test_yellowness_ASTME313(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTME313( np.array([95.00000000, 100.00000000, 105.00000000]) ), 4.340000000000003, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTME313( np.array([105.00000000, 100.00000000, 95.00000000]) ), 28.660000000000011, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTME313( np.array([100.00000000, 100.00000000, 100.00000000]) ), 16.500000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( yellowness_ASTME313( np.array([95.00000000, 100.00000000, 105.00000000]), YELLOWNESS_COEFFICIENTS_ASTME313[ @@ -245,7 +255,7 @@ def test_yellowness_ASTME313(self): ]["C"], ), 10.089500000000001, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_yellowness_ASTME313(self): @@ -259,14 +269,14 @@ def test_n_dimensional_yellowness_ASTME313(self): XYZ = np.tile(XYZ, (6, 1)) YI = np.tile(YI, 6) - np.testing.assert_array_almost_equal( - yellowness_ASTME313(XYZ), YI, decimal=7 + np.testing.assert_allclose( + yellowness_ASTME313(XYZ), YI, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) YI = np.reshape(YI, (2, 3)) - np.testing.assert_array_almost_equal( - yellowness_ASTME313(XYZ), YI, decimal=7 + np.testing.assert_allclose( + yellowness_ASTME313(XYZ), YI, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_yellowness_ASTME313(self): @@ -281,8 +291,10 @@ def test_domain_range_scale_yellowness_ASTME313(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - yellowness_ASTME313(XYZ * factor), YI * factor, decimal=7 + np.testing.assert_allclose( + yellowness_ASTME313(XYZ * factor), + YI * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -318,10 +330,10 @@ def test_domain_range_scale_yellowness(self): for method, value in zip(m, v): for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( yellowness(XYZ * factor, method), value * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/colorimetry/tristimulus_values.py b/colour/colorimetry/tristimulus_values.py index 5a0ae139e1..4215ec5a9e 100644 --- a/colour/colorimetry/tristimulus_values.py +++ b/colour/colorimetry/tristimulus_values.py @@ -65,10 +65,11 @@ filter_kwargs, from_range_100, get_domain_range_scale, + int_digest, + is_caching_enabled, optional, runtime_warning, validate_method, - int_digest, ) __author__ = "Colour Developers" @@ -261,7 +262,10 @@ def lagrange_coefficients_ASTME2022( ) hash_key = hash((interval, interval_type)) - if hash_key in _CACHE_LAGRANGE_INTERPOLATING_COEFFICIENTS: + if ( + is_caching_enabled() + and hash_key in _CACHE_LAGRANGE_INTERPOLATING_COEFFICIENTS + ): return np.copy(_CACHE_LAGRANGE_INTERPOLATING_COEFFICIENTS[hash_key]) r_n = np.linspace(1 / interval, 1 - (1 / interval), interval - 1) @@ -391,7 +395,10 @@ def tristimulus_weighting_factors_ASTME2022( global _CACHE_TRISTIMULUS_WEIGHTING_FACTORS # noqa: PLW0602 hash_key = hash((cmfs, illuminant, shape, k, get_domain_range_scale())) - if hash_key in _CACHE_TRISTIMULUS_WEIGHTING_FACTORS: + if ( + is_caching_enabled() + and hash_key in _CACHE_TRISTIMULUS_WEIGHTING_FACTORS + ): return np.copy(_CACHE_TRISTIMULUS_WEIGHTING_FACTORS[hash_key]) Y = cmfs.values @@ -1279,7 +1286,7 @@ def sd_to_XYZ( ) ) - if hash_key in _CACHE_SD_TO_XYZ: + if is_caching_enabled() and hash_key in _CACHE_SD_TO_XYZ: return np.copy(_CACHE_SD_TO_XYZ[hash_key]) function = SD_TO_XYZ_METHODS[method] diff --git a/colour/colorimetry/whiteness.py b/colour/colorimetry/whiteness.py index defa19b5f1..2d401294b3 100644 --- a/colour/colorimetry/whiteness.py +++ b/colour/colorimetry/whiteness.py @@ -49,9 +49,9 @@ CanonicalMapping, as_float, as_float_array, - get_domain_range_scale, filter_kwargs, from_range_100, + get_domain_range_scale, to_domain_100, tsplit, tstack, diff --git a/colour/colorimetry/yellowness.py b/colour/colorimetry/yellowness.py index eb0a3ae9c8..7eb3490767 100644 --- a/colour/colorimetry/yellowness.py +++ b/colour/colorimetry/yellowness.py @@ -34,7 +34,7 @@ import numpy as np from colour.algebra import sdiv, sdiv_mode -from colour.hints import Any, ArrayLike, NDArrayFloat, Literal +from colour.hints import Any, ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, as_float, diff --git a/colour/constants/__init__.py b/colour/constants/__init__.py index 36ac6b11fc..e9898fd333 100644 --- a/colour/constants/__init__.py +++ b/colour/constants/__init__.py @@ -9,8 +9,12 @@ FLOATING_POINT_NUMBER_PATTERN, INTEGER_THRESHOLD, EPSILON, - DEFAULT_INT_DTYPE, - DEFAULT_FLOAT_DTYPE, + DTYPE_INT_DEFAULT, + DTYPE_FLOAT_DEFAULT, + TOLERANCE_ABSOLUTE_DEFAULT, + TOLERANCE_RELATIVE_DEFAULT, + TOLERANCE_ABSOLUTE_TESTS, + TOLERANCE_RELATIVE_TESTS, ) __all__ = [ @@ -27,6 +31,10 @@ "FLOATING_POINT_NUMBER_PATTERN", "INTEGER_THRESHOLD", "EPSILON", - "DEFAULT_INT_DTYPE", - "DEFAULT_FLOAT_DTYPE", + "DTYPE_INT_DEFAULT", + "DTYPE_FLOAT_DEFAULT", + "TOLERANCE_ABSOLUTE_DEFAULT", + "TOLERANCE_RELATIVE_DEFAULT", + "TOLERANCE_ABSOLUTE_TESTS", + "TOLERANCE_RELATIVE_TESTS", ] diff --git a/colour/constants/common.py b/colour/constants/common.py index 409e8e1bc4..924b10c061 100644 --- a/colour/constants/common.py +++ b/colour/constants/common.py @@ -9,13 +9,14 @@ from __future__ import annotations import os + import numpy as np +from colour.hints import DTypeFloat, Type, Union, cast from colour.utilities.documentation import ( DocstringFloat, is_documentation_building, ) -from colour.hints import DTypeFloat, Type, Union, cast __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -28,8 +29,12 @@ "FLOATING_POINT_NUMBER_PATTERN", "INTEGER_THRESHOLD", "EPSILON", - "DEFAULT_INT_DTYPE", - "DEFAULT_FLOAT_DTYPE", + "DTYPE_INT_DEFAULT", + "DTYPE_FLOAT_DEFAULT", + "TOLERANCE_ABSOLUTE_DEFAULT", + "TOLERANCE_RELATIVE_DEFAULT", + "TOLERANCE_ABSOLUTE_TESTS", + "TOLERANCE_RELATIVE_TESTS", ] FLOATING_POINT_NUMBER_PATTERN: str = "[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?" @@ -49,7 +54,7 @@ computations. """ -DEFAULT_INT_DTYPE: Type[np.int32 | np.int64] = cast( +DTYPE_INT_DEFAULT: Type[np.int32 | np.int64] = cast( Type[Union[np.int32, np.int64]], np.sctypeDict.get( os.environ.get("COLOUR_SCIENCE__DEFAULT_INT_DTYPE", "int64"), np.int64 @@ -58,11 +63,23 @@ """Default int number dtype.""" -DEFAULT_FLOAT_DTYPE: Type[DTypeFloat] = cast( +DTYPE_FLOAT_DEFAULT: Type[DTypeFloat] = cast( Type[DTypeFloat], np.sctypeDict.get( os.environ.get("COLOUR_SCIENCE__DEFAULT_FLOAT_DTYPE", "float64"), np.float64, ), ) -"""Default float point number dtype.""" +"""Default floating point number dtype.""" + +TOLERANCE_ABSOLUTE_DEFAULT: float = 1e-8 +"""Default absolute tolerance for computations.""" + +TOLERANCE_RELATIVE_DEFAULT: float = 1e-8 +"""Default relative tolerance for computations.""" + +TOLERANCE_ABSOLUTE_TESTS: float = 1e-7 +"""Absolute tolerance for computations during unit tests.""" + +TOLERANCE_RELATIVE_TESTS: float = 1e-7 +"""Relative tolerance for computations during unit tests.""" diff --git a/colour/continuous/abstract.py b/colour/continuous/abstract.py index e14460f6e6..8f12ce7329 100644 --- a/colour/continuous/abstract.py +++ b/colour/continuous/abstract.py @@ -10,10 +10,11 @@ from __future__ import annotations -import numpy as np from abc import ABC, abstractmethod from copy import deepcopy +import numpy as np + from colour.hints import ( Any, ArrayLike, @@ -33,8 +34,8 @@ as_float, attest, closest, - is_uniform, is_string, + is_uniform, optional, ) diff --git a/colour/continuous/multi_signals.py b/colour/continuous/multi_signals.py index c04a2887ae..b25691fb91 100644 --- a/colour/continuous/multi_signals.py +++ b/colour/continuous/multi_signals.py @@ -9,12 +9,14 @@ from __future__ import annotations -import numpy as np from collections.abc import Iterator, Mapping, ValuesView -from colour.constants import DEFAULT_FLOAT_DTYPE +import numpy as np + +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.continuous import AbstractContinuousFunction, Signal from colour.hints import ( + TYPE_CHECKING, Any, ArrayLike, Callable, @@ -26,9 +28,8 @@ ProtocolExtrapolator, ProtocolInterpolator, Real, - Sequence, Self, - TYPE_CHECKING, + Sequence, Type, cast, ) @@ -1002,15 +1003,19 @@ def __eq__(self, other: Any) -> bool: False """ + # NOTE: Comparing "interpolator_kwargs" and "extrapolator_kwargs" using + # their string representation because of presence of NaNs. if isinstance(other, MultiSignals): return all( [ np.array_equal(self.domain, other.domain), np.array_equal(self.range, other.range), self.interpolator is other.interpolator, - self.interpolator_kwargs == other.interpolator_kwargs, + str(self.interpolator_kwargs) + == str(other.interpolator_kwargs), self.extrapolator is other.extrapolator, - self.extrapolator_kwargs == other.extrapolator_kwargs, + str(self.extrapolator_kwargs) + == str(other.extrapolator_kwargs), self.labels == other.labels, ] ) @@ -1059,7 +1064,7 @@ def arithmetical_operation( a: ArrayLike | AbstractContinuousFunction, operation: Literal["+", "-", "*", "/", "**"], in_place: bool = False, - ) -> AbstractContinuousFunction: + ) -> MultiSignals: """ Perform given arithmetical operation with operand :math:`a`, the operation can be either performed on a copy or in-place. @@ -1170,7 +1175,7 @@ def arithmetical_operation( [ 9. 347. 378. 409.]] """ - multi_signals = cast(MultiSignals, self if in_place else self.copy()) + multi_signals = self if in_place else self.copy() if isinstance(a, MultiSignals): attest( @@ -1430,7 +1435,7 @@ def multi_signals_unpack_data( [ 1000. 120.]] """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) settings = {} settings.update(kwargs) @@ -1550,7 +1555,7 @@ def fill_nan( self, method: Literal["Constant", "Interpolation"] | str = "Interpolation", default: Real = 0, - ) -> AbstractContinuousFunction: + ) -> MultiSignals: """ Fill NaNs in independent domain variable :math:`x` and corresponding range variable :math:`y` using given method. diff --git a/colour/continuous/signal.py b/colour/continuous/signal.py index 0930de122e..7f37e87023 100644 --- a/colour/continuous/signal.py +++ b/colour/continuous/signal.py @@ -9,25 +9,27 @@ from __future__ import annotations -import numpy as np +from collections.abc import Iterator, Mapping, Sequence, ValuesView from operator import ( add, - mul, - pow, - sub, - truediv, iadd, imul, ipow, isub, itruediv, + mul, + pow, + sub, + truediv, ) -from collections.abc import Iterator, Mapping, Sequence, ValuesView + +import numpy as np from colour.algebra import Extrapolator, KernelInterpolator -from colour.constants import DEFAULT_FLOAT_DTYPE +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.continuous import AbstractContinuousFunction from colour.hints import ( + TYPE_CHECKING, Any, ArrayLike, Callable, @@ -39,7 +41,6 @@ ProtocolInterpolator, Real, Self, - TYPE_CHECKING, Type, Union, cast, @@ -250,7 +251,7 @@ def __init__( ) -> None: super().__init__(kwargs.get("name")) - self._dtype: Type[DTypeFloat] = DEFAULT_FLOAT_DTYPE + self._dtype: Type[DTypeFloat] = DTYPE_FLOAT_DEFAULT self._domain: NDArrayFloat = np.array([]) self._range: NDArrayFloat = np.array([]) self._interpolator: Type[ProtocolInterpolator] = KernelInterpolator @@ -390,7 +391,7 @@ def range(self, value: ArrayLike): # noqa: A003 # Empty domain occurs during __init__ because range is set before domain attest( - self._domain.size == 0 or value.size == self._domain.size, + self._domain.size in (0, self._domain.size), '"domain" and "range" variables must have same size!', ) @@ -809,7 +810,7 @@ def __setitem__(self, x: ArrayLike | slice, y: ArrayLike): self._function = None # Invalidate the underlying continuous function. - def __contains__(self, x: ArrayLike) -> bool: + def __contains__(self, x: ArrayLike | slice) -> bool: """ Return whether the continuous signal contains given independent domain variable :math:`x`. @@ -883,15 +884,19 @@ def __eq__(self, other: Any) -> bool: False """ + # NOTE: Comparing "interpolator_kwargs" and "extrapolator_kwargs" using + # their string representation because of presence of NaNs. if isinstance(other, Signal): return all( [ np.array_equal(self._domain, other.domain), np.array_equal(self._range, other.range), self._interpolator is other.interpolator, - self._interpolator_kwargs == other.interpolator_kwargs, + repr(self._interpolator_kwargs) + == repr(other.interpolator_kwargs), self._extrapolator is other.extrapolator, - self._extrapolator_kwargs == other.extrapolator_kwargs, + repr(self._extrapolator_kwargs) + == repr(other.extrapolator_kwargs), ] ) else: @@ -1174,7 +1179,7 @@ def signal_unpack_data( [ 10. 20. 30. 40. 50. 60. 70. 80. 90. 100.] """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) domain_unpacked: NDArrayFloat = np.array([]) range_unpacked: NDArrayFloat = np.array([]) @@ -1224,7 +1229,7 @@ def fill_nan( self, method: Literal["Constant", "Interpolation"] | str = "Interpolation", default: Real = 0, - ) -> AbstractContinuousFunction: + ) -> Signal: """ Fill NaNs in independent domain variable :math:`x` and corresponding range variable :math:`y` using given method. diff --git a/colour/continuous/tests/test_multi_signal.py b/colour/continuous/tests/test_multi_signal.py index 754c140c4f..8385055a01 100644 --- a/colour/continuous/tests/test_multi_signal.py +++ b/colour/continuous/tests/test_multi_signal.py @@ -1,16 +1,18 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.continuous.multi_signals` module.""" -import numpy as np -import unittest +import pickle import textwrap +import unittest + +import numpy as np from colour.algebra import ( CubicSplineInterpolator, Extrapolator, KernelInterpolator, ) -from colour.constants import DEFAULT_FLOAT_DTYPE +from colour.constants import DTYPE_FLOAT_DEFAULT, TOLERANCE_ABSOLUTE_TESTS from colour.continuous import MultiSignals, Signal from colour.utilities import ( ColourRuntimeWarning, @@ -92,13 +94,23 @@ def test_required_methods(self): for method in required_methods: self.assertIn(method, dir(MultiSignals)) + def test_pickling(self): + """ + Test whether the :class:``colour.continuous.signal.MultiSignals` class + can be pickled. + """ + + data = pickle.dumps(self._multi_signals) + data = pickle.loads(data) # noqa: S301 + self.assertEqual(self._multi_signals, data) + def test_dtype(self): """ Test :func:`colour.continuous.multi_signals.MultiSignals.dtype` property. """ - self.assertEqual(self._multi_signals.dtype, DEFAULT_FLOAT_DTYPE) + self.assertEqual(self._multi_signals.dtype, DTYPE_FLOAT_DEFAULT) multi_signals = self._multi_signals.copy() multi_signals.dtype = np.float32 @@ -112,12 +124,12 @@ def test_domain(self): multi_signals = self._multi_signals.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.array([0, 1, 2])], np.array( [[10.0, 20.0, 30.0], [20.0, 30.0, 40.0], [30.0, 40.0, 50.0]] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals.domain = self._domain_1 * 10 @@ -126,12 +138,12 @@ def test_domain(self): multi_signals.domain, self._domain_1 * 10 ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.array([0, 1, 2]) * 10], np.array( [[10.0, 20.0, 30.0], [20.0, 30.0, 40.0], [30.0, 40.0, 50.0]] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) domain = np.linspace(0, 1, 10) @@ -152,12 +164,12 @@ def test_range(self): multi_signals = self._multi_signals.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.array([0, 1, 2])], np.array( [[10.0, 20.0, 30.0], [20.0, 30.0, 40.0], [30.0, 40.0, 50.0]] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals.range = self._range_1 * 10 @@ -166,26 +178,26 @@ def test_range(self): multi_signals.range, tstack([self._range_1] * 3) * 10 ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.array([0, 1, 2])], np.array( [[10.0, 10.0, 10.0], [20.0, 20.0, 20.0], [30.0, 30.0, 30.0]] ) * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals.range = self._range_2 * 10 np.testing.assert_array_equal(multi_signals.range, self._range_2 * 10) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.array([0, 1, 2])], np.array( [[10.0, 20.0, 30.0], [20.0, 30.0, 40.0], [30.0, 40.0, 50.0]] ) * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_interpolator(self): @@ -196,7 +208,7 @@ def test_interpolator(self): multi_signals = self._multi_signals.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.linspace(0, 5, 5)], np.array( [ @@ -207,12 +219,12 @@ def test_interpolator(self): [60.00000000, 70.00000000, 80.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals.interpolator = CubicSplineInterpolator - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.linspace(0, 5, 5)], np.array( [ @@ -223,7 +235,7 @@ def test_interpolator(self): [60.00000000, 70.00000000, 80.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_interpolator_kwargs(self): @@ -234,7 +246,7 @@ def test_interpolator_kwargs(self): multi_signals = self._multi_signals.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.linspace(0, 5, 5)], np.array( [ @@ -245,7 +257,7 @@ def test_interpolator_kwargs(self): [60.00000000, 70.00000000, 80.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals.interpolator_kwargs = { @@ -253,7 +265,7 @@ def test_interpolator_kwargs(self): "kernel_kwargs": {"a": 1}, } - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.linspace(0, 5, 5)], np.array( [ @@ -264,7 +276,7 @@ def test_interpolator_kwargs(self): [60.00000000, 70.00000000, 80.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_extrapolator(self): @@ -289,12 +301,12 @@ def test_extrapolator_kwargs(self): "method": "Linear", } - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.array([-1000, 1000])], np.array( [[-9990.0, -9980.0, -9970.0], [10010.0, 10020.0, 10030.0]] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_function(self): @@ -477,11 +489,13 @@ def test__getitem__(self): method. """ - np.testing.assert_array_almost_equal( - self._multi_signals[0], np.array([10.0, 20.0, 30.0]), decimal=7 + np.testing.assert_allclose( + self._multi_signals[0], + np.array([10.0, 20.0, 30.0]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals[np.array([0, 1, 2])], np.array( [ @@ -490,10 +504,10 @@ def test__getitem__(self): [30.0, 40.0, 50.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals[np.linspace(0, 5, 5)], np.array( [ @@ -504,20 +518,24 @@ def test__getitem__(self): [60.00000000, 70.00000000, 80.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) attest(np.all(np.isnan(self._multi_signals[np.array([-1000, 1000])]))) - np.testing.assert_array_almost_equal( - self._multi_signals[:], self._multi_signals.range, decimal=7 + np.testing.assert_allclose( + self._multi_signals[:], + self._multi_signals.range, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - self._multi_signals[:, :], self._multi_signals.range, decimal=7 + np.testing.assert_allclose( + self._multi_signals[:, :], + self._multi_signals.range, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals[0:3], np.array( [ @@ -526,10 +544,10 @@ def test__getitem__(self): [30.0, 40.0, 50.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals[:, 0:2], np.array( [ @@ -545,7 +563,7 @@ def test__getitem__(self): [100.0, 110.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals = self._multi_signals.copy() @@ -581,12 +599,14 @@ def test__setitem__(self): multi_signals = self._multi_signals.copy() multi_signals[0] = 20 - np.testing.assert_array_almost_equal( - multi_signals[0], np.array([20.0, 20.0, 20.0]), decimal=7 + np.testing.assert_allclose( + multi_signals[0], + np.array([20.0, 20.0, 20.0]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals[np.array([0, 1, 2])] = 30 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[np.array([0, 1, 2])], np.array( [ @@ -595,11 +615,11 @@ def test__setitem__(self): [30.0, 30.0, 30.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals[np.linspace(0, 5, 5)] = 50 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.domain, np.array( [ @@ -618,9 +638,9 @@ def test__setitem__(self): 9.00, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.range, np.array( [ @@ -639,11 +659,11 @@ def test__setitem__(self): [100.0, 110.0, 120.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals[np.array([0, 1, 2])] = np.array([10, 20, 30]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.range, np.array( [ @@ -662,13 +682,13 @@ def test__setitem__(self): [100.0, 110.0, 120.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals[np.array([0, 1, 2])] = np.reshape( np.arange(1, 10, 1), (3, 3) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.range, np.array( [ @@ -687,22 +707,22 @@ def test__setitem__(self): [100.0, 110.0, 120.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals[:] = 40 - np.testing.assert_array_almost_equal( - multi_signals.range, 40, decimal=7 + np.testing.assert_allclose( + multi_signals.range, 40, atol=TOLERANCE_ABSOLUTE_TESTS ) multi_signals[:, :] = 50 - np.testing.assert_array_almost_equal( - multi_signals.range, 50, decimal=7 + np.testing.assert_allclose( + multi_signals.range, 50, atol=TOLERANCE_ABSOLUTE_TESTS ) multi_signals = self._multi_signals.copy() multi_signals[0:3] = 40 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals[0:3], np.array( [ @@ -711,11 +731,11 @@ def test__setitem__(self): [40.0, 40.0, 40.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals[:, 0:2] = 50 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.range, np.array( [ @@ -731,7 +751,7 @@ def test__setitem__(self): [50.0, 50.0, 120.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test__contains__(self): @@ -827,103 +847,113 @@ def test_arithmetical_operation(self): arithmetical_operation` method. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals.arithmetical_operation(10, "+", False).range, self._range_2 + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals.arithmetical_operation(10, "-", False).range, self._range_2 - 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals.arithmetical_operation(10, "*", False).range, self._range_2 * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals.arithmetical_operation(10, "/", False).range, self._range_2 / 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals.arithmetical_operation(10, "**", False).range, self._range_2**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._multi_signals + 10).range, self._range_2 + 10, decimal=7 + np.testing.assert_allclose( + (self._multi_signals + 10).range, + self._range_2 + 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._multi_signals - 10).range, self._range_2 - 10, decimal=7 + np.testing.assert_allclose( + (self._multi_signals - 10).range, + self._range_2 - 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._multi_signals * 10).range, self._range_2 * 10, decimal=7 + np.testing.assert_allclose( + (self._multi_signals * 10).range, + self._range_2 * 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._multi_signals / 10).range, self._range_2 / 10, decimal=7 + np.testing.assert_allclose( + (self._multi_signals / 10).range, + self._range_2 / 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._multi_signals**10).range, self._range_2**10, decimal=7 + np.testing.assert_allclose( + (self._multi_signals**10).range, + self._range_2**10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals = self._multi_signals.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.arithmetical_operation(10, "+", True).range, self._range_2 + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.arithmetical_operation(10, "-", True).range, self._range_2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.arithmetical_operation(10, "*", True).range, self._range_2 * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.arithmetical_operation(10, "/", True).range, self._range_2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.arithmetical_operation(10, "**", True).range, self._range_2**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals = self._multi_signals.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.arithmetical_operation( self._range_2, "+", False ).range, self._range_2 + self._range_2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.arithmetical_operation( multi_signals, "+", False ).range, self._range_2 + self._range_2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_is_uniform(self): @@ -1051,7 +1081,7 @@ def test_fill_nan(self): multi_signals[3:7] = np.nan - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.fill_nan().range, np.array( [ @@ -1067,12 +1097,12 @@ def test_fill_nan(self): [100.0, 110.0, 120.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) multi_signals[3:7] = np.nan - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( multi_signals.fill_nan(method="Constant").range, np.array( [ @@ -1088,7 +1118,7 @@ def test_fill_nan(self): [100.0, 110.0, 120.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_distance(self): @@ -1097,14 +1127,16 @@ def test_domain_distance(self): domain_distance` method. """ - self.assertAlmostEqual( - self._multi_signals.domain_distance(0.5), 0.5, places=7 + np.testing.assert_allclose( + self._multi_signals.domain_distance(0.5), + 0.5, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._multi_signals.domain_distance(np.linspace(0, 9, 10) + 0.5), np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_to_dataframe(self): diff --git a/colour/continuous/tests/test_signal.py b/colour/continuous/tests/test_signal.py index e7ea60965f..c5ade6088c 100644 --- a/colour/continuous/tests/test_signal.py +++ b/colour/continuous/tests/test_signal.py @@ -1,16 +1,18 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.continuous.signal` module.""" -import numpy as np -import unittest +import pickle import textwrap +import unittest + +import numpy as np from colour.algebra import ( CubicSplineInterpolator, Extrapolator, KernelInterpolator, ) -from colour.constants import DEFAULT_FLOAT_DTYPE +from colour.constants import DTYPE_FLOAT_DEFAULT, TOLERANCE_ABSOLUTE_TESTS from colour.continuous import Signal from colour.utilities import ColourRuntimeWarning, attest, is_pandas_installed @@ -78,10 +80,20 @@ def test_required_methods(self): for method in required_methods: self.assertIn(method, dir(Signal)) + def test_pickling(self): + """ + Test whether the :class:``colour.continuous.signal.Signal` class can be + pickled. + """ + + data = pickle.dumps(self._signal) + data = pickle.loads(data) # noqa: S301 + self.assertEqual(self._signal, data) + def test_dtype(self): """Test :func:`colour.continuous.signal.Signal.dtype` property.""" - self.assertEqual(self._signal.dtype, DEFAULT_FLOAT_DTYPE) + self.assertEqual(self._signal.dtype, DTYPE_FLOAT_DEFAULT) signal = self._signal.copy() signal.dtype = np.float32 @@ -92,20 +104,20 @@ def test_domain(self): signal = self._signal.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.array([0, 1, 2])], np.array([10.0, 20.0, 30.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal.domain = np.arange(0, 10, 1) * 10 np.testing.assert_array_equal(signal.domain, np.arange(0, 10, 1) * 10) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.array([0, 1, 2]) * 10], np.array([10.0, 20.0, 30.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) domain = np.linspace(0, 1, 10) @@ -123,20 +135,20 @@ def test_range(self): signal = self._signal.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.array([0, 1, 2])], np.array([10.0, 20.0, 30.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal.range = self._range * 10 np.testing.assert_array_equal(signal.range, self._range * 10) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.array([0, 1, 2])], np.array([10.0, 20.0, 30.0]) * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def assert_warns(): @@ -151,7 +163,7 @@ def test_interpolator(self): signal = self._signal.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.linspace(0, 5, 5)], np.array( [ @@ -162,15 +174,15 @@ def test_interpolator(self): 60.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal.interpolator = CubicSplineInterpolator - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.linspace(0, 5, 5)], np.array([10.0, 22.5, 35.0, 47.5, 60.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_interpolator_kwargs(self): @@ -181,7 +193,7 @@ def test_interpolator_kwargs(self): signal = self._signal.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.linspace(0, 5, 5)], np.array( [ @@ -192,12 +204,12 @@ def test_interpolator_kwargs(self): 60.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal.interpolator_kwargs = {"window": 1, "kernel_kwargs": {"a": 1}} - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.linspace(0, 5, 5)], np.array( [ @@ -208,7 +220,7 @@ def test_interpolator_kwargs(self): 60.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_extrapolator(self): @@ -230,10 +242,10 @@ def test_extrapolator_kwargs(self): "method": "Linear", } - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal[np.array([-1000, 1000])], np.array([-9990.0, 10010.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_function(self): @@ -334,13 +346,13 @@ def test__getitem__(self): self.assertEqual(self._signal[0], 10.0) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal[np.array([0, 1, 2])], np.array([10.0, 20.0, 30.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal[np.linspace(0, 5, 5)], np.array( [ @@ -351,7 +363,7 @@ def test__getitem__(self): 60.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) attest(np.all(np.isnan(self._signal[np.array([-1000, 1000])]))) @@ -379,7 +391,7 @@ def test__setitem__(self): signal = self._signal.copy() signal[0] = 20 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.range, np.array( [20.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0] @@ -387,25 +399,25 @@ def test__setitem__(self): ) signal[np.array([0, 1, 2])] = 30 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.range, np.array( [30.0, 30.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal[0:3] = 40 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.range, np.array( [40.0, 40.0, 40.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal[np.linspace(0, 5, 5)] = 50 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.domain, np.array( [ @@ -424,9 +436,9 @@ def test__setitem__(self): 9.00, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.range, np.array( [ @@ -445,11 +457,11 @@ def test__setitem__(self): 100.0, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal[np.array([0, 1, 2])] = np.array([10, 20, 30]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.range, np.array( [ @@ -468,7 +480,7 @@ def test__setitem__(self): 100.0, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test__contains__(self): @@ -548,100 +560,110 @@ def test_arithmetical_operation(self): method. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal.arithmetical_operation(10, "+", False).range, self._range + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal.arithmetical_operation(10, "-", False).range, self._range - 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal.arithmetical_operation(10, "*", False).range, self._range * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal.arithmetical_operation(10, "/", False).range, self._range / 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal.arithmetical_operation(10, "**", False).range, self._range**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._signal + 10).range, self._range + 10, decimal=7 + np.testing.assert_allclose( + (self._signal + 10).range, + self._range + 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._signal - 10).range, self._range - 10, decimal=7 + np.testing.assert_allclose( + (self._signal - 10).range, + self._range - 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._signal * 10).range, self._range * 10, decimal=7 + np.testing.assert_allclose( + (self._signal * 10).range, + self._range * 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._signal / 10).range, self._range / 10, decimal=7 + np.testing.assert_allclose( + (self._signal / 10).range, + self._range / 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (self._signal**10).range, self._range**10, decimal=7 + np.testing.assert_allclose( + (self._signal**10).range, + self._range**10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal = self._signal.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.arithmetical_operation(10, "+", True).range, self._range + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.arithmetical_operation(10, "-", True).range, self._range, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.arithmetical_operation(10, "*", True).range, self._range * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.arithmetical_operation(10, "/", True).range, self._range, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.arithmetical_operation(10, "**", True).range, self._range**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal = self._signal.copy() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.arithmetical_operation(self._range, "+", False).range, signal.range + self._range, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.arithmetical_operation(signal, "+", False).range, signal.range + signal._range, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_is_uniform(self): @@ -706,35 +728,37 @@ def test_fill_nan(self): signal[3:7] = np.nan - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.fill_nan().range, np.array( [10.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 90.0, 100.0] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) signal[3:7] = np.nan - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( signal.fill_nan(method="Constant").range, np.array( [10.0, 20.0, 30.0, 0.0, 0.0, 0.0, 0.0, 80.0, 90.0, 100.0] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_distance(self): """Test :func:`colour.continuous.signal.Signal.domain_distance` method.""" - self.assertAlmostEqual( - self._signal.domain_distance(0.5), 0.5, places=7 + np.testing.assert_allclose( + self._signal.domain_distance(0.5), + 0.5, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._signal.domain_distance(np.linspace(0, 9, 10) + 0.5), np.array([0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_to_series(self): diff --git a/colour/contrast/barten1999.py b/colour/contrast/barten1999.py index 9566b9c9a1..7e7628e17b 100644 --- a/colour/contrast/barten1999.py +++ b/colour/contrast/barten1999.py @@ -31,7 +31,7 @@ import numpy as np from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float +from colour.utilities import as_float, as_float_array __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/contrast/tests/test_barten1999.py b/colour/contrast/tests/test_barten1999.py index 1e1622c6ed..c2e6e335d5 100644 --- a/colour/contrast/tests/test_barten1999.py +++ b/colour/contrast/tests/test_barten1999.py @@ -1,17 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.contrast.barten1999` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.contrast import ( + contrast_sensitivity_function_Barten1999, + maximum_angular_size_Barten1999, optical_MTF_Barten1999, pupil_diameter_Barten1999, - sigma_Barten1999, retinal_illuminance_Barten1999, - maximum_angular_size_Barten1999, - contrast_sensitivity_function_Barten1999, + sigma_Barten1999, ) from colour.utilities import ignore_numpy_errors @@ -44,16 +46,22 @@ def test_optical_MTF_Barten1999(self): definition. """ - np.testing.assert_array_almost_equal( - optical_MTF_Barten1999(4, 0.01), 0.968910791191297, decimal=7 + np.testing.assert_allclose( + optical_MTF_Barten1999(4, 0.01), + 0.968910791191297, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - optical_MTF_Barten1999(8, 0.01), 0.881323136669471, decimal=7 + np.testing.assert_allclose( + optical_MTF_Barten1999(8, 0.01), + 0.881323136669471, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - optical_MTF_Barten1999(4, 0.05), 0.454040738727245, decimal=7 + np.testing.assert_allclose( + optical_MTF_Barten1999(4, 0.05), + 0.454040738727245, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_optical_MTF_Barten1999(self): @@ -69,15 +77,19 @@ def test_n_dimensional_optical_MTF_Barten1999(self): u = np.tile(u, (6, 1)) sigma = np.tile(sigma, (6, 1)) M_opt = np.tile(M_opt, (6, 1)) - np.testing.assert_array_almost_equal( - optical_MTF_Barten1999(u, sigma), M_opt, decimal=7 + np.testing.assert_allclose( + optical_MTF_Barten1999(u, sigma), + M_opt, + atol=TOLERANCE_ABSOLUTE_TESTS, ) u = np.reshape(u, (2, 3, 3)) sigma = np.reshape(sigma, (2, 3, 3)) M_opt = np.reshape(M_opt, (2, 3, 3)) - np.testing.assert_array_almost_equal( - optical_MTF_Barten1999(u, sigma), M_opt, decimal=7 + np.testing.assert_allclose( + optical_MTF_Barten1999(u, sigma), + M_opt, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -104,16 +116,22 @@ def test_pupil_diameter_Barten1999(self): definition. """ - np.testing.assert_array_almost_equal( - pupil_diameter_Barten1999(20, 60), 3.262346170373243, decimal=7 + np.testing.assert_allclose( + pupil_diameter_Barten1999(20, 60), + 3.262346170373243, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - pupil_diameter_Barten1999(0.2, 600), 3.262346170373243, decimal=7 + np.testing.assert_allclose( + pupil_diameter_Barten1999(0.2, 600), + 3.262346170373243, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - pupil_diameter_Barten1999(20, 60, 30), 3.519054451149336, decimal=7 + np.testing.assert_allclose( + pupil_diameter_Barten1999(20, 60, 30), + 3.519054451149336, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_pupil_diameter_Barten1999(self): @@ -130,15 +148,19 @@ def test_n_dimensional_pupil_diameter_Barten1999(self): L = np.tile(L, (6, 1)) X_0 = np.tile(X_0, (6, 1)) d = np.tile(d, (6, 1)) - np.testing.assert_array_almost_equal( - pupil_diameter_Barten1999(L, X_0, Y_0), d, decimal=7 + np.testing.assert_allclose( + pupil_diameter_Barten1999(L, X_0, Y_0), + d, + atol=TOLERANCE_ABSOLUTE_TESTS, ) L = np.reshape(L, (2, 3, 3)) X_0 = np.reshape(X_0, (2, 3, 3)) d = np.reshape(d, (2, 3, 3)) - np.testing.assert_array_almost_equal( - pupil_diameter_Barten1999(L, X_0, Y_0), d, decimal=7 + np.testing.assert_allclose( + pupil_diameter_Barten1999(L, X_0, Y_0), + d, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -162,28 +184,28 @@ class TestSigmaBarten1999(unittest.TestCase): def test_sigma_Barten1999(self): """Test :func:`colour.contrast.barten1999.sigma_Barten1999` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sigma_Barten1999(0.5 / 60, 0.08 / 60, 2.1), 0.008791157173231, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sigma_Barten1999(0.75 / 60, 0.08 / 60, 2.1), 0.012809761902549, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sigma_Barten1999(0.5 / 60, 0.16 / 60, 2.1), 0.010040141654601, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sigma_Barten1999(0.5 / 60, 0.08 / 60, 2.5), 0.008975274678558, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_sigma_Barten1999(self): @@ -200,15 +222,19 @@ def test_n_dimensional_sigma_Barten1999(self): sigma_0 = np.tile(sigma_0, (6, 1)) C_ab = np.tile(C_ab, (6, 1)) sigma = np.tile(sigma, (6, 1)) - np.testing.assert_array_almost_equal( - sigma_Barten1999(sigma_0, C_ab, d), sigma, decimal=7 + np.testing.assert_allclose( + sigma_Barten1999(sigma_0, C_ab, d), + sigma, + atol=TOLERANCE_ABSOLUTE_TESTS, ) sigma_0 = np.reshape(sigma_0, (2, 3, 3)) C_ab = np.reshape(C_ab, (2, 3, 3)) sigma = np.reshape(sigma, (2, 3, 3)) - np.testing.assert_array_almost_equal( - sigma_Barten1999(sigma_0, C_ab, d), sigma, decimal=7 + np.testing.assert_allclose( + sigma_Barten1999(sigma_0, C_ab, d), + sigma, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -235,22 +261,22 @@ def test_retinal_illuminance_Barten1999(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( retinal_illuminance_Barten1999(20, 2.1, True), 66.082316060529919, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( retinal_illuminance_Barten1999(20, 2.5, True), 91.815644777503664, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( retinal_illuminance_Barten1999(20, 2.1, False), 69.272118011654939, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_retinal_illuminance_Barten1999(self): @@ -266,15 +292,19 @@ def test_n_dimensional_retinal_illuminance_Barten1999(self): L = np.tile(L, (6, 1)) d = np.tile(d, (6, 1)) E = np.tile(E, (6, 1)) - np.testing.assert_array_almost_equal( - retinal_illuminance_Barten1999(L, d), E, decimal=7 + np.testing.assert_allclose( + retinal_illuminance_Barten1999(L, d), + E, + atol=TOLERANCE_ABSOLUTE_TESTS, ) L = np.reshape(L, (2, 3, 3)) d = np.reshape(d, (2, 3, 3)) E = np.reshape(E, (2, 3, 3)) - np.testing.assert_array_almost_equal( - retinal_illuminance_Barten1999(L, d), E, decimal=7 + np.testing.assert_allclose( + retinal_illuminance_Barten1999(L, d), + E, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -301,34 +331,34 @@ def test_maximum_angular_size_Barten1999(self): maximum_angular_size_Barten1999` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( maximum_angular_size_Barten1999(4, 60, 12, 15), 3.572948005052482, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( maximum_angular_size_Barten1999(8, 60, 12, 15), 1.851640199545103, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( maximum_angular_size_Barten1999(4, 120, 12, 15), 3.577708763999663, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( maximum_angular_size_Barten1999(4, 60, 24, 15), 3.698001308168194, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( maximum_angular_size_Barten1999(4, 60, 12, 30), 6.324555320336758, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_maximum_angular_size_Barten1999(self): @@ -346,15 +376,19 @@ def test_n_dimensional_maximum_angular_size_Barten1999(self): u = np.tile(u, (6, 1)) X_0 = np.tile(X_0, (6, 1)) X = np.tile(X, (6, 1)) - np.testing.assert_array_almost_equal( - maximum_angular_size_Barten1999(u, X_0, X_max, N_max), X, decimal=7 + np.testing.assert_allclose( + maximum_angular_size_Barten1999(u, X_0, X_max, N_max), + X, + atol=TOLERANCE_ABSOLUTE_TESTS, ) u = np.reshape(u, (2, 3, 3)) X_0 = np.reshape(X_0, (2, 3, 3)) X = np.reshape(X, (2, 3, 3)) - np.testing.assert_array_almost_equal( - maximum_angular_size_Barten1999(u, X_0, X_max, N_max), X, decimal=7 + np.testing.assert_allclose( + maximum_angular_size_Barten1999(u, X_0, X_max, N_max), + X, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -381,7 +415,7 @@ def test_contrast_sensitivity_function_Barten1999(self): contrast_sensitivity_function_Barten1999` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=4, sigma=0.01, @@ -393,10 +427,10 @@ def test_contrast_sensitivity_function_Barten1999(self): p=1.2 * 10**6, ), 352.761342126727020, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=8, sigma=0.01, @@ -408,10 +442,10 @@ def test_contrast_sensitivity_function_Barten1999(self): p=1.2 * 10**6, ), 177.706338840717340, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=4, sigma=0.02, @@ -423,10 +457,10 @@ def test_contrast_sensitivity_function_Barten1999(self): p=1.2 * 10**6, ), 320.872401634215750, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=4, sigma=0.01, @@ -438,10 +472,10 @@ def test_contrast_sensitivity_function_Barten1999(self): p=1.2 * 10**6, ), 455.171315756946400, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=4, sigma=0.01, @@ -453,10 +487,10 @@ def test_contrast_sensitivity_function_Barten1999(self): p=1.2 * 10**6, ), 352.996281545740660, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=4, sigma=0.01, @@ -468,10 +502,10 @@ def test_contrast_sensitivity_function_Barten1999(self): p=1.2 * 10**6, ), 358.881580104493650, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=4, sigma=0.01, @@ -492,10 +526,10 @@ def test_contrast_sensitivity_function_Barten1999(self): Y_max=12, p=1.2 * 10**6, ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=4, sigma=0.01, @@ -507,7 +541,7 @@ def test_contrast_sensitivity_function_Barten1999(self): p=1.4 * 10**6, ), 374.791328640476140, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_contrast_sensitivity_function_Barten1999(self): @@ -527,23 +561,23 @@ def test_n_dimensional_contrast_sensitivity_function_Barten1999(self): u = np.tile(u, (6, 1)) E = np.tile(E, (6, 1)) S = np.tile(S, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=u, sigma=sigma, E=E, X_0=X_0 ), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) u = np.reshape(u, (2, 3, 3)) E = np.reshape(E, (2, 3, 3)) S = np.reshape(S, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( contrast_sensitivity_function_Barten1999( u=u, sigma=sigma, E=E, X_0=X_0 ), S, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/corresponding/datasets/breneman1987.py b/colour/corresponding/datasets/breneman1987.py index 35dd2ed143..f41d07575f 100644 --- a/colour/corresponding/datasets/breneman1987.py +++ b/colour/corresponding/datasets/breneman1987.py @@ -13,10 +13,10 @@ doi:10.1364/JOSAA.4.001115 """ -import numpy as np - from collections import namedtuple +import numpy as np + from colour.utilities.documentation import ( DocstringDict, is_documentation_building, diff --git a/colour/corresponding/prediction.py b/colour/corresponding/prediction.py index 6d59747cc0..60f1842f93 100644 --- a/colour/corresponding/prediction.py +++ b/colour/corresponding/prediction.py @@ -38,9 +38,10 @@ from __future__ import annotations -import numpy as np from collections import namedtuple +import numpy as np + from colour.adaptation import ( chromatic_adaptation_CIE1994, chromatic_adaptation_CMCCAT2000, @@ -49,10 +50,16 @@ chromatic_adaptation_Zhai2018, ) from colour.corresponding import ( - BRENEMAN_EXPERIMENTS, BRENEMAN_EXPERIMENT_PRIMARIES_CHROMATICITIES, + BRENEMAN_EXPERIMENTS, +) +from colour.hints import ( + Any, + ArrayLike, + Literal, + LiteralChromaticAdaptationTransform, + Tuple, ) -from colour.hints import Any, ArrayLike, Literal, Tuple from colour.models import ( Luv_to_uv, Luv_uv_to_xy, @@ -63,8 +70,8 @@ ) from colour.utilities import ( CanonicalMapping, - attest, as_float_scalar, + attest, domain_range_scale, filter_kwargs, full, @@ -513,21 +520,7 @@ def corresponding_chromaticities_prediction_CMCCAT2000( def corresponding_chromaticities_prediction_VonKries( experiment: Literal[1, 2, 3, 4, 6, 8, 9, 11, 12] | CorrespondingColourDataset = 1, - transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] - | str = "CAT02", + transform: LiteralChromaticAdaptationTransform | str = "CAT02", ) -> Tuple[CorrespondingChromaticitiesPrediction, ...]: """ Return the corresponding chromaticities prediction for *Von Kries* diff --git a/colour/corresponding/tests/test_prediction.py b/colour/corresponding/tests/test_prediction.py index b08729cd8a..3cb8122044 100644 --- a/colour/corresponding/tests/test_prediction.py +++ b/colour/corresponding/tests/test_prediction.py @@ -3,13 +3,11 @@ from __future__ import annotations -import numpy as np import unittest -from colour.corresponding.prediction import ( - CorrespondingColourDataset, - convert_experiment_results_Breneman1987, -) +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.corresponding import ( corresponding_chromaticities_prediction_CIE1994, corresponding_chromaticities_prediction_CMCCAT2000, @@ -17,9 +15,12 @@ corresponding_chromaticities_prediction_VonKries, corresponding_chromaticities_prediction_Zhai2018, ) +from colour.corresponding.prediction import ( + CorrespondingColourDataset, + convert_experiment_results_Breneman1987, +) from colour.hints import NDArrayFloat - __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" __license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" @@ -241,40 +242,40 @@ def test_convert_experiment_results_Breneman1987(self): 1 ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( corresponding_colour_dataset.XYZ_r, DATASET_CORRESPONDING_COLOUR_1.XYZ_r, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( corresponding_colour_dataset.XYZ_t, DATASET_CORRESPONDING_COLOUR_1.XYZ_t, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( corresponding_colour_dataset.XYZ_cr, DATASET_CORRESPONDING_COLOUR_1.XYZ_cr, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( corresponding_colour_dataset.XYZ_ct, DATASET_CORRESPONDING_COLOUR_1.XYZ_ct, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( corresponding_colour_dataset.Y_r, DATASET_CORRESPONDING_COLOUR_1.Y_r, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( corresponding_colour_dataset.Y_t, DATASET_CORRESPONDING_COLOUR_1.Y_t, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -293,7 +294,7 @@ def test_corresponding_chromaticities_prediction_Fairchild1990(self): corresponding_chromaticities_prediction_Fairchild1990` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array( [ (p.uv_m, p.uv_p) @@ -301,7 +302,7 @@ def test_corresponding_chromaticities_prediction_Fairchild1990(self): ] ), DATA_PREDICTION_FAIRCHILD1990, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -317,7 +318,7 @@ def test_corresponding_chromaticities_prediction_CIE1994(self): corresponding_chromaticities_prediction_CIE1994` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array( [ (p.uv_m, p.uv_p) @@ -325,7 +326,7 @@ def test_corresponding_chromaticities_prediction_CIE1994(self): ] ), DATA_PREDICTION_CIE1994, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -342,7 +343,7 @@ def test_corresponding_chromaticities_prediction_CMCCAT2000(self): corresponding_chromaticities_prediction_CMCCAT2000` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array( [ (p.uv_m, p.uv_p) @@ -350,7 +351,7 @@ def test_corresponding_chromaticities_prediction_CMCCAT2000(self): ] ), DATA_PREDICTION_CMCCAT2000, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -367,7 +368,7 @@ def test_corresponding_chromaticities_prediction_VonKries(self): corresponding_chromaticities_prediction_VonKries` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array( [ (p.uv_m, p.uv_p) @@ -375,7 +376,7 @@ def test_corresponding_chromaticities_prediction_VonKries(self): ] ), DATA_PREDICTION_VONKRIES, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -392,7 +393,7 @@ def test_corresponding_chromaticities_prediction_Zhai2018(self): corresponding_chromaticities_prediction_Zhai2018` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array( [ (p.uv_m, p.uv_p) @@ -400,5 +401,5 @@ def test_corresponding_chromaticities_prediction_Zhai2018(self): ] ), DATA_PREDICTION_ZHAI2018, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/difference/cam02_ucs.py b/colour/difference/cam02_ucs.py index d602e8e376..8480783806 100644 --- a/colour/difference/cam02_ucs.py +++ b/colour/difference/cam02_ucs.py @@ -20,8 +20,8 @@ import numpy as np -from colour.models.cam02_ucs import COEFFICIENTS_UCS_LUO2006 from colour.hints import ArrayLike, NDArrayFloat +from colour.models.cam02_ucs import COEFFICIENTS_UCS_LUO2006 from colour.utilities import as_float, tsplit __author__ = "Colour Developers" diff --git a/colour/difference/cam16_ucs.py b/colour/difference/cam16_ucs.py index 09c3680200..06ccc3ae04 100644 --- a/colour/difference/cam16_ucs.py +++ b/colour/difference/cam16_ucs.py @@ -19,10 +19,10 @@ """ from colour.difference.cam02_ucs import ( - delta_E_Luo2006, delta_E_CAM02LCD, delta_E_CAM02SCD, delta_E_CAM02UCS, + delta_E_Luo2006, ) from colour.models.cam16_ucs import ( _UCS_Luo2006_callable_to_UCS_Li2017_docstring, diff --git a/colour/difference/delta_e.py b/colour/difference/delta_e.py index bdddcf6a31..72f3e7db01 100644 --- a/colour/difference/delta_e.py +++ b/colour/difference/delta_e.py @@ -45,7 +45,7 @@ from colour.algebra import euclidean_distance from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float, to_domain_100, tsplit +from colour.utilities import as_float, to_domain_100, tsplit, zeros from colour.utilities.documentation import ( DocstringFloat, is_documentation_building, @@ -225,7 +225,9 @@ def delta_E_CIE1994( delta_A = a_1 - a_2 delta_B = b_1 - b_2 - delta_H = np.sqrt(delta_A**2 + delta_B**2 - delta_C**2) + radical = delta_A**2 + delta_B**2 - delta_C**2 + delta_H = zeros(radical.shape) + delta_H[radical > 0] = np.sqrt(radical[radical > 0]) L = (delta_L / (k_L * s_L)) ** 2 C = (delta_C / (k_C * s_C)) ** 2 diff --git a/colour/difference/huang2015.py b/colour/difference/huang2015.py index ec35a3569f..ff09b59196 100644 --- a/colour/difference/huang2015.py +++ b/colour/difference/huang2015.py @@ -23,7 +23,7 @@ import numpy as np -from colour.hints import ArrayLike, NDArrayFloat, Literal +from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import CanonicalMapping, tsplit, validate_method __author__ = "Colour Developers" diff --git a/colour/difference/stress.py b/colour/difference/stress.py index f174362137..ac071d8223 100644 --- a/colour/difference/stress.py +++ b/colour/difference/stress.py @@ -23,7 +23,7 @@ import numpy as np from colour.algebra import sdiv, sdiv_mode -from colour.hints import ArrayLike, NDArrayFloat, Literal +from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, as_float, diff --git a/colour/difference/tests/test__init__.py b/colour/difference/tests/test__init__.py index ee07a93c9f..a5095bd5ee 100644 --- a/colour/difference/tests/test__init__.py +++ b/colour/difference/tests/test__init__.py @@ -1,11 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.difference` module.""" -import numpy as np import unittest -from colour.difference import delta_E +import numpy as np +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.difference import delta_E from colour.utilities import domain_range_scale __author__ = "Colour Developers" @@ -39,10 +40,10 @@ def test_domain_range_scale_delta_E(self): for method, value in zip(m, v): for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E(Lab_1 * factor, Lab_2 * factor, method), value, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/difference/tests/test_cam02_ucs.py b/colour/difference/tests/test_cam02_ucs.py index 8f7731cea7..375f847e31 100644 --- a/colour/difference/tests/test_cam02_ucs.py +++ b/colour/difference/tests/test_cam02_ucs.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.difference.cam02_ucs` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.difference import ( delta_E_CAM02LCD, delta_E_CAM02SCD, @@ -35,17 +37,17 @@ class TestDelta_E_Luo2006(unittest.TestCase): def test_delta_E_Luo2006(self): """Test :func:`colour.difference.cam02_ucs.delta_E_Luo2006` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_Luo2006( np.array([54.90433134, -0.08450395, -0.06854831]), np.array([54.80352754, -3.96940084, -13.57591013]), COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], ), 14.055546437777583, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_Luo2006( np.array([54.90433134, -0.08450395, -0.06854831]), np.array([54.80352754, -3.96940084, -13.57591013]), @@ -55,10 +57,10 @@ def test_delta_E_Luo2006(self): np.array([54.90433134, -0.08450395, -0.06854831]), np.array([54.80352754, -3.96940084, -13.57591013]), ), - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_Luo2006( np.array([54.90433134, -0.08450395, -0.06854831]), np.array([54.80352754, -3.96940084, -13.57591013]), @@ -68,10 +70,10 @@ def test_delta_E_Luo2006(self): np.array([54.90433134, -0.08450395, -0.06854831]), np.array([54.80352754, -3.96940084, -13.57591013]), ), - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_Luo2006( np.array([54.90433134, -0.08450395, -0.06854831]), np.array([54.80352754, -3.96940084, -13.57591013]), @@ -81,7 +83,7 @@ def test_delta_E_Luo2006(self): np.array([54.90433134, -0.08450395, -0.06854831]), np.array([54.80352754, -3.96940084, -13.57591013]), ), - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_delta_E_Luo2006(self): @@ -99,23 +101,23 @@ def test_n_dimensional_delta_E_Luo2006(self): Jpapbp_1 = np.tile(Jpapbp_1, (6, 1)) Jpapbp_2 = np.tile(Jpapbp_2, (6, 1)) delta_E_p = np.tile(delta_E_p, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_Luo2006( Jpapbp_1, Jpapbp_2, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), delta_E_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Jpapbp_1 = np.reshape(Jpapbp_1, (2, 3, 3)) Jpapbp_2 = np.reshape(Jpapbp_2, (2, 3, 3)) delta_E_p = np.reshape(delta_E_p, (2, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_Luo2006( Jpapbp_1, Jpapbp_2, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), delta_E_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/difference/tests/test_delta_e.py b/colour/difference/tests/test_delta_e.py index a432b63361..939620af3a 100644 --- a/colour/difference/tests/test_delta_e.py +++ b/colour/difference/tests/test_delta_e.py @@ -9,10 +9,13 @@ 30(1), 21-30. doi:10.1002/col.20070 """ -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.algebra import euclidean_distance +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.difference import ( delta_E_CIE1976, delta_E_CIE1994, @@ -20,8 +23,6 @@ delta_E_CMC, delta_E_ITP, ) - -from colour.algebra import euclidean_distance from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -60,10 +61,10 @@ def test_delta_E_CIE1976(self): Lab_1 = np.tile(Lab_1, (6, 1)).reshape([2, 3, 3]) Lab_2 = np.tile(Lab_2, (6, 1)).reshape([2, 3, 3]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_CIE1976(Lab_1, Lab_2), euclidean_distance(Lab_1, Lab_2), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_delta_E_CIE1976(self): @@ -84,10 +85,10 @@ def test_domain_range_scale_delta_E_CIE1976(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_CIE1976(Lab_1 * factor, Lab_2 * factor), euclidean_distance(Lab_1, Lab_2), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -107,61 +108,61 @@ class TestDelta_E_CIE1994(unittest.TestCase): def test_delta_E_CIE1994(self): """Test :func:`colour.difference.delta_e.delta_E_CIE1994` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE1994( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 426.67945353, 72.39590835]), ), 83.779225500887094, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE1994( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 74.05216981, 276.45318193]), ), 10.053931954553839, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE1994( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 8.32281957, -73.58297716]), ), 57.535453706667425, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE1994( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 426.67945353, 72.39590835]), textiles=True, ), 88.335553057506502, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE1994( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 74.05216981, 276.45318193]), textiles=True, ), 10.612657890048272, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE1994( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 8.32281957, -73.58297716]), textiles=True, ), 60.368687261063329, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_delta_E_CIE1994(self): @@ -177,15 +178,19 @@ def test_n_dimensional_delta_E_CIE1994(self): Lab_1 = np.tile(Lab_1, (6, 1)) Lab_2 = np.tile(Lab_2, (6, 1)) delta_E = np.tile(delta_E, 6) - np.testing.assert_array_almost_equal( - delta_E_CIE1994(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_CIE1994(Lab_1, Lab_2), + delta_E, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Lab_1 = np.reshape(Lab_1, (2, 3, 3)) Lab_2 = np.reshape(Lab_2, (2, 3, 3)) delta_E = np.reshape(delta_E, (2, 3)) - np.testing.assert_array_almost_equal( - delta_E_CIE1994(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_CIE1994(Lab_1, Lab_2), + delta_E, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_delta_E_CIE1994(self): @@ -201,10 +206,10 @@ def test_domain_range_scale_delta_E_CIE1994(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_CIE1994(Lab_1 * factor, Lab_2 * factor), delta_E, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -228,61 +233,61 @@ class TestDelta_E_CIE2000(unittest.TestCase): def test_delta_E_CIE2000(self): """Test :func:`colour.difference.delta_e.delta_E_CIE2000` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE2000( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 426.67945353, 72.39590835]), ), 94.03564903, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE2000( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 74.05216981, 276.45318193]), ), 14.87906419, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE2000( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 8.32281957, -73.58297716]), ), 68.23111251, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE2000( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([50.00000000, 426.67945353, 72.39590835]), textiles=True, ), 95.79205352, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE2000( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([50.00000000, 74.05216981, 276.45318193]), textiles=True, ), 23.55420943, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CIE2000( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([50.00000000, 8.32281957, -73.58297716]), textiles=True, ), 70.63213819, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_delta_E_CIE2000(self): @@ -298,15 +303,19 @@ def test_n_dimensional_delta_E_CIE2000(self): Lab_1 = np.tile(Lab_1, (6, 1)) Lab_2 = np.tile(Lab_2, (6, 1)) delta_E = np.tile(delta_E, 6) - np.testing.assert_array_almost_equal( - delta_E_CIE2000(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_CIE2000(Lab_1, Lab_2), + delta_E, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Lab_1 = np.reshape(Lab_1, (2, 3, 3)) Lab_2 = np.reshape(Lab_2, (2, 3, 3)) delta_E = np.reshape(delta_E, (2, 3)) - np.testing.assert_array_almost_equal( - delta_E_CIE2000(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_CIE2000(Lab_1, Lab_2), + delta_E, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_delta_E_CIE2000(self): @@ -322,10 +331,10 @@ def test_domain_range_scale_delta_E_CIE2000(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_CIE2000(Lab_1 * factor, Lab_2 * factor), delta_E, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -504,8 +513,8 @@ def test_delta_E_CIE2000_Sharma2004(self): ] ) - np.testing.assert_array_almost_equal( - delta_E_CIE2000(Lab_1, Lab_2), d_E, decimal=4 + np.testing.assert_allclose( + delta_E_CIE2000(Lab_1, Lab_2), d_E, atol=1e-4 ) @@ -518,61 +527,61 @@ class TestDelta_E_CMC(unittest.TestCase): def test_delta_E_CMC(self): """Test :func:`colour.difference.delta_e.delta_E_CMC` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CMC( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 426.67945353, 72.39590835]), ), 172.70477129, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CMC( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 74.05216981, 276.45318193]), ), 20.59732717, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CMC( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 8.32281957, -73.58297716]), ), 121.71841479, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CMC( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 426.67945353, 72.39590835]), l=1, ), 172.70477129, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CMC( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 74.05216981, 276.45318193]), l=1, ), 20.59732717, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_CMC( np.array([100.00000000, 21.57210357, 272.22819350]), np.array([100.00000000, 8.32281957, -73.58297716]), l=1, ), 121.71841479, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_delta_E_CMC(self): @@ -588,15 +597,15 @@ def test_n_dimensional_delta_E_CMC(self): Lab_1 = np.tile(Lab_1, (6, 1)) Lab_2 = np.tile(Lab_2, (6, 1)) delta_E = np.tile(delta_E, 6) - np.testing.assert_array_almost_equal( - delta_E_CMC(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_CMC(Lab_1, Lab_2), delta_E, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab_1 = np.reshape(Lab_1, (2, 3, 3)) Lab_2 = np.reshape(Lab_2, (2, 3, 3)) delta_E = np.reshape(delta_E, (2, 3)) - np.testing.assert_array_almost_equal( - delta_E_CMC(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_CMC(Lab_1, Lab_2), delta_E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_delta_E_CMC(self): @@ -612,10 +621,10 @@ def test_domain_range_scale_delta_E_CMC(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_CMC(Lab_1 * factor, Lab_2 * factor), delta_E, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -639,94 +648,94 @@ class TestDelta_E_ITP(unittest.TestCase): def test_delta_E_ITP(self): """Test :func:`colour.difference.delta_e.delta_E_ITP` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (110, 82, 69), Dark Skin np.array([0.4885468072, -0.04739350675, 0.07475401302]), np.array([0.4899203231, -0.04567508203, 0.07361341775]), ), 1.426572247, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (110, 82, 69), 100% White np.array([0.7538438727, 0, -6.25e-16]), np.array([0.7538912244, 0.001930922514, -0.0003599955951]), ), 0.7426668055, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (0, 0, 0), 100% Black np.array([0.1596179061, 0, -1.21e-16]), np.array([0.1603575152, 0.02881444889, -0.009908665843]), ), 12.60096264, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (255, 0, 0), 100% Red np.array([0.5965650331, -0.2083210482, 0.3699729716]), np.array([0.596263079, -0.1629742033, 0.3617767026]), ), 17.36012552, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (0, 255, 0), 100% Green np.array([0.7055787513, -0.4063731514, -0.07278767382]), np.array([0.7046946082, -0.3771037586, -0.07141626753]), ), 10.60227327, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (255, 0, 0), 100% Blue np.array([0.5180652611, 0.2932420978, -0.1873112695]), np.array([0.5167090868, 0.298191609, -0.1824609953]), ), 4.040270489, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (0, 255, 255), 100% Cyan np.array([0.7223275939, -0.01290632441, -0.1139004748]), np.array([0.7215329274, -0.007863821961, -0.1106683944]), ), 3.00633812, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (255, 0, 255), 100% Magenta np.array([0.6401125212, 0.280225698, 0.1665590804]), np.array([0.640473651, 0.2819981563, 0.1654050172]), ), 1.07944277, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_ITP( # RGB: (255, 255, 0), 100% Yellow np.array([0.7413041405, -0.3638807621, 0.04959414794]), np.array([0.7412815181, -0.3299076141, 0.04545287368]), ), 12.5885645, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/difference/tests/test_din99.py b/colour/difference/tests/test_din99.py index f76e070330..f7f99385ad 100644 --- a/colour/difference/tests/test_din99.py +++ b/colour/difference/tests/test_din99.py @@ -1,12 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.difference.din99` module.""" -import numpy as np import unittest from itertools import product -from colour.difference import delta_E_DIN99 +import numpy as np +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.difference import delta_E_DIN99 from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -30,61 +31,61 @@ class TestDelta_E_DIN99(unittest.TestCase): def test_delta_E_DIN99(self): """Test :func:`colour.difference.din99.delta_E_DIN99` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_DIN99( np.array([60.25740000, -34.00990000, 36.26770000]), np.array([60.46260000, -34.17510000, 39.43870000]), ), 1.177216620111552, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_DIN99( np.array([63.01090000, -31.09610000, -5.86630000]), np.array([62.81870000, -29.79460000, -4.08640000]), ), 0.987529977993114, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_DIN99( np.array([35.08310000, -44.11640000, 3.79330000]), np.array([35.02320000, -40.07160000, 1.59010000]), ), 1.535894757971742, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_DIN99( np.array([60.25740000, -34.00990000, 36.26770000]), np.array([60.46260000, -34.17510000, 39.43870000]), textiles=True, ), 1.215652775586509, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_DIN99( np.array([63.01090000, -31.09610000, -5.86630000]), np.array([62.81870000, -29.79460000, -4.08640000]), textiles=True, ), 1.025997138865984, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( delta_E_DIN99( np.array([35.08310000, -44.11640000, 3.79330000]), np.array([35.02320000, -40.07160000, 1.59010000]), textiles=True, ), 1.539922810033725, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_delta_E_DIN99(self): @@ -100,15 +101,15 @@ def test_n_dimensional_delta_E_DIN99(self): Lab_1 = np.tile(Lab_1, (6, 1)) Lab_2 = np.tile(Lab_2, (6, 1)) delta_E = np.tile(delta_E, 6) - np.testing.assert_array_almost_equal( - delta_E_DIN99(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_DIN99(Lab_1, Lab_2), delta_E, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab_1 = np.reshape(Lab_1, (2, 3, 3)) Lab_2 = np.reshape(Lab_2, (2, 3, 3)) delta_E = np.reshape(delta_E, (2, 3)) - np.testing.assert_array_almost_equal( - delta_E_DIN99(Lab_1, Lab_2), delta_E, decimal=7 + np.testing.assert_allclose( + delta_E_DIN99(Lab_1, Lab_2), delta_E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_delta_E_DIN99(self): @@ -124,10 +125,10 @@ def test_domain_range_scale_delta_E_DIN99(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( delta_E_DIN99(Lab_1 * factor, Lab_2 * factor), delta_E, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/difference/tests/test_huang2015.py b/colour/difference/tests/test_huang2015.py index 21a8a671b8..5dfa86cdc6 100644 --- a/colour/difference/tests/test_huang2015.py +++ b/colour/difference/tests/test_huang2015.py @@ -1,9 +1,11 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.difference.huang2015` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.difference import power_function_Huang2015 __author__ = "Colour Developers" @@ -32,10 +34,10 @@ def test_power_function_Huang2015(self): d_E = np.array([2.0425, 2.8615, 3.4412]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( power_function_Huang2015(d_E), np.array([2.35748796, 2.98505036, 3.39651062]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/difference/tests/test_stress.py b/colour/difference/tests/test_stress.py index 017a15d593..d3b887fac7 100644 --- a/colour/difference/tests/test_stress.py +++ b/colour/difference/tests/test_stress.py @@ -1,9 +1,11 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.difference.stress` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.difference import index_stress __author__ = "Colour Developers" @@ -33,8 +35,10 @@ def test_index_stress(self): d_E = np.array([2.0425, 2.8615, 3.4412]) d_V = np.array([1.2644, 1.2630, 1.8731]) - self.assertAlmostEqual( - index_stress(d_E, d_V), 0.121170939369957, places=7 + np.testing.assert_allclose( + index_stress(d_E, d_V), + 0.121170939369957, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/examples/algebra/examples_interpolation.py b/colour/examples/algebra/examples_interpolation.py index 2dd52cb2d2..15cb37d5af 100644 --- a/colour/examples/algebra/examples_interpolation.py +++ b/colour/examples/algebra/examples_interpolation.py @@ -1,8 +1,9 @@ """Showcases interpolation computations.""" +import os + import matplotlib.pyplot as plt import numpy as np -import os import colour from colour.hints import cast diff --git a/colour/examples/characterisation/examples_colour_checkers.py b/colour/examples/characterisation/examples_colour_checkers.py index 91940365ef..8236cb8751 100644 --- a/colour/examples/characterisation/examples_colour_checkers.py +++ b/colour/examples/characterisation/examples_colour_checkers.py @@ -1,8 +1,9 @@ """Showcases colour rendition charts computations.""" -import numpy as np from pprint import pprint +import numpy as np + import colour from colour.utilities import message_box diff --git a/colour/examples/characterisation/examples_correction.py b/colour/examples/characterisation/examples_correction.py index 50dfe440cc..c5294e0135 100644 --- a/colour/examples/characterisation/examples_correction.py +++ b/colour/examples/characterisation/examples_correction.py @@ -1,6 +1,7 @@ """Showcases colour correction computations.""" import numpy as np + import colour from colour.utilities import message_box diff --git a/colour/examples/colorimetry/examples_luminance.py b/colour/examples/colorimetry/examples_luminance.py index 254648a4b3..e94c90e073 100644 --- a/colour/examples/colorimetry/examples_luminance.py +++ b/colour/examples/colorimetry/examples_luminance.py @@ -1,7 +1,6 @@ """Showcases *Luminance* computations.""" import colour - from colour.utilities import message_box message_box('"Luminance" Computations') diff --git a/colour/examples/contrast/examples_contrast.py b/colour/examples/contrast/examples_contrast.py index e24b88613c..4f1e3f12f1 100644 --- a/colour/examples/contrast/examples_contrast.py +++ b/colour/examples/contrast/examples_contrast.py @@ -7,8 +7,8 @@ import colour from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float, as_float_array, message_box from colour.plotting import colour_style, plot_single_function +from colour.utilities import as_float, as_float_array, message_box message_box("Contrast Sensitivity Computations") diff --git a/colour/examples/examples_colour.py b/colour/examples/examples_colour.py index bfb0739aad..c7f1a9ca63 100644 --- a/colour/examples/examples_colour.py +++ b/colour/examples/examples_colour.py @@ -1,16 +1,17 @@ """Showcases overall *Colour* examples.""" -import numpy as np import warnings +import numpy as np + import colour from colour.hints import ArrayLike from colour.utilities import ( filter_warnings, message_box, - warning, runtime_warning, usage_warning, + warning, ) message_box("Automatic Colour Conversion Graph") diff --git a/colour/examples/io/examples_luts.py b/colour/examples/io/examples_luts.py index eb2c8764bc..7cde31369b 100644 --- a/colour/examples/io/examples_luts.py +++ b/colour/examples/io/examples_luts.py @@ -1,8 +1,9 @@ """Showcases Look Up Table (LUT) data related examples.""" -import numpy as np import os +import numpy as np + import colour from colour.utilities import message_box diff --git a/colour/examples/io/resources/babelcolor_average.csv b/colour/examples/io/resources/babelcolor_average.csv index 65b9117777..abefbc929e 100644 --- a/colour/examples/io/resources/babelcolor_average.csv +++ b/colour/examples/io/resources/babelcolor_average.csv @@ -1 +1,37 @@ -wavelength,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 380,0.055,0.117,0.130,0.051,0.144,0.136,0.054,0.122,0.096,0.092,0.061,0.063,0.066,0.052,0.050,0.058,0.145,0.108,0.189,0.171,0.144,0.105,0.068,0.031 390,0.058,0.143,0.177,0.054,0.198,0.179,0.054,0.164,0.115,0.116,0.061,0.063,0.079,0.053,0.049,0.054,0.195,0.141,0.255,0.232,0.192,0.131,0.077,0.032 400,0.061,0.175,0.251,0.056,0.294,0.247,0.053,0.229,0.131,0.146,0.062,0.063,0.102,0.054,0.048,0.052,0.283,0.192,0.423,0.365,0.272,0.163,0.084,0.032 410,0.062,0.191,0.306,0.057,0.375,0.297,0.054,0.286,0.135,0.169,0.063,0.064,0.146,0.055,0.047,0.052,0.346,0.236,0.660,0.507,0.331,0.180,0.087,0.033 420,0.062,0.196,0.324,0.058,0.408,0.320,0.054,0.327,0.133,0.178,0.064,0.064,0.200,0.057,0.047,0.053,0.362,0.261,0.811,0.567,0.350,0.186,0.089,0.033 430,0.062,0.199,0.330,0.059,0.421,0.337,0.055,0.361,0.132,0.173,0.066,0.064,0.244,0.059,0.047,0.054,0.354,0.286,0.862,0.583,0.357,0.190,0.090,0.033 440,0.062,0.204,0.333,0.060,0.426,0.355,0.055,0.388,0.130,0.158,0.069,0.065,0.282,0.061,0.047,0.056,0.334,0.317,0.877,0.588,0.361,0.193,0.092,0.033 450,0.062,0.213,0.331,0.061,0.426,0.381,0.055,0.400,0.128,0.139,0.075,0.066,0.309,0.066,0.047,0.059,0.306,0.353,0.884,0.590,0.363,0.194,0.092,0.033 460,0.062,0.228,0.323,0.062,0.419,0.419,0.056,0.392,0.125,0.119,0.085,0.067,0.308,0.075,0.046,0.067,0.276,0.390,0.891,0.591,0.363,0.194,0.091,0.032 470,0.062,0.251,0.311,0.063,0.403,0.466,0.057,0.362,0.120,0.101,0.105,0.068,0.278,0.093,0.045,0.081,0.248,0.426,0.896,0.590,0.361,0.192,0.090,0.032 480,0.062,0.280,0.298,0.065,0.379,0.510,0.058,0.316,0.115,0.087,0.139,0.071,0.231,0.125,0.044,0.107,0.218,0.446,0.899,0.588,0.359,0.191,0.090,0.032 490,0.063,0.309,0.285,0.067,0.346,0.546,0.061,0.260,0.110,0.075,0.192,0.076,0.178,0.178,0.044,0.152,0.190,0.444,0.904,0.588,0.358,0.191,0.090,0.032 500,0.065,0.329,0.269,0.075,0.311,0.567,0.068,0.209,0.105,0.066,0.271,0.087,0.130,0.246,0.045,0.225,0.168,0.423,0.907,0.589,0.358,0.191,0.090,0.032 510,0.070,0.333,0.250,0.101,0.281,0.574,0.089,0.168,0.100,0.060,0.376,0.125,0.094,0.307,0.046,0.336,0.149,0.385,0.909,0.589,0.359,0.192,0.090,0.032 520,0.076,0.315,0.231,0.145,0.254,0.569,0.125,0.138,0.095,0.056,0.476,0.206,0.070,0.337,0.047,0.462,0.127,0.337,0.911,0.591,0.360,0.192,0.090,0.032 530,0.079,0.286,0.214,0.178,0.229,0.551,0.154,0.117,0.093,0.053,0.531,0.305,0.054,0.334,0.048,0.559,0.107,0.283,0.910,0.590,0.360,0.192,0.090,0.032 540,0.081,0.273,0.199,0.184,0.214,0.524,0.174,0.104,0.092,0.051,0.549,0.383,0.046,0.317,0.049,0.616,0.100,0.231,0.911,0.590,0.361,0.192,0.090,0.032 550,0.084,0.276,0.185,0.170,0.208,0.488,0.199,0.096,0.093,0.051,0.546,0.431,0.042,0.293,0.050,0.650,0.102,0.185,0.914,0.590,0.361,0.192,0.090,0.032 560,0.091,0.277,0.169,0.149,0.202,0.445,0.248,0.090,0.096,0.052,0.528,0.469,0.039,0.262,0.054,0.672,0.104,0.146,0.913,0.589,0.360,0.192,0.090,0.032 570,0.103,0.289,0.157,0.133,0.194,0.400,0.335,0.086,0.108,0.052,0.504,0.518,0.038,0.230,0.060,0.694,0.109,0.118,0.916,0.591,0.362,0.193,0.090,0.032 580,0.119,0.339,0.149,0.122,0.193,0.350,0.444,0.084,0.156,0.051,0.471,0.568,0.038,0.198,0.072,0.710,0.137,0.101,0.915,0.590,0.362,0.192,0.090,0.032 590,0.134,0.420,0.145,0.115,0.200,0.299,0.538,0.084,0.265,0.052,0.428,0.607,0.038,0.165,0.104,0.723,0.200,0.090,0.916,0.590,0.361,0.192,0.089,0.032 600,0.143,0.488,0.142,0.109,0.214,0.252,0.587,0.084,0.399,0.058,0.381,0.628,0.038,0.135,0.178,0.731,0.290,0.082,0.914,0.587,0.359,0.191,0.089,0.032 610,0.147,0.525,0.141,0.105,0.230,0.221,0.595,0.084,0.500,0.073,0.347,0.637,0.039,0.115,0.312,0.739,0.400,0.076,0.915,0.585,0.358,0.189,0.088,0.032 620,0.151,0.546,0.141,0.104,0.241,0.204,0.591,0.084,0.556,0.096,0.327,0.640,0.039,0.104,0.467,0.746,0.516,0.074,0.918,0.583,0.355,0.188,0.087,0.032 630,0.158,0.562,0.141,0.106,0.254,0.196,0.587,0.085,0.579,0.119,0.318,0.642,0.040,0.098,0.581,0.752,0.615,0.073,0.919,0.580,0.352,0.186,0.086,0.032 640,0.168,0.578,0.143,0.109,0.279,0.191,0.584,0.090,0.588,0.141,0.312,0.645,0.041,0.094,0.644,0.758,0.687,0.073,0.921,0.578,0.350,0.184,0.086,0.032 650,0.179,0.595,0.147,0.112,0.313,0.188,0.584,0.098,0.591,0.166,0.310,0.648,0.042,0.092,0.675,0.764,0.732,0.074,0.923,0.576,0.348,0.182,0.085,0.032 660,0.188,0.612,0.152,0.114,0.348,0.191,0.590,0.109,0.593,0.194,0.314,0.651,0.044,0.093,0.690,0.769,0.760,0.076,0.924,0.574,0.345,0.181,0.084,0.032 670,0.190,0.625,0.154,0.114,0.366,0.199,0.603,0.123,0.594,0.227,0.327,0.653,0.045,0.097,0.698,0.771,0.774,0.077,0.922,0.572,0.343,0.179,0.084,0.032 680,0.186,0.638,0.150,0.112,0.366,0.212,0.620,0.143,0.598,0.265,0.345,0.657,0.046,0.102,0.706,0.776,0.783,0.076,0.922,0.571,0.340,0.178,0.083,0.032 690,0.181,0.656,0.144,0.112,0.359,0.223,0.639,0.169,0.602,0.309,0.363,0.664,0.046,0.108,0.715,0.782,0.793,0.075,0.925,0.569,0.338,0.176,0.083,0.032 700,0.182,0.678,0.136,0.115,0.358,0.232,0.655,0.205,0.607,0.355,0.376,0.673,0.048,0.113,0.724,0.790,0.803,0.073,0.927,0.568,0.335,0.174,0.082,0.032 710,0.187,0.700,0.132,0.120,0.365,0.233,0.663,0.244,0.609,0.396,0.381,0.680,0.052,0.115,0.730,0.796,0.812,0.072,0.930,0.568,0.334,0.173,0.081,0.032 720,0.196,0.717,0.135,0.125,0.377,0.229,0.663,0.287,0.609,0.436,0.378,0.684,0.057,0.114,0.734,0.799,0.817,0.074,0.930,0.566,0.332,0.172,0.081,0.032 730,0.209,0.734,0.147,0.130,0.398,0.229,0.667,0.332,0.610,0.478,0.379,0.688,0.065,0.114,0.738,0.804,0.825,0.079,0.933,0.566,0.331,0.171,0.081,0.033 \ No newline at end of file +wavelength,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 +380,0.055,0.117,0.130,0.051,0.144,0.136,0.054,0.122,0.096,0.092,0.061,0.063,0.066,0.052,0.050,0.058,0.145,0.108,0.189,0.171,0.144,0.105,0.068,0.031 +390,0.058,0.143,0.177,0.054,0.198,0.179,0.054,0.164,0.115,0.116,0.061,0.063,0.079,0.053,0.049,0.054,0.195,0.141,0.255,0.232,0.192,0.131,0.077,0.032 +400,0.061,0.175,0.251,0.056,0.294,0.247,0.053,0.229,0.131,0.146,0.062,0.063,0.102,0.054,0.048,0.052,0.283,0.192,0.423,0.365,0.272,0.163,0.084,0.032 +410,0.062,0.191,0.306,0.057,0.375,0.297,0.054,0.286,0.135,0.169,0.063,0.064,0.146,0.055,0.047,0.052,0.346,0.236,0.660,0.507,0.331,0.180,0.087,0.033 +420,0.062,0.196,0.324,0.058,0.408,0.320,0.054,0.327,0.133,0.178,0.064,0.064,0.200,0.057,0.047,0.053,0.362,0.261,0.811,0.567,0.350,0.186,0.089,0.033 +430,0.062,0.199,0.330,0.059,0.421,0.337,0.055,0.361,0.132,0.173,0.066,0.064,0.244,0.059,0.047,0.054,0.354,0.286,0.862,0.583,0.357,0.190,0.090,0.033 +440,0.062,0.204,0.333,0.060,0.426,0.355,0.055,0.388,0.130,0.158,0.069,0.065,0.282,0.061,0.047,0.056,0.334,0.317,0.877,0.588,0.361,0.193,0.092,0.033 +450,0.062,0.213,0.331,0.061,0.426,0.381,0.055,0.400,0.128,0.139,0.075,0.066,0.309,0.066,0.047,0.059,0.306,0.353,0.884,0.590,0.363,0.194,0.092,0.033 +460,0.062,0.228,0.323,0.062,0.419,0.419,0.056,0.392,0.125,0.119,0.085,0.067,0.308,0.075,0.046,0.067,0.276,0.390,0.891,0.591,0.363,0.194,0.091,0.032 +470,0.062,0.251,0.311,0.063,0.403,0.466,0.057,0.362,0.120,0.101,0.105,0.068,0.278,0.093,0.045,0.081,0.248,0.426,0.896,0.590,0.361,0.192,0.090,0.032 +480,0.062,0.280,0.298,0.065,0.379,0.510,0.058,0.316,0.115,0.087,0.139,0.071,0.231,0.125,0.044,0.107,0.218,0.446,0.899,0.588,0.359,0.191,0.090,0.032 +490,0.063,0.309,0.285,0.067,0.346,0.546,0.061,0.260,0.110,0.075,0.192,0.076,0.178,0.178,0.044,0.152,0.190,0.444,0.904,0.588,0.358,0.191,0.090,0.032 +500,0.065,0.329,0.269,0.075,0.311,0.567,0.068,0.209,0.105,0.066,0.271,0.087,0.130,0.246,0.045,0.225,0.168,0.423,0.907,0.589,0.358,0.191,0.090,0.032 +510,0.070,0.333,0.250,0.101,0.281,0.574,0.089,0.168,0.100,0.060,0.376,0.125,0.094,0.307,0.046,0.336,0.149,0.385,0.909,0.589,0.359,0.192,0.090,0.032 +520,0.076,0.315,0.231,0.145,0.254,0.569,0.125,0.138,0.095,0.056,0.476,0.206,0.070,0.337,0.047,0.462,0.127,0.337,0.911,0.591,0.360,0.192,0.090,0.032 +530,0.079,0.286,0.214,0.178,0.229,0.551,0.154,0.117,0.093,0.053,0.531,0.305,0.054,0.334,0.048,0.559,0.107,0.283,0.910,0.590,0.360,0.192,0.090,0.032 +540,0.081,0.273,0.199,0.184,0.214,0.524,0.174,0.104,0.092,0.051,0.549,0.383,0.046,0.317,0.049,0.616,0.100,0.231,0.911,0.590,0.361,0.192,0.090,0.032 +550,0.084,0.276,0.185,0.170,0.208,0.488,0.199,0.096,0.093,0.051,0.546,0.431,0.042,0.293,0.050,0.650,0.102,0.185,0.914,0.590,0.361,0.192,0.090,0.032 +560,0.091,0.277,0.169,0.149,0.202,0.445,0.248,0.090,0.096,0.052,0.528,0.469,0.039,0.262,0.054,0.672,0.104,0.146,0.913,0.589,0.360,0.192,0.090,0.032 +570,0.103,0.289,0.157,0.133,0.194,0.400,0.335,0.086,0.108,0.052,0.504,0.518,0.038,0.230,0.060,0.694,0.109,0.118,0.916,0.591,0.362,0.193,0.090,0.032 +580,0.119,0.339,0.149,0.122,0.193,0.350,0.444,0.084,0.156,0.051,0.471,0.568,0.038,0.198,0.072,0.710,0.137,0.101,0.915,0.590,0.362,0.192,0.090,0.032 +590,0.134,0.420,0.145,0.115,0.200,0.299,0.538,0.084,0.265,0.052,0.428,0.607,0.038,0.165,0.104,0.723,0.200,0.090,0.916,0.590,0.361,0.192,0.089,0.032 +600,0.143,0.488,0.142,0.109,0.214,0.252,0.587,0.084,0.399,0.058,0.381,0.628,0.038,0.135,0.178,0.731,0.290,0.082,0.914,0.587,0.359,0.191,0.089,0.032 +610,0.147,0.525,0.141,0.105,0.230,0.221,0.595,0.084,0.500,0.073,0.347,0.637,0.039,0.115,0.312,0.739,0.400,0.076,0.915,0.585,0.358,0.189,0.088,0.032 +620,0.151,0.546,0.141,0.104,0.241,0.204,0.591,0.084,0.556,0.096,0.327,0.640,0.039,0.104,0.467,0.746,0.516,0.074,0.918,0.583,0.355,0.188,0.087,0.032 +630,0.158,0.562,0.141,0.106,0.254,0.196,0.587,0.085,0.579,0.119,0.318,0.642,0.040,0.098,0.581,0.752,0.615,0.073,0.919,0.580,0.352,0.186,0.086,0.032 +640,0.168,0.578,0.143,0.109,0.279,0.191,0.584,0.090,0.588,0.141,0.312,0.645,0.041,0.094,0.644,0.758,0.687,0.073,0.921,0.578,0.350,0.184,0.086,0.032 +650,0.179,0.595,0.147,0.112,0.313,0.188,0.584,0.098,0.591,0.166,0.310,0.648,0.042,0.092,0.675,0.764,0.732,0.074,0.923,0.576,0.348,0.182,0.085,0.032 +660,0.188,0.612,0.152,0.114,0.348,0.191,0.590,0.109,0.593,0.194,0.314,0.651,0.044,0.093,0.690,0.769,0.760,0.076,0.924,0.574,0.345,0.181,0.084,0.032 +670,0.190,0.625,0.154,0.114,0.366,0.199,0.603,0.123,0.594,0.227,0.327,0.653,0.045,0.097,0.698,0.771,0.774,0.077,0.922,0.572,0.343,0.179,0.084,0.032 +680,0.186,0.638,0.150,0.112,0.366,0.212,0.620,0.143,0.598,0.265,0.345,0.657,0.046,0.102,0.706,0.776,0.783,0.076,0.922,0.571,0.340,0.178,0.083,0.032 +690,0.181,0.656,0.144,0.112,0.359,0.223,0.639,0.169,0.602,0.309,0.363,0.664,0.046,0.108,0.715,0.782,0.793,0.075,0.925,0.569,0.338,0.176,0.083,0.032 +700,0.182,0.678,0.136,0.115,0.358,0.232,0.655,0.205,0.607,0.355,0.376,0.673,0.048,0.113,0.724,0.790,0.803,0.073,0.927,0.568,0.335,0.174,0.082,0.032 +710,0.187,0.700,0.132,0.120,0.365,0.233,0.663,0.244,0.609,0.396,0.381,0.680,0.052,0.115,0.730,0.796,0.812,0.072,0.930,0.568,0.334,0.173,0.081,0.032 +720,0.196,0.717,0.135,0.125,0.377,0.229,0.663,0.287,0.609,0.436,0.378,0.684,0.057,0.114,0.734,0.799,0.817,0.074,0.930,0.566,0.332,0.172,0.081,0.032 +730,0.209,0.734,0.147,0.130,0.398,0.229,0.667,0.332,0.610,0.478,0.379,0.688,0.065,0.114,0.738,0.804,0.825,0.079,0.933,0.566,0.331,0.171,0.081,0.033 diff --git a/colour/examples/models/examples_rgb.py b/colour/examples/models/examples_rgb.py index 9cb77791ed..415ab3ffab 100644 --- a/colour/examples/models/examples_rgb.py +++ b/colour/examples/models/examples_rgb.py @@ -1,8 +1,9 @@ """Showcases *RGB* *colourspaces* computations.""" -import numpy as np from pprint import pprint +import numpy as np + import colour from colour.utilities import message_box diff --git a/colour/examples/plotting/examples_blindness.py b/colour/examples/plotting/examples_blindness.py index 4740666160..bd58ad6e53 100644 --- a/colour/examples/plotting/examples_blindness.py +++ b/colour/examples/plotting/examples_blindness.py @@ -1,8 +1,9 @@ """Showcases corresponding colour blindness plotting examples.""" -import numpy as np import os +import numpy as np + import colour from colour.plotting import ( colour_style, diff --git a/colour/examples/plotting/examples_characterisation_plots.py b/colour/examples/plotting/examples_characterisation_plots.py index 96c2eaa1f3..18a63114b3 100644 --- a/colour/examples/plotting/examples_characterisation_plots.py +++ b/colour/examples/plotting/examples_characterisation_plots.py @@ -5,8 +5,8 @@ import colour from colour.plotting import ( colour_style, - plot_single_colour_checker, plot_multi_sds, + plot_single_colour_checker, ) from colour.utilities import message_box diff --git a/colour/examples/plotting/examples_colorimetry_plots.py b/colour/examples/plotting/examples_colorimetry_plots.py index d54a2715d6..5bdde1c1e0 100644 --- a/colour/examples/plotting/examples_colorimetry_plots.py +++ b/colour/examples/plotting/examples_colorimetry_plots.py @@ -5,9 +5,9 @@ import colour from colour.plotting import ( SD_ASTMG173_ETR, + colour_style, plot_blackbody_colours, plot_blackbody_spectral_radiance, - colour_style, plot_multi_cmfs, plot_multi_illuminant_sds, plot_multi_lightness_functions, diff --git a/colour/examples/plotting/examples_models_plots.py b/colour/examples/plotting/examples_models_plots.py index 2d29735009..4daaf99b93 100644 --- a/colour/examples/plotting/examples_models_plots.py +++ b/colour/examples/plotting/examples_models_plots.py @@ -1,18 +1,19 @@ """Showcases colour models plotting examples.""" -import numpy as np from pprint import pprint +import numpy as np + import colour from colour.plotting import ( - plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931, - plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS, - plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS, + colour_style, + plot_multi_cctfs, plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931, plot_RGB_chromaticities_in_chromaticity_diagram_CIE1960UCS, plot_RGB_chromaticities_in_chromaticity_diagram_CIE1976UCS, - colour_style, - plot_multi_cctfs, + plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931, + plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS, + plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS, plot_single_cctf, ) from colour.utilities import message_box diff --git a/colour/examples/plotting/examples_section_plots.py b/colour/examples/plotting/examples_section_plots.py index 6eb1775d79..d889b058cc 100644 --- a/colour/examples/plotting/examples_section_plots.py +++ b/colour/examples/plotting/examples_section_plots.py @@ -6,8 +6,8 @@ import colour.plotting from colour.plotting import ( colour_style, - plot_visible_spectrum_section, plot_RGB_colourspace_section, + plot_visible_spectrum_section, ) from colour.utilities import message_box diff --git a/colour/examples/plotting/examples_tm3018.py b/colour/examples/plotting/examples_tm3018.py index 2780da4c7d..17d4f6431d 100644 --- a/colour/examples/plotting/examples_tm3018.py +++ b/colour/examples/plotting/examples_tm3018.py @@ -2,8 +2,8 @@ import colour from colour.plotting import ( - plot_single_sd_colour_rendition_report, colour_style, + plot_single_sd_colour_rendition_report, ) from colour.utilities import message_box diff --git a/colour/examples/plotting/examples_volume_plots.py b/colour/examples/plotting/examples_volume_plots.py index 2d0e89b085..796e98767f 100644 --- a/colour/examples/plotting/examples_volume_plots.py +++ b/colour/examples/plotting/examples_volume_plots.py @@ -3,9 +3,9 @@ import numpy as np from colour.plotting import ( + colour_style, plot_RGB_colourspaces_gamuts, plot_RGB_scatter, - colour_style, ) from colour.utilities import message_box diff --git a/colour/geometry/intersection.py b/colour/geometry/intersection.py index dc8c11c257..12b7318ba3 100644 --- a/colour/geometry/intersection.py +++ b/colour/geometry/intersection.py @@ -21,9 +21,10 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass +import numpy as np + from colour.algebra import euclidean_distance, sdiv, sdiv_mode from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import as_float_array, tsplit, tstack diff --git a/colour/geometry/primitives.py b/colour/geometry/primitives.py index a615f069db..16cfa15d7c 100644 --- a/colour/geometry/primitives.py +++ b/colour/geometry/primitives.py @@ -21,7 +21,7 @@ import numpy as np -from colour.constants import DEFAULT_INT_DTYPE, DEFAULT_FLOAT_DTYPE +from colour.constants import DTYPE_FLOAT_DEFAULT, DTYPE_INT_DEFAULT from colour.hints import ( Any, DTypeFloat, @@ -39,8 +39,8 @@ filter_kwargs, ones, optional, - zeros, validate_method, + zeros, ) __author__ = "Colour Developers" @@ -101,11 +101,11 @@ def primitive_grid( dtype_vertices :class:`numpy.dtype` to use for the grid vertices, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. dtype_indexes :class:`numpy.dtype` to use for the grid indexes, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_INT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_INT_DEFAULT` attribute. Returns ------- @@ -137,8 +137,8 @@ def primitive_grid( axis = MAPPING_PLANE_TO_AXIS.get(axis, axis).lower() # pyright: ignore - dtype_vertices = optional(dtype_vertices, DEFAULT_FLOAT_DTYPE) - dtype_indexes = optional(dtype_indexes, DEFAULT_INT_DTYPE) + dtype_vertices = optional(dtype_vertices, DTYPE_FLOAT_DEFAULT) + dtype_indexes = optional(dtype_indexes, DTYPE_INT_DEFAULT) x_grid = width_segments y_grid = height_segments @@ -263,11 +263,11 @@ def primitive_cube( dtype_vertices :class:`numpy.dtype` to use for the grid vertices, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. dtype_indexes :class:`numpy.dtype` to use for the grid indexes, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_INT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_INT_DEFAULT` attribute. Returns ------- @@ -351,8 +351,8 @@ def primitive_cube( ] ) - dtype_vertices = optional(dtype_vertices, DEFAULT_FLOAT_DTYPE) - dtype_indexes = optional(dtype_indexes, DEFAULT_INT_DTYPE) + dtype_vertices = optional(dtype_vertices, DTYPE_FLOAT_DEFAULT) + dtype_indexes = optional(dtype_indexes, DTYPE_INT_DEFAULT) w_s, h_s, d_s = width_segments, height_segments, depth_segments @@ -472,13 +472,13 @@ def primitive( :func:`colour.geometry.primitive_cube`}, :class:`numpy.dtype` to use for the grid indexes, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_INT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_INT_DEFAULT` attribute. dtype_vertices {:func:`colour.geometry.primitive_grid`, :func:`colour.geometry.primitive_cube`}, :class:`numpy.dtype` to use for the grid vertices, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. height {:func:`colour.geometry.primitive_grid`, :func:`colour.geometry.primitive_cube`}, diff --git a/colour/geometry/section.py b/colour/geometry/section.py index aa7cf78db9..5b8cd0a65d 100644 --- a/colour/geometry/section.py +++ b/colour/geometry/section.py @@ -12,7 +12,7 @@ import numpy as np from colour.algebra import linear_conversion -from colour.constants import DEFAULT_FLOAT_DTYPE +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.hints import Any, ArrayLike, Literal, NDArrayFloat, cast from colour.utilities import ( as_float_array, @@ -135,7 +135,7 @@ def close_chord(vertices: ArrayLike) -> NDArrayFloat: def unique_vertices( vertices: ArrayLike, - decimals: int = np.finfo(cast(Any, DEFAULT_FLOAT_DTYPE)).precision - 1, + decimals: int = np.finfo(cast(Any, DTYPE_FLOAT_DEFAULT)).precision - 1, ) -> NDArrayFloat: """ Return the unique vertices from given vertices. diff --git a/colour/geometry/tests/test_ellipse.py b/colour/geometry/tests/test_ellipse.py index 80367e4c40..f588c055e8 100644 --- a/colour/geometry/tests/test_ellipse.py +++ b/colour/geometry/tests/test_ellipse.py @@ -1,14 +1,16 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.geometry.ellipse` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.geometry import ( - ellipse_coefficients_general_form, ellipse_coefficients_canonical_form, - point_at_angle_on_ellipse, + ellipse_coefficients_general_form, ellipse_fitting_Halir1998, + point_at_angle_on_ellipse, ) __author__ = "Colour Developers" @@ -38,20 +40,20 @@ def test_ellipse_coefficients_canonical_form(self): ellipse_coefficients_canonical_form` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ellipse_coefficients_canonical_form( np.array([2.5, -3.0, 2.5, -1.0, -1.0, -3.5]) ), np.array([0.5, 0.5, 2, 1, 45]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ellipse_coefficients_canonical_form( np.array([1.0, 0.0, 1.0, 0.0, 0.0, -1.0]) ), np.array([0.0, 0.0, 1, 1, 0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -67,16 +69,16 @@ def test_ellipse_coefficients_general_form(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ellipse_coefficients_general_form(np.array([0.5, 0.5, 2, 1, 45])), np.array([2.5, -3.0, 2.5, -1.0, -1.0, -3.5]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ellipse_coefficients_general_form(np.array([0.0, 0.0, 1, 1, 0])), np.array([1.0, 0.0, 1.0, 0.0, 0.0, -1.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -92,15 +94,15 @@ def test_point_at_angle_on_ellipse(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( point_at_angle_on_ellipse( np.array([0, 90, 180, 270]), np.array([0.0, 0.0, 2, 1, 0]) ), np.array([[2, 0], [0, 1], [-2, 0], [0, -1]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( point_at_angle_on_ellipse( np.linspace(0, 360, 10), np.array([0.5, 0.5, 2, 1, 45]) ), @@ -118,7 +120,7 @@ def test_point_at_angle_on_ellipse(self): [1.91421356, 1.91421356], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -134,7 +136,7 @@ def test_ellipse_fitting_Halir1998(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ellipse_fitting_Halir1998( np.array([[2, 0], [0, 1], [-2, 0], [0, -1]]) ), @@ -148,7 +150,7 @@ def test_ellipse_fitting_Halir1998(self): -0.97014250, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/geometry/tests/test_intersection.py b/colour/geometry/tests/test_intersection.py index d5746257c8..3a3cf7533d 100644 --- a/colour/geometry/tests/test_intersection.py +++ b/colour/geometry/tests/test_intersection.py @@ -1,9 +1,11 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.geometry.intersection` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.geometry import ( extend_line_segment, intersect_line_segments, @@ -31,33 +33,33 @@ class TestExtendLineSegment(unittest.TestCase): def test_extend_line_segment(self): """Test :func:`colour.geometry.intersection.extend_line_segment` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( extend_line_segment( np.array([0.95694934, 0.13720932]), np.array([0.28382835, 0.60608318]), ), np.array([-0.5367248, 1.17765341]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( extend_line_segment( np.array([0.95694934, 0.13720932]), np.array([0.28382835, 0.60608318]), 5, ), np.array([-3.81893739, 3.46393435]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( extend_line_segment( np.array([0.95694934, 0.13720932]), np.array([0.28382835, 0.60608318]), -1, ), np.array([1.1043815, 0.03451295]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -90,7 +92,7 @@ def test_intersect_line_segments(self): s = intersect_line_segments(l_1, l_2) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( s.xy, np.array( [ @@ -108,7 +110,7 @@ def test_intersect_line_segments(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_array_equal( diff --git a/colour/geometry/tests/test_primitives.py b/colour/geometry/tests/test_primitives.py index c28dfc784a..16dcdb23a2 100644 --- a/colour/geometry/tests/test_primitives.py +++ b/colour/geometry/tests/test_primitives.py @@ -1,13 +1,15 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.geometry.primitives` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.geometry import ( MAPPING_PLANE_TO_AXIS, - primitive_grid, primitive_cube, + primitive_grid, ) __author__ = "Colour Developers" @@ -36,7 +38,7 @@ def test_primitive_grid(self): """ vertices, faces, outline = primitive_grid() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["position"], np.array( [ @@ -46,22 +48,22 @@ def test_primitive_grid(self): [0.5, -0.5, 0.0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["uv"], np.array([[0, 1], [1, 1], [0, 0], [1, 0]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["normal"], np.array([[0, 0, 1], [0, 0, 1], [0, 0, 1], [0, 0, 1]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["colour"], np.array( [ @@ -71,7 +73,7 @@ def test_primitive_grid(self): [1, 0, 0, 1], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_equal(faces, np.array([[0, 2, 1], [2, 3, 1]])) @@ -88,7 +90,7 @@ def test_primitive_grid(self): axis="+z", ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["position"], np.array( [ @@ -100,10 +102,10 @@ def test_primitive_grid(self): [0.10000000, -0.20000000, 0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["uv"], np.array( [ @@ -115,10 +117,10 @@ def test_primitive_grid(self): [1.00000000, 0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["normal"], np.array( [ @@ -130,10 +132,10 @@ def test_primitive_grid(self): [0, 0, 1], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["colour"], np.array( [ @@ -145,7 +147,7 @@ def test_primitive_grid(self): [0.75000000, 0.00000000, 0.00000000, 1.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_equal( @@ -177,12 +179,12 @@ def test_primitive_grid(self): ) for plane in MAPPING_PLANE_TO_AXIS: - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_grid(axis=plane)[0]["position"], primitive_grid(axis=MAPPING_PLANE_TO_AXIS[plane])[0][ "position" ], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -199,7 +201,7 @@ def test_primitive_cube(self): """ vertices, faces, outline = primitive_cube() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["position"], np.array( [ @@ -229,10 +231,10 @@ def test_primitive_cube(self): [0.5, 0.5, -0.5], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["uv"], np.array( [ @@ -262,10 +264,10 @@ def test_primitive_cube(self): [1, 0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["normal"], np.array( [ @@ -295,10 +297,10 @@ def test_primitive_cube(self): [1, 0, 0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["colour"], np.array( [ @@ -328,7 +330,7 @@ def test_primitive_cube(self): [1, 1, 0, 1], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_equal( @@ -392,7 +394,7 @@ def test_primitive_cube(self): depth_segments=3, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["position"], np.array( [ @@ -450,10 +452,10 @@ def test_primitive_cube(self): [0.10000000, 0.30000001, -0.20000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["uv"], np.array( [ @@ -511,10 +513,10 @@ def test_primitive_cube(self): [1.00000000, 0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["normal"], np.array( [ @@ -572,10 +574,10 @@ def test_primitive_cube(self): [1, 0, 0], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices["colour"], np.array( [ @@ -633,7 +635,7 @@ def test_primitive_cube(self): [0.66666669, 1.00000000, 0.16666667, 1.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_equal( @@ -785,12 +787,12 @@ def test_primitive_cube(self): ) for plane in MAPPING_PLANE_TO_AXIS: - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_cube(planes=[plane])[0]["position"], primitive_cube(planes=[MAPPING_PLANE_TO_AXIS[plane]])[0][ "position" ], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/geometry/tests/test_section.py b/colour/geometry/tests/test_section.py index 19c7a1fc63..ccc8d8e2e8 100644 --- a/colour/geometry/tests/test_section.py +++ b/colour/geometry/tests/test_section.py @@ -1,15 +1,17 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.geometry.section` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.geometry import hull_section, primitive_cube from colour.geometry.section import ( - edges_to_chord, close_chord, + edges_to_chord, unique_vertices, ) -from colour.geometry import primitive_cube, hull_section from colour.utilities import is_trimesh_installed __author__ = "Colour Developers" @@ -49,7 +51,7 @@ def test_edges_to_chord(self): ] ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( edges_to_chord(edges), np.array( [ @@ -71,9 +73,10 @@ def test_edges_to_chord(self): [0.0, -0.5, 0.0], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( edges_to_chord(edges, 5), np.array( [ @@ -95,6 +98,7 @@ def test_edges_to_chord(self): [-0.5, 0.5, 0.0], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -107,9 +111,10 @@ class TestCloseChord(unittest.TestCase): def test_close_chord(self): """Test :func:`colour.geometry.section.close_chord` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( close_chord(np.array([[0.0, 0.5, 0.0], [0.0, 0.0, 0.5]])), np.array([[0.0, 0.5, 0.0], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0]]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -122,14 +127,15 @@ class TestUniqueVertices(unittest.TestCase): def test_unique_vertices(self): """Test :func:`colour.geometry.section.unique_vertices` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( unique_vertices( np.array([[0.0, 0.5, 0.0], [0.0, 0.0, 0.5], [0.0, 0.5, 0.0]]) ), np.array([[0.0, 0.5, 0.0], [0.0, 0.0, 0.5]]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( unique_vertices( np.array( [[0.0, 0.51, 0.0], [0.0, 0.0, 0.51], [0.0, 0.52, 0.0]] @@ -137,6 +143,7 @@ def test_unique_vertices(self): 1, ), np.array([[0.0, 0.5, 0.0], [0.0, 0.0, 0.5]]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -157,7 +164,7 @@ def test_hull_section(self): vertices, faces, _outline = primitive_cube(1, 1, 1, 2, 2, 2) hull = trimesh.Trimesh(vertices["position"], faces, process=False) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hull_section(hull, origin=0), np.array( [ @@ -172,9 +179,10 @@ def test_hull_section(self): [0.0, -0.5, 0.0], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hull_section(hull, axis="+x", origin=0), np.array( [ @@ -189,9 +197,10 @@ def test_hull_section(self): [0.0, 0.0, -0.5], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hull_section(hull, axis="+y", origin=0), np.array( [ @@ -206,10 +215,11 @@ def test_hull_section(self): [0.0, 0.0, -0.5], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) hull.vertices = (hull.vertices + 0.5) * 2 - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hull_section(hull, origin=0.5, normalise=True), np.array( [ @@ -224,6 +234,7 @@ def test_hull_section(self): [1.0, 0.0, 1.0], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertRaises(ValueError, hull_section, hull, origin=-1) diff --git a/colour/geometry/tests/test_vertices.py b/colour/geometry/tests/test_vertices.py index 01203e0d24..1984a50c37 100644 --- a/colour/geometry/tests/test_vertices.py +++ b/colour/geometry/tests/test_vertices.py @@ -1,14 +1,16 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.geometry.vertices` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.geometry import ( MAPPING_PLANE_TO_AXIS, - primitive_vertices_quad_mpl, - primitive_vertices_grid_mpl, primitive_vertices_cube_mpl, + primitive_vertices_grid_mpl, + primitive_vertices_quad_mpl, primitive_vertices_sphere, ) @@ -39,25 +41,25 @@ def test_primitive_vertices_quad_mpl(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_quad_mpl(), np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_quad_mpl(axis="+y"), np.array([[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_quad_mpl(axis="+x"), np.array([[0, 0, 0], [0, 1, 0], [0, 1, 1], [0, 0, 1]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_quad_mpl( width=0.2, height=0.4, @@ -73,10 +75,10 @@ def test_primitive_vertices_quad_mpl(self): [0.2, 0.8, 0.6], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_quad_mpl( width=-0.2, height=-0.4, @@ -92,14 +94,14 @@ def test_primitive_vertices_quad_mpl(self): [-0.2, -0.8, -0.6], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) for plane in ("xy", "xz", "yz"): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_quad_mpl(axis=plane), primitive_vertices_quad_mpl(axis=MAPPING_PLANE_TO_AXIS[plane]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertRaises( @@ -119,25 +121,25 @@ def test_primitive_vertices_grid_mpl(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_grid_mpl(), np.array([[[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_grid_mpl(axis="+y"), np.array([[[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_grid_mpl(axis="+x"), np.array([[[0, 0, 0], [0, 1, 0], [0, 1, 1], [0, 0, 1]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_grid_mpl( width=0.2, height=0.4, @@ -163,10 +165,10 @@ def test_primitive_vertices_grid_mpl(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_grid_mpl( width=-0.2, height=-0.4, @@ -192,7 +194,7 @@ def test_primitive_vertices_grid_mpl(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -208,7 +210,7 @@ def test_primitive_vertices_cube_mpl(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(), np.array( [ @@ -250,46 +252,46 @@ def test_primitive_vertices_cube_mpl(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(planes=["+x"]), np.array([[[1, 0, 0], [1, 1, 0], [1, 1, 1], [1, 0, 1]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(planes=["-x"]), np.array([[[0, 0, 0], [0, 1, 0], [0, 1, 1], [0, 0, 1]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(planes=["+y"]), np.array([[[0, 1, 0], [1, 1, 0], [1, 1, 1], [0, 1, 1]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(planes=["-y"]), np.array([[[0, 0, 0], [1, 0, 0], [1, 0, 1], [0, 0, 1]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(planes=["+z"]), np.array([[[0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(planes=["-z"]), np.array([[[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl( width=0.2, height=0.4, @@ -435,10 +437,10 @@ def test_primitive_vertices_cube_mpl(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl( width=-0.2, height=-0.4, @@ -584,16 +586,16 @@ def test_primitive_vertices_cube_mpl(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) for plane in MAPPING_PLANE_TO_AXIS: - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_cube_mpl(planes=[plane]), primitive_vertices_cube_mpl( planes=[MAPPING_PLANE_TO_AXIS[plane]] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -609,7 +611,7 @@ def test_primitive_vertices_sphere(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_sphere(), np.array( [ @@ -703,10 +705,10 @@ def test_primitive_vertices_sphere(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_sphere(intermediate=True), np.array( [ @@ -792,10 +794,10 @@ def test_primitive_vertices_sphere(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_sphere(segments=6, axis="+y"), np.array( [ @@ -855,10 +857,10 @@ def test_primitive_vertices_sphere(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_sphere(segments=6, axis="+x"), np.array( [ @@ -918,10 +920,10 @@ def test_primitive_vertices_sphere(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_sphere( radius=100, segments=6, @@ -986,14 +988,14 @@ def test_primitive_vertices_sphere(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) for plane in ("xy", "xz", "yz"): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( primitive_vertices_sphere(axis=plane), primitive_vertices_sphere(axis=MAPPING_PLANE_TO_AXIS[plane]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertRaises( diff --git a/colour/geometry/vertices.py b/colour/geometry/vertices.py index b60f2366f0..a48dcfd958 100644 --- a/colour/geometry/vertices.py +++ b/colour/geometry/vertices.py @@ -27,8 +27,8 @@ ones, tsplit, tstack, - zeros, validate_method, + zeros, ) __author__ = "Colour Developers" diff --git a/colour/graph/conversion.py b/colour/graph/conversion.py index caac96fe61..d499939155 100644 --- a/colour/graph/conversion.py +++ b/colour/graph/conversion.py @@ -11,19 +11,42 @@ from __future__ import annotations import inspect -import numpy as np import textwrap from collections import namedtuple from copy import copy from functools import partial from pprint import pformat +import numpy as np + import colour +from colour.appearance import ( + CAM16_to_XYZ, + CAM_Specification_CAM16, + CAM_Specification_CIECAM02, + CAM_Specification_CIECAM16, + CAM_Specification_Hellwig2022, + CIECAM02_to_XYZ, + CIECAM16_to_XYZ, + Hellwig2022_to_XYZ, + Kim2009_to_XYZ, + XYZ_to_ATD95, + XYZ_to_CAM16, + XYZ_to_CIECAM02, + XYZ_to_CIECAM16, + XYZ_to_Hellwig2022, + XYZ_to_Hunt, + XYZ_to_Kim2009, + XYZ_to_LLAB, + XYZ_to_Nayatani95, + XYZ_to_RLAB, + XYZ_to_ZCAM, + ZCAM_to_XYZ, +) +from colour.appearance.ciecam02 import CAM_KWARGS_CIECAM02_sRGB from colour.colorimetry import ( CCS_ILLUMINANTS, TVS_ILLUMINANTS_HUNTERLAB, -) -from colour.colorimetry import ( colorimetric_purity, complementary_wavelength, dominant_wavelength, @@ -34,9 +57,9 @@ luminous_efficiency, luminous_flux, sd_to_XYZ, + wavelength_to_XYZ, whiteness, yellowness, - wavelength_to_XYZ, ) from colour.hints import ( Any, @@ -48,8 +71,6 @@ Optional, cast, ) -from colour.recovery import XYZ_to_sd -from colour.models import RGB_COLOURSPACE_sRGB from colour.models import ( CAM02LCD_to_JMh_CIECAM02, CAM02SCD_to_JMh_CIECAM02, @@ -57,9 +78,9 @@ CAM16LCD_to_JMh_CAM16, CAM16SCD_to_JMh_CAM16, CAM16UCS_to_JMh_CAM16, - CMYK_to_CMY, CMY_to_CMYK, CMY_to_RGB, + CMYK_to_CMY, DIN99_to_XYZ, HCL_to_RGB, HSL_to_RGB, @@ -68,10 +89,10 @@ Hunter_Rdab_to_XYZ, ICaCb_to_XYZ, ICtCp_to_XYZ, - IHLS_to_RGB, IgPgTg_to_XYZ, - IPT_to_XYZ, + IHLS_to_RGB, IPT_Ragoo2021_to_XYZ, + IPT_to_XYZ, JMh_CAM16_to_CAM16LCD, JMh_CAM16_to_CAM16SCD, JMh_CAM16_to_CAM16UCS, @@ -79,19 +100,20 @@ JMh_CIECAM02_to_CAM02SCD, JMh_CIECAM02_to_CAM02UCS, Jzazbz_to_XYZ, - LCHab_to_Lab, - LCHuv_to_Luv, Lab_to_LCHab, Lab_to_XYZ, + LCHab_to_Lab, + LCHuv_to_Luv, Luv_to_LCHuv, - Luv_to_XYZ, Luv_to_uv, + Luv_to_XYZ, Luv_uv_to_xy, - OSA_UCS_to_XYZ, Oklab_to_XYZ, + OSA_UCS_to_XYZ, Prismatic_to_RGB, ProLab_to_XYZ, RGB_Colourspace, + RGB_COLOURSPACE_sRGB, RGB_luminance, RGB_to_CMY, RGB_to_HCL, @@ -102,13 +124,15 @@ RGB_to_RGB, RGB_to_XYZ, RGB_to_YCbCr, - RGB_to_YCoCg, RGB_to_YcCbcCrc, - UCS_to_XYZ, + RGB_to_YCoCg, UCS_to_uv, + UCS_to_XYZ, UCS_uv_to_xy, UVW_to_XYZ, XYZ_to_DIN99, + XYZ_to_hdr_CIELab, + XYZ_to_hdr_IPT, XYZ_to_Hunter_Lab, XYZ_to_Hunter_Rdab, XYZ_to_ICaCb, @@ -119,21 +143,19 @@ XYZ_to_Jzazbz, XYZ_to_Lab, XYZ_to_Luv, - XYZ_to_OSA_UCS, XYZ_to_Oklab, + XYZ_to_OSA_UCS, XYZ_to_ProLab, XYZ_to_RGB, + XYZ_to_sRGB, XYZ_to_UCS, XYZ_to_UVW, - XYZ_to_hdr_CIELab, - XYZ_to_hdr_IPT, - XYZ_to_sRGB, XYZ_to_xy, XYZ_to_xyY, XYZ_to_Yrg, YCbCr_to_RGB, - YCoCg_to_RGB, YcCbcCrc_to_RGB, + YCoCg_to_RGB, Yrg_to_XYZ, cctf_decoding, cctf_encoding, @@ -142,46 +164,23 @@ sRGB_to_XYZ, uv_to_Luv, uv_to_UCS, - xyY_to_XYZ, - xyY_to_xy, xy_to_Luv_uv, xy_to_UCS_uv, - xy_to_XYZ, xy_to_xyY, + xy_to_XYZ, + xyY_to_xy, + xyY_to_XYZ, ) from colour.notation import ( HEX_to_RGB, RGB_to_HEX, keyword_to_RGB_CSSColor3, - munsell_value, munsell_colour_to_xyY, + munsell_value, xyY_to_munsell_colour, ) from colour.quality import colour_quality_scale, colour_rendering_index -from colour.appearance import ( - CAM_Specification_CAM16, - CAM_Specification_CIECAM02, - CAM_Specification_CIECAM16, - CAM_Specification_Hellwig2022, - CAM16_to_XYZ, - CIECAM02_to_XYZ, - CIECAM16_to_XYZ, - Kim2009_to_XYZ, - Hellwig2022_to_XYZ, - XYZ_to_ATD95, - XYZ_to_CAM16, - XYZ_to_CIECAM02, - XYZ_to_CIECAM16, - XYZ_to_Hellwig2022, - XYZ_to_Hunt, - XYZ_to_Kim2009, - XYZ_to_LLAB, - XYZ_to_Nayatani95, - XYZ_to_RLAB, - XYZ_to_ZCAM, - ZCAM_to_XYZ, -) -from colour.appearance.ciecam02 import CAM_KWARGS_CIECAM02_sRGB +from colour.recovery import XYZ_to_sd from colour.temperature import CCT_to_mired, CCT_to_uv, mired_to_CCT, uv_to_CCT from colour.utilities import ( as_float_array, @@ -1020,7 +1019,7 @@ def _build_graph() -> networkx.DiGraph: # pyright: ignore # noqa: F821 CONVERSION_GRAPH: ( - Optional[networkx.DiGraph] # pyright: ignore # noqa: F821, UP007 + Optional[nx.DiGraph] # pyright: ignore # noqa: F821, UP007 ) = None """Automatic colour conversion graph.""" @@ -1060,7 +1059,7 @@ def _conversion_path(source: str, target: str) -> List[Callable]: # Updating the :attr:`CONVERSION_GRAPH` attributes. colour.graph.CONVERSION_GRAPH = CONVERSION_GRAPH = _build_graph() - path = nx.shortest_path(CONVERSION_GRAPH, source, target) + path = nx.shortest_path(cast(nx.DiGraph, CONVERSION_GRAPH), source, target) return [ CONVERSION_GRAPH.get_edge_data(a, b)[ # pyright: ignore @@ -1156,15 +1155,15 @@ def describe_conversion_path( conversion_path = _conversion_path(source, target) + joined_conversion_path = " --> ".join( + [ + f'"{_lower_order_function(conversion_function).__name__}"' + for conversion_function in conversion_path + ] + ) + message_box( - "[ Conversion Path ]\n\n{}".format( - " --> ".join( - [ - f'"{_lower_order_function(conversion_function).__name__}"' - for conversion_function in conversion_path - ] - ) - ), + f"[ Conversion Path ]\n\n{joined_conversion_path}", width, padding, print_callable, @@ -1220,7 +1219,7 @@ def convert(a: Any, source: str, target: str, **kwargs: Any) -> Any: colour representation using the automatic colour conversion graph. The conversion is performed by finding the shortest path in a - `NetworkX `__ :class:`DiGraph` class instance. + `NetworkX `__ :class:`DiGraph` class instance. The conversion path adopts the **'1'** domain-range scale and the object :math:`a` is expected to be *soft* normalised accordingly. For example, diff --git a/colour/graph/tests/test_conversion.py b/colour/graph/tests/test_conversion.py index 654e60d71f..fec2d7fde4 100644 --- a/colour/graph/tests/test_conversion.py +++ b/colour/graph/tests/test_conversion.py @@ -1,13 +1,15 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.graph.conversion` module.""" -import numpy as np import unittest +import numpy as np + from colour.characterisation import SDS_COLOURCHECKERS from colour.colorimetry import CCS_ILLUMINANTS, SDS_ILLUMINANTS +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.graph import convert, describe_conversion_path from colour.models import COLOURSPACE_MODELS, RGB_COLOURSPACE_ACES2065_1 -from colour.graph import describe_conversion_path, convert __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -58,18 +60,24 @@ class TestConvert(unittest.TestCase): def test_convert(self): """Test :func:`colour.graph.conversion.convert` definition.""" + # NOTE: Reduced precision for random unit tests failure. RGB_a = convert( SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"], "Spectral Distribution", "sRGB", ) - np.testing.assert_array_almost_equal( - RGB_a, np.array([0.49034776, 0.30185875, 0.23587685]), decimal=7 + np.testing.assert_allclose( + RGB_a, + np.array([0.49034776, 0.30185875, 0.23587685]), + atol=5e-5, ) + # NOTE: Reduced precision for random unit tests failure. Jpapbp = convert(RGB_a, "Output-Referred RGB", "CAM16UCS") - np.testing.assert_array_almost_equal( - Jpapbp, np.array([0.40738741, 0.12046560, 0.09284385]), decimal=7 + np.testing.assert_allclose( + Jpapbp, + np.array([0.40738741, 0.12046560, 0.09284385]), + atol=5e-4, ) RGB_b = convert( @@ -78,21 +86,21 @@ def test_convert(self): # NOTE: The "CIE XYZ" tristimulus values to "sRGB" matrix is given # rounded at 4 decimals as per "IEC 61966-2-1:1999" and thus preventing # exact roundtrip. - np.testing.assert_allclose(RGB_a, RGB_b, rtol=1e-4, atol=1e-4) + np.testing.assert_allclose(RGB_a, RGB_b, atol=1e-4) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert("#808080", "Hexadecimal", "Scene-Referred RGB"), np.array([0.21586050, 0.21586050, 0.21586050]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( convert("#808080", "Hexadecimal", "RGB Luminance"), 0.21586050, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert( convert( np.array([0.5, 0.5, 0.5]), @@ -103,10 +111,11 @@ def test_convert(self): "YCbCr", ), np.array([0.49215686, 0.50196078, 0.50196078]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + # NOTE: Reduced precision for random unit tests failure. + np.testing.assert_allclose( convert( RGB_a, "RGB", @@ -114,7 +123,7 @@ def test_convert(self): RGB_to_RGB={"output_colourspace": RGB_COLOURSPACE_ACES2065_1}, ), np.array([0.37308227, 0.31241444, 0.24746366]), - decimal=7, + atol=5e-5, ) # Consistency check to verify that all the colour models are properly @@ -136,12 +145,12 @@ def test_convert_direct_keyword_argument_passing(self): illuminant = CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][ "D50" ] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert( a, "CIE XYZ", "CIE UVW", XYZ_to_UVW={"illuminant": illuminant} ), convert(a, "CIE XYZ", "CIE UVW", illuminant=illuminant), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) # Illuminant "ndarray" is converted to tuple here so that it can diff --git a/colour/hints/__init__.py b/colour/hints/__init__.py index 392dbab947..6736620c75 100644 --- a/colour/hints/__init__.py +++ b/colour/hints/__init__.py @@ -16,6 +16,7 @@ from typing import ( # noqa: UP035 Any, Callable, + ClassVar, Dict, List, Literal, @@ -50,6 +51,7 @@ "ModuleType", "Any", "Callable", + "ClassVar", "Dict", "Generator", "Iterable", @@ -92,6 +94,22 @@ "ProtocolExtrapolator", "ProtocolLUTSequenceItem", "LiteralWarning", + "LiteralChromaticAdaptationTransform", + "LiteralColourspaceModel", + "LiteralRGBColourspace", + "LiteralLogEncoding", + "LiteralLogDecoding", + "LiteralOETF", + "LiteralOETFInverse", + "LiteralEOTF", + "LiteralEOTFInverse", + "LiteralCCTFEncoding", + "LiteralCCTFDecoding", + "LiteralOOTF", + "LiteralOOTFInverse", + "LiteralLUTReadMethod", + "LiteralLUTWriteMethod", + "LiteralFontScaling", ] RegexFlag = NewType("RegexFlag", re.RegexFlag) @@ -175,6 +193,396 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArray: # noqa: D102 "default", "error", "ignore", "always", "module", "once" ] +# NOTE: The following literals are automatically generated by the *invoke* +# *literalise* task. Please do not edit this section manually! + +# LITERALISE::BEGIN +LiteralChromaticAdaptationTransform = Literal[ + "Bianco 2010", + "Bianco PC 2010", + "Bradford", + "CAT02", + "CAT02 Brill 2008", + "CAT16", + "CMCCAT2000", + "CMCCAT97", + "Fairchild", + "Sharp", + "Von Kries", + "XYZ Scaling", +] +LiteralColourspaceModel = Literal[ + "CAM02LCD", + "CAM02SCD", + "CAM02UCS", + "CAM16LCD", + "CAM16SCD", + "CAM16UCS", + "CIE Lab", + "CIE Luv", + "CIE UCS", + "CIE UVW", + "CIE XYZ", + "CIE xyY", + "DIN99", + "HCL", + "HSL", + "HSV", + "Hunter Lab", + "Hunter Rdab", + "ICaCb", + "ICtCp", + "IHLS", + "IPT", + "IPT Ragoo 2021", + "IgPgTg", + "Jzazbz", + "OSA UCS", + "Oklab", + "RGB", + "YCbCr", + "YCoCg", + "Yrg", + "hdr-CIELAB", + "hdr-IPT", +] +LiteralRGBColourspace = Literal[ + "ACES2065-1", + "ACEScc", + "ACEScct", + "ACEScg", + "ACESproxy", + "ALEXA Wide Gamut", + "ARRI Wide Gamut 3", + "ARRI Wide Gamut 4", + "Adobe RGB (1998)", + "Adobe Wide Gamut RGB", + "Apple RGB", + "Best RGB", + "Beta RGB", + "Blackmagic Wide Gamut", + "CIE RGB", + "Cinema Gamut", + "ColorMatch RGB", + "DCDM XYZ", + "DCI-P3", + "DCI-P3-P", + "DJI D-Gamut", + "DRAGONcolor", + "DRAGONcolor2", + "DaVinci Wide Gamut", + "Display P3", + "Don RGB 4", + "EBU Tech. 3213-E", + "ECI RGB v2", + "ERIMM RGB", + "Ekta Space PS 5", + "F-Gamut", + "FilmLight E-Gamut", + "ITU-R BT.2020", + "ITU-R BT.470 - 525", + "ITU-R BT.470 - 625", + "ITU-R BT.709", + "ITU-T H.273 - 22 Unspecified", + "ITU-T H.273 - Generic Film", + "Max RGB", + "N-Gamut", + "NTSC (1953)", + "NTSC (1987)", + "P3-D65", + "PLASA ANSI E1.54", + "Pal/Secam", + "ProPhoto RGB", + "Protune Native", + "REDWideGamutRGB", + "REDcolor", + "REDcolor2", + "REDcolor3", + "REDcolor4", + "RIMM RGB", + "ROMM RGB", + "Russell RGB", + "S-Gamut", + "S-Gamut3", + "S-Gamut3.Cine", + "SMPTE 240M", + "SMPTE C", + "Sharp RGB", + "V-Gamut", + "Venice S-Gamut3", + "Venice S-Gamut3.Cine", + "Xtreme RGB", + "aces", + "adobe1998", + "prophoto", + "sRGB", +] +LiteralLogEncoding = Literal[ + "ACEScc", + "ACEScct", + "ACESproxy", + "ARRI LogC3", + "ARRI LogC4", + "Apple Log Profile", + "Canon Log", + "Canon Log 2", + "Canon Log 3", + "Cineon", + "D-Log", + "ERIMM RGB", + "F-Log", + "F-Log2", + "Filmic Pro 6", + "L-Log", + "Log2", + "Log3G10", + "Log3G12", + "N-Log", + "PLog", + "Panalog", + "Protune", + "REDLog", + "REDLogFilm", + "S-Log", + "S-Log2", + "S-Log3", + "T-Log", + "V-Log", + "ViperLog", +] +LiteralLogDecoding = Literal[ + "ACEScc", + "ACEScct", + "ACESproxy", + "ARRI LogC3", + "ARRI LogC4", + "Apple Log Profile", + "Canon Log", + "Canon Log 2", + "Canon Log 3", + "Cineon", + "D-Log", + "ERIMM RGB", + "F-Log", + "F-Log2", + "Filmic Pro 6", + "L-Log", + "Log2", + "Log3G10", + "Log3G12", + "N-Log", + "PLog", + "Panalog", + "Protune", + "REDLog", + "REDLogFilm", + "S-Log", + "S-Log2", + "S-Log3", + "T-Log", + "V-Log", + "ViperLog", +] +LiteralOETF = Literal[ + "ARIB STD-B67", + "Blackmagic Film Generation 5", + "DaVinci Intermediate", + "ITU-R BT.2020", + "ITU-R BT.2100 HLG", + "ITU-R BT.2100 PQ", + "ITU-R BT.601", + "ITU-R BT.709", + "ITU-T H.273 IEC 61966-2", + "ITU-T H.273 Log", + "ITU-T H.273 Log Sqrt", + "SMPTE 240M", +] +LiteralOETFInverse = Literal[ + "ARIB STD-B67", + "Blackmagic Film Generation 5", + "DaVinci Intermediate", + "ITU-R BT.2020", + "ITU-R BT.2100 HLG", + "ITU-R BT.2100 PQ", + "ITU-R BT.601", + "ITU-R BT.709", + "ITU-T H.273 IEC 61966-2", + "ITU-T H.273 Log", + "ITU-T H.273 Log Sqrt", +] +LiteralEOTF = Literal[ + "DCDM", + "DICOM GSDF", + "ITU-R BT.1886", + "ITU-R BT.2100 HLG", + "ITU-R BT.2100 PQ", + "ITU-T H.273 ST.428-1", + "SMPTE 240M", + "ST 2084", + "sRGB", +] +LiteralEOTFInverse = Literal[ + "DCDM", + "DICOM GSDF", + "ITU-R BT.1886", + "ITU-R BT.2100 HLG", + "ITU-R BT.2100 PQ", + "ITU-T H.273 ST.428-1", + "ST 2084", + "sRGB", +] +LiteralCCTFEncoding = Literal[ + "ACEScc", + "ACEScct", + "ACESproxy", + "ARIB STD-B67", + "ARRI LogC3", + "ARRI LogC4", + "Apple Log Profile", + "Blackmagic Film Generation 5", + "Canon Log", + "Canon Log 2", + "Canon Log 3", + "Cineon", + "D-Log", + "DCDM", + "DICOM GSDF", + "DaVinci Intermediate", + "ERIMM RGB", + "F-Log", + "F-Log2", + "Filmic Pro 6", + "Gamma 2.2", + "Gamma 2.4", + "Gamma 2.6", + "ITU-R BT.1886", + "ITU-R BT.2020", + "ITU-R BT.2100 HLG", + "ITU-R BT.2100 PQ", + "ITU-R BT.601", + "ITU-R BT.709", + "ITU-T H.273 IEC 61966-2", + "ITU-T H.273 Log", + "ITU-T H.273 Log Sqrt", + "ITU-T H.273 ST.428-1", + "L-Log", + "Log2", + "Log3G10", + "Log3G12", + "N-Log", + "PLog", + "Panalog", + "ProPhoto RGB", + "Protune", + "REDLog", + "REDLogFilm", + "RIMM RGB", + "ROMM RGB", + "S-Log", + "S-Log2", + "S-Log3", + "SMPTE 240M", + "ST 2084", + "T-Log", + "V-Log", + "ViperLog", + "sRGB", +] +LiteralCCTFDecoding = Literal[ + "ACEScc", + "ACEScct", + "ACESproxy", + "ARIB STD-B67", + "ARRI LogC3", + "ARRI LogC4", + "Apple Log Profile", + "Blackmagic Film Generation 5", + "Canon Log", + "Canon Log 2", + "Canon Log 3", + "Cineon", + "D-Log", + "DCDM", + "DICOM GSDF", + "DaVinci Intermediate", + "ERIMM RGB", + "F-Log", + "F-Log2", + "Filmic Pro 6", + "Gamma 2.2", + "Gamma 2.4", + "Gamma 2.6", + "ITU-R BT.1886", + "ITU-R BT.2020", + "ITU-R BT.2100 HLG", + "ITU-R BT.2100 PQ", + "ITU-R BT.601", + "ITU-R BT.709", + "ITU-T H.273 IEC 61966-2", + "ITU-T H.273 Log", + "ITU-T H.273 Log Sqrt", + "ITU-T H.273 ST.428-1", + "L-Log", + "Log2", + "Log3G10", + "Log3G12", + "N-Log", + "PLog", + "Panalog", + "ProPhoto RGB", + "Protune", + "REDLog", + "REDLogFilm", + "RIMM RGB", + "ROMM RGB", + "S-Log", + "S-Log2", + "S-Log3", + "SMPTE 240M", + "ST 2084", + "T-Log", + "V-Log", + "ViperLog", + "sRGB", +] +LiteralOOTF = Literal["ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ"] +LiteralOOTFInverse = Literal["ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ"] +LiteralLUTReadMethod = Literal[ + "Cinespace", + "Iridas Cube", + "Resolve Cube", + "Sony SPI1D", + "Sony SPI3D", + "Sony SPImtx", +] +LiteralLUTWriteMethod = Literal[ + "Cinespace", + "Iridas Cube", + "Resolve Cube", + "Sony SPI1D", + "Sony SPI3D", + "Sony SPImtx", +] +LiteralFontScaling = Literal[ + "xx-small", + "x-small", + "small", + "medium", + "large", + "x-large", + "xx-large", + "larger", + "smaller", + "xx-small-colour-science", + "x-small-colour-science", + "small-colour-science", + "medium-colour-science", + "large-colour-science", + "x-large-colour-science", + "xx-large-colour-science", +] +# LITERALISE::END + def arraylike(a: ArrayLike) -> NDArray: # noqa: ARG001 ... diff --git a/colour/io/ctl.py b/colour/io/ctl.py index 2eea8f0516..9ecb7002cd 100644 --- a/colour/io/ctl.py +++ b/colour/io/ctl.py @@ -13,10 +13,11 @@ from __future__ import annotations import os -import numpy as np import subprocess -import textwrap import tempfile +import textwrap + +import numpy as np from colour.hints import ( Any, @@ -27,8 +28,8 @@ ) from colour.io import as_3_channels_image, read_image, write_image from colour.utilities import ( - as_float_array, as_float, + as_float_array, optional, required, ) diff --git a/colour/io/image.py b/colour/io/image.py index 4e067e4fef..92e642a527 100644 --- a/colour/io/image.py +++ b/colour/io/image.py @@ -7,10 +7,12 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass, field +import numpy as np + from colour.hints import ( + TYPE_CHECKING, Any, ArrayLike, DTypeReal, @@ -19,7 +21,6 @@ NDArrayReal, Optional, Sequence, - TYPE_CHECKING, Tuple, Type, cast, @@ -29,8 +30,8 @@ as_float_array, as_int_array, attest, - is_openimageio_installed, filter_kwargs, + is_openimageio_installed, optional, required, tstack, @@ -106,7 +107,7 @@ class ImageAttribute_Specification: if is_openimageio_installed(): # pragma: no cover - from OpenImageIO import UINT8, UINT16, HALF, FLOAT, DOUBLE + from OpenImageIO import DOUBLE, FLOAT, HALF, UINT8, UINT16 MAPPING_BIT_DEPTH: CanonicalMapping = CanonicalMapping( { diff --git a/colour/io/luts/__init__.py b/colour/io/luts/__init__.py index 40c5aeb6f2..30ff2737ce 100644 --- a/colour/io/luts/__init__.py +++ b/colour/io/luts/__init__.py @@ -15,11 +15,10 @@ import os -from colour.hints import Any, Literal +from colour.hints import Any, LiteralLUTReadMethod, LiteralLUTWriteMethod from colour.utilities import ( CanonicalMapping, filter_kwargs, - optional, validate_method, ) @@ -103,16 +102,7 @@ def read_LUT( path: str, - method: Literal[ - "Cinespace", - "Iridas Cube", - "Resolve Cube", - "Sony SPI1D", - "Sony SPI3D", - "Sony SPImtx", - ] - | str - | None = None, + method: LiteralLUTReadMethod | str | None = None, **kwargs: Any, ) -> LUT1D | LUT3x1D | LUT3D | LUTSequence | LUTOperatorMatrix: """ @@ -217,12 +207,12 @@ def read_LUT( Offset : [ 0. 0. 0. 0.] """ - method = optional( - method, MAPPING_EXTENSION_TO_LUT_FORMAT[os.path.splitext(path)[-1]] + method = ( + MAPPING_EXTENSION_TO_LUT_FORMAT[os.path.splitext(path)[-1]].lower() + if method is None + else validate_method(method, tuple(LUT_WRITE_METHODS)) ) - method = validate_method(method, tuple(LUT_READ_METHODS)) - function = LUT_READ_METHODS[method] try: @@ -260,16 +250,7 @@ def write_LUT( LUT: LUT1D | LUT3x1D | LUT3D | LUTSequence | LUTOperatorMatrix, path: str, decimals: int = 7, - method: Literal[ - "Cinespace", - "Iridas Cube", - "Resolve Cube", - "Sony SPI1D", - "Sony SPI3D", - "Sony SPImtx", - ] - | str - | None = None, + method: LiteralLUTWriteMethod | str | None = None, **kwargs: Any, ) -> bool: """ @@ -337,12 +318,12 @@ def write_LUT( >>> write_LUT(LUT, "My_LUT.cube") # doctest: +SKIP """ - method = optional( - method, MAPPING_EXTENSION_TO_LUT_FORMAT[os.path.splitext(path)[-1]] + method = ( + MAPPING_EXTENSION_TO_LUT_FORMAT[os.path.splitext(path)[-1]].lower() + if method is None + else validate_method(method, tuple(LUT_WRITE_METHODS)) ) - method = validate_method(method, tuple(LUT_WRITE_METHODS)) - if method == "iridas cube" and isinstance(LUT, LUTSequence): method = "resolve cube" diff --git a/colour/io/luts/cinespace_csp.py b/colour/io/luts/cinespace_csp.py index 3344761832..d64d327e00 100644 --- a/colour/io/luts/cinespace_csp.py +++ b/colour/io/luts/cinespace_csp.py @@ -20,7 +20,7 @@ import numpy as np from colour.hints import ArrayLike, List, NDArrayFloat -from colour.io.luts import LUT1D, LUT3x1D, LUT3D, LUTSequence +from colour.io.luts import LUT1D, LUT3D, LUT3x1D, LUTSequence from colour.utilities import ( as_float_array, as_int_array, @@ -204,7 +204,7 @@ def _parse_table_section(lines): ) ): LUT = LUT3x1D( - domain=pre_LUT.reshape(3, 4).transpose()[0:2], + domain=pre_LUT.reshape([3, 4]).transpose()[0:2], name=title, comments=comments, table=table, diff --git a/colour/io/luts/iridas_cube.py b/colour/io/luts/iridas_cube.py index 2aaa6f3687..27a7f4bedc 100644 --- a/colour/io/luts/iridas_cube.py +++ b/colour/io/luts/iridas_cube.py @@ -18,7 +18,7 @@ import numpy as np -from colour.io.luts import LUT1D, LUT3x1D, LUT3D, LUTSequence +from colour.io.luts import LUT1D, LUT3D, LUT3x1D, LUTSequence from colour.io.luts.common import path_to_title from colour.utilities import ( as_float_array, diff --git a/colour/io/luts/lut.py b/colour/io/luts/lut.py index 7e6a9294d5..7defade81b 100644 --- a/colour/io/luts/lut.py +++ b/colour/io/luts/lut.py @@ -12,21 +12,22 @@ from __future__ import annotations -import numpy as np from abc import ABC, abstractmethod from copy import deepcopy from operator import ( add, - mul, - pow, - sub, - truediv, iadd, imul, ipow, isub, itruediv, + mul, + pow, + sub, + truediv, ) + +import numpy as np from scipy.spatial import KDTree from colour.algebra import ( @@ -42,7 +43,6 @@ Literal, NDArrayFloat, Sequence, - Self, Type, cast, ) @@ -53,12 +53,12 @@ as_int_array, as_int_scalar, attest, - is_numeric, + full, is_iterable, + is_numeric, is_string, - full, - multiline_str, multiline_repr, + multiline_str, optional, runtime_warning, tsplit, @@ -401,7 +401,7 @@ def __ne__(self, other: Any) -> bool: return not (self == other) - def __add__(self, a: ArrayLike | Self) -> Self: + def __add__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for addition. @@ -418,7 +418,7 @@ def __add__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "+") - def __iadd__(self, a: ArrayLike | Self) -> Self: + def __iadd__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for in-place addition. @@ -435,7 +435,7 @@ def __iadd__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "+", True) - def __sub__(self, a: ArrayLike | Self) -> Self: + def __sub__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for subtraction. @@ -452,7 +452,7 @@ def __sub__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "-") - def __isub__(self, a: ArrayLike | Self) -> Self: + def __isub__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for in-place subtraction. @@ -469,7 +469,7 @@ def __isub__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "-", True) - def __mul__(self, a: ArrayLike | Self) -> Self: + def __mul__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for multiplication. @@ -486,7 +486,7 @@ def __mul__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "*") - def __imul__(self, a: ArrayLike | Self) -> Self: + def __imul__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for in-place multiplication. @@ -503,7 +503,7 @@ def __imul__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "*", True) - def __div__(self, a: ArrayLike | Self) -> Self: + def __div__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for division. @@ -520,7 +520,7 @@ def __div__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "/") - def __idiv__(self, a: ArrayLike | Self) -> Self: + def __idiv__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for in-place division. @@ -540,7 +540,7 @@ def __idiv__(self, a: ArrayLike | Self) -> Self: __itruediv__ = __idiv__ __truediv__ = __div__ - def __pow__(self, a: ArrayLike | Self) -> Self: + def __pow__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for exponentiation. @@ -557,7 +557,7 @@ def __pow__(self, a: ArrayLike | Self) -> Self: return self.arithmetical_operation(a, "**") - def __ipow__(self, a: ArrayLike | Self) -> Self: + def __ipow__(self, a: ArrayLike | AbstractLUT) -> AbstractLUT: """ Implement support for in-place exponentiation. @@ -576,10 +576,10 @@ def __ipow__(self, a: ArrayLike | Self) -> Self: def arithmetical_operation( self, - a: ArrayLike | Self, + a: ArrayLike | AbstractLUT, operation: Literal["+", "-", "*", "/", "**"], in_place: bool = False, - ) -> Self: + ) -> AbstractLUT: """ Perform given arithmetical operation with :math:`a` operand, the operation can be either performed on a copy or in-place, must be @@ -706,7 +706,7 @@ def linear_table( Linear table. """ - def copy(self) -> Self: + def copy(self) -> AbstractLUT: """ Return a copy of the sub-class instance. @@ -719,7 +719,7 @@ def copy(self) -> Self: return deepcopy(self) @abstractmethod - def invert(self, **kwargs: Any) -> Self: + def invert(self, **kwargs: Any) -> AbstractLUT: """ Compute and returns an inverse copy of the *LUT*. @@ -766,13 +766,12 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArrayFloat: Interpolated *RGB* colourspace array. """ - @abstractmethod def convert( self, - cls: Type[Self], + cls: Type[AbstractLUT], force_conversion: bool = False, **kwargs: Any, - ) -> Self: + ) -> AbstractLUT: """ Convert the *LUT* to given ``cls`` class instance. @@ -809,6 +808,10 @@ def convert( If the conversion is destructive. """ + return LUT_to_LUT( + self, cls, force_conversion, **kwargs # pyright: ignore + ) + class LUT1D(AbstractLUT): """ @@ -835,7 +838,6 @@ class LUT1D(AbstractLUT): - :meth:`~colour.LUT1D.linear_table` - :meth:`~colour.LUT1D.invert` - :meth:`~colour.LUT1D.apply` - - :meth:`~colour.LUT1D.convert` Examples -------- @@ -1009,7 +1011,7 @@ def linear_table( return np.linspace(domain[0], domain[1], as_int_scalar(size)) - def invert(self, **kwargs: Any) -> Self: # noqa: ARG002 + def invert(self, **kwargs: Any) -> LUT1D: # noqa: ARG002 """ Compute and returns an inverse copy of the *LUT*. @@ -1131,80 +1133,6 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArrayFloat: return RGB_interpolator(RGB) - def convert( - self, - cls: Type[AbstractLUT], - force_conversion: bool = False, - **kwargs: Any, - ) -> AbstractLUT: - """ - Convert the *LUT* to given ``cls`` class instance. - - Parameters - ---------- - cls - *LUT* class instance. - force_conversion - Whether to force the conversion as it might be destructive. - - Other Parameters - ---------------- - interpolator - Interpolator class type to use as interpolating function. - interpolator_kwargs - Arguments to use when instantiating the interpolating function. - size - Expected table size in case of an upcast to a :class:`LUT3D` class - instance. - - Returns - ------- - :class:`colour.LUT1D` or :class:`colour.LUT3x1D` or \ -:class:`colour.LUT3D` - Converted *LUT* class instance. - - Warnings - -------- - Some conversions are destructive and raise a :class:`ValueError` - exception by default. - - Raises - ------ - ValueError - If the conversion is destructive. - - Examples - -------- - >>> LUT = LUT1D() - >>> print(LUT.convert(LUT1D)) - LUT1D - Unity 10 - Converted 1D to 1D - ------------------------------------- - - Dimensions : 1 - Domain : [ 0. 1.] - Size : (10,) - >>> print(LUT.convert(LUT3x1D)) - LUT3x1D - Unity 10 - Converted 1D to 3x1D - ----------------------------------------- - - Dimensions : 2 - Domain : [[ 0. 0. 0.] - [ 1. 1. 1.]] - Size : (10, 3) - >>> print(LUT.convert(LUT3D, force_conversion=True)) - LUT3D - Unity 10 - Converted 1D to 3D - ------------------------------------- - - Dimensions : 3 - Domain : [[ 0. 0. 0.] - [ 1. 1. 1.]] - Size : (33, 33, 33, 3) - """ - - return LUT_to_LUT( - self, cls, force_conversion, **kwargs # pyright: ignore - ) - # ------------------------------------------------------------------------# # --- API Changes and Deprecation Management ---# # ------------------------------------------------------------------------# @@ -1224,7 +1152,7 @@ def as_LUT( # noqa: D102 ) ) - return self.convert(cls, force_conversion, **kwargs) + return self.convert(cls, force_conversion, **kwargs) # pyright: ignore class LUT3x1D(AbstractLUT): @@ -1252,7 +1180,6 @@ class LUT3x1D(AbstractLUT): - :meth:`~colour.LUT3x1D.linear_table` - :meth:`~colour.LUT3x1D.invert` - :meth:`~colour.LUT3x1D.apply` - - :meth:`~colour.LUT3x1D.convert` Examples -------- @@ -1493,7 +1420,7 @@ def linear_table( samples = [ np.pad( axis, - (0, np.max(size_array) - len(axis)), + (0, np.max(size_array) - len(axis)), # pyright: ignore mode="constant", constant_values=np.nan, ) @@ -1502,7 +1429,7 @@ def linear_table( return tstack(samples) - def invert(self, **kwargs: Any) -> Self: # noqa: ARG002 + def invert(self, **kwargs: Any) -> LUT3x1D: # noqa: ARG002 """ Compute and returns an inverse copy of the *LUT*. @@ -1685,80 +1612,6 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArrayFloat: return tstack(RGB_i) - def convert( - self, - cls: Type[AbstractLUT], - force_conversion: bool = False, - **kwargs: Any, - ) -> AbstractLUT: - """ - Convert the *LUT* to given ``cls`` class instance. - - Parameters - ---------- - cls - *LUT* class instance. - force_conversion - Whether to force the conversion as it might be destructive. - - Other Parameters - ---------------- - interpolator - Interpolator class type to use as interpolating function. - interpolator_kwargs - Arguments to use when instantiating the interpolating function. - size - Expected table size in case of an upcast to a :class:`LUT3D` class - instance. - - Returns - ------- - :class:`colour.LUT1D` or :class:`colour.LUT3x1D` or \ -:class:`colour.LUT3D` - Converted *LUT* class instance. - - Warnings - -------- - Some conversions are destructive and raise a :class:`ValueError` - exception by default. - - Raises - ------ - ValueError - If the conversion is destructive. - - Examples - -------- - >>> LUT = LUT3x1D() - >>> print(LUT.convert(LUT1D, force_conversion=True)) - LUT1D - Unity 10 - Converted 3x1D to 1D - --------------------------------------- - - Dimensions : 1 - Domain : [ 0. 1.] - Size : (10,) - >>> print(LUT.convert(LUT3x1D)) - LUT3x1D - Unity 10 - Converted 3x1D to 3x1D - ------------------------------------------- - - Dimensions : 2 - Domain : [[ 0. 0. 0.] - [ 1. 1. 1.]] - Size : (10, 3) - >>> print(LUT.convert(LUT3D, force_conversion=True)) - LUT3D - Unity 10 - Converted 3x1D to 3D - --------------------------------------- - - Dimensions : 3 - Domain : [[ 0. 0. 0.] - [ 1. 1. 1.]] - Size : (33, 33, 33, 3) - """ - - return LUT_to_LUT( - self, cls, force_conversion, **kwargs # pyright: ignore - ) - # ------------------------------------------------------------------------# # --- API Changes and Deprecation Management ---# # ------------------------------------------------------------------------# @@ -1778,7 +1631,7 @@ def as_LUT( # noqa: D102 ) ) - return self.convert(cls, force_conversion, **kwargs) + return self.convert(cls, force_conversion, **kwargs) # pyright: ignore class LUT3D(AbstractLUT): @@ -1806,7 +1659,6 @@ class LUT3D(AbstractLUT): - :meth:`~colour.LUT3D.linear_table` - :meth:`~colour.LUT3D.invert` - :meth:`~colour.LUT3D.apply` - - :meth:`~colour.LUT3D.convert` Examples -------- @@ -2132,7 +1984,7 @@ def linear_table( return table - def invert(self, **kwargs: Any) -> Self: + def invert(self, **kwargs: Any) -> LUT3D: """ Compute and returns an inverse copy of the *LUT*. @@ -2339,80 +2191,6 @@ def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArrayFloat: return RGB_i - def convert( - self, - cls: Type[AbstractLUT], - force_conversion: bool = False, - **kwargs: Any, - ) -> AbstractLUT: - """ - Convert the *LUT* to given ``cls`` class instance. - - Parameters - ---------- - cls - *LUT* class instance. - force_conversion - Whether to force the conversion as it might be destructive. - - Other Parameters - ---------------- - interpolator - Interpolator class type to use as interpolating function. - interpolator_kwargs - Arguments to use when instantiating the interpolating function. - size - Expected table size in case of a downcast from a :class:`LUT3D` - class instance. - - Returns - ------- - :class:`colour.LUT1D` or :class:`colour.LUT3x1D` or \ -:class:`colour.LUT3D` - Converted *LUT* class instance. - - Warnings - -------- - Some conversions are destructive and raise a :class:`ValueError` - exception by default. - - Raises - ------ - ValueError - If the conversion is destructive. - - Examples - -------- - >>> LUT = LUT3D() - >>> print(LUT.convert(LUT1D, force_conversion=True)) - LUT1D - Unity 33 - Converted 3D to 1D - ------------------------------------- - - Dimensions : 1 - Domain : [ 0. 1.] - Size : (10,) - >>> print(LUT.convert(LUT3x1D, force_conversion=True)) - LUT3x1D - Unity 33 - Converted 3D to 3x1D - ----------------------------------------- - - Dimensions : 2 - Domain : [[ 0. 0. 0.] - [ 1. 1. 1.]] - Size : (10, 3) - >>> print(LUT.convert(LUT3D)) - LUT3D - Unity 33 - Converted 3D to 3D - ------------------------------------- - - Dimensions : 3 - Domain : [[ 0. 0. 0.] - [ 1. 1. 1.]] - Size : (33, 33, 33, 3) - """ - - return LUT_to_LUT( - self, cls, force_conversion, **kwargs # pyright: ignore - ) - # ------------------------------------------------------------------------# # --- API Changes and Deprecation Management ---# # ------------------------------------------------------------------------# @@ -2432,12 +2210,12 @@ def as_LUT( # noqa: D102 ) ) - return self.convert(cls, force_conversion, **kwargs) + return self.convert(cls, force_conversion, **kwargs) # pyright: ignore def LUT_to_LUT( LUT, - cls: LUT1D | LUT3x1D | LUT3D, + cls: AbstractLUT, force_conversion: bool = False, **kwargs: Any, ) -> AbstractLUT: diff --git a/colour/io/luts/operator.py b/colour/io/luts/operator.py index df62ac1e79..c81f9048ce 100644 --- a/colour/io/luts/operator.py +++ b/colour/io/luts/operator.py @@ -10,9 +10,10 @@ from __future__ import annotations -import numpy as np from abc import ABC, abstractmethod +import numpy as np + from colour.algebra import vector_dot from colour.hints import ( Any, diff --git a/colour/io/luts/resolve_cube.py b/colour/io/luts/resolve_cube.py index e0ac0c3f10..1fa8ae1619 100644 --- a/colour/io/luts/resolve_cube.py +++ b/colour/io/luts/resolve_cube.py @@ -19,7 +19,7 @@ import numpy as np -from colour.io.luts import LUT1D, LUT3x1D, LUT3D, LUTSequence +from colour.io.luts import LUT1D, LUT3D, LUT3x1D, LUTSequence from colour.io.luts.common import path_to_title from colour.utilities import ( as_float_array, diff --git a/colour/io/luts/sequence.py b/colour/io/luts/sequence.py index 0a3bf2c531..dd697f9dbe 100644 --- a/colour/io/luts/sequence.py +++ b/colour/io/luts/sequence.py @@ -301,7 +301,7 @@ def __ne__(self, other) -> bool: return not (self == other) - def insert(self, index: int, item: ProtocolLUTSequenceItem): + def insert(self, index: int, value: ProtocolLUTSequenceItem): """ Insert given *LUT* at given index into the *LUT* sequence. @@ -309,17 +309,17 @@ def insert(self, index: int, item: ProtocolLUTSequenceItem): ---------- index Index to insert the item at into the *LUT* sequence. - item + value *LUT* to insert into the *LUT* sequence. """ attest( - isinstance(item, ProtocolLUTSequenceItem), + isinstance(value, ProtocolLUTSequenceItem), '"value" items must implement the "ProtocolLUTSequenceItem" ' "protocol!", ) - self._sequence.insert(index, item) + self._sequence.insert(index, value) def apply(self, RGB: ArrayLike, **kwargs: Any) -> NDArrayFloat: """ diff --git a/colour/io/luts/sony_spimtx.py b/colour/io/luts/sony_spimtx.py index 698e6a2d33..a56751624d 100644 --- a/colour/io/luts/sony_spimtx.py +++ b/colour/io/luts/sony_spimtx.py @@ -12,9 +12,9 @@ import numpy as np -from colour.constants import DEFAULT_FLOAT_DTYPE -from colour.io.luts.common import path_to_title +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.io.luts import LUTOperatorMatrix +from colour.io.luts.common import path_to_title __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -64,7 +64,7 @@ def read_LUT_SonySPImtx(path: str) -> LUTOperatorMatrix: Offset : [ 0. 0. 0. 0.] """ - matrix = np.loadtxt(path, dtype=DEFAULT_FLOAT_DTYPE) + matrix = np.loadtxt(path, dtype=DTYPE_FLOAT_DEFAULT) matrix = np.reshape(matrix, (3, 4)) offset = matrix[:, 3] / 65535 matrix = matrix[:3, :3] diff --git a/colour/io/luts/tests/resources/cinespace/Explicit_Domain.csp b/colour/io/luts/tests/resources/cinespace/Explicit_Domain.csp index cbb7a7d0c8..12347eaa8f 100644 --- a/colour/io/luts/tests/resources/cinespace/Explicit_Domain.csp +++ b/colour/io/luts/tests/resources/cinespace/Explicit_Domain.csp @@ -7,14 +7,14 @@ The cube's transform is the identity. END METADATA 11 -0.0000000 0.1000000 0.2000000 0.3000000 0.4000000 0.5000000 0.6000000 0.7000000 0.8000000 0.9000000 1.0000000 -0.0000000 0.1000000 0.2000000 0.3000000 0.4000000 0.5000000 0.6000000 0.7000000 0.8000000 0.9000000 1.0000000 +0.0000000 0.1000000 0.2000000 0.3000000 0.4000000 0.5000000 0.6000000 0.7000000 0.8000000 0.9000000 1.0000000 +0.0000000 0.1000000 0.2000000 0.3000000 0.4000000 0.5000000 0.6000000 0.7000000 0.8000000 0.9000000 1.0000000 6 -0.0000000 0.2000000 0.4000000 0.6000000 0.8000000 1.0000000 -0.0000000 0.2000000 0.4000000 0.6000000 0.8000000 1.0000000 +0.0000000 0.2000000 0.4000000 0.6000000 0.8000000 1.0000000 +0.0000000 0.2000000 0.4000000 0.6000000 0.8000000 1.0000000 5 -0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 -0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 +0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 +0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 2 3 4 0.0000000 0.0000000 0.0000000 diff --git a/colour/io/luts/tests/resources/cinespace/Ragged_Domain.csp b/colour/io/luts/tests/resources/cinespace/Ragged_Domain.csp index 1470410b06..6329d75f89 100644 --- a/colour/io/luts/tests/resources/cinespace/Ragged_Domain.csp +++ b/colour/io/luts/tests/resources/cinespace/Ragged_Domain.csp @@ -6,14 +6,14 @@ Ragged 3x1D END METADATA 6 -0.0000000 0.1000000 0.2000000 0.4000000 0.8000000 1.2000000 -0.4545455 0.5000000 0.5454545 0.6363636 0.8181818 1.0000000 +0.0000000 0.1000000 0.2000000 0.4000000 0.8000000 1.2000000 +0.4545455 0.5000000 0.5454545 0.6363636 0.8181818 1.0000000 3 --0.1000000 0.5000000 1.0000000 -0.4090909 0.6818182 0.9090909 +-0.1000000 0.5000000 1.0000000 +0.4090909 0.6818182 0.9090909 5 --1.0000000 -0.5000000 0.0000000 0.5000000 1.0000000 -0.0000000 0.2272727 0.4545455 0.6818182 0.9090909 +-1.0000000 -0.5000000 0.0000000 0.5000000 1.0000000 +0.0000000 0.2272727 0.4545455 0.6818182 0.9090909 2 -2.0000000 -2.0000000 -2.0000000 diff --git a/colour/io/luts/tests/resources/cinespace/Three_Dimensional_Table_With_Shaper.csp b/colour/io/luts/tests/resources/cinespace/Three_Dimensional_Table_With_Shaper.csp index 23c8fa4af7..53c84fb107 100644 --- a/colour/io/luts/tests/resources/cinespace/Three_Dimensional_Table_With_Shaper.csp +++ b/colour/io/luts/tests/resources/cinespace/Three_Dimensional_Table_With_Shaper.csp @@ -10,14 +10,14 @@ A second "LUT3D" comment. END METADATA 10 --0.1000000 0.2444444 0.5888889 0.9333333 1.2777778 1.6222222 1.9666667 2.3111111 2.6555556 3.0000000 --0.3511192 0.5271086 0.7860854 0.9691262 1.1178635 1.2459617 1.3599219 1.4634339 1.5588269 1.6476816 +-0.1000000 0.2444444 0.5888889 0.9333333 1.2777778 1.6222222 1.9666667 2.3111111 2.6555556 3.0000000 +-0.3511192 0.5271086 0.7860854 0.9691262 1.1178635 1.2459617 1.3599219 1.4634339 1.5588269 1.6476816 10 --0.1000000 0.2444444 0.5888889 0.9333333 1.2777778 1.6222222 1.9666667 2.3111111 2.6555556 3.0000000 --0.3511192 0.5271086 0.7860854 0.9691262 1.1178635 1.2459617 1.3599219 1.4634339 1.5588269 1.6476816 +-0.1000000 0.2444444 0.5888889 0.9333333 1.2777778 1.6222222 1.9666667 2.3111111 2.6555556 3.0000000 +-0.3511192 0.5271086 0.7860854 0.9691262 1.1178635 1.2459617 1.3599219 1.4634339 1.5588269 1.6476816 10 --0.1000000 0.2444444 0.5888889 0.9333333 1.2777778 1.6222222 1.9666667 2.3111111 2.6555556 3.0000000 --0.3511192 0.5271086 0.7860854 0.9691262 1.1178635 1.2459617 1.3599219 1.4634339 1.5588269 1.6476816 +-0.1000000 0.2444444 0.5888889 0.9333333 1.2777778 1.6222222 1.9666667 2.3111111 2.6555556 3.0000000 +-0.3511192 0.5271086 0.7860854 0.9691262 1.1178635 1.2459617 1.3599219 1.4634339 1.5588269 1.6476816 3 3 3 0.9277778 0.9063014 0.9020062 diff --git a/colour/io/luts/tests/resources/cinespace/Uncommon_3x1D_With_Pre_Lut.csp b/colour/io/luts/tests/resources/cinespace/Uncommon_3x1D_With_Pre_Lut.csp index d9bc5c1466..2ff1e9a4c0 100644 --- a/colour/io/luts/tests/resources/cinespace/Uncommon_3x1D_With_Pre_Lut.csp +++ b/colour/io/luts/tests/resources/cinespace/Uncommon_3x1D_With_Pre_Lut.csp @@ -7,14 +7,14 @@ LogC to Linear END METADATA 5 --0.0172904 0.0415196 0.5133834 5.3571636 55.0795767 -0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 +-0.0172904 0.0415196 0.5133834 5.3571636 55.0795767 +0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 5 --0.0172904 0.0415196 0.5133834 5.3571636 55.0795767 -0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 +-0.0172904 0.0415196 0.5133834 5.3571636 55.0795767 +0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 5 --0.0172904 0.0415196 0.5133834 5.3571636 55.0795767 -0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 +-0.0172904 0.0415196 0.5133834 5.3571636 55.0795767 +0.0000000 0.2500000 0.5000000 0.7500000 1.0000000 5 -0.0172904 -0.0172904 -0.0172904 diff --git a/colour/io/luts/tests/resources/iridas_cube/ACES_Proxy_10_to_ACES.cube b/colour/io/luts/tests/resources/iridas_cube/ACES_Proxy_10_to_ACES.cube index 6d467a0213..c60ea1c943 100644 --- a/colour/io/luts/tests/resources/iridas_cube/ACES_Proxy_10_to_ACES.cube +++ b/colour/io/luts/tests/resources/iridas_cube/ACES_Proxy_10_to_ACES.cube @@ -31,4 +31,4 @@ LUT_1D_SIZE 32 178.5 178.5 178.5 282.1 282.1 282.1 445.7 445.7 445.7 -704.3 704.3 704.3 \ No newline at end of file +704.3 704.3 704.3 diff --git a/colour/io/luts/tests/resources/iridas_cube/Demo.cube b/colour/io/luts/tests/resources/iridas_cube/Demo.cube index c1672b9c14..1bfc5ed294 100644 --- a/colour/io/luts/tests/resources/iridas_cube/Demo.cube +++ b/colour/io/luts/tests/resources/iridas_cube/Demo.cube @@ -5,4 +5,4 @@ DOMAIN_MAX 1 2 3 0 0 0 # Comments can go anywhere 0.5 1 1.5 -1 1 1 \ No newline at end of file +1 1 1 diff --git a/colour/io/luts/tests/resources/iridas_cube/Three_Dimensional_Table.cube b/colour/io/luts/tests/resources/iridas_cube/Three_Dimensional_Table.cube index e0a6e33387..4e84b3db98 100644 --- a/colour/io/luts/tests/resources/iridas_cube/Three_Dimensional_Table.cube +++ b/colour/io/luts/tests/resources/iridas_cube/Three_Dimensional_Table.cube @@ -6,4 +6,4 @@ LUT_3D_SIZE 2 0 .25 1 1 .25 1 0 1 1 -1 1 1 \ No newline at end of file +1 1 1 diff --git a/colour/io/luts/tests/resources/resolve_cube/ACES_Proxy_10_to_ACES.cube b/colour/io/luts/tests/resources/resolve_cube/ACES_Proxy_10_to_ACES.cube index 6d467a0213..c60ea1c943 100644 --- a/colour/io/luts/tests/resources/resolve_cube/ACES_Proxy_10_to_ACES.cube +++ b/colour/io/luts/tests/resources/resolve_cube/ACES_Proxy_10_to_ACES.cube @@ -31,4 +31,4 @@ LUT_1D_SIZE 32 178.5 178.5 178.5 282.1 282.1 282.1 445.7 445.7 445.7 -704.3 704.3 704.3 \ No newline at end of file +704.3 704.3 704.3 diff --git a/colour/io/luts/tests/resources/resolve_cube/Demo.cube b/colour/io/luts/tests/resources/resolve_cube/Demo.cube index 88c7ebfd4f..9a70e79fa5 100644 --- a/colour/io/luts/tests/resources/resolve_cube/Demo.cube +++ b/colour/io/luts/tests/resources/resolve_cube/Demo.cube @@ -4,4 +4,4 @@ LUT_1D_SIZE 3 LUT_1D_INPUT_RANGE 0 3 0 0 0 1.5 1.5 1.5 -3 3 3 \ No newline at end of file +3 3 3 diff --git a/colour/io/luts/tests/resources/resolve_cube/Three_Dimensional_Table.cube b/colour/io/luts/tests/resources/resolve_cube/Three_Dimensional_Table.cube index e0a6e33387..4e84b3db98 100644 --- a/colour/io/luts/tests/resources/resolve_cube/Three_Dimensional_Table.cube +++ b/colour/io/luts/tests/resources/resolve_cube/Three_Dimensional_Table.cube @@ -6,4 +6,4 @@ LUT_3D_SIZE 2 0 .25 1 1 .25 1 0 1 1 -1 1 1 \ No newline at end of file +1 1 1 diff --git a/colour/io/luts/tests/resources/sony_spimtx/Matrix_Offset.spimtx b/colour/io/luts/tests/resources/sony_spimtx/Matrix_Offset.spimtx index 800a200a58..052a73a931 100644 --- a/colour/io/luts/tests/resources/sony_spimtx/Matrix_Offset.spimtx +++ b/colour/io/luts/tests/resources/sony_spimtx/Matrix_Offset.spimtx @@ -1,3 +1,3 @@ 1. 0. 0. 0. 0. 1. 0. 0. -0. 0. 1. 65535. \ No newline at end of file +0. 0. 1. 65535. diff --git a/colour/io/luts/tests/resources/sony_spimtx/p3_to_xyz16.spimtx b/colour/io/luts/tests/resources/sony_spimtx/p3_to_xyz16.spimtx index 03e316e3e0..0398946edf 100644 --- a/colour/io/luts/tests/resources/sony_spimtx/p3_to_xyz16.spimtx +++ b/colour/io/luts/tests/resources/sony_spimtx/p3_to_xyz16.spimtx @@ -1,4 +1,3 @@ .44488 .27717 .17237 0 .20936 .7217 .06895 0 0 .04707 .9078 0 - diff --git a/colour/io/luts/tests/test__init__.py b/colour/io/luts/tests/test__init__.py index f411874a47..83482edd90 100644 --- a/colour/io/luts/tests/test__init__.py +++ b/colour/io/luts/tests/test__init__.py @@ -3,12 +3,14 @@ from __future__ import annotations -import numpy as np import os import shutil import tempfile import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import LUTSequence, read_LUT, write_LUT __author__ = "Colour Developers" @@ -40,7 +42,7 @@ def test_read_LUT(self): os.path.join(ROOT_LUTS, "sony_spi1d", "eotf_sRGB_1D.spi1d") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.table, np.array( [ @@ -62,6 +64,7 @@ def test_read_LUT(self): 2.53715520e00, ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_1.name, "eotf sRGB 1D") self.assertEqual(LUT_1.dimensions, 1) @@ -75,7 +78,7 @@ def test_read_LUT(self): LUT_2 = read_LUT( os.path.join(ROOT_LUTS, "resolve_cube", "LogC_Video.cube") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2[0].table, np.array( [ @@ -97,9 +100,20 @@ def test_read_LUT(self): [1.00000000, 1.00000000, 1.00000000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_2[1].size, 4) + self.assertEqual( + read_LUT( + os.path.join(ROOT_LUTS, "sony_spi1d", "eotf_sRGB_1D.spi1d") + ), + read_LUT( + os.path.join(ROOT_LUTS, "sony_spi1d", "eotf_sRGB_1D.spi1d"), + method="Sony SPI1D", + ), + ) + def test_raise_exception_read_LUT(self): """ Test :func:`colour.io.luts.__init__.read_LUT` definition raised @@ -179,6 +193,22 @@ def test_write_LUT(self): self.assertEqual(LUT_2_r, LUT_2_t) + write_LUT( + LUT_1_r, + os.path.join(self._temporary_directory, "eotf_sRGB_1D"), + method="Sony SPI1D", + ) + + self.assertEqual( + read_LUT( + os.path.join(self._temporary_directory, "eotf_sRGB_1D.spi1d") + ), + read_LUT( + os.path.join(self._temporary_directory, "eotf_sRGB_1D"), + method="Sony SPI1D", + ), + ) + if __name__ == "__main__": unittest.main() diff --git a/colour/io/luts/tests/test_cinespace_csp.py b/colour/io/luts/tests/test_cinespace_csp.py index 6d683a3012..0f2530d27f 100644 --- a/colour/io/luts/tests/test_cinespace_csp.py +++ b/colour/io/luts/tests/test_cinespace_csp.py @@ -3,14 +3,15 @@ from __future__ import annotations -import numpy as np import os -import unittest import shutil import tempfile +import unittest + +import numpy as np -from colour.io import LUT1D, LUT3x1D -from colour.io import read_LUT_Cinespace, write_LUT_Cinespace +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.io import LUT1D, LUT3x1D, read_LUT_Cinespace, write_LUT_Cinespace from colour.utilities import tstack __author__ = "Colour Developers" @@ -47,7 +48,7 @@ def test_read_LUT_Cinespace(self): os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.csp") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.table, np.array( [ @@ -85,6 +86,7 @@ def test_read_LUT_Cinespace(self): [7.04300000e02, 7.04300000e02, 7.04300000e02], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_1.name, "ACES Proxy 10 to ACES") self.assertEqual(LUT_1.dimensions, 2) @@ -203,10 +205,10 @@ def test_write_LUT_Cinespace(self): LUT_4_r = read_LUT_Cinespace( os.path.join(ROOT_LUTS, "Ragged_Domain.csp") ) - np.testing.assert_array_almost_equal(LUT_4_t.domain, LUT_4_r.domain) - np.testing.assert_array_almost_equal( - LUT_4_t.table, LUT_4_r.table, decimal=6 + np.testing.assert_allclose( + LUT_4_t.domain, LUT_4_r.domain, atol=TOLERANCE_ABSOLUTE_TESTS ) + np.testing.assert_allclose(LUT_4_t.table, LUT_4_r.table, atol=5e-5) LUT_5_r = read_LUT_Cinespace( os.path.join(ROOT_LUTS, "Three_Dimensional_Table_With_Shaper.csp") diff --git a/colour/io/luts/tests/test_iridas_cube.py b/colour/io/luts/tests/test_iridas_cube.py index 094658b5ee..ea30ad9600 100644 --- a/colour/io/luts/tests/test_iridas_cube.py +++ b/colour/io/luts/tests/test_iridas_cube.py @@ -3,12 +3,14 @@ from __future__ import annotations -import numpy as np import os -import unittest import shutil import tempfile +import unittest + +import numpy as np +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import ( LUT1D, LUTSequence, @@ -50,7 +52,7 @@ def test_read_LUT_IridasCube(self): os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.cube") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.table, np.array( [ @@ -88,6 +90,7 @@ def test_read_LUT_IridasCube(self): [7.04300000e02, 7.04300000e02, 7.04300000e02], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_1.name, "ACES Proxy 10 to ACES") self.assertEqual(LUT_1.dimensions, 2) diff --git a/colour/io/luts/tests/test_lut.py b/colour/io/luts/tests/test_lut.py index 1b05fa3949..3ddcc65bd3 100644 --- a/colour/io/luts/tests/test_lut.py +++ b/colour/io/luts/tests/test_lut.py @@ -3,21 +3,21 @@ from __future__ import annotations -import numpy as np import os import textwrap import unittest +import numpy as np + from colour.algebra import ( CubicSplineInterpolator, LinearInterpolator, random_triplet_generator, spow, - table_interpolation_trilinear, table_interpolation_tetrahedral, + table_interpolation_trilinear, ) -from colour.io.luts.lut import AbstractLUT -from colour.io.luts import LUT1D, LUT3x1D, LUT3D, LUT_to_LUT +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import ( Any, Callable, @@ -25,6 +25,8 @@ ProtocolInterpolator, Type, ) +from colour.io.luts import LUT1D, LUT3D, LUT3x1D, LUT_to_LUT +from colour.io.luts.lut import AbstractLUT from colour.utilities import as_float_array, tsplit, tstack __author__ = "Colour Developers" @@ -181,8 +183,8 @@ def test__init__(self): LUT = self._LUT_factory(self._table_1) - np.testing.assert_array_almost_equal( - LUT.table, self._table_1, decimal=7 + np.testing.assert_allclose( + LUT.table, self._table_1, atol=TOLERANCE_ABSOLUTE_TESTS ) self.assertEqual(str(id(LUT)), LUT.name) @@ -212,7 +214,9 @@ def test_table(self): table_1 = self._table_1 * 0.8 + 0.1 LUT.table = table_1 - np.testing.assert_array_almost_equal(LUT.table, table_1, decimal=7) + np.testing.assert_allclose( + LUT.table, table_1, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_name(self): """ @@ -399,98 +403,108 @@ def test_arithmetical_operation(self): LUT_1 = self._LUT_factory() LUT_2 = self._LUT_factory() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.arithmetical_operation(10, "+", False).table, self._table_1 + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.arithmetical_operation(10, "-", False).table, self._table_1 - 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.arithmetical_operation(10, "*", False).table, self._table_1 * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.arithmetical_operation(10, "/", False).table, self._table_1 / 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.arithmetical_operation(10, "**", False).table, self._table_1**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (LUT_1 + 10).table, self._table_1 + 10, decimal=7 + np.testing.assert_allclose( + (LUT_1 + 10).table, + self._table_1 + 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (LUT_1 - 10).table, self._table_1 - 10, decimal=7 + np.testing.assert_allclose( + (LUT_1 - 10).table, + self._table_1 - 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (LUT_1 * 10).table, self._table_1 * 10, decimal=7 + np.testing.assert_allclose( + (LUT_1 * 10).table, + self._table_1 * 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (LUT_1 / 10).table, self._table_1 / 10, decimal=7 + np.testing.assert_allclose( + (LUT_1 / 10).table, + self._table_1 / 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - (LUT_1**10).table, self._table_1**10, decimal=7 + np.testing.assert_allclose( + (LUT_1**10).table, + self._table_1**10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.arithmetical_operation(10, "+", True).table, self._table_1 + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.arithmetical_operation(10, "-", True).table, self._table_1, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.arithmetical_operation(10, "*", True).table, self._table_1 * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.arithmetical_operation(10, "/", True).table, self._table_1, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.arithmetical_operation(10, "**", True).table, self._table_1**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) LUT_2 = self._LUT_factory() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.arithmetical_operation(self._table_1, "+", False).table, LUT_2.table + self._table_1, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.arithmetical_operation(LUT_2, "+", False).table, LUT_2.table + LUT_2.table, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_linear_table(self): @@ -505,16 +519,18 @@ def test_linear_table(self): LUT_1 = self._LUT_factory() - np.testing.assert_array_almost_equal( - LUT_1.linear_table(self._size), self._table_1, decimal=7 + np.testing.assert_allclose( + LUT_1.linear_table(self._size), + self._table_1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( spow( self._LUT_factory.linear_table(**self._table_3_kwargs), 1 / 2.6 ), self._table_3, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_copy(self): @@ -546,16 +562,20 @@ def test_invert(self): interpolator=self._interpolator_1, **self._invert_kwargs_1 ) - np.testing.assert_array_almost_equal( - LUT_i.apply(RANDOM_TRIPLETS), self._inverted_apply_1, decimal=7 + np.testing.assert_allclose( + LUT_i.apply(RANDOM_TRIPLETS), + self._inverted_apply_1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) LUT_i = self._LUT_factory(self._table_2).invert( interpolator=self._interpolator_2, **self._invert_kwargs_2 ) - np.testing.assert_array_almost_equal( - LUT_i.apply(RANDOM_TRIPLETS), self._inverted_apply_2, decimal=7 + np.testing.assert_allclose( + LUT_i.apply(RANDOM_TRIPLETS), + self._inverted_apply_2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) LUT_i = self._LUT_factory(self._table_2, domain=self._domain_4) @@ -565,8 +585,10 @@ def test_invert(self): interpolator=self._interpolator_2, **self._invert_kwargs_2 ) - np.testing.assert_array_almost_equal( - LUT_i.apply(RANDOM_TRIPLETS), self._inverted_apply_2, decimal=7 + np.testing.assert_allclose( + LUT_i.apply(RANDOM_TRIPLETS), + self._inverted_apply_2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) except NotImplementedError: pass @@ -583,26 +605,32 @@ def test_apply(self): LUT_1 = self._LUT_factory(self._table_2) - np.testing.assert_array_almost_equal( - LUT_1.apply(RANDOM_TRIPLETS), self._applied_1, decimal=7 + np.testing.assert_allclose( + LUT_1.apply(RANDOM_TRIPLETS), + self._applied_1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) LUT_2 = self._LUT_factory(domain=self._domain_2) LUT_2.table = spow(LUT_2.table, 1 / 2.2) - np.testing.assert_array_almost_equal( - LUT_2.apply(RANDOM_TRIPLETS), self._applied_2, decimal=7 + np.testing.assert_allclose( + LUT_2.apply(RANDOM_TRIPLETS), + self._applied_2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) LUT_3 = self._LUT_factory(self._table_3, domain=self._domain_3) - np.testing.assert_array_almost_equal( - LUT_3.apply(RANDOM_TRIPLETS), self._applied_3, decimal=7 + np.testing.assert_allclose( + LUT_3.apply(RANDOM_TRIPLETS), + self._applied_3, + atol=TOLERANCE_ABSOLUTE_TESTS, ) LUT_4 = self._LUT_factory(self._table_2) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_4.apply( RANDOM_TRIPLETS, direction="Inverse", @@ -611,7 +639,7 @@ def test_apply(self): **self._invert_kwargs_1, ), self._applied_4, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1160,7 +1188,7 @@ def test_LUT_to_LUT(self): LUT = LUT_to_LUT(self._LUT_1, LUT3D, force_conversion=True, size=5) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT.table, np.array( [ @@ -1351,7 +1379,7 @@ def test_LUT_to_LUT(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) # "LUT" 3x1D to "LUT" 1D. @@ -1394,7 +1422,7 @@ def test_LUT_to_LUT(self): LUT = LUT_to_LUT(self._LUT_2, LUT3D, force_conversion=True, size=5) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT.table, np.array( [ @@ -1585,7 +1613,7 @@ def test_LUT_to_LUT(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) # "LUT" 3D to "LUT" 1D. @@ -1600,7 +1628,7 @@ def test_LUT_to_LUT(self): channel_weights=channel_weights, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT.table, np.array( [ @@ -1622,6 +1650,7 @@ def test_LUT_to_LUT(self): 1.00000000, ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) channel_weights = np.array([1 / 3, 1 / 3, 1 / 3]) @@ -1633,7 +1662,7 @@ def test_LUT_to_LUT(self): channel_weights=channel_weights, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT.table, np.array( [ @@ -1655,6 +1684,7 @@ def test_LUT_to_LUT(self): 0.93781796, ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) # "LUT" 3D to "LUT" 3x1D. @@ -1662,7 +1692,7 @@ def test_LUT_to_LUT(self): LUT = LUT_to_LUT(self._LUT_3, LUT3x1D, force_conversion=True, size=16) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT.table, np.array( [ @@ -1684,6 +1714,7 @@ def test_LUT_to_LUT(self): [1.00000000, 1.00000000, 1.00000000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) # "LUT" 3D to "LUT" 3D. diff --git a/colour/io/luts/tests/test_operator.py b/colour/io/luts/tests/test_operator.py index 6c267c10ed..9a1a2623a2 100644 --- a/colour/io/luts/tests/test_operator.py +++ b/colour/io/luts/tests/test_operator.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.io.luts.operator` module.""" -import numpy as np import textwrap import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io.luts import AbstractLUTSequenceOperator, LUTOperatorMatrix from colour.utilities import tstack, zeros @@ -176,7 +178,7 @@ def test_apply(self): np.testing.assert_array_equal(LUTOperatorMatrix().apply(RGB), RGB) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._lut_operator_matrix.apply(RGB), np.array( [ @@ -187,9 +189,10 @@ def test_apply(self): [0.45000000, 1.50000000, 2.55000000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._lut_operator_matrix.apply(RGB, apply_offset_first=True), np.array( [ @@ -200,13 +203,14 @@ def test_apply(self): [0.33333333, 1.53333333, 2.73333333], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGBA = tstack([samples, samples, samples, samples]) np.testing.assert_array_equal(LUTOperatorMatrix().apply(RGBA), RGBA) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._lut_operator_matrix.apply(RGBA), np.array( [ @@ -217,9 +221,10 @@ def test_apply(self): [0.65000000, 1.96666667, 3.28333333, 4.60000000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._lut_operator_matrix.apply(RGBA, apply_offset_first=True), np.array( [ @@ -230,6 +235,7 @@ def test_apply(self): [0.73333333, 2.46666667, 4.20000000, 5.93333333], ], ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/io/luts/tests/test_resolve_cube.py b/colour/io/luts/tests/test_resolve_cube.py index d22ff7a159..26a41c37ec 100644 --- a/colour/io/luts/tests/test_resolve_cube.py +++ b/colour/io/luts/tests/test_resolve_cube.py @@ -3,12 +3,14 @@ from __future__ import annotations -import numpy as np import os -import unittest import shutil import tempfile +import unittest + +import numpy as np +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import LUT1D, read_LUT_ResolveCube, write_LUT_ResolveCube __author__ = "Colour Developers" @@ -45,7 +47,7 @@ def test_read_LUT_ResolveCube(self): os.path.join(ROOT_LUTS, "ACES_Proxy_10_to_ACES.cube") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.table, np.array( [ @@ -83,6 +85,7 @@ def test_read_LUT_ResolveCube(self): [7.04300000e02, 7.04300000e02, 7.04300000e02], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_1.name, "ACES Proxy 10 to ACES") self.assertEqual(LUT_1.dimensions, 2) @@ -107,7 +110,7 @@ def test_read_LUT_ResolveCube(self): LUT_4 = read_LUT_ResolveCube( os.path.join(ROOT_LUTS, "LogC_Video.cube") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_4[0].table, np.array( [ @@ -129,6 +132,7 @@ def test_read_LUT_ResolveCube(self): [1.00000000, 1.00000000, 1.00000000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_4[1].size, 4) diff --git a/colour/io/luts/tests/test_sequence.py b/colour/io/luts/tests/test_sequence.py index 8883d522d8..79b36e11c0 100644 --- a/colour/io/luts/tests/test_sequence.py +++ b/colour/io/luts/tests/test_sequence.py @@ -3,18 +3,20 @@ from __future__ import annotations -import numpy as np import textwrap import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.hints import Any, ArrayLike, NDArrayFloat from colour.io.luts import ( - AbstractLUTSequenceOperator, LUT1D, - LUT3x1D, LUT3D, + AbstractLUTSequenceOperator, + LUT3x1D, LUTSequence, ) -from colour.hints import Any, ArrayLike, NDArrayFloat from colour.models import gamma_function from colour.utilities import as_float_array, tstack @@ -452,7 +454,7 @@ def apply( samples = np.linspace(0, 1, 5) RGB = tstack([samples, samples, samples]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_sequence.apply(RGB, GammaOperator={"direction": "Inverse"}), np.array( [ @@ -463,6 +465,7 @@ def apply( [0.75000000, 0.75000000, 0.75000000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/io/luts/tests/test_sony_spi1d.py b/colour/io/luts/tests/test_sony_spi1d.py index 37ac47f26a..26c4b4f280 100644 --- a/colour/io/luts/tests/test_sony_spi1d.py +++ b/colour/io/luts/tests/test_sony_spi1d.py @@ -3,12 +3,14 @@ from __future__ import annotations -import numpy as np import os import shutil import tempfile import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import read_LUT_SonySPI1D, write_LUT_SonySPI1D __author__ = "Colour Developers" @@ -42,7 +44,7 @@ def test_read_LUT_SonySPI1D(self): os.path.join(ROOT_LUTS, "eotf_sRGB_1D.spi1d") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.table, np.array( [ @@ -64,6 +66,7 @@ def test_read_LUT_SonySPI1D(self): 2.53715520e00, ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_1.name, "eotf sRGB 1D") self.assertEqual(LUT_1.dimensions, 1) diff --git a/colour/io/luts/tests/test_sony_spi3d.py b/colour/io/luts/tests/test_sony_spi3d.py index 91c65548e5..8a243ea48f 100644 --- a/colour/io/luts/tests/test_sony_spi3d.py +++ b/colour/io/luts/tests/test_sony_spi3d.py @@ -3,12 +3,14 @@ from __future__ import annotations -import numpy as np import os import shutil import tempfile import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import ( LUT3D, LUTSequence, @@ -48,7 +50,7 @@ def test_read_LUT_SonySPI3D(self): os.path.join(ROOT_LUTS, "Colour_Correct.spi3d") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.table, np.array( [ @@ -158,6 +160,7 @@ def test_read_LUT_SonySPI3D(self): ], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_1.name, "Colour Correct") self.assertEqual(LUT_1.dimensions, 3) diff --git a/colour/io/luts/tests/test_sony_spimtx.py b/colour/io/luts/tests/test_sony_spimtx.py index 3c9ffeabae..0c149cf2a3 100644 --- a/colour/io/luts/tests/test_sony_spimtx.py +++ b/colour/io/luts/tests/test_sony_spimtx.py @@ -3,12 +3,14 @@ from __future__ import annotations -import numpy as np import os import shutil import tempfile import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import read_LUT_SonySPImtx, write_LUT_SonySPImtx __author__ = "Colour Developers" @@ -43,7 +45,7 @@ def test_read_LUT_SonySPImtx(self): LUT_1 = read_LUT_SonySPImtx(os.path.join(ROOT_LUTS, "dt.spimtx")) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_1.matrix, np.array( [ @@ -53,16 +55,19 @@ def test_read_LUT_SonySPImtx(self): [0.000000, 0.000000, 0.000000, 1.000000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - LUT_1.offset, np.array([0.000000, 0.000000, 0.000000, 0.000000]) + np.testing.assert_allclose( + LUT_1.offset, + np.array([0.000000, 0.000000, 0.000000, 0.000000]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_1.name, "dt") LUT_2 = read_LUT_SonySPImtx( os.path.join(ROOT_LUTS, "p3_to_xyz16.spimtx") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_2.matrix, np.array( [ @@ -72,16 +77,19 @@ def test_read_LUT_SonySPImtx(self): [0.00000, 0.00000, 0.00000, 1.00000], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - LUT_2.offset, np.array([0.000000, 0.000000, 0.000000, 0.000000]) + np.testing.assert_allclose( + LUT_2.offset, + np.array([0.000000, 0.000000, 0.000000, 0.000000]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_2.name, "p3 to xyz16") LUT_3 = read_LUT_SonySPImtx( os.path.join(ROOT_LUTS, "Matrix_Offset.spimtx") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LUT_3.matrix, np.array( [ @@ -91,9 +99,12 @@ def test_read_LUT_SonySPImtx(self): [0.0, 0.0, 0.0, 1.0], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - LUT_3.offset, np.array([0.0, 0.0, 1.0, 0.0]) + np.testing.assert_allclose( + LUT_3.offset, + np.array([0.0, 0.0, 1.0, 0.0]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(LUT_3.name, "Matrix Offset") diff --git a/colour/io/ocio.py b/colour/io/ocio.py index 9805dffcf4..1057cd35a1 100644 --- a/colour/io/ocio.py +++ b/colour/io/ocio.py @@ -11,9 +11,9 @@ import numpy as np -from colour.io import as_3_channels_image from colour.hints import Any, ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float, required +from colour.io import as_3_channels_image +from colour.utilities import as_float, as_float_array, required __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -135,9 +135,9 @@ def process_image_OpenColorIO( config = kwargs.get("config") config = ( - ocio.Config.CreateFromEnv() + ocio.Config.CreateFromEnv() # pyright: ignore if config is None - else ocio.Config.CreateFromFile(config) + else ocio.Config.CreateFromFile(config) # pyright: ignore ) a = as_float_array(a) @@ -148,7 +148,9 @@ def process_image_OpenColorIO( processor = config.getProcessor(*args).getDefaultCPUProcessor() - image_desc = ocio.PackedImageDesc(a, width, height, channels) + image_desc = ocio.PackedImageDesc( # pyright: ignore + a, width, height, channels + ) processor.apply(image_desc) diff --git a/colour/io/tabular.py b/colour/io/tabular.py index bc316c2347..13d1e8c647 100644 --- a/colour/io/tabular.py +++ b/colour/io/tabular.py @@ -12,12 +12,13 @@ from __future__ import annotations import csv -import numpy as np import os import tempfile +import numpy as np + from colour.colorimetry import SpectralDistribution -from colour.constants import DEFAULT_FLOAT_DTYPE +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.hints import Any, Dict, NDArrayFloat, cast from colour.utilities import filter_kwargs @@ -121,7 +122,7 @@ def read_spectral_data_from_csv_file( "case_sensitive": True, "deletechars": "", "replace_space": " ", - "dtype": DEFAULT_FLOAT_DTYPE, + "dtype": DTYPE_FLOAT_DEFAULT, } settings.update(**kwargs) diff --git a/colour/io/tests/resources/Adjust_Exposure_Float.ctl b/colour/io/tests/resources/Adjust_Exposure_Float.ctl index d85aa7dd60..aaef9a1e8b 100644 --- a/colour/io/tests/resources/Adjust_Exposure_Float.ctl +++ b/colour/io/tests/resources/Adjust_Exposure_Float.ctl @@ -17,4 +17,4 @@ void main gOut = gIn * pow(2, exposure); bOut = bIn * pow(2, exposure); aOut = aIn; -} \ No newline at end of file +} diff --git a/colour/io/tests/resources/Adjust_Exposure_Float3.ctl b/colour/io/tests/resources/Adjust_Exposure_Float3.ctl index 5e33c3edb1..ca44d5e285 100644 --- a/colour/io/tests/resources/Adjust_Exposure_Float3.ctl +++ b/colour/io/tests/resources/Adjust_Exposure_Float3.ctl @@ -5,11 +5,11 @@ float[3] adjust_exposure(float rgbIn[3], float exposureIn) float rgbOut[3]; float exposure = pow(2, exposureIn); - + rgbOut[0] = rgbIn[0] * exposure; rgbOut[1] = rgbIn[1] * exposure; rgbOut[2] = rgbIn[2] * exposure; - + return rgbOut; } @@ -29,9 +29,9 @@ void main float rgbIn[3] = {rIn, gIn, bIn}; float rgbOut[3] = adjust_exposure(rgbIn, exposure); - + rOut = rgbOut[0]; gOut = rgbOut[1]; bOut = rgbOut[2]; aOut = aIn; -} \ No newline at end of file +} diff --git a/colour/io/tests/resources/ESPD2021_0104_231446.xls b/colour/io/tests/resources/ESPD2021_0104_231446.xls index 11f61f3567..76e2f32e0e 100644 --- a/colour/io/tests/resources/ESPD2021_0104_231446.xls +++ b/colour/io/tests/resources/ESPD2021_0104_231446.xls @@ -1,7 +1,7 @@ Model Name CV600 Serial Number 19J00789 Time 2021/01/04_23:14:46 -Memo +Memo LUX 695.154907 fc 64.605476 CCT 5198.000000 diff --git a/colour/io/tests/resources/Invalid.spdx b/colour/io/tests/resources/Invalid.spdx index db71b1e79e..8fa841de1c 100755 --- a/colour/io/tests/resources/Invalid.spdx +++ b/colour/io/tests/resources/Invalid.spdx @@ -1,2 +1,2 @@ - - \ No newline at end of file + + diff --git a/colour/io/tests/resources/colorchecker_n_ohta.csv b/colour/io/tests/resources/colorchecker_n_ohta.csv index 76ef66c4af..e6a3b8f224 100644 --- a/colour/io/tests/resources/colorchecker_n_ohta.csv +++ b/colour/io/tests/resources/colorchecker_n_ohta.csv @@ -79,4 +79,4 @@ wavelength,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24 765,0.465,0.799,0.107,0.368,0.515,0.301,0.639,0.259,0.584,0.495,0.436,0.698,0.154,0.111,0.727,0.781,0.813,0.191,0.881,0.554,0.328,0.185,0.084,0.032 770,0.448,0.771,0.11,0.355,0.5,0.297,0.616,0.275,0.566,0.482,0.426,0.673,0.168,0.112,0.702,0.752,0.785,0.2,0.88,0.553,0.327,0.184,0.083,0.032 775,0.432,0.747,0.115,0.346,0.491,0.296,0.598,0.294,0.551,0.471,0.413,0.653,0.186,0.112,0.68,0.728,0.765,0.208,0.88,0.551,0.326,0.184,0.083,0.032 -780,0.421,0.734,0.12,0.341,0.487,0.296,0.582,0.316,0.54,0.467,0.404,0.639,0.204,0.112,0.664,0.71,0.752,0.214,0.879,0.55,0.325,0.183,0.083,0.032 \ No newline at end of file +780,0.421,0.734,0.12,0.341,0.487,0.296,0.582,0.316,0.54,0.467,0.404,0.639,0.204,0.112,0.664,0.71,0.752,0.214,0.879,0.55,0.325,0.183,0.083,0.032 diff --git a/colour/io/tests/resources/colorchecker_n_ohta_transposed.csv b/colour/io/tests/resources/colorchecker_n_ohta_transposed.csv index aee1f4440a..a537a21938 100644 --- a/colour/io/tests/resources/colorchecker_n_ohta_transposed.csv +++ b/colour/io/tests/resources/colorchecker_n_ohta_transposed.csv @@ -22,4 +22,4 @@ wavelength 380 385 390 395 400 405 410 415 420 425 430 435 440 445 450 455 460 4 21 0.138 0.167 0.206 0.249 0.289 0.324 0.346 0.354 0.357 0.358 0.359 0.36 0.361 0.362 0.362 0.361 0.361 0.359 0.358 0.358 0.357 0.356 0.356 0.356 0.356 0.356 0.356 0.356 0.357 0.357 0.357 0.358 0.358 0.358 0.358 0.358 0.359 0.359 0.36 0.361 0.361 0.361 0.361 0.361 0.36 0.36 0.359 0.358 0.357 0.356 0.355 0.354 0.353 0.352 0.351 0.35 0.349 0.348 0.346 0.346 0.345 0.344 0.343 0.342 0.341 0.34 0.339 0.338 0.337 0.336 0.335 0.334 0.333 0.332 0.331 0.33 0.329 0.328 0.327 0.326 0.325 22 0.113 0.131 0.15 0.169 0.183 0.193 0.199 0.201 0.202 0.203 0.203 0.204 0.205 0.205 0.205 0.205 0.204 0.204 0.203 0.203 0.202 0.202 0.202 0.202 0.202 0.202 0.202 0.202 0.202 0.202 0.203 0.203 0.203 0.203 0.203 0.203 0.203 0.203 0.204 0.204 0.205 0.205 0.205 0.205 0.204 0.204 0.204 0.203 0.203 0.202 0.201 0.201 0.2 0.199 0.198 0.198 0.197 0.197 0.196 0.195 0.195 0.194 0.194 0.193 0.192 0.192 0.191 0.191 0.19 0.189 0.189 0.188 0.188 0.187 0.187 0.186 0.185 0.185 0.184 0.184 0.183 23 0.074 0.079 0.084 0.088 0.091 0.093 0.094 0.094 0.094 0.094 0.094 0.095 0.095 0.095 0.095 0.094 0.094 0.094 0.094 0.093 0.093 0.093 0.093 0.092 0.092 0.093 0.093 0.093 0.093 0.093 0.093 0.093 0.093 0.093 0.093 0.092 0.093 0.093 0.093 0.093 0.093 0.093 0.093 0.092 0.092 0.092 0.092 0.091 0.091 0.091 0.09 0.09 0.09 0.09 0.089 0.089 0.089 0.088 0.088 0.088 0.087 0.087 0.087 0.087 0.086 0.086 0.086 0.086 0.085 0.085 0.085 0.085 0.085 0.084 0.084 0.084 0.084 0.084 0.083 0.083 0.083 -24 0.032 0.033 0.033 0.034 0.035 0.035 0.036 0.036 0.036 0.036 0.036 0.036 0.035 0.035 0.035 0.035 0.035 0.035 0.035 0.035 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 \ No newline at end of file +24 0.032 0.033 0.033 0.034 0.035 0.035 0.036 0.036 0.036 0.036 0.036 0.036 0.035 0.035 0.035 0.035 0.035 0.035 0.035 0.035 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.034 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.033 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 0.032 diff --git a/colour/io/tests/resources/config-aces-reference.ocio.yaml b/colour/io/tests/resources/config-aces-reference.ocio.yaml index 52169e293d..cfca62c7d1 100644 --- a/colour/io/tests/resources/config-aces-reference.ocio.yaml +++ b/colour/io/tests/resources/config-aces-reference.ocio.yaml @@ -584,4 +584,4 @@ colorspaces: categories: [file-io] encoding: log allocation: uniform - to_scene_reference: ! {style: PANASONIC_VLOG-VGAMUT_to_ACES2065-1} \ No newline at end of file + to_scene_reference: ! {style: PANASONIC_VLOG-VGAMUT_to_ACES2065-1} diff --git a/colour/io/tests/resources/linss2_10e_5.csv b/colour/io/tests/resources/linss2_10e_5.csv index 9600473ef5..fd92c71793 100644 --- a/colour/io/tests/resources/linss2_10e_5.csv +++ b/colour/io/tests/resources/linss2_10e_5.csv @@ -86,4 +86,4 @@ 815, 2.34468E-06, 2.16878E-07, 820, 1.74666E-06, 1.65158E-07, 825, 1.30241E-06, 1.25508E-07, -830, 9.74306E-07, 9.53411E-08, \ No newline at end of file +830, 9.74306E-07, 9.53411E-08, diff --git a/colour/io/tests/resources/uprtek.xls.txt b/colour/io/tests/resources/uprtek.xls.txt index 17a2c64275..86d66188d5 100644 --- a/colour/io/tests/resources/uprtek.xls.txt +++ b/colour/io/tests/resources/uprtek.xls.txt @@ -1,7 +1,7 @@ Model Name CV600 Serial Number 19J00789 Time 2021/01/04_23:14:46 -Memo +Memo LUX 695.154907 fc 64.605476 CCT 5198.000000 diff --git a/colour/io/tests/test_ctl.py b/colour/io/tests/test_ctl.py index fa0e42293c..ee0146bfd2 100644 --- a/colour/io/tests/test_ctl.py +++ b/colour/io/tests/test_ctl.py @@ -3,20 +3,22 @@ from __future__ import annotations -import numpy as np import os import shutil import tempfile import textwrap import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import ( ctl_render, process_image_ctl, + read_image, template_ctl_transform_float, template_ctl_transform_float3, ) -from colour.io import read_image from colour.utilities import full, is_ctlrender_installed __author__ = "Colour Developers" @@ -91,10 +93,10 @@ def test_ctl_render(self): # pragma: no cover "-force", ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( read_image(path_output)[..., 0:3], read_image(path_input) * [1, 2, 4], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) ctl_render( @@ -110,10 +112,10 @@ def test_ctl_render(self): # pragma: no cover env=dict(os.environ, CTL_MODULE_PATH=ROOT_RESOURCES), ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( read_image(path_output)[..., 0:3], read_image(path_input) * 2, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -147,7 +149,6 @@ def test_process_image_ctl(self): # pragma: no cover "-force", ), 0.18 / 2, - rtol=0.0001, atol=0.0001, ) @@ -159,7 +160,6 @@ def test_process_image_ctl(self): # pragma: no cover }, ), np.array([0.18 / 2, 0.18, 0.18 * 2]), - rtol=0.0001, atol=0.0001, ) @@ -171,7 +171,6 @@ def test_process_image_ctl(self): # pragma: no cover }, ), np.array([[0.18 / 2, 0.18, 0.18 * 2]]), - rtol=0.0001, atol=0.0001, ) @@ -183,7 +182,6 @@ def test_process_image_ctl(self): # pragma: no cover }, ), np.array([[[0.18 / 2, 0.18, 0.18 * 2]]]), - rtol=0.0001, atol=0.0001, ) @@ -195,7 +193,6 @@ def test_process_image_ctl(self): # pragma: no cover }, ), full([4, 2, 3], 0.18) * [0.5, 1.0, 2.0], - rtol=0.0001, atol=0.0001, ) diff --git a/colour/io/tests/test_image.py b/colour/io/tests/test_image.py index 9444f02975..6996957966 100644 --- a/colour/io/tests/test_image.py +++ b/colour/io/tests/test_image.py @@ -3,19 +3,26 @@ from __future__ import annotations -import numpy as np import os import platform import shutil -import unittest import tempfile +import unittest + +import numpy as np -from colour.io import convert_bit_depth -from colour.io import read_image_OpenImageIO, write_image_OpenImageIO -from colour.io import read_image_Imageio, write_image_Imageio -from colour.io import read_image, write_image -from colour.io import as_3_channels_image -from colour.io import ImageAttribute_Specification +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.io import ( + ImageAttribute_Specification, + as_3_channels_image, + convert_bit_depth, + read_image, + read_image_Imageio, + read_image_OpenImageIO, + write_image, + write_image_Imageio, + write_image_OpenImageIO, +) from colour.utilities import attest, full, is_openimageio_installed __author__ = "Colour Developers" @@ -73,7 +80,7 @@ def test_convert_bit_depth(self): self.assertIs( convert_bit_depth(a, "float16").dtype, np.dtype("float16") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert_bit_depth(a, "float16"), np.array( [ @@ -89,13 +96,13 @@ def test_convert_bit_depth(self): 1.0000, ] ), - decimal=3, + atol=5e-4, ) self.assertIs( convert_bit_depth(a, "float32").dtype, np.dtype("float32") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert_bit_depth(a, "float32"), np.array( [ @@ -111,7 +118,7 @@ def test_convert_bit_depth(self): 1.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertIs( @@ -136,7 +143,7 @@ def test_convert_bit_depth(self): self.assertIs( convert_bit_depth(a, "float16").dtype, np.dtype("float16") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert_bit_depth(a, "float16"), np.array( [ @@ -152,13 +159,13 @@ def test_convert_bit_depth(self): 1.0000, ] ), - decimal=3, + atol=5e-2, ) self.assertIs( convert_bit_depth(a, "float32").dtype, np.dtype("float32") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert_bit_depth(a, "float32"), np.array( [ @@ -174,7 +181,7 @@ def test_convert_bit_depth(self): 1.00000000, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertIs( @@ -215,7 +222,7 @@ def test_convert_bit_depth(self): self.assertIs( convert_bit_depth(a, "float16").dtype, np.dtype("float16") ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( convert_bit_depth(a, "float16"), np.array( [ @@ -231,14 +238,14 @@ def test_convert_bit_depth(self): 1.0000, ] ), - decimal=3, + atol=5e-4, ) self.assertIs( convert_bit_depth(a, "float32").dtype, np.dtype("float32") ) - np.testing.assert_array_almost_equal( - convert_bit_depth(a, "float32"), a, decimal=7 + np.testing.assert_allclose( + convert_bit_depth(a, "float32"), a, atol=TOLERANCE_ABSOLUTE_TESTS ) self.assertIs( @@ -407,10 +414,10 @@ def test_write_image_OpenImageIO(self): # pragma: no cover if write_attribute.name == read_attribute.name: attribute_exists = True if isinstance(write_attribute.value, tuple): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( write_attribute.value, read_attribute.value, - decimal=5, + atol=TOLERANCE_ABSOLUTE_TESTS, ) else: self.assertEqual( diff --git a/colour/io/tests/test_ocio.py b/colour/io/tests/test_ocio.py index af51d6b3de..a0ee3adf29 100644 --- a/colour/io/tests/test_ocio.py +++ b/colour/io/tests/test_ocio.py @@ -3,10 +3,12 @@ from __future__ import annotations -import numpy as np import os import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import process_image_OpenColorIO from colour.utilities import full, is_opencolorio_installed @@ -47,7 +49,7 @@ def test_process_image_OpenColorIO(self): a = full([4, 2, 3], 0.18) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( process_image_OpenColorIO( a, "ACES - ACES2065-1", "ACES - ACEScct", config=config ), @@ -71,10 +73,10 @@ def test_process_image_OpenColorIO(self): ], ] ), - decimal=5, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( process_image_OpenColorIO( a, "ACES - ACES2065-1", @@ -103,7 +105,7 @@ def test_process_image_OpenColorIO(self): ], ] ), - decimal=5, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/io/tests/test_tabular.py b/colour/io/tests/test_tabular.py index fc84951065..7f0ee8e8a3 100644 --- a/colour/io/tests/test_tabular.py +++ b/colour/io/tests/test_tabular.py @@ -5,13 +5,13 @@ import os import shutil -import unittest import tempfile +import unittest from colour.colorimetry import SpectralDistribution, SpectralShape from colour.io import ( - read_spectral_data_from_csv_file, read_sds_from_csv_file, + read_spectral_data_from_csv_file, write_sds_to_csv_file, ) diff --git a/colour/io/tests/test_tm2714.py b/colour/io/tests/test_tm2714.py index 12d1c3299e..5714692239 100644 --- a/colour/io/tests/test_tm2714.py +++ b/colour/io/tests/test_tm2714.py @@ -3,16 +3,18 @@ from __future__ import annotations -import numpy as np import os import re import shutil -import unittest import tempfile import textwrap +import unittest from copy import deepcopy +import numpy as np + from colour.colorimetry import SpectralDistribution +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import List, Tuple, cast from colour.io.tm2714 import Header_IESTM2714, SpectralDistribution_IESTM2714 from colour.utilities import optional @@ -595,7 +597,9 @@ def test_read(self, sd: SpectralDistribution | None = None): sd_r = SpectralDistribution(FLUORESCENT_FILE_SPECTRAL_DATA) np.testing.assert_array_equal(sd_r.domain, sd.domain) - np.testing.assert_array_almost_equal(sd_r.values, sd.values, decimal=7) + np.testing.assert_allclose( + sd_r.values, sd.values, atol=TOLERANCE_ABSOLUTE_TESTS + ) test_read: List[ Tuple[dict, Header_IESTM2714 | SpectralDistribution_IESTM2714] @@ -620,10 +624,10 @@ def test_raise_exception_read(self): sd = SpectralDistribution_IESTM2714() self.assertRaises(ValueError, sd.read) - sd = SpectralDistribution_IESTM2714( - os.path.join(ROOT_RESOURCES, "Invalid.spdx") - ) - self.assertRaises(ValueError, sd.read) + with self.assertRaises(ValueError): + sd = SpectralDistribution_IESTM2714( + os.path.join(ROOT_RESOURCES, "Invalid.spdx") + ) def test_write(self): """ diff --git a/colour/io/tests/test_uprtek_sekonic.py b/colour/io/tests/test_uprtek_sekonic.py index 2a2c84c76b..b1eaa9457b 100644 --- a/colour/io/tests/test_uprtek_sekonic.py +++ b/colour/io/tests/test_uprtek_sekonic.py @@ -3,15 +3,17 @@ from __future__ import annotations import json -import numpy as np import os import unittest +import numpy as np + from colour.colorimetry import SpectralDistribution +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import Any from colour.io import ( - SpectralDistribution_UPRTek, SpectralDistribution_Sekonic, + SpectralDistribution_UPRTek, ) __author__ = "Colour Developers" @@ -111,7 +113,9 @@ def test_read(self): sd_r = SpectralDistribution(self._spectral_data) np.testing.assert_array_equal(sd_r.domain, sd.domain) - np.testing.assert_array_almost_equal(sd_r.values, sd.values, decimal=6) + np.testing.assert_allclose( + sd_r.values, sd.values, atol=TOLERANCE_ABSOLUTE_TESTS + ) for key, value in self._header.items(): for specification in sd.header.mapping.elements: diff --git a/colour/io/tm2714.py b/colour/io/tm2714.py index 4cd183ff16..7bf3932ced 100644 --- a/colour/io/tm2714.py +++ b/colour/io/tm2714.py @@ -18,8 +18,8 @@ import os import re from dataclasses import dataclass, field -from xml.etree import ElementTree from xml.dom import minidom +from xml.etree import ElementTree from colour.colorimetry import SpectralDistribution from colour.hints import Any, Callable, Literal @@ -28,11 +28,11 @@ as_float_array, as_float_scalar, attest, - optional, - multiline_str, - multiline_repr, is_numeric, is_string, + multiline_repr, + multiline_str, + optional, tstack, ) @@ -871,7 +871,7 @@ class SpectralDistribution_IESTM2714(SpectralDistribution): >>> directory = join(dirname(__file__), "tests", "resources") >>> sd = SpectralDistribution_IESTM2714( ... join(directory, "Fluorescent.spdx") - ... ).read() + ... ) >>> sd.name # doctest: +SKIP 'Unknown - N/A - Rare earth fluorescent lamp' >>> sd.header.comments @@ -1004,6 +1004,9 @@ def __init__( self._bandwidth_corrected: bool | None = None self.bandwidth_corrected = bandwidth_corrected + if self.path is not None and os.path.exists(self.path): + self.read() + @property def mapping(self) -> Structure: """ @@ -1322,7 +1325,7 @@ def __str__(self) -> str: >>> print( ... SpectralDistribution_IESTM2714( ... join(directory, "Fluorescent.spdx") - ... ).read() + ... ) ... ) ... # doctest: +ELLIPSIS IES TM-27-14 Spectral Distribution @@ -1496,9 +1499,7 @@ def __repr__(self) -> str: -------- >>> from os.path import dirname, join >>> directory = join(dirname(__file__), "tests", "resources") - >>> SpectralDistribution_IESTM2714( - ... join(directory, "Fluorescent.spdx") - ... ).read() + >>> SpectralDistribution_IESTM2714(join(directory, "Fluorescent.spdx")) ... # doctest: +ELLIPSIS SpectralDistribution_IESTM2714('...', Header_IESTM2714('Unknown', @@ -1663,7 +1664,7 @@ def read(self) -> SpectralDistribution_IESTM2714: >>> directory = join(dirname(__file__), "tests", "resources") >>> sd = SpectralDistribution_IESTM2714( ... join(directory, "Fluorescent.spdx") - ... ).read() + ... ) >>> sd.name # doctest: +SKIP 'Unknown - N/A - Rare earth fluorescent lamp' >>> sd.header.comments @@ -1756,7 +1757,7 @@ def write(self) -> bool: >>> directory = join(dirname(__file__), "tests", "resources") >>> sd = SpectralDistribution_IESTM2714( ... join(directory, "Fluorescent.spdx") - ... ).read() + ... ) >>> temporary_directory = mkdtemp() >>> sd.path = join(temporary_directory, "Fluorescent.spdx") >>> sd.write() diff --git a/colour/io/uprtek_sekonic.py b/colour/io/uprtek_sekonic.py index 598b91dcf5..59e947cf08 100644 --- a/colour/io/uprtek_sekonic.py +++ b/colour/io/uprtek_sekonic.py @@ -17,8 +17,8 @@ import re from collections import defaultdict -from colour.io import SpectralDistribution_IESTM2714 from colour.hints import Any, cast +from colour.io import SpectralDistribution_IESTM2714 from colour.utilities import as_float_array, as_float_scalar __author__ = "Colour Developers" @@ -62,7 +62,7 @@ class SpectralDistribution_UPRTek(SpectralDistribution_IESTM2714): >>> sd = SpectralDistribution_UPRTek( ... join(directory, "ESPD2021_0104_231446.xls") ... ) - >>> print(sd.read().align(SpectralShape(380, 780, 10))) + >>> print(sd.align(SpectralShape(380, 780, 10))) ... # doctest: +ELLIPSIS UPRTek ====== @@ -156,15 +156,15 @@ class SpectralDistribution_UPRTek(SpectralDistribution_IESTM2714): ... # doctest: +SKIP """ - def __init__(self, path: str, **kwargs: Any) -> None: - super().__init__(path, **kwargs) - - self._delimiter: str = "\t" - self._spectral_section: str = "380" - self._spectral_data_pattern: str = "(\\d{3})nm" + _DELIMITER: str = "\t" + _SPECTRAL_SECTION: str = "380" + _SPECTRAL_DATA_PATTERN: str = "(\\d{3})nm" + def __init__(self, path: str, **kwargs: Any) -> None: self._metadata: dict = {} + super().__init__(path, **kwargs) + @property def metadata(self) -> dict: """ @@ -379,7 +379,7 @@ def as_array(a: Any) -> list: spectral_sections = defaultdict(list) with open(path, encoding="utf-8") as csv_file: - content = csv.reader(csv_file, delimiter=self._delimiter) + content = csv.reader(csv_file, delimiter=self._DELIMITER) spectral_section = 0 for row in content: @@ -389,11 +389,11 @@ def as_array(a: Any) -> list: attribute, tokens = row[0], row[1:] value = tokens[0] if len(tokens) == 1 else tokens - match = re.match(self._spectral_data_pattern, attribute) + match = re.match(self._SPECTRAL_DATA_PATTERN, attribute) if match: wavelength = match.group(1) - if wavelength == self._spectral_section: + if wavelength == self._SPECTRAL_SECTION: spectral_section += 1 spectral_sections[spectral_section].append( @@ -532,13 +532,13 @@ class SpectralDistribution_Sekonic(SpectralDistribution_UPRTek): ... # doctest: +SKIP """ + _DELIMITER: str = "," + _SPECTRAL_SECTION: str = "380" + _SPECTRAL_DATA_PATTERN: str = "Spectral Data (\\d{3})\\[nm\\]" + def __init__(self, path: str, **kwargs: Any) -> None: super().__init__(path, **kwargs) - self._delimiter: str = "," - self._spectral_section: str = "380" - self._spectral_data_pattern: str = "Spectral Data (\\d{3})\\[nm\\]" - def __str__(self) -> str: """ Return a formatted string representation of the *Sekonic* spectral diff --git a/colour/models/__init__.py b/colour/models/__init__.py index cfbf69cb6f..05efa58486 100644 --- a/colour/models/__init__.py +++ b/colour/models/__init__.py @@ -125,6 +125,8 @@ log_decoding_ACEScc, log_encoding_ACEScct, log_decoding_ACEScct, + log_encoding_AppleLogProfile, + log_decoding_AppleLogProfile, oetf_ARIBSTDB67, oetf_inverse_ARIBSTDB67, log_encoding_ARRILogC3, @@ -535,6 +537,8 @@ "log_decoding_ACEScc", "log_encoding_ACEScct", "log_decoding_ACEScct", + "log_encoding_AppleLogProfile", + "log_decoding_AppleLogProfile", "oetf_ARIBSTDB67", "oetf_inverse_ARIBSTDB67", "log_encoding_ARRILogC3", diff --git a/colour/models/cam02_ucs.py b/colour/models/cam02_ucs.py index e3b335db17..e66bda6064 100644 --- a/colour/models/cam02_ucs.py +++ b/colour/models/cam02_ucs.py @@ -27,9 +27,10 @@ from __future__ import annotations -import numpy as np from collections import namedtuple +import numpy as np + from colour.algebra import cartesian_to_polar, polar_to_cartesian from colour.hints import Any, ArrayLike, NDArrayFloat, cast from colour.utilities import ( diff --git a/colour/models/cam16_ucs.py b/colour/models/cam16_ucs.py index 501203b840..830a10c47c 100644 --- a/colour/models/cam16_ucs.py +++ b/colour/models/cam16_ucs.py @@ -31,23 +31,23 @@ import re from functools import partial -from colour.hints import Callable, Any, ArrayLike, NDArrayFloat, cast +from colour.hints import Any, ArrayLike, Callable, NDArrayFloat, cast from colour.models.cam02_ucs import ( COEFFICIENTS_UCS_LUO2006, - JMh_CIECAM02_to_UCS_Luo2006, - UCS_Luo2006_to_JMh_CIECAM02, - JMh_CIECAM02_to_CAM02LCD, CAM02LCD_to_JMh_CIECAM02, - JMh_CIECAM02_to_CAM02SCD, + CAM02LCD_to_XYZ, CAM02SCD_to_JMh_CIECAM02, - JMh_CIECAM02_to_CAM02UCS, + CAM02SCD_to_XYZ, CAM02UCS_to_JMh_CIECAM02, + CAM02UCS_to_XYZ, + JMh_CIECAM02_to_CAM02LCD, + JMh_CIECAM02_to_CAM02SCD, + JMh_CIECAM02_to_CAM02UCS, + JMh_CIECAM02_to_UCS_Luo2006, + UCS_Luo2006_to_JMh_CIECAM02, XYZ_to_CAM02LCD, - CAM02LCD_to_XYZ, XYZ_to_CAM02SCD, - CAM02SCD_to_XYZ, XYZ_to_CAM02UCS, - CAM02UCS_to_XYZ, ) from colour.utilities import ( as_float_array, @@ -341,9 +341,9 @@ def UCS_Li2017_to_XYZ( """ from colour.appearance import ( + CAM16_to_XYZ, CAM_KWARGS_CIECAM02_sRGB, CAM_Specification_CAM16, - CAM16_to_XYZ, ) domain_range_reference = get_domain_range_scale() == "reference" diff --git a/colour/models/cie_lab.py b/colour/models/cie_lab.py index ca860d5781..fc33addc88 100644 --- a/colour/models/cie_lab.py +++ b/colour/models/cie_lab.py @@ -24,7 +24,7 @@ intermediate_luminance_function_CIE1976, ) from colour.hints import ArrayLike, NDArrayFloat -from colour.models import xy_to_xyY, xyY_to_XYZ, Jab_to_JCh, JCh_to_Jab +from colour.models import Jab_to_JCh, JCh_to_Jab, xy_to_xyY, xyY_to_XYZ from colour.utilities import ( from_range_1, from_range_100, diff --git a/colour/models/cie_luv.py b/colour/models/cie_luv.py index 9af2eb49ee..9ddf5a5acd 100644 --- a/colour/models/cie_luv.py +++ b/colour/models/cie_luv.py @@ -37,10 +37,10 @@ luminance_CIE1976, ) from colour.hints import ArrayLike, NDArrayFloat -from colour.models import xy_to_xyY, xyY_to_XYZ, Jab_to_JCh, JCh_to_Jab +from colour.models import Jab_to_JCh, JCh_to_Jab, xy_to_xyY, xyY_to_XYZ from colour.utilities import ( - domain_range_scale, as_float_scalar, + domain_range_scale, from_range_1, from_range_100, full, diff --git a/colour/models/cie_uvw.py b/colour/models/cie_uvw.py index 9a3e9410a5..f0fc79d89c 100644 --- a/colour/models/cie_uvw.py +++ b/colour/models/cie_uvw.py @@ -23,8 +23,8 @@ UCS_uv_to_xy, XYZ_to_xy, xy_to_UCS_uv, - xyY_to_XYZ, xyY_to_xy, + xyY_to_XYZ, ) from colour.utilities import from_range_100, to_domain_100, tsplit, tstack diff --git a/colour/models/common.py b/colour/models/common.py index e3fed1d1a3..485bf1d84b 100644 --- a/colour/models/common.py +++ b/colour/models/common.py @@ -63,26 +63,33 @@ "CAM16LCD", "CAM16SCD", "CAM16UCS", - "CIE XYZ", - "CIE xyY", "CIE Lab", "CIE Luv", "CIE UCS", "CIE UVW", + "CIE XYZ", + "CIE xyY", "DIN99", + "HCL", + "HSL", + "HSV", "Hunter Lab", "Hunter Rdab", "ICaCb", "ICtCp", - "IPT", + "IHLS", "IPT Ragoo 2021", + "IPT", "IgPgTg", "Jzazbz", "OSA UCS", "Oklab", + "RGB", + "YCbCr", + "YCoCg", + "Yrg", "hdr-CIELAB", "hdr-IPT", - "Yrg", ) if is_documentation_building(): # pragma: no cover COLOURSPACE_MODELS = DocstringTuple(COLOURSPACE_MODELS) @@ -93,32 +100,39 @@ COLOURSPACE_MODELS_AXIS_LABELS: CanonicalMapping = CanonicalMapping( { - "CAM02LCD": ("$J^\\prime$", "$a^\\prime$", "$b^\\prime$"), - "CAM02SCD": ("$J^\\prime$", "$a^\\prime$", "$b^\\prime$"), - "CAM02UCS": ("$J^\\prime$", "$a^\\prime$", "$b^\\prime$"), - "CAM16LCD": ("$J^\\prime$", "$a^\\prime$", "$b^\\prime$"), - "CAM16SCD": ("$J^\\prime$", "$a^\\prime$", "$b^\\prime$"), - "CAM16UCS": ("$J^\\prime$", "$a^\\prime$", "$b^\\prime$"), - "CIE XYZ": ("X", "Y", "Z"), - "CIE xyY": ("x", "y", "Y"), + "CAM02LCD": ("$J^'$", "$a^'$", "$b^'$"), + "CAM02SCD": ("$J^'$", "$a^'$", "$b^'$"), + "CAM02UCS": ("$J^'$", "$a^'$", "$b^'$"), + "CAM16LCD": ("$J^'$", "$a^'$", "$b^'$"), + "CAM16SCD": ("$J^'$", "$a^'$", "$b^'$"), + "CAM16UCS": ("$J^'$", "$a^'$", "$b^'$"), "CIE Lab": ("$L^*$", "$a^*$", "$b^*$"), - "CIE Luv": ("$L^*$", "$u^\\prime$", "$v^\\prime$"), + "CIE Luv": ("$L^*$", "$u^'$", "$v^'$"), "CIE UCS": ("U", "V", "W"), "CIE UVW": ("U", "V", "W"), + "CIE XYZ": ("X", "Y", "Z"), + "CIE xyY": ("x", "y", "Y"), "DIN99": ("$L_{99}$", "$a_{99}$", "$b_{99}$"), + "HCL": ("H", "C", "L"), + "HSL": ("H", "S", "L"), + "HSV": ("H", "S", "V"), "Hunter Lab": ("$L^*$", "$a^*$", "$b^*$"), "Hunter Rdab": ("Rd", "a", "b"), "ICaCb": ("$I$", "$C_a$", "$C_b$"), "ICtCp": ("$I$", "$C_T$", "$C_P$"), - "IPT": ("I", "P", "T"), + "IHLS": ("H", "Y", "S"), "IPT Ragoo 2021": ("I", "P", "T"), + "IPT": ("I", "P", "T"), "IgPgTg": ("$I_G$", "$P_G$", "$T_G$"), "Jzazbz": ("$J_z$", "$a_z$", "$b_z$"), "OSA UCS": ("L", "j", "g"), "Oklab": ("$L$", "$a$", "$b$"), + "RGB": ("R", "G", "B"), + "YCbCr": ("Y", "$C_b$", "$C_r$"), + "YCoCg": ("Y", "$C_o$", "$C_g$"), + "Yrg": ("Y", "r", "g"), "hdr-CIELAB": ("L hdr", "a hdr", "b hdr"), "hdr-IPT": ("I hdr", "P hdr", "T hdr"), - "Yrg": ("Y", "r", "g"), } ) """Colourspace models labels mapping.""" @@ -135,26 +149,33 @@ "CAM16LCD": np.array([100, 100, 100]), "CAM16SCD": np.array([100, 100, 100]), "CAM16UCS": np.array([100, 100, 100]), - "CIE XYZ": np.array([1, 1, 1]), - "CIE xyY": np.array([1, 1, 1]), "CIE Lab": np.array([100, 100, 100]), "CIE Luv": np.array([100, 100, 100]), "CIE UCS": np.array([1, 1, 1]), "CIE UVW": np.array([100, 100, 100]), + "CIE XYZ": np.array([1, 1, 1]), + "CIE xyY": np.array([1, 1, 1]), "DIN99": np.array([100, 100, 100]), + "HCL": np.array([1, 1, 1]), + "HSL": np.array([1, 1, 1]), + "HSV": np.array([1, 1, 1]), "Hunter Lab": np.array([100, 100, 100]), "Hunter Rdab": np.array([100, 100, 100]), "ICaCb": np.array([1, 1, 1]), "ICtCp": np.array([1, 1, 1]), - "IPT": np.array([1, 1, 1]), + "IHLS": np.array([1, 1, 1]), "IPT Ragoo 2021": np.array([1, 1, 1]), + "IPT": np.array([1, 1, 1]), "IgPgTg": np.array([1, 1, 1]), "Jzazbz": np.array([1, 1, 1]), "OSA UCS": np.array([100, 100, 100]), "Oklab": np.array([1, 1, 1]), + "RGB": np.array([1, 1, 1]), + "YCbCr": np.array([1, 1, 1]), + "YCoCg": np.array([1, 1, 1]), + "Yrg": np.array([1, 1, 1]), "hdr-CIELAB": np.array([100, 100, 100]), "hdr-IPT": np.array([100, 100, 100]), - "Yrg": np.array([1, 1, 1]), } ) """Colourspace models domain-range scale **'1'** to **'Reference'** mapping.""" diff --git a/colour/models/din99.py b/colour/models/din99.py index 161dcf0eeb..f65efb2fbd 100644 --- a/colour/models/din99.py +++ b/colour/models/din99.py @@ -32,9 +32,9 @@ from colour.utilities import ( CanonicalMapping, from_range_100, + to_domain_100, tsplit, tstack, - to_domain_100, validate_method, ) diff --git a/colour/models/hdr_ipt.py b/colour/models/hdr_ipt.py index bb09727b1f..982d73234f 100644 --- a/colour/models/hdr_ipt.py +++ b/colour/models/hdr_ipt.py @@ -34,10 +34,10 @@ ) from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.models.ipt import ( - MATRIX_IPT_XYZ_TO_LMS, - MATRIX_IPT_LMS_TO_XYZ, - MATRIX_IPT_LMS_P_TO_IPT, MATRIX_IPT_IPT_TO_LMS_P, + MATRIX_IPT_LMS_P_TO_IPT, + MATRIX_IPT_LMS_TO_XYZ, + MATRIX_IPT_XYZ_TO_LMS, ) from colour.utilities import ( as_float_array, diff --git a/colour/models/icacb.py b/colour/models/icacb.py index f849f2db62..39a24aad8f 100644 --- a/colour/models/icacb.py +++ b/colour/models/icacb.py @@ -20,8 +20,8 @@ from colour.hints import ArrayLike, NDArrayFloat from colour.models import Iab_to_XYZ, XYZ_to_Iab from colour.models.rgb.transfer_functions import ( - eotf_ST2084, eotf_inverse_ST2084, + eotf_ST2084, ) from colour.utilities import domain_range_scale diff --git a/colour/models/igpgtg.py b/colour/models/igpgtg.py index b8228f7645..4aecb0ca5f 100644 --- a/colour/models/igpgtg.py +++ b/colour/models/igpgtg.py @@ -17,9 +17,10 @@ from __future__ import annotations import numpy as np + from colour.algebra import spow -from colour.models import Iab_to_XYZ, XYZ_to_Iab from colour.hints import ArrayLike, NDArrayFloat, cast +from colour.models import Iab_to_XYZ, XYZ_to_Iab __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/models/ipt.py b/colour/models/ipt.py index dab2bf8eb0..9cdaf2653c 100644 --- a/colour/models/ipt.py +++ b/colour/models/ipt.py @@ -19,12 +19,13 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.algebra import spow -from colour.models import Iab_to_XYZ, XYZ_to_Iab from colour.hints import ArrayLike, NDArrayFloat +from colour.models import Iab_to_XYZ, XYZ_to_Iab from colour.utilities import as_float, from_range_degrees, to_domain_1, tsplit __author__ = "Colour Developers" diff --git a/colour/models/oklab.py b/colour/models/oklab.py index 13bfc02f20..085b712272 100644 --- a/colour/models/oklab.py +++ b/colour/models/oklab.py @@ -16,12 +16,13 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.algebra import spow -from colour.models import Iab_to_XYZ, XYZ_to_Iab from colour.hints import ArrayLike, NDArrayFloat +from colour.models import Iab_to_XYZ, XYZ_to_Iab __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/models/ragoo2021.py b/colour/models/ragoo2021.py index b04f61b10f..6439e1e388 100644 --- a/colour/models/ragoo2021.py +++ b/colour/models/ragoo2021.py @@ -18,12 +18,13 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.algebra import spow -from colour.models import Iab_to_XYZ, XYZ_to_Iab from colour.hints import ArrayLike, NDArrayFloat +from colour.models import Iab_to_XYZ, XYZ_to_Iab __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/models/rgb/__init__.py b/colour/models/rgb/__init__.py index 67aac9e851..37ed9d1e41 100644 --- a/colour/models/rgb/__init__.py +++ b/colour/models/rgb/__init__.py @@ -19,6 +19,8 @@ log_decoding_ACEScc, log_encoding_ACEScct, log_decoding_ACEScct, + log_encoding_AppleLogProfile, + log_decoding_AppleLogProfile, oetf_ARIBSTDB67, oetf_inverse_ARIBSTDB67, log_encoding_ARRILogC3, @@ -290,6 +292,8 @@ "log_decoding_ACEScc", "log_encoding_ACEScct", "log_decoding_ACEScct", + "log_encoding_AppleLogProfile", + "log_decoding_AppleLogProfile", "oetf_ARIBSTDB67", "oetf_inverse_ARIBSTDB67", "log_encoding_ARRILogC3", diff --git a/colour/models/rgb/common.py b/colour/models/rgb/common.py index d5276c7595..6ca47d453b 100644 --- a/colour/models/rgb/common.py +++ b/colour/models/rgb/common.py @@ -8,7 +8,11 @@ from __future__ import annotations from colour.colorimetry import CCS_ILLUMINANTS -from colour.hints import ArrayLike, Literal, NDArrayFloat +from colour.hints import ( + ArrayLike, + LiteralChromaticAdaptationTransform, + NDArrayFloat, +) from colour.models.rgb import RGB_COLOURSPACES, RGB_to_XYZ, XYZ_to_RGB __author__ = "Colour Developers" @@ -29,20 +33,7 @@ def XYZ_to_sRGB( illuminant: ArrayLike = CCS_ILLUMINANTS[ "CIE 1931 2 Degree Standard Observer" ]["D65"], - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", apply_cctf_encoding: bool = True, @@ -103,20 +94,7 @@ def sRGB_to_XYZ( illuminant: ArrayLike = CCS_ILLUMINANTS[ "CIE 1931 2 Degree Standard Observer" ]["D65"], - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", apply_cctf_decoding: bool = True, diff --git a/colour/models/rgb/datasets/aces.py b/colour/models/rgb/datasets/aces.py index bdfdd34c21..db52b3487d 100644 --- a/colour/models/rgb/datasets/aces.py +++ b/colour/models/rgb/datasets/aces.py @@ -60,13 +60,13 @@ from colour.models.rgb import ( RGB_Colourspace, linear_function, - normalised_primary_matrix, - log_encoding_ACEScc, log_decoding_ACEScc, - log_encoding_ACEScct, log_decoding_ACEScct, - log_encoding_ACESproxy, log_decoding_ACESproxy, + log_encoding_ACEScc, + log_encoding_ACEScct, + log_encoding_ACESproxy, + normalised_primary_matrix, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/adobe_rgb_1998.py b/colour/models/rgb/datasets/adobe_rgb_1998.py index 9ab8865521..791ecd2944 100644 --- a/colour/models/rgb/datasets/adobe_rgb_1998.py +++ b/colour/models/rgb/datasets/adobe_rgb_1998.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import RGB_Colourspace, gamma_function diff --git a/colour/models/rgb/datasets/adobe_wide_gamut_rgb.py b/colour/models/rgb/datasets/adobe_wide_gamut_rgb.py index 247669e673..56fbd819e0 100644 --- a/colour/models/rgb/datasets/adobe_wide_gamut_rgb.py +++ b/colour/models/rgb/datasets/adobe_wide_gamut_rgb.py @@ -15,9 +15,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/apple_rgb.py b/colour/models/rgb/datasets/apple_rgb.py index b003d69282..7731d8b18b 100644 --- a/colour/models/rgb/datasets/apple_rgb.py +++ b/colour/models/rgb/datasets/apple_rgb.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/arri.py b/colour/models/rgb/datasets/arri.py index 9b22108aea..13ba9400fe 100644 --- a/colour/models/rgb/datasets/arri.py +++ b/colour/models/rgb/datasets/arri.py @@ -25,10 +25,10 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - log_encoding_ARRILogC3, log_decoding_ARRILogC3, - log_encoding_ARRILogC4, log_decoding_ARRILogC4, + log_encoding_ARRILogC3, + log_encoding_ARRILogC4, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/best_rgb.py b/colour/models/rgb/datasets/best_rgb.py index 47d34c4f09..f5628cadb6 100644 --- a/colour/models/rgb/datasets/best_rgb.py +++ b/colour/models/rgb/datasets/best_rgb.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/beta_rgb.py b/colour/models/rgb/datasets/beta_rgb.py index c9b427b2e4..32d0f53f64 100644 --- a/colour/models/rgb/datasets/beta_rgb.py +++ b/colour/models/rgb/datasets/beta_rgb.py @@ -15,9 +15,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/cie_rgb.py b/colour/models/rgb/datasets/cie_rgb.py index 9f4c0d89be..268f28becf 100644 --- a/colour/models/rgb/datasets/cie_rgb.py +++ b/colour/models/rgb/datasets/cie_rgb.py @@ -16,9 +16,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import RGB_Colourspace, gamma_function diff --git a/colour/models/rgb/datasets/color_match_rgb.py b/colour/models/rgb/datasets/color_match_rgb.py index 3ea2e55525..e8a3f0b8f9 100644 --- a/colour/models/rgb/datasets/color_match_rgb.py +++ b/colour/models/rgb/datasets/color_match_rgb.py @@ -15,9 +15,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/dcdm_xyz.py b/colour/models/rgb/datasets/dcdm_xyz.py index b149e3d1a3..c374de80d1 100644 --- a/colour/models/rgb/datasets/dcdm_xyz.py +++ b/colour/models/rgb/datasets/dcdm_xyz.py @@ -23,8 +23,8 @@ from colour.models.rgb import ( RGB_Colourspace, eotf_DCDM, - normalised_primary_matrix, eotf_inverse_DCDM, + normalised_primary_matrix, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/dci_p3.py b/colour/models/rgb/datasets/dci_p3.py index 37e5ae958d..c81c49c6cd 100644 --- a/colour/models/rgb/datasets/dci_p3.py +++ b/colour/models/rgb/datasets/dci_p3.py @@ -26,9 +26,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/dji_d_gamut.py b/colour/models/rgb/datasets/dji_d_gamut.py index 289c52c144..49831695b9 100644 --- a/colour/models/rgb/datasets/dji_d_gamut.py +++ b/colour/models/rgb/datasets/dji_d_gamut.py @@ -22,8 +22,8 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - log_encoding_DJIDLog, log_decoding_DJIDLog, + log_encoding_DJIDLog, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/don_rgb_4.py b/colour/models/rgb/datasets/don_rgb_4.py index fa90175521..cbefeaffac 100644 --- a/colour/models/rgb/datasets/don_rgb_4.py +++ b/colour/models/rgb/datasets/don_rgb_4.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/eci_rgb_v2.py b/colour/models/rgb/datasets/eci_rgb_v2.py index 3d8e1eab32..6303dee61b 100644 --- a/colour/models/rgb/datasets/eci_rgb_v2.py +++ b/colour/models/rgb/datasets/eci_rgb_v2.py @@ -15,9 +15,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import ( CCS_ILLUMINANTS, lightness_CIE1976, diff --git a/colour/models/rgb/datasets/ekta_space_ps5.py b/colour/models/rgb/datasets/ekta_space_ps5.py index d7d13b0e85..a0c3e11de3 100644 --- a/colour/models/rgb/datasets/ekta_space_ps5.py +++ b/colour/models/rgb/datasets/ekta_space_ps5.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/filmlight_e_gamut.py b/colour/models/rgb/datasets/filmlight_e_gamut.py index 656701f698..e316f57da9 100644 --- a/colour/models/rgb/datasets/filmlight_e_gamut.py +++ b/colour/models/rgb/datasets/filmlight_e_gamut.py @@ -20,8 +20,8 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - log_encoding_FilmLightTLog, log_decoding_FilmLightTLog, + log_encoding_FilmLightTLog, normalised_primary_matrix, ) diff --git a/colour/models/rgb/datasets/fujifilm_f_gamut.py b/colour/models/rgb/datasets/fujifilm_f_gamut.py index 47239505a1..631e40813a 100644 --- a/colour/models/rgb/datasets/fujifilm_f_gamut.py +++ b/colour/models/rgb/datasets/fujifilm_f_gamut.py @@ -17,15 +17,15 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - log_encoding_FLog, log_decoding_FLog, + log_encoding_FLog, ) from colour.models.rgb.datasets.itur_bt_2020 import ( - PRIMARIES_BT2020, - WHITEPOINT_NAME_BT2020, CCS_WHITEPOINT_BT2020, MATRIX_BT2020_TO_XYZ, MATRIX_XYZ_TO_BT2020, + PRIMARIES_BT2020, + WHITEPOINT_NAME_BT2020, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/itur_bt_470.py b/colour/models/rgb/datasets/itur_bt_470.py index 750296ef5f..07ace5308a 100644 --- a/colour/models/rgb/datasets/itur_bt_470.py +++ b/colour/models/rgb/datasets/itur_bt_470.py @@ -18,9 +18,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/itur_bt_709.py b/colour/models/rgb/datasets/itur_bt_709.py index 50f6639143..36fbec7f76 100644 --- a/colour/models/rgb/datasets/itur_bt_709.py +++ b/colour/models/rgb/datasets/itur_bt_709.py @@ -24,9 +24,9 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, + normalised_primary_matrix, oetf_BT709, oetf_inverse_BT709, - normalised_primary_matrix, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/max_rgb.py b/colour/models/rgb/datasets/max_rgb.py index 9f9e083de1..bdab619952 100644 --- a/colour/models/rgb/datasets/max_rgb.py +++ b/colour/models/rgb/datasets/max_rgb.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/nikon_n_gamut.py b/colour/models/rgb/datasets/nikon_n_gamut.py index 22701f032d..b5e0645466 100644 --- a/colour/models/rgb/datasets/nikon_n_gamut.py +++ b/colour/models/rgb/datasets/nikon_n_gamut.py @@ -19,15 +19,15 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - log_encoding_NLog, log_decoding_NLog, + log_encoding_NLog, ) from colour.models.rgb.datasets.itur_bt_2020 import ( - PRIMARIES_BT2020, - WHITEPOINT_NAME_BT2020, CCS_WHITEPOINT_BT2020, MATRIX_BT2020_TO_XYZ, MATRIX_XYZ_TO_BT2020, + PRIMARIES_BT2020, + WHITEPOINT_NAME_BT2020, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/ntsc.py b/colour/models/rgb/datasets/ntsc.py index 48362e5b88..4df7eb700e 100644 --- a/colour/models/rgb/datasets/ntsc.py +++ b/colour/models/rgb/datasets/ntsc.py @@ -25,20 +25,20 @@ from colour.hints import NDArrayFloat from colour.models.rgb import RGB_Colourspace from colour.models.rgb.datasets.itur_bt_470 import ( - PRIMARIES_BT470_525, CCS_WHITEPOINT_BT470_525, - WHITEPOINT_NAME_BT470_525, MATRIX_BT470_525_TO_XYZ, MATRIX_XYZ_TO_BT470_525, + PRIMARIES_BT470_525, RGB_COLOURSPACE_BT470_525, + WHITEPOINT_NAME_BT470_525, ) from colour.models.rgb.datasets.smpte_c import ( - PRIMARIES_SMPTE_C, - WHITEPOINT_NAME_SMPTE_C, CCS_WHITEPOINT_SMPTE_C, MATRIX_SMPTE_C_TO_XYZ, MATRIX_XYZ_TO_SMPTE_C, + PRIMARIES_SMPTE_C, RGB_COLOURSPACE_SMPTE_C, + WHITEPOINT_NAME_SMPTE_C, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/p3_d65.py b/colour/models/rgb/datasets/p3_d65.py index 076826896e..78d940ba8d 100644 --- a/colour/models/rgb/datasets/p3_d65.py +++ b/colour/models/rgb/datasets/p3_d65.py @@ -9,9 +9,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/pal_secam.py b/colour/models/rgb/datasets/pal_secam.py index 12aaea1277..1fb6109b44 100644 --- a/colour/models/rgb/datasets/pal_secam.py +++ b/colour/models/rgb/datasets/pal_secam.py @@ -20,12 +20,12 @@ from colour.hints import NDArrayFloat from colour.models.rgb import RGB_Colourspace from colour.models.rgb.datasets.itur_bt_470 import ( - PRIMARIES_BT470_625, CCS_WHITEPOINT_BT470_625, - WHITEPOINT_NAME_BT470_625, MATRIX_BT470_625_TO_XYZ, MATRIX_XYZ_TO_BT470_625, + PRIMARIES_BT470_625, RGB_COLOURSPACE_BT470_625, + WHITEPOINT_NAME_BT470_625, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/panasonic_v_gamut.py b/colour/models/rgb/datasets/panasonic_v_gamut.py index 9d750306a6..642647f1b7 100644 --- a/colour/models/rgb/datasets/panasonic_v_gamut.py +++ b/colour/models/rgb/datasets/panasonic_v_gamut.py @@ -20,8 +20,8 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - log_encoding_VLog, log_decoding_VLog, + log_encoding_VLog, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/red.py b/colour/models/rgb/datasets/red.py index 207d31f840..d765763915 100644 --- a/colour/models/rgb/datasets/red.py +++ b/colour/models/rgb/datasets/red.py @@ -33,11 +33,11 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - normalised_primary_matrix, - log_encoding_REDLogFilm, + log_decoding_Log3G10, log_decoding_REDLogFilm, log_encoding_Log3G10, - log_decoding_Log3G10, + log_encoding_REDLogFilm, + normalised_primary_matrix, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/rimm_romm_rgb.py b/colour/models/rgb/datasets/rimm_romm_rgb.py index e169f7110a..2e2a41c7f4 100644 --- a/colour/models/rgb/datasets/rimm_romm_rgb.py +++ b/colour/models/rgb/datasets/rimm_romm_rgb.py @@ -26,15 +26,14 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - cctf_encoding_ROMMRGB, + cctf_decoding_RIMMRGB, cctf_decoding_ROMMRGB, cctf_encoding_RIMMRGB, - cctf_decoding_RIMMRGB, - log_encoding_ERIMMRGB, + cctf_encoding_ROMMRGB, log_decoding_ERIMMRGB, + log_encoding_ERIMMRGB, ) - __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" __license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" diff --git a/colour/models/rgb/datasets/russell_rgb.py b/colour/models/rgb/datasets/russell_rgb.py index 4461727990..d28647295b 100644 --- a/colour/models/rgb/datasets/russell_rgb.py +++ b/colour/models/rgb/datasets/russell_rgb.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry.datasets import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/smpte_240m.py b/colour/models/rgb/datasets/smpte_240m.py index 879c705380..1e8a8476b8 100644 --- a/colour/models/rgb/datasets/smpte_240m.py +++ b/colour/models/rgb/datasets/smpte_240m.py @@ -23,9 +23,9 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, + eotf_SMPTE240M, normalised_primary_matrix, oetf_SMPTE240M, - eotf_SMPTE240M, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/datasets/smpte_c.py b/colour/models/rgb/datasets/smpte_c.py index a328eaff1e..bcf937e6eb 100644 --- a/colour/models/rgb/datasets/smpte_c.py +++ b/colour/models/rgb/datasets/smpte_c.py @@ -16,9 +16,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/datasets/sony.py b/colour/models/rgb/datasets/sony.py index 853a88d77e..1deb4c4867 100644 --- a/colour/models/rgb/datasets/sony.py +++ b/colour/models/rgb/datasets/sony.py @@ -51,10 +51,10 @@ from colour.hints import NDArrayFloat from colour.models.rgb import ( RGB_Colourspace, - log_encoding_SLog2, log_decoding_SLog2, - log_encoding_SLog3, log_decoding_SLog3, + log_encoding_SLog2, + log_encoding_SLog3, normalised_primary_matrix, ) diff --git a/colour/models/rgb/datasets/tests/test__init__.py b/colour/models/rgb/datasets/tests/test__init__.py index 59d50a826c..cba5304f1d 100644 --- a/colour/models/rgb/datasets/tests/test__init__.py +++ b/colour/models/rgb/datasets/tests/test__init__.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.datasets` module.""" -import numpy as np import pickle import unittest from copy import deepcopy +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( RGB_COLOURSPACES, normalised_primary_matrix, @@ -40,7 +42,7 @@ def test_transformation_matrices(self): tolerances = { "Adobe RGB (1998)": 1e-5, "ARRI Wide Gamut 3": 1e-6, - "DJI D-Gamut": 1e-4, + "DJI D-Gamut": 5e-4, "ERIMM RGB": 1e-3, "ProPhoto RGB": 1e-3, "REDWideGamutRGB": 1e-6, @@ -59,23 +61,19 @@ def test_transformation_matrices(self): np.testing.assert_allclose( colourspace.matrix_RGB_to_XYZ, M, - rtol=tolerance, atol=tolerance, - verbose=False, ) RGB = np.dot(colourspace.matrix_XYZ_to_RGB, XYZ_r) XYZ = np.dot(colourspace.matrix_RGB_to_XYZ, RGB) - np.testing.assert_allclose( - XYZ_r, XYZ, rtol=tolerance, atol=tolerance, verbose=False - ) + np.testing.assert_allclose(XYZ_r, XYZ, atol=tolerance) # Derived transformation matrices. colourspace = deepcopy(colourspace) # noqa: PLW2901 colourspace.use_derived_transformation_matrices(True) RGB = np.dot(colourspace.matrix_XYZ_to_RGB, XYZ_r) XYZ = np.dot(colourspace.matrix_RGB_to_XYZ, RGB) - np.testing.assert_array_almost_equal(XYZ_r, XYZ, decimal=7) + np.testing.assert_allclose(XYZ_r, XYZ, atol=tolerance) def test_cctf(self): """ @@ -86,7 +84,7 @@ def test_cctf(self): ignored_colourspaces = ("ACESproxy",) - decimals = {"DJI D-Gamut": 1, "F-Gamut": 4, "N-Gamut": 3} + tolerance = {"DJI D-Gamut": 0.1, "F-Gamut": 1e-4, "N-Gamut": 1e-3} samples = np.hstack( [np.linspace(0, 1, int(1e5)), np.linspace(0, 65504, 65504 * 10)] @@ -99,10 +97,10 @@ def test_cctf(self): cctf_encoding_s = colourspace.cctf_encoding(samples) cctf_decoding_s = colourspace.cctf_decoding(cctf_encoding_s) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( samples, cctf_decoding_s, - decimal=decimals.get(colourspace.name, 7), + atol=tolerance.get(colourspace.name, TOLERANCE_ABSOLUTE_TESTS), ) def test_n_dimensional_cctf(self): @@ -112,41 +110,41 @@ def test_n_dimensional_cctf(self): colourspace models n-dimensional arrays support. """ - decimals = {"DJI D-Gamut": 6, "F-Gamut": 4} + tolerance = {"DJI D-Gamut": 1e-6, "F-Gamut": 1e-4} for colourspace in RGB_COLOURSPACES.values(): value_cctf_encoding = 0.5 value_cctf_decoding = colourspace.cctf_decoding( colourspace.cctf_encoding(value_cctf_encoding) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( value_cctf_encoding, value_cctf_decoding, - decimal=decimals.get(colourspace.name, 7), + atol=tolerance.get(colourspace.name, 1e-7), ) value_cctf_encoding = np.tile(value_cctf_encoding, 6) value_cctf_decoding = np.tile(value_cctf_decoding, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( value_cctf_encoding, value_cctf_decoding, - decimal=decimals.get(colourspace.name, 7), + atol=tolerance.get(colourspace.name, 1e-7), ) value_cctf_encoding = np.reshape(value_cctf_encoding, (3, 2)) value_cctf_decoding = np.reshape(value_cctf_decoding, (3, 2)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( value_cctf_encoding, value_cctf_decoding, - decimal=decimals.get(colourspace.name, 7), + atol=tolerance.get(colourspace.name, 1e-7), ) value_cctf_encoding = np.reshape(value_cctf_encoding, (3, 2, 1)) value_cctf_decoding = np.reshape(value_cctf_decoding, (3, 2, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( value_cctf_encoding, value_cctf_decoding, - decimal=decimals.get(colourspace.name, 7), + atol=tolerance.get(colourspace.name, 1e-7), ) @ignore_numpy_errors diff --git a/colour/models/rgb/datasets/xtreme_rgb.py b/colour/models/rgb/datasets/xtreme_rgb.py index b7b21ff374..d843d11482 100644 --- a/colour/models/rgb/datasets/xtreme_rgb.py +++ b/colour/models/rgb/datasets/xtreme_rgb.py @@ -14,9 +14,10 @@ from __future__ import annotations -import numpy as np from functools import partial +import numpy as np + from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import NDArrayFloat from colour.models.rgb import ( diff --git a/colour/models/rgb/derivation.py b/colour/models/rgb/derivation.py index 82c4133e02..88760d5849 100644 --- a/colour/models/rgb/derivation.py +++ b/colour/models/rgb/derivation.py @@ -28,7 +28,12 @@ import numpy as np from colour.adaptation import chromatic_adaptation_VonKries -from colour.hints import ArrayLike, Literal, NDArrayFloat, Tuple +from colour.hints import ( + ArrayLike, + LiteralChromaticAdaptationTransform, + NDArrayFloat, + Tuple, +) from colour.models import XYZ_to_xy, XYZ_to_xyY, xy_to_XYZ from colour.utilities import as_float, as_float_array, ones, tsplit @@ -129,20 +134,7 @@ def chromatically_adapted_primaries( primaries: ArrayLike, whitepoint_t: ArrayLike, whitepoint_r: ArrayLike, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str = "CAT02", ) -> NDArrayFloat: """ diff --git a/colour/models/rgb/hanbury2003.py b/colour/models/rgb/hanbury2003.py index c12fec15d6..91a3d92135 100644 --- a/colour/models/rgb/hanbury2003.py +++ b/colour/models/rgb/hanbury2003.py @@ -24,8 +24,8 @@ from colour.utilities import ( from_range_1, to_domain_1, - tstack, tsplit, + tstack, zeros, ) diff --git a/colour/models/rgb/ictcp.py b/colour/models/rgb/ictcp.py index 2eb65f2b87..4fd39de2c7 100644 --- a/colour/models/rgb/ictcp.py +++ b/colour/models/rgb/ictcp.py @@ -31,11 +31,16 @@ from colour.algebra import vector_dot from colour.colorimetry import CCS_ILLUMINANTS -from colour.hints import ArrayLike, Literal, NDArrayFloat +from colour.hints import ( + ArrayLike, + Literal, + LiteralChromaticAdaptationTransform, + NDArrayFloat, +) from colour.models.rgb import RGB_COLOURSPACES, RGB_to_XYZ, XYZ_to_RGB from colour.models.rgb.transfer_functions import ( - eotf_ST2084, eotf_inverse_ST2084, + eotf_ST2084, oetf_BT2100_HLG, oetf_inverse_BT2100_HLG, ) @@ -400,20 +405,7 @@ def ICtCp_to_RGB( def XYZ_to_ICtCp( XYZ: ArrayLike, illuminant=CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"], - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", method: Literal[ @@ -532,20 +524,7 @@ def XYZ_to_ICtCp( def ICtCp_to_XYZ( ICtCp: ArrayLike, illuminant=CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"], - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", method: Literal[ diff --git a/colour/models/rgb/itut_h_273.py b/colour/models/rgb/itut_h_273.py index 81b018381c..2323783c13 100644 --- a/colour/models/rgb/itut_h_273.py +++ b/colour/models/rgb/itut_h_273.py @@ -55,92 +55,93 @@ """ import functools -import numpy as np from dataclasses import dataclass from enum import IntEnum, auto +import numpy as np + +from colour.hints import Any, Callable, Dict, NDArrayFloat, Union from colour.models.rgb.datasets.dcdm_xyz import ( - PRIMARIES_DCDM_XYZ, - WHITEPOINT_NAME_DCDM_XYZ, CCS_WHITEPOINT_DCDM_XYZ, MATRIX_DCDM_XYZ_TO_XYZ, MATRIX_XYZ_TO_DCDM_XYZ, + PRIMARIES_DCDM_XYZ, + WHITEPOINT_NAME_DCDM_XYZ, ) from colour.models.rgb.datasets.dci_p3 import ( - PRIMARIES_DCI_P3, - WHITEPOINT_NAME_DCI_P3, CCS_WHITEPOINT_DCI_P3, MATRIX_DCI_P3_TO_XYZ, MATRIX_XYZ_TO_DCI_P3, -) -from colour.models.rgb.datasets.itur_bt_2020 import ( - PRIMARIES_BT2020, - WHITEPOINT_NAME_BT2020, - CCS_WHITEPOINT_BT2020, - MATRIX_BT2020_TO_XYZ, - MATRIX_XYZ_TO_BT2020, + PRIMARIES_DCI_P3, + WHITEPOINT_NAME_DCI_P3, ) from colour.models.rgb.datasets.itur_bt_470 import ( - PRIMARIES_BT470_525, CCS_WHITEPOINT_BT470_525, - WHITEPOINT_NAME_BT470_525, + CCS_WHITEPOINT_BT470_625, MATRIX_BT470_525_TO_XYZ, + MATRIX_BT470_625_TO_XYZ, MATRIX_XYZ_TO_BT470_525, + MATRIX_XYZ_TO_BT470_625, + PRIMARIES_BT470_525, PRIMARIES_BT470_625, - CCS_WHITEPOINT_BT470_625, + WHITEPOINT_NAME_BT470_525, WHITEPOINT_NAME_BT470_625, - MATRIX_BT470_625_TO_XYZ, - MATRIX_XYZ_TO_BT470_625, ) from colour.models.rgb.datasets.itur_bt_709 import ( - PRIMARIES_BT709, CCS_WHITEPOINT_BT709, - WHITEPOINT_NAME_BT709, MATRIX_BT709_TO_XYZ, MATRIX_XYZ_TO_BT709, + PRIMARIES_BT709, + WHITEPOINT_NAME_BT709, +) +from colour.models.rgb.datasets.itur_bt_2020 import ( + CCS_WHITEPOINT_BT2020, + MATRIX_BT2020_TO_XYZ, + MATRIX_XYZ_TO_BT2020, + PRIMARIES_BT2020, + WHITEPOINT_NAME_BT2020, ) from colour.models.rgb.datasets.itut_h_273 import ( - PRIMARIES_H273_GENERIC_FILM, - WHITEPOINT_NAME_H273_GENERIC_FILM, + CCS_WHITEPOINT_H273_22_UNSPECIFIED, CCS_WHITEPOINT_H273_GENERIC_FILM, + MATRIX_H273_22_UNSPECIFIED_RGB_TO_XYZ, MATRIX_H273_GENERIC_FILM_RGB_TO_XYZ, + MATRIX_XYZ_TO_H273_22_UNSPECIFIED_RGB, MATRIX_XYZ_TO_H273_GENERIC_FILM_RGB, PRIMARIES_H273_22_UNSPECIFIED, + PRIMARIES_H273_GENERIC_FILM, WHITEPOINT_NAME_H273_22_UNSPECIFIED, - CCS_WHITEPOINT_H273_22_UNSPECIFIED, - MATRIX_H273_22_UNSPECIFIED_RGB_TO_XYZ, - MATRIX_XYZ_TO_H273_22_UNSPECIFIED_RGB, + WHITEPOINT_NAME_H273_GENERIC_FILM, ) from colour.models.rgb.datasets.p3_d65 import ( - PRIMARIES_P3_D65, - WHITEPOINT_NAME_P3_D65, CCS_WHITEPOINT_P3_D65, MATRIX_P3_D65_TO_XYZ, MATRIX_XYZ_TO_P3_D65, + PRIMARIES_P3_D65, + WHITEPOINT_NAME_P3_D65, ) from colour.models.rgb.datasets.smpte_240m import ( - PRIMARIES_SMPTE_240M, - WHITEPOINT_NAME_SMPTE_240M, CCS_WHITEPOINT_SMPTE_240M, MATRIX_SMPTE_240M_TO_XYZ, MATRIX_XYZ_TO_SMPTE_240M, + PRIMARIES_SMPTE_240M, + WHITEPOINT_NAME_SMPTE_240M, ) from colour.models.rgb.transfer_functions import ( eotf_inverse_H273_ST428_1, eotf_inverse_ST2084, gamma_function, linear_function, + oetf_BT601, + oetf_BT709, oetf_BT1361, oetf_BT2020, oetf_BT2100_HLG, - oetf_BT601, - oetf_BT709, oetf_H273_IEC61966_2, oetf_H273_Log, oetf_H273_LogSqrt, oetf_SMPTE240M, ) -from colour.hints import Any, Callable, Dict, NDArrayFloat, Union from colour.utilities import message_box, multiline_str from colour.utilities.documentation import ( DocstringDict, diff --git a/colour/models/rgb/rgb_colourspace.py b/colour/models/rgb/rgb_colourspace.py index bf6ab3a633..d3ae2d936e 100644 --- a/colour/models/rgb/rgb_colourspace.py +++ b/colour/models/rgb/rgb_colourspace.py @@ -25,20 +25,22 @@ from __future__ import annotations -import numpy as np from copy import deepcopy +import numpy as np + from colour.adaptation import matrix_chromatic_adaptation_VonKries from colour.algebra import matrix_dot, vector_dot from colour.hints import ( Any, ArrayLike, Callable, - Literal, + LiteralChromaticAdaptationTransform, + LiteralRGBColourspace, NDArrayFloat, cast, ) -from colour.models import xy_to_XYZ, xy_to_xyY, xyY_to_XYZ +from colour.models import xy_to_xyY, xy_to_XYZ, xyY_to_XYZ from colour.models.rgb import ( chromatically_adapted_primaries, normalised_primary_matrix, @@ -49,11 +51,11 @@ domain_range_scale, filter_kwargs, from_range_1, - multiline_str, + is_string, multiline_repr, + multiline_str, optional, to_domain_1, - is_string, usage_warning, validate_method, ) @@ -843,20 +845,7 @@ def chromatically_adapt( self, whitepoint: ArrayLike, whitepoint_name: str | None = None, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str = "CAT02", ) -> RGB_Colourspace: """ @@ -949,22 +938,9 @@ def copy(self) -> RGB_Colourspace: def XYZ_to_RGB( XYZ: ArrayLike, - colourspace: RGB_Colourspace | str, + colourspace: RGB_Colourspace | LiteralRGBColourspace | str, illuminant: ArrayLike | None = None, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", apply_cctf_encoding: bool = False, @@ -1097,22 +1073,9 @@ def XYZ_to_RGB( def RGB_to_XYZ( RGB: ArrayLike, - colourspace: RGB_Colourspace | str, + colourspace: RGB_Colourspace | LiteralRGBColourspace | str, illuminant: ArrayLike | None = None, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", apply_cctf_decoding: bool = False, @@ -1244,22 +1207,9 @@ def RGB_to_XYZ( def matrix_RGB_to_RGB( - input_colourspace: RGB_Colourspace | str, - output_colourspace: RGB_Colourspace | str, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + input_colourspace: RGB_Colourspace | LiteralRGBColourspace | str, + output_colourspace: RGB_Colourspace | LiteralRGBColourspace | str, + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", ) -> NDArrayFloat: @@ -1341,22 +1291,9 @@ def matrix_RGB_to_RGB( def RGB_to_RGB( RGB: ArrayLike, - input_colourspace: RGB_Colourspace | str, - output_colourspace: RGB_Colourspace | str, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + input_colourspace: RGB_Colourspace | LiteralRGBColourspace | str, + output_colourspace: RGB_Colourspace | LiteralRGBColourspace | str, + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", apply_cctf_decoding: bool = False, diff --git a/colour/models/rgb/tests/test_cmyk.py b/colour/models/rgb/tests/test_cmyk.py index bb51bfa8bf..61ccdb3d6c 100644 --- a/colour/models/rgb/tests/test_cmyk.py +++ b/colour/models/rgb/tests/test_cmyk.py @@ -1,15 +1,17 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.cmyk` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.cmyk import ( - RGB_to_CMY, - CMY_to_RGB, CMY_to_CMYK, + CMY_to_RGB, CMYK_to_CMY, + RGB_to_CMY, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,22 +39,22 @@ class TestRGB_to_CMY(unittest.TestCase): def test_RGB_to_CMY(self): """Test :func:`colour.models.rgb.cmyk.RGB_to_CMY` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_CMY(np.array([0.45620519, 0.03081071, 0.04091952])), np.array([0.54379481, 0.96918929, 0.95908048]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_CMY(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([1.00000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_CMY(np.array([1.00000000, 1.00000000, 1.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_CMY(self): @@ -66,11 +68,15 @@ def test_n_dimensional_RGB_to_CMY(self): RGB = np.tile(RGB, (6, 1)) CMY = np.tile(CMY, (6, 1)) - np.testing.assert_array_almost_equal(RGB_to_CMY(RGB), CMY, decimal=7) + np.testing.assert_allclose( + RGB_to_CMY(RGB), CMY, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.reshape(RGB, (2, 3, 3)) CMY = np.reshape(CMY, (2, 3, 3)) - np.testing.assert_array_almost_equal(RGB_to_CMY(RGB), CMY, decimal=7) + np.testing.assert_allclose( + RGB_to_CMY(RGB), CMY, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_RGB_to_CMY(self): """ @@ -84,8 +90,10 @@ def test_domain_range_scale_RGB_to_CMY(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_CMY(RGB * factor), CMY * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_CMY(RGB * factor), + CMY * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -109,22 +117,22 @@ class TestCMY_to_RGB(unittest.TestCase): def test_CMY_to_RGB(self): """Test :func:`colour.models.rgb.cmyk.CMY_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMY_to_RGB(np.array([0.54379481, 0.96918929, 0.95908048])), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMY_to_RGB(np.array([1.00000000, 1.00000000, 1.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMY_to_RGB(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([1.00000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CMY_to_RGB(self): @@ -138,11 +146,15 @@ def test_n_dimensional_CMY_to_RGB(self): CMY = np.tile(CMY, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal(CMY_to_RGB(CMY), RGB, decimal=7) + np.testing.assert_allclose( + CMY_to_RGB(CMY), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) CMY = np.reshape(CMY, (2, 3, 3)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal(CMY_to_RGB(CMY), RGB, decimal=7) + np.testing.assert_allclose( + CMY_to_RGB(CMY), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_CMY_to_RGB(self): """ @@ -156,8 +168,10 @@ def test_domain_range_scale_CMY_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - CMY_to_RGB(CMY * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + CMY_to_RGB(CMY * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -178,22 +192,22 @@ class TestCMY_to_CMYK(unittest.TestCase): def test_CMY_to_CMYK(self): """Test :func:`colour.models.rgb.cmyk.CMY_to_CMYK` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMY_to_CMYK(np.array([0.54379481, 0.96918929, 0.95908048])), np.array([0.00000000, 0.93246304, 0.91030457, 0.54379481]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMY_to_CMYK(np.array([0.15000000, 1.00000000, 1.00000000])), np.array([0.00000000, 1.00000000, 1.00000000, 0.15000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMY_to_CMYK(np.array([0.15000000, 0.00000000, 0.00000000])), np.array([0.15000000, 0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CMY_to_CMYK(self): @@ -207,11 +221,15 @@ def test_n_dimensional_CMY_to_CMYK(self): CMY = np.tile(CMY, (6, 1)) CMYK = np.tile(CMYK, (6, 1)) - np.testing.assert_array_almost_equal(CMY_to_CMYK(CMY), CMYK, decimal=7) + np.testing.assert_allclose( + CMY_to_CMYK(CMY), CMYK, atol=TOLERANCE_ABSOLUTE_TESTS + ) CMY = np.reshape(CMY, (2, 3, 3)) CMYK = np.reshape(CMYK, (2, 3, 4)) - np.testing.assert_array_almost_equal(CMY_to_CMYK(CMY), CMYK, decimal=7) + np.testing.assert_allclose( + CMY_to_CMYK(CMY), CMYK, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_CMY_to_CMYK(self): """ @@ -225,8 +243,10 @@ def test_domain_range_scale_CMY_to_CMYK(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - CMY_to_CMYK(CMY * factor), CMYK * factor, decimal=7 + np.testing.assert_allclose( + CMY_to_CMYK(CMY * factor), + CMYK * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -250,28 +270,28 @@ class TestCMYK_to_CMY(unittest.TestCase): def test_CMYK_to_CMY(self): """Test :func:`colour.models.rgb.cmyk.CMYK_to_CMY` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMYK_to_CMY( np.array([0.00000000, 0.93246304, 0.91030457, 0.54379481]) ), np.array([0.54379481, 0.96918929, 0.95908048]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMYK_to_CMY( np.array([0.00000000, 1.00000000, 1.00000000, 0.15000000]) ), np.array([0.15000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CMYK_to_CMY( np.array([0.15000000, 0.00000000, 0.00000000, 0.00000000]) ), np.array([0.15000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CMYK_to_CMY(self): @@ -285,11 +305,15 @@ def test_n_dimensional_CMYK_to_CMY(self): CMYK = np.tile(CMYK, (6, 1)) CMY = np.tile(CMY, (6, 1)) - np.testing.assert_array_almost_equal(CMYK_to_CMY(CMYK), CMY, decimal=7) + np.testing.assert_allclose( + CMYK_to_CMY(CMYK), CMY, atol=TOLERANCE_ABSOLUTE_TESTS + ) CMYK = np.reshape(CMYK, (2, 3, 4)) CMY = np.reshape(CMY, (2, 3, 3)) - np.testing.assert_array_almost_equal(CMYK_to_CMY(CMYK), CMY, decimal=7) + np.testing.assert_allclose( + CMYK_to_CMY(CMYK), CMY, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_CMYK_to_CMY(self): """ @@ -303,8 +327,10 @@ def test_domain_range_scale_CMYK_to_CMY(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - CMYK_to_CMY(CMYK * factor), CMY * factor, decimal=7 + np.testing.assert_allclose( + CMYK_to_CMY(CMYK * factor), + CMY * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/tests/test_common.py b/colour/models/rgb/tests/test_common.py index 802667596f..32502c04d6 100644 --- a/colour/models/rgb/tests/test_common.py +++ b/colour/models/rgb/tests/test_common.py @@ -1,9 +1,11 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.common` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import XYZ_to_sRGB, sRGB_to_XYZ __author__ = "Colour Developers" @@ -28,53 +30,53 @@ class TestXYZ_to_sRGB(unittest.TestCase): def test_XYZ_to_sRGB(self): """Test :func:`colour.models.rgb.common.XYZ_to_sRGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_sRGB(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.70573936, 0.19248266, 0.22354169]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_sRGB(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.25847003, 0.58276102, 0.29718877]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_sRGB( np.array([0.07818780, 0.06157201, 0.28099326]), np.array([0.34570, 0.35850]), ), np.array([0.09838967, 0.25404426, 0.65130925]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_sRGB( np.array([0.00000000, 0.00000000, 0.00000000]), np.array([0.44757, 0.40745]), ), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_sRGB( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.44757, 0.40745]), chromatic_adaptation_transform="Bradford", ), np.array([0.60873814, 0.23259548, 0.43714892]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_sRGB( np.array([0.20654008, 0.12197225, 0.05136952]), apply_cctf_encoding=False, ), np.array([0.45620520, 0.03081070, 0.04091953]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -87,53 +89,53 @@ class TestsRGB_to_XYZ(unittest.TestCase): def test_sRGB_to_XYZ(self): """Test :func:`colour.models.rgb.common.sRGB_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sRGB_to_XYZ(np.array([0.70573936, 0.19248266, 0.22354169])), np.array([0.20654290, 0.12197943, 0.05137140]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sRGB_to_XYZ(np.array([0.25847003, 0.58276102, 0.29718877])), np.array([0.14222582, 0.23043727, 0.10496290]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sRGB_to_XYZ( np.array([0.09838967, 0.25404426, 0.65130925]), np.array([0.34570, 0.35850]), ), np.array([0.07819162, 0.06157356, 0.28099475]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sRGB_to_XYZ( np.array([0.00000000, 0.00000000, 0.00000000]), np.array([0.44757, 0.40745]), ), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sRGB_to_XYZ( np.array([0.60873814, 0.23259548, 0.43714892]), np.array([0.44757, 0.40745]), chromatic_adaptation_transform="Bradford", ), np.array([0.20654449, 0.12197792, 0.05137030]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sRGB_to_XYZ( np.array([0.45620520, 0.03081070, 0.04091953]), apply_cctf_decoding=False, ), np.array([0.20654291, 0.12197943, 0.05137141]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/models/rgb/tests/test_cylindrical.py b/colour/models/rgb/tests/test_cylindrical.py index 66f5d8bdb3..7866c50381 100644 --- a/colour/models/rgb/tests/test_cylindrical.py +++ b/colour/models/rgb/tests/test_cylindrical.py @@ -1,17 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.cylindrical` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.cylindrical import ( - RGB_to_HSV, - HSV_to_RGB, - RGB_to_HSL, + HCL_to_RGB, HSL_to_RGB, + HSV_to_RGB, RGB_to_HCL, - HCL_to_RGB, + RGB_to_HSL, + RGB_to_HSV, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -41,28 +43,28 @@ class TestRGB_to_HSV(unittest.TestCase): def test_RGB_to_HSV(self): """Test :func:`colour.models.rgb.cylindrical.RGB_to_HSV` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSV(np.array([0.45620519, 0.03081071, 0.04091952])), np.array([0.99603944, 0.93246304, 0.45620519]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSV(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSV(np.array([1.00000000, 1.00000000, 1.00000000])), np.array([0.00000000, 0.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSV(np.array([0.00000000, 1.00000000, 1.00000000])), np.array([0.50000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_HSV(self): @@ -76,11 +78,15 @@ def test_n_dimensional_RGB_to_HSV(self): RGB = np.tile(RGB, (6, 1)) HSV = np.tile(HSV, (6, 1)) - np.testing.assert_array_almost_equal(RGB_to_HSV(RGB), HSV, decimal=7) + np.testing.assert_allclose( + RGB_to_HSV(RGB), HSV, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.reshape(RGB, (2, 3, 3)) HSV = np.reshape(HSV, (2, 3, 3)) - np.testing.assert_array_almost_equal(RGB_to_HSV(RGB), HSV, decimal=7) + np.testing.assert_allclose( + RGB_to_HSV(RGB), HSV, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_RGB_to_HSV(self): """ @@ -94,8 +100,10 @@ def test_domain_range_scale_RGB_to_HSV(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_HSV(RGB * factor), HSV * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_HSV(RGB * factor), + HSV * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -119,28 +127,28 @@ class TestHSV_to_RGB(unittest.TestCase): def test_HSV_to_RGB(self): """Test :func:`colour.models.rgb.cylindrical.HSV_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSV_to_RGB(np.array([0.99603944, 0.93246304, 0.45620519])), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSV_to_RGB(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSV_to_RGB(np.array([0.00000000, 0.00000000, 1.00000000])), np.array([1.00000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSV_to_RGB(np.array([0.50000000, 1.00000000, 1.00000000])), np.array([0.00000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_HSV_to_RGB(self): @@ -154,11 +162,15 @@ def test_n_dimensional_HSV_to_RGB(self): HSV = np.tile(HSV, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal(HSV_to_RGB(HSV), RGB, decimal=7) + np.testing.assert_allclose( + HSV_to_RGB(HSV), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) HSV = np.reshape(HSV, (2, 3, 3)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal(HSV_to_RGB(HSV), RGB, decimal=7) + np.testing.assert_allclose( + HSV_to_RGB(HSV), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_HSV_to_RGB(self): """ @@ -172,8 +184,10 @@ def test_domain_range_scale_HSV_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - HSV_to_RGB(HSV * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + HSV_to_RGB(HSV * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -197,28 +211,28 @@ class TestRGB_to_HSL(unittest.TestCase): def test_RGB_to_HSL(self): """Test :func:`colour.models.rgb.cylindrical.RGB_to_HSL` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSL(np.array([0.45620519, 0.03081071, 0.04091952])), np.array([0.99603944, 0.87347144, 0.24350795]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSL(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSL(np.array([1.00000000, 1.00000000, 1.00000000])), np.array([0.00000000, 0.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HSL(np.array([1.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 1.00000000, 0.50000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_HSL(self): @@ -232,11 +246,15 @@ def test_n_dimensional_RGB_to_HSL(self): RGB = np.tile(RGB, (6, 1)) HSL = np.tile(HSL, (6, 1)) - np.testing.assert_array_almost_equal(RGB_to_HSL(RGB), HSL, decimal=7) + np.testing.assert_allclose( + RGB_to_HSL(RGB), HSL, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.reshape(RGB, (2, 3, 3)) HSL = np.reshape(HSL, (2, 3, 3)) - np.testing.assert_array_almost_equal(RGB_to_HSL(RGB), HSL, decimal=7) + np.testing.assert_allclose( + RGB_to_HSL(RGB), HSL, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_RGB_to_HSL(self): """ @@ -250,8 +268,10 @@ def test_domain_range_scale_RGB_to_HSL(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_HSL(RGB * factor), HSL * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_HSL(RGB * factor), + HSL * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -275,28 +295,28 @@ class TestHSL_to_RGB(unittest.TestCase): def test_HSL_to_RGB(self): """Test :func:`colour.models.rgb.cylindrical.HSL_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSL_to_RGB(np.array([0.99603944, 0.87347144, 0.24350795])), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSL_to_RGB(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSL_to_RGB(np.array([0.00000000, 0.00000000, 1.00000000])), np.array([1.00000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HSL_to_RGB(np.array([0.00000000, 1.00000000, 0.50000000])), np.array([1.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_HSL_to_RGB(self): @@ -310,11 +330,15 @@ def test_n_dimensional_HSL_to_RGB(self): HSL = np.tile(HSL, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal(HSL_to_RGB(HSL), RGB, decimal=7) + np.testing.assert_allclose( + HSL_to_RGB(HSL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) HSL = np.reshape(HSL, (2, 3, 3)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal(HSL_to_RGB(HSL), RGB, decimal=7) + np.testing.assert_allclose( + HSL_to_RGB(HSL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_HSL_to_RGB(self): """ @@ -328,8 +352,10 @@ def test_domain_range_scale_HSL_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - HSL_to_RGB(HSL * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + HSL_to_RGB(HSL * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -353,28 +379,28 @@ class TestRGB_to_HCL(unittest.TestCase): def test_RGB_to_HCL(self): """Test :func:`colour.models.rgb.cylindrical.RGB_to_HCL` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HCL(np.array([0.45620519, 0.03081071, 0.04091952])), np.array([-0.03167854, 0.2841715, 0.22859647]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HCL(np.array([1.00000000, 2.00000000, 0.50000000])), np.array([1.83120102, 1.0075282, 1.00941024]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HCL(np.array([2.00000000, 1.00000000, 0.50000000])), np.array([0.30909841, 1.0075282, 1.00941024]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_HCL(np.array([0.50000000, 1.00000000, 2.00000000])), np.array([-2.40349351, 1.0075282, 1.00941024]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_HCL(self): @@ -388,11 +414,15 @@ def test_n_dimensional_RGB_to_HCL(self): RGB = np.tile(RGB, (6, 1)) HCL = np.tile(HCL, (6, 1)) - np.testing.assert_array_almost_equal(RGB_to_HCL(RGB), HCL, decimal=7) + np.testing.assert_allclose( + RGB_to_HCL(RGB), HCL, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.reshape(RGB, (2, 3, 3)) HCL = np.reshape(HCL, (2, 3, 3)) - np.testing.assert_array_almost_equal(RGB_to_HCL(RGB), HCL, decimal=7) + np.testing.assert_allclose( + RGB_to_HCL(RGB), HCL, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_RGB_to_HCL(self): """ @@ -406,8 +436,10 @@ def test_domain_range_scale_RGB_to_HCL(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_HCL(RGB * factor), HCL * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_HCL(RGB * factor), + HCL * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -431,28 +463,28 @@ class TestHCL_to_RGB(unittest.TestCase): def test_HCL_to_RGB(self): """Test :func:`colour.models.rgb.cylindrical.HCL_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HCL_to_RGB(np.array([-0.03167854, 0.28417150, 0.22859647])), np.array([0.45620333, 0.03081048, 0.04091925]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HCL_to_RGB(np.array([1.00000000, 2.00000000, 0.50000000])), np.array([0.92186029, 0.71091922, -2.26364935]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HCL_to_RGB(np.array([2.00000000, 1.00000000, 0.50000000])), np.array([-0.31368585, 1.00732462, -0.51534497]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HCL_to_RGB(np.array([0.50000000, 1.00000000, 2.00000000])), np.array([3.88095422, 3.11881934, 2.40881719]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_HCL_to_RGB(self): @@ -466,11 +498,15 @@ def test_n_dimensional_HCL_to_RGB(self): HCL = np.tile(HCL, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal(HCL_to_RGB(HCL), RGB, decimal=7) + np.testing.assert_allclose( + HCL_to_RGB(HCL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) HCL = np.reshape(HCL, (2, 3, 3)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal(HCL_to_RGB(HCL), RGB, decimal=7) + np.testing.assert_allclose( + HCL_to_RGB(HCL), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_HCL_to_RGB(self): """ @@ -484,8 +520,10 @@ def test_domain_range_scale_HCL_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - HCL_to_RGB(HCL * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + HCL_to_RGB(HCL * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/tests/test_derivation.py b/colour/models/rgb/tests/test_derivation.py index 9cc6ac7668..5183445ada 100644 --- a/colour/models/rgb/tests/test_derivation.py +++ b/colour/models/rgb/tests/test_derivation.py @@ -2,18 +2,20 @@ """Define the unit tests for the :mod:`colour.models.rgb.derivation` module.""" import contextlib -import numpy as np import re import unittest from itertools import product + +import numpy as np from numpy.linalg import LinAlgError +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - normalised_primary_matrix, + RGB_luminance, + RGB_luminance_equation, chromatically_adapted_primaries, + normalised_primary_matrix, primaries_whitepoint, - RGB_luminance_equation, - RGB_luminance, ) from colour.models.rgb.derivation import xy_to_z from colour.utilities import ignore_numpy_errors @@ -44,16 +46,22 @@ class Testxy_to_z(unittest.TestCase): def test_xy_to_z(self): """Test :func:`colour.models.rgb.derivation.xy_to_z` definition.""" - np.testing.assert_array_almost_equal( - xy_to_z(np.array([0.2500, 0.2500])), 0.50000000, decimal=7 + np.testing.assert_allclose( + xy_to_z(np.array([0.2500, 0.2500])), + 0.50000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - xy_to_z(np.array([0.0001, -0.0770])), 1.07690000, decimal=7 + np.testing.assert_allclose( + xy_to_z(np.array([0.0001, -0.0770])), + 1.07690000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - xy_to_z(np.array([0.0000, 1.0000])), 0.00000000, decimal=7 + np.testing.assert_allclose( + xy_to_z(np.array([0.0000, 1.0000])), + 0.00000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_z(self): @@ -70,11 +78,15 @@ def test_n_dimensional_xy_to_z(self): z, 6, ) - np.testing.assert_array_almost_equal(xy_to_z(xy), z, decimal=7) + np.testing.assert_allclose( + xy_to_z(xy), z, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) z = np.reshape(z, (2, 3)) - np.testing.assert_array_almost_equal(xy_to_z(xy), z, decimal=7) + np.testing.assert_allclose( + xy_to_z(xy), z, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_xy_to_z(self): @@ -100,7 +112,7 @@ def test_normalised_primary_matrix(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalised_primary_matrix( np.array( [0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700] @@ -114,10 +126,10 @@ def test_normalised_primary_matrix(self): [0.00000000, 0.00000000, 1.00882518], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalised_primary_matrix( np.array([0.640, 0.330, 0.300, 0.600, 0.150, 0.060]), np.array([0.3127, 0.3290]), @@ -129,7 +141,7 @@ def test_normalised_primary_matrix(self): [0.01933082, 0.11919478, 0.95053215], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -160,7 +172,7 @@ def test_chromatically_adapted_primaries(self): chromatically_adapted_primaries` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatically_adapted_primaries( np.array( [0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700] @@ -175,10 +187,10 @@ def test_chromatically_adapted_primaries(self): [-0.05880375, -0.12573056], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatically_adapted_primaries( np.array([0.640, 0.330, 0.300, 0.600, 0.150, 0.060]), np.array([0.31270, 0.32900]), @@ -191,10 +203,10 @@ def test_chromatically_adapted_primaries(self): [0.15236177, 0.06118676], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( chromatically_adapted_primaries( np.array([0.640, 0.330, 0.300, 0.600, 0.150, 0.060]), np.array([0.31270, 0.32900]), @@ -208,7 +220,7 @@ def test_chromatically_adapted_primaries(self): [0.15589322, 0.06604921], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -247,7 +259,7 @@ def test_primaries_whitepoint(self): ] ) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( P, np.array( [ @@ -256,10 +268,10 @@ def test_primaries_whitepoint(self): [0.00010, -0.07700], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - W, np.array([0.32168, 0.33767]), decimal=7 + np.testing.assert_allclose( + W, np.array([0.32168, 0.33767]), atol=TOLERANCE_ABSOLUTE_TESTS ) P, W = primaries_whitepoint( @@ -271,7 +283,7 @@ def test_primaries_whitepoint(self): ] ) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( P, np.array( [ @@ -280,10 +292,12 @@ def test_primaries_whitepoint(self): [0.15001662, 0.06000665], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - W, np.array([0.31271591, 0.32900148]), decimal=7 + np.testing.assert_allclose( + W, + np.array([0.31271591, 0.32900148]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -350,7 +364,7 @@ def test_RGB_luminance(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( RGB_luminance( np.array([0.18, 0.18, 0.18]), np.array( @@ -359,10 +373,10 @@ def test_RGB_luminance(self): np.array([0.32168, 0.33767]), ), 0.18000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( RGB_luminance( np.array([0.21959402, 0.06986677, 0.04703877]), np.array( @@ -371,17 +385,17 @@ def test_RGB_luminance(self): np.array([0.32168, 0.33767]), ), 0.123014562384318, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( RGB_luminance( np.array([0.45620519, 0.03081071, 0.04091952]), np.array([0.6400, 0.3300, 0.3000, 0.6000, 0.1500, 0.0600]), np.array([0.31270, 0.32900]), ), 0.121995947729870, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_luminance(self): @@ -399,11 +413,15 @@ def test_n_dimensional_RGB_luminance(self): RGB = np.tile(RGB, (6, 1)) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal(RGB_luminance(RGB, P, W), Y) + np.testing.assert_allclose( + RGB_luminance(RGB, P, W), Y, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.reshape(RGB, (2, 3, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal(RGB_luminance(RGB, P, W), Y) + np.testing.assert_allclose( + RGB_luminance(RGB, P, W), Y, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_RGB_luminance(self): diff --git a/colour/models/rgb/tests/test_hanbury2003.py b/colour/models/rgb/tests/test_hanbury2003.py index 37861aa435..9de43e779e 100644 --- a/colour/models/rgb/tests/test_hanbury2003.py +++ b/colour/models/rgb/tests/test_hanbury2003.py @@ -1,10 +1,12 @@ """Defines unit tests for :mod:`colour.models.rgb.hanbury2003` module.""" -import numpy as np import unittest from itertools import product -from colour.models.rgb import RGB_to_IHLS, IHLS_to_RGB +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models.rgb import IHLS_to_RGB, RGB_to_IHLS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -29,22 +31,22 @@ class TestRGB_to_IHLS(unittest.TestCase): def test_RGB_to_IHLS(self): """Test :func:`colour.models.rgb.hanbury2003.RGB_to_IHLS` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_IHLS(np.array([0.45620519, 0.03081071, 0.04091952])), np.array([6.26236117, 0.12197943, 0.42539448]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_IHLS(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_IHLS(np.array([1.00000000, 1.00000000, 1.00000000])), np.array([0.00000000, 1.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_IHLS(self): @@ -58,11 +60,15 @@ def test_n_dimensional_RGB_to_IHLS(self): RGB = np.tile(RGB, (6, 1)) HYS = np.tile(HYS, (6, 1)) - np.testing.assert_array_almost_equal(RGB_to_IHLS(RGB), HYS, decimal=7) + np.testing.assert_allclose( + RGB_to_IHLS(RGB), HYS, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.reshape(RGB, (2, 3, 3)) HYS = np.reshape(HYS, (2, 3, 3)) - np.testing.assert_array_almost_equal(RGB_to_IHLS(RGB), HYS, decimal=7) + np.testing.assert_allclose( + RGB_to_IHLS(RGB), HYS, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_RGB_to_IHLS(self): """ @@ -76,8 +82,10 @@ def test_domain_range_scale_RGB_to_IHLS(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_IHLS(RGB * factor), HYS * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_IHLS(RGB * factor), + HYS * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -101,22 +109,22 @@ class TestIHLS_to_RGB(unittest.TestCase): def test_IHLS_to_RGB(self): """Test :func:`colour.models.rgb.hanbury2003.IHLS_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IHLS_to_RGB(np.array([6.26236117, 0.12197943, 0.42539448])), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IHLS_to_RGB(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IHLS_to_RGB(np.array([0.00000000, 1.00000000, 0.00000000])), np.array([1.00000000, 1.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_IHLS_to_RGB(self): @@ -130,11 +138,15 @@ def test_n_dimensional_IHLS_to_RGB(self): HYS = np.tile(HYS, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal(IHLS_to_RGB(HYS), RGB, decimal=7) + np.testing.assert_allclose( + IHLS_to_RGB(HYS), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) HYS = np.reshape(HYS, (2, 3, 3)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal(IHLS_to_RGB(HYS), RGB, decimal=7) + np.testing.assert_allclose( + IHLS_to_RGB(HYS), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_IHLS_to_RGB(self): """ @@ -148,8 +160,10 @@ def test_domain_range_scale_IHLS_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - IHLS_to_RGB(HYS * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + IHLS_to_RGB(HYS * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/tests/test_ictcp.py b/colour/models/rgb/tests/test_ictcp.py index 523da1464a..ea8fcf287c 100644 --- a/colour/models/rgb/tests/test_ictcp.py +++ b/colour/models/rgb/tests/test_ictcp.py @@ -1,15 +1,17 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.ictcp` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb import ( - RGB_to_ICtCp, ICtCp_to_RGB, - XYZ_to_ICtCp, ICtCp_to_XYZ, + RGB_to_ICtCp, + XYZ_to_ICtCp, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,62 +39,62 @@ class TestRGB_to_ICtCp(unittest.TestCase): def test_RGB_to_ICtCp(self): """Test :func:`colour.models.rgb.ictcp.RGB_to_ICtCp` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_ICtCp(np.array([0.45620519, 0.03081071, 0.04091952])), np.array([0.07351364, 0.00475253, 0.09351596]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_ICtCp( np.array([0.45620519, 0.03081071, 0.04091952]), L_p=4000 ), np.array([0.10516931, 0.00514031, 0.12318730]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_ICtCp( np.array([0.45620519, 0.03081071, 0.04091952]), L_p=1000 ), np.array([0.17079612, 0.00485580, 0.17431356]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_ICtCp( np.array([0.45620519, 0.03081071, 0.04091952]), method="ITU-R BT.2100-1 PQ", ), np.array([0.07351364, 0.00475253, 0.09351596]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_ICtCp( np.array([0.45620519, 0.03081071, 0.04091952]), method="ITU-R BT.2100-2 PQ", ), np.array([0.07351364, 0.00475253, 0.09351596]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_ICtCp( np.array([0.45620519, 0.03081071, 0.04091952]), method="ITU-R BT.2100-1 HLG", ), np.array([0.62567899, -0.03622422, 0.67786522]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_ICtCp( np.array([0.45620519, 0.03081071, 0.04091952]), method="ITU-R BT.2100-2 HLG", ), np.array([0.62567899, -0.01984490, 0.35911259]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_ICtCp(self): @@ -106,14 +108,14 @@ def test_n_dimensional_RGB_to_ICtCp(self): RGB = np.tile(RGB, (6, 1)) ICtCp = np.tile(ICtCp, (6, 1)) - np.testing.assert_array_almost_equal( - RGB_to_ICtCp(RGB), ICtCp, decimal=7 + np.testing.assert_allclose( + RGB_to_ICtCp(RGB), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS ) RGB = np.reshape(RGB, (2, 3, 3)) ICtCp = np.reshape(ICtCp, (2, 3, 3)) - np.testing.assert_array_almost_equal( - RGB_to_ICtCp(RGB), ICtCp, decimal=7 + np.testing.assert_allclose( + RGB_to_ICtCp(RGB), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_RGB_to_ICtCp(self): @@ -128,8 +130,10 @@ def test_domain_range_scale_RGB_to_ICtCp(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_ICtCp(RGB * factor), ICtCp * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_ICtCp(RGB * factor), + ICtCp * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -153,62 +157,62 @@ class TestICtCp_to_RGB(unittest.TestCase): def test_ICtCp_to_RGB(self): """Test :func:`colour.models.rgb.ictcp.ICtCp_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_RGB(np.array([0.07351364, 0.00475253, 0.09351596])), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_RGB( np.array([0.10516931, 0.00514031, 0.12318730]), L_p=4000 ), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_RGB( np.array([0.17079612, 0.00485580, 0.17431356]), L_p=1000 ), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_RGB( np.array([0.07351364, 0.00475253, 0.09351596]), method="ITU-R BT.2100-1 PQ", ), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_RGB( np.array([0.07351364, 0.00475253, 0.09351596]), method="ITU-R BT.2100-2 PQ", ), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_RGB( np.array([0.62567899, -0.03622422, 0.67786522]), method="ITU-R BT.2100-1 HLG", ), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_RGB( np.array([0.62567899, -0.01984490, 0.35911259]), method="ITU-R BT.2100-2 HLG", ), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ICtCp_to_RGB(self): @@ -222,14 +226,14 @@ def test_n_dimensional_ICtCp_to_RGB(self): ICtCp = np.tile(ICtCp, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal( - ICtCp_to_RGB(ICtCp), RGB, decimal=7 + np.testing.assert_allclose( + ICtCp_to_RGB(ICtCp), RGB, atol=TOLERANCE_ABSOLUTE_TESTS ) ICtCp = np.reshape(ICtCp, (2, 3, 3)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ICtCp_to_RGB(ICtCp), RGB, decimal=7 + np.testing.assert_allclose( + ICtCp_to_RGB(ICtCp), RGB, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ICtCp_to_RGB(self): @@ -244,8 +248,10 @@ def test_domain_range_scale_ICtCp_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ICtCp_to_RGB(ICtCp * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + ICtCp_to_RGB(ICtCp * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -269,81 +275,81 @@ class TestXYZ_to_ICtCp(unittest.TestCase): def test_XYZ_to_ICtCp(self): """Test :func:`colour.models.rgb.ictcp.XYZ_to_ICtCp` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.06858097, -0.00283842, 0.06020983]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.34570, 0.35850]), ), np.array([0.06792437, 0.00452089, 0.05514480]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.34570, 0.35850]), chromatic_adaptation_transform="Bradford", ), np.array([0.06783951, 0.00476111, 0.05523093]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), L_p=4000 ), np.array([0.09871102, -0.00447247, 0.07984812]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), L_p=1000 ), np.array([0.16173872, -0.00792543, 0.11409458]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), method="ITU-R BT.2100-1 PQ", ), np.array([0.06858097, -0.00283842, 0.06020983]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), method="ITU-R BT.2100-2 PQ", ), np.array([0.06858097, -0.00283842, 0.06020983]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), method="ITU-R BT.2100-1 HLG", ), np.array([0.59242792, -0.06824263, 0.47421473]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICtCp( np.array([0.20654008, 0.12197225, 0.05136952]), method="ITU-R BT.2100-2 HLG", ), np.array([0.59242792, -0.03740730, 0.25122675]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_ICtCp(self): @@ -357,14 +363,14 @@ def test_n_dimensional_XYZ_to_ICtCp(self): XYZ = np.tile(XYZ, (6, 1)) ICtCp = np.tile(ICtCp, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_ICtCp(XYZ), ICtCp, decimal=7 + np.testing.assert_allclose( + XYZ_to_ICtCp(XYZ), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) ICtCp = np.reshape(ICtCp, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_ICtCp(XYZ), ICtCp, decimal=7 + np.testing.assert_allclose( + XYZ_to_ICtCp(XYZ), ICtCp, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_ICtCp(self): @@ -379,8 +385,10 @@ def test_domain_range_scale_XYZ_to_ICtCp(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_ICtCp(XYZ * factor), ICtCp * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_ICtCp(XYZ * factor), + ICtCp * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -404,81 +412,81 @@ class TestICtCp_to_XYZ(unittest.TestCase): def test_ICtCp_to_XYZ(self): """Test :func:`colour.models.rgb.ictcp.ICtCp_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ(np.array([0.06858097, -0.00283842, 0.06020983])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.06792437, 0.00452089, 0.05514480]), np.array([0.34570, 0.35850]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.06783951, 0.00476111, 0.05523093]), np.array([0.34570, 0.35850]), chromatic_adaptation_transform="Bradford", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.09871102, -0.00447247, 0.07984812]), L_p=4000 ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.16173872, -0.00792543, 0.11409458]), L_p=1000 ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.06858097, -0.00283842, 0.06020983]), method="ITU-R BT.2100-1 PQ", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.06858097, -0.00283842, 0.06020983]), method="ITU-R BT.2100-2 PQ", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.59242792, -0.06824263, 0.47421473]), method="ITU-R BT.2100-1 HLG", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICtCp_to_XYZ( np.array([0.59242792, -0.03740730, 0.25122675]), method="ITU-R BT.2100-2 HLG", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ICtCp_to_XYZ(self): @@ -492,14 +500,14 @@ def test_n_dimensional_ICtCp_to_XYZ(self): ICtCp = np.tile(ICtCp, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - ICtCp_to_XYZ(ICtCp), XYZ, decimal=7 + np.testing.assert_allclose( + ICtCp_to_XYZ(ICtCp), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) ICtCp = np.reshape(ICtCp, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ICtCp_to_XYZ(ICtCp), XYZ, decimal=7 + np.testing.assert_allclose( + ICtCp_to_XYZ(ICtCp), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ICtCp_to_XYZ(self): @@ -514,8 +522,10 @@ def test_domain_range_scale_ICtCp_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ICtCp_to_XYZ(ICtCp * factor), XYZ * factor, decimal=7 + np.testing.assert_allclose( + ICtCp_to_XYZ(ICtCp * factor), + XYZ * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/tests/test_itut_h_273.py b/colour/models/rgb/tests/test_itut_h_273.py index f3ab6b2036..a1c4ad96fe 100644 --- a/colour/models/rgb/tests/test_itut_h_273.py +++ b/colour/models/rgb/tests/test_itut_h_273.py @@ -5,8 +5,8 @@ from colour.models import ( describe_video_signal_colour_primaries, - describe_video_signal_transfer_characteristics, describe_video_signal_matrix_coefficients, + describe_video_signal_transfer_characteristics, ) __author__ = "Colour Developers" diff --git a/colour/models/rgb/tests/test_prismatic.py b/colour/models/rgb/tests/test_prismatic.py index 25cae8a186..65dcef7f6c 100644 --- a/colour/models/rgb/tests/test_prismatic.py +++ b/colour/models/rgb/tests/test_prismatic.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.prismatic` module.""" -import numpy as np import unittest from itertools import product -from colour.models.rgb import RGB_to_Prismatic, Prismatic_to_RGB +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models.rgb import Prismatic_to_RGB, RGB_to_Prismatic from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -30,16 +32,16 @@ class TestRGB_to_Prismatic(unittest.TestCase): def test_RGB_to_Prismatic(self): """Test :func:`colour.models.rgb.prismatic.RGB_to_Prismatic` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_Prismatic(np.array([0.0, 0.0, 0.0])), np.array([0.0, 0.0, 0.0, 0.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_Prismatic(np.array([0.25, 0.50, 0.75])), np.array([0.7500000, 0.1666667, 0.3333333, 0.5000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_Prismatic(self): @@ -53,14 +55,14 @@ def test_n_dimensional_RGB_to_Prismatic(self): RGB = np.tile(RGB, (6, 1)) Lrgb = np.tile(Lrgb, (6, 1)) - np.testing.assert_array_almost_equal( - RGB_to_Prismatic(RGB), Lrgb, decimal=7 + np.testing.assert_allclose( + RGB_to_Prismatic(RGB), Lrgb, atol=TOLERANCE_ABSOLUTE_TESTS ) RGB = np.reshape(RGB, (2, 3, 3)) Lrgb = np.reshape(Lrgb, (2, 3, 4)) - np.testing.assert_array_almost_equal( - RGB_to_Prismatic(RGB), Lrgb, decimal=7 + np.testing.assert_allclose( + RGB_to_Prismatic(RGB), Lrgb, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_RGB_to_Prismatic(self): @@ -75,8 +77,10 @@ def test_domain_range_scale_RGB_to_Prismatic(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_Prismatic(RGB * factor), Lrgb * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_Prismatic(RGB * factor), + Lrgb * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -100,18 +104,18 @@ class TestPrismatic_to_RGB(unittest.TestCase): def test_Prismatic_to_RGB(self): """Test :func:`colour.models.rgb.prismatic.Prismatic_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Prismatic_to_RGB(np.array([0.0, 0.0, 0.0, 0.0])), np.array([0.0, 0.0, 0.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Prismatic_to_RGB( np.array([0.7500000, 0.1666667, 0.3333333, 0.5000000]) ), np.array([0.25, 0.50, 0.75]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Prismatic_to_RGB(self): @@ -125,14 +129,14 @@ def test_n_dimensional_Prismatic_to_RGB(self): Lrgb = np.tile(Lrgb, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal( - Prismatic_to_RGB(Lrgb), RGB, decimal=7 + np.testing.assert_allclose( + Prismatic_to_RGB(Lrgb), RGB, atol=TOLERANCE_ABSOLUTE_TESTS ) Lrgb = np.reshape(Lrgb, (2, 3, 4)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Prismatic_to_RGB(Lrgb), RGB, decimal=7 + np.testing.assert_allclose( + Prismatic_to_RGB(Lrgb), RGB, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Prismatic_to_RGB(self): @@ -147,8 +151,10 @@ def test_domain_range_scale_Prismatic_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - Prismatic_to_RGB(Lrgb * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + Prismatic_to_RGB(Lrgb * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/tests/test_rgb_colourspace.py b/colour/models/rgb/tests/test_rgb_colourspace.py index d2ee9643d4..974a50a726 100644 --- a/colour/models/rgb/tests/test_rgb_colourspace.py +++ b/colour/models/rgb/tests/test_rgb_colourspace.py @@ -3,27 +3,29 @@ Define the unit tests for the :mod:`colour.models.rgb.rgb_colourspace` module. """ -import numpy as np import re import textwrap import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( RGB_COLOURSPACE_ACES2065_1, - RGB_COLOURSPACE_sRGB, RGB_COLOURSPACES, RGB_Colourspace, - XYZ_to_RGB, - RGB_to_XYZ, + RGB_COLOURSPACE_sRGB, RGB_to_RGB, - matrix_RGB_to_RGB, + RGB_to_XYZ, + XYZ_to_RGB, chromatically_adapted_primaries, - normalised_primary_matrix, eotf_inverse_sRGB, eotf_sRGB, + linear_function, + matrix_RGB_to_RGB, + normalised_primary_matrix, ) -from colour.models import linear_function from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -183,7 +185,7 @@ def test_use_derived_transformation_matrices(self): self._colourspace.use_derived_transformation_matrices() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._colourspace.matrix_RGB_to_XYZ, np.array( [ @@ -192,9 +194,9 @@ def test_use_derived_transformation_matrices(self): [0.00000000, 0.00000000, 1.00882518], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._colourspace.matrix_XYZ_to_RGB, np.array( [ @@ -203,7 +205,7 @@ def test_use_derived_transformation_matrices(self): [0.00000000, 0.00000000, 0.99125202], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self._colourspace.use_derived_matrix_RGB_to_XYZ = False @@ -226,7 +228,7 @@ def test_chromatically_adapt(self): whitepoint_t, "D50", "Bradford" ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace.primaries, np.array( [ @@ -235,15 +237,15 @@ def test_chromatically_adapt(self): [0.01596756, -0.06423550], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - colourspace.whitepoint, whitepoint_t, decimal=7 + np.testing.assert_allclose( + colourspace.whitepoint, whitepoint_t, atol=TOLERANCE_ABSOLUTE_TESTS ) self.assertEqual(colourspace.whitepoint_name, "D50") - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace.primaries, chromatically_adapted_primaries( self._colourspace.primaries, @@ -251,25 +253,25 @@ def test_chromatically_adapt(self): whitepoint_t, "Bradford", ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace.matrix_RGB_to_XYZ, normalised_primary_matrix( colourspace.primaries, colourspace.whitepoint ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace.matrix_XYZ_to_RGB, np.linalg.inv( normalised_primary_matrix( colourspace.primaries, colourspace.whitepoint ) ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_copy(self): @@ -293,7 +295,7 @@ def test_XYZ_to_RGB(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), RGB_COLOURSPACE_sRGB, @@ -302,30 +304,30 @@ def test_XYZ_to_RGB(self): True, ), np.array([0.70556403, 0.19112904, 0.22341005]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), RGB_COLOURSPACE_sRGB, apply_cctf_encoding=True, ), np.array([0.72794351, 0.18184112, 0.17951801]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), RGB_COLOURSPACE_ACES2065_1, np.array([0.34570, 0.35850]), ), np.array([0.21959099, 0.06985815, 0.04703704]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), "sRGB", @@ -340,11 +342,11 @@ def test_XYZ_to_RGB(self): "Bradford", True, ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) # TODO: Remove tests when dropping deprecated signature support. - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), np.array([0.34570, 0.35850]), @@ -360,10 +362,10 @@ def test_XYZ_to_RGB(self): eotf_inverse_sRGB, ), np.array([0.70556599, 0.19109268, 0.22340812]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), np.array([0.34570, 0.35850]), @@ -379,10 +381,10 @@ def test_XYZ_to_RGB(self): eotf_inverse_sRGB, ), np.array([0.72794579, 0.18180021, 0.17951580]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), np.array([0.34570, 0.35850]), @@ -396,10 +398,10 @@ def test_XYZ_to_RGB(self): ), ), np.array([0.21959099, 0.06985815, 0.04703704]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB( np.array([0.21638819, 0.12570000, 0.03847493]), np.array([0.34570, 0.35850]), @@ -413,7 +415,7 @@ def test_XYZ_to_RGB(self): ), ), np.array([0.45620801, 0.03079991, 0.04091883]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_RGB(self): @@ -428,26 +430,26 @@ def test_n_dimensional_XYZ_to_RGB(self): XYZ = np.tile(XYZ, (6, 1)) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True), RGB, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) W_R = np.tile(W_R, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True), RGB, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) W_R = np.reshape(W_R, (2, 3, 2)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB(XYZ, "sRGB", W_R, "Bradford", True), RGB, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_RGB(self): @@ -463,10 +465,10 @@ def test_domain_range_scale_XYZ_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_RGB(XYZ * factor, "sRGB", W_R), RGB * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -496,7 +498,7 @@ def test_RGB_to_XYZ(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.70556403, 0.19112904, 0.22341005]), RGB_COLOURSPACE_sRGB, @@ -505,30 +507,30 @@ def test_RGB_to_XYZ(self): True, ), np.array([0.21639121, 0.12570714, 0.03847642]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.72794351, 0.18184112, 0.17951801]), RGB_COLOURSPACE_sRGB, apply_cctf_decoding=True, ), np.array([0.21639100, 0.12570754, 0.03847682]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.21959099, 0.06985815, 0.04703704]), RGB_COLOURSPACE_ACES2065_1, np.array([0.34570, 0.35850]), ), np.array([0.21638819, 0.12570000, 0.03847493]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.21638819, 0.12570000, 0.03847493]), "sRGB", @@ -543,11 +545,11 @@ def test_RGB_to_XYZ(self): "Bradford", True, ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) # TODO: Remove tests when dropping deprecated signature support. - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.70556599, 0.19109268, 0.22340812]), np.array([0.31270, 0.32900]), @@ -563,10 +565,10 @@ def test_RGB_to_XYZ(self): eotf_sRGB, ), np.array([0.21638819, 0.12570000, 0.03847493]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.72794579, 0.18180021, 0.17951580]), np.array([0.31270, 0.32900]), @@ -582,10 +584,10 @@ def test_RGB_to_XYZ(self): eotf_sRGB, ), np.array([0.21638819, 0.12570000, 0.03847493]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.21959099, 0.06985815, 0.04703704]), np.array([0.32168, 0.33767]), @@ -599,10 +601,10 @@ def test_RGB_to_XYZ(self): ), ), np.array([0.21638819, 0.12570000, 0.03847493]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ( np.array([0.45620801, 0.03079991, 0.04091883]), np.array([0.31270, 0.32900, 1.00000]), @@ -616,7 +618,7 @@ def test_RGB_to_XYZ(self): ), ), np.array([0.21638819, 0.12570000, 0.03847493]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_XYZ(self): @@ -631,20 +633,26 @@ def test_n_dimensional_RGB_to_XYZ(self): RGB = np.tile(RGB, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), XYZ, decimal=7 + np.testing.assert_allclose( + RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) W_R = np.tile(W_R, (6, 1)) - np.testing.assert_array_almost_equal( - RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), XYZ, decimal=7 + np.testing.assert_allclose( + RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB = np.reshape(RGB, (2, 3, 3)) W_R = np.reshape(W_R, (2, 3, 2)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), XYZ, decimal=7 + np.testing.assert_allclose( + RGB_to_XYZ(RGB, "sRGB", W_R, "Bradford", True), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_RGB(self): @@ -660,10 +668,10 @@ def test_domain_range_scale_XYZ_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_XYZ(RGB * factor, "sRGB", W_R), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -697,7 +705,7 @@ def test_matrix_RGB_to_RGB(self): aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"] sRGB_colourspace = RGB_COLOURSPACES["sRGB"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace), np.array( [ @@ -706,10 +714,10 @@ def test_matrix_RGB_to_RGB(self): [-0.01592501, -0.14780637, 1.16380582], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_RGB_to_RGB(sRGB_colourspace, aces_2065_1_colourspace), np.array( [ @@ -718,10 +726,10 @@ def test_matrix_RGB_to_RGB(self): [0.01738718, 0.10873911, 0.87382059], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_RGB_to_RGB( aces_2065_1_colourspace, aces_cg_colourspace, "Bradford" ), @@ -732,10 +740,10 @@ def test_matrix_RGB_to_RGB(self): [0.00831615, -0.00603245, 0.99771630], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_RGB_to_RGB( aces_2065_1_colourspace, sRGB_colourspace, "Bradford" ), @@ -746,10 +754,10 @@ def test_matrix_RGB_to_RGB(self): [-0.01532020, -0.15299256, 1.16838720], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace, None), np.array( [ @@ -758,13 +766,13 @@ def test_matrix_RGB_to_RGB(self): [-0.01711199, -0.14854588, 1.08104848], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_RGB_to_RGB(aces_2065_1_colourspace, sRGB_colourspace), matrix_RGB_to_RGB("ACES2065-1", "sRGB"), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -780,27 +788,27 @@ def test_RGB_to_RGB(self): aces_2065_1_colourspace = RGB_COLOURSPACES["ACES2065-1"] sRGB_colourspace = RGB_COLOURSPACES["sRGB"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( np.array([0.21931722, 0.06950287, 0.04694832]), aces_2065_1_colourspace, sRGB_colourspace, ), np.array([0.45595289, 0.03040780, 0.04087313]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( np.array([0.45595571, 0.03039702, 0.04087245]), sRGB_colourspace, aces_2065_1_colourspace, ), np.array([0.21931722, 0.06950287, 0.04694832]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( np.array([0.21931722, 0.06950287, 0.04694832]), aces_2065_1_colourspace, @@ -808,10 +816,10 @@ def test_RGB_to_RGB(self): "Bradford", ), np.array([0.45597530, 0.03030054, 0.04086041]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( np.array([0.21931722, 0.06950287, 0.04694832]), aces_2065_1_colourspace, @@ -819,13 +827,13 @@ def test_RGB_to_RGB(self): None, ), np.array([0.46484236, 0.02963459, 0.03667609]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) aces_cg_colourspace = RGB_COLOURSPACES["ACEScg"] aces_cc_colourspace = RGB_COLOURSPACES["ACEScc"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( np.array([0.21931722, 0.06950287, 0.04694832]), aces_cg_colourspace, @@ -834,10 +842,10 @@ def test_RGB_to_RGB(self): apply_cctf_encoding=True, ), np.array([0.42985679, 0.33522924, 0.30292336]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( np.array([0.46956438, 0.48137533, 0.43788601]), aces_cc_colourspace, @@ -846,7 +854,7 @@ def test_RGB_to_RGB(self): apply_cctf_encoding=True, ), np.array([0.60983062, 0.67896356, 0.50435764]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_equal( @@ -860,7 +868,7 @@ def test_RGB_to_RGB(self): np.array([120, 59, 46]), ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( np.array([0.21931722, 0.06950287, 0.04694832]), aces_2065_1_colourspace, @@ -871,7 +879,7 @@ def test_RGB_to_RGB(self): "ACES2065-1", "sRGB", ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_RGB(self): @@ -887,18 +895,18 @@ def test_n_dimensional_RGB_to_RGB(self): RGB_i = np.tile(RGB_i, (6, 1)) RGB_o = np.tile(RGB_o, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace), RGB_o, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) RGB_i = np.reshape(RGB_i, (2, 3, 3)) RGB_o = np.reshape(RGB_o, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB(RGB_i, aces_2065_1_colourspace, sRGB_colourspace), RGB_o, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_RGB(self): @@ -915,14 +923,14 @@ def test_domain_range_scale_XYZ_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_RGB( RGB_i * factor, aces_2065_1_colourspace, sRGB_colourspace, ), RGB_o * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/tests/test_ycbcr.py b/colour/models/rgb/tests/test_ycbcr.py index 0f32bc45ab..24b3bffbf5 100644 --- a/colour/models/rgb/tests/test_ycbcr.py +++ b/colour/models/rgb/tests/test_ycbcr.py @@ -1,20 +1,22 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.ycbcr` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.ycbcr import ( - round_BT2100, - ranges_YCbCr, - matrix_YCbCr, - offset_YCbCr, + WEIGHTS_YCBCR, RGB_to_YCbCr, - YCbCr_to_RGB, RGB_to_YcCbcCrc, + YCbCr_to_RGB, YcCbcCrc_to_RGB, - WEIGHTS_YCBCR, + matrix_YCbCr, + offset_YCbCr, + ranges_YCbCr, + round_BT2100, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -61,52 +63,52 @@ class TestRangeYCbCr(unittest.TestCase): def test_ranges_YCbCr(self): """Test :func:`colour.models.rgb.ycbcr.ranges_YCbCr` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(8, True, True), np.array([16.00000000, 235.00000000, 16.00000000, 240.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(8, True, False), np.array([0.06274510, 0.92156863, 0.06274510, 0.94117647]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(8, False, True), np.array([0.00000000, 255.00000000, 0.50000000, 255.50000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(8, False, False), np.array([0.00000000, 1.00000000, -0.50000000, 0.50000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(10, True, True), np.array([64.00000000, 940.00000000, 64.00000000, 960.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(10, True, False), np.array([0.06256109, 0.91886608, 0.06256109, 0.93841642]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(10, False, True), np.array([0.00000000, 1023.00000000, 0.50000000, 1023.50000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ranges_YCbCr(10, False, False), np.array([0.00000000, 1.00000000, -0.50000000, 0.50000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -119,7 +121,7 @@ class TestMatrixYCbCr(unittest.TestCase): def test_matrix_YCbCr(self): """Test :func:`colour.models.rgb.ycbcr.matrix_YCbCr` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_YCbCr(), np.array( [ @@ -128,10 +130,10 @@ def test_matrix_YCbCr(self): [1.00000000, 1.85560000, 0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_YCbCr(K=WEIGHTS_YCBCR["ITU-R BT.601"]), np.array( [ @@ -140,10 +142,10 @@ def test_matrix_YCbCr(self): [1.00000000, 1.77200000, -0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_YCbCr(is_legal=True), np.array( [ @@ -152,10 +154,10 @@ def test_matrix_YCbCr(self): [1.16438356, 2.11240179, -0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_YCbCr(bits=10), np.array( [ @@ -164,10 +166,10 @@ def test_matrix_YCbCr(self): [1.00000000, 1.85560000, 0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( matrix_YCbCr(bits=10, is_int=True), np.array( [ @@ -176,7 +178,7 @@ def test_matrix_YCbCr(self): [0.00097752, 0.00181388, 0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -189,28 +191,28 @@ class TestOffsetYCbCr(unittest.TestCase): def test_offset_YCbCr(self): """Test :func:`colour.models.rgb.ycbcr.offset_YCbCr` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( offset_YCbCr(), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( offset_YCbCr(is_legal=True), np.array([0.06274510, 0.50196078, 0.50196078]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( offset_YCbCr(bits=10), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( offset_YCbCr(bits=10, is_int=True), np.array([0.00000000, 512.00000000, 512.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -223,13 +225,13 @@ class TestRGB_to_YCbCr(unittest.TestCase): def test_RGB_to_YCbCr(self): """Test :func:`colour.models.rgb.ycbcr.RGB_to_YCbCr` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_YCbCr(np.array([0.75, 0.75, 0.0])), np.array([0.66035745, 0.17254902, 0.53216593]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_YCbCr( np.array([0.25, 0.5, 0.75]), K=WEIGHTS_YCBCR["ITU-R BT.601"], @@ -238,10 +240,10 @@ def test_RGB_to_YCbCr(self): out_bits=10, ), np.array([461, 662, 382]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_YCbCr( np.array([0.0, 0.75, 0.75]), K=WEIGHTS_YCBCR["ITU-R BT.2020"], @@ -249,17 +251,17 @@ def test_RGB_to_YCbCr(self): out_legal=False, ), np.array([0.55297500, 0.10472255, -0.37500000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_YCbCr( np.array([0.75, 0.0, 0.75]), K=WEIGHTS_YCBCR["ITU-R BT.709"], out_range=(16 / 255, 235 / 255, 15.5 / 255, 239.5 / 255), ), np.array([0.24618980, 0.75392897, 0.79920662]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_YCbCr(self): @@ -275,19 +277,19 @@ def test_n_dimensional_RGB_to_YCbCr(self): RGB = np.reshape(RGB, (4, 3)) YCbCr = np.tile(YCbCr, 4) YCbCr = np.reshape(YCbCr, (4, 3)) - np.testing.assert_array_almost_equal(RGB_to_YCbCr(RGB), YCbCr) + np.testing.assert_allclose(RGB_to_YCbCr(RGB), YCbCr) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 3)) YCbCr = np.tile(YCbCr, 4) YCbCr = np.reshape(YCbCr, (4, 4, 3)) - np.testing.assert_array_almost_equal(RGB_to_YCbCr(RGB), YCbCr) + np.testing.assert_allclose(RGB_to_YCbCr(RGB), YCbCr) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 4, 3)) YCbCr = np.tile(YCbCr, 4) YCbCr = np.reshape(YCbCr, (4, 4, 4, 3)) - np.testing.assert_array_almost_equal(RGB_to_YCbCr(RGB), YCbCr) + np.testing.assert_allclose(RGB_to_YCbCr(RGB), YCbCr) def test_domain_range_scale_RGB_to_YCbCr(self): """ @@ -301,8 +303,10 @@ def test_domain_range_scale_RGB_to_YCbCr(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_YCbCr(RGB * factor), YCbCr * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_YCbCr(RGB * factor), + YCbCr * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -326,13 +330,13 @@ class TestYCbCr_to_RGB(unittest.TestCase): def test_YCbCr_to_RGB(self): """Test :func:`colour.models.rgb.ycbcr.YCbCr_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( YCbCr_to_RGB(np.array([0.66035745, 0.17254902, 0.53216593])), np.array([0.75, 0.75, 0.0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( YCbCr_to_RGB( np.array([471, 650, 390]), in_bits=10, @@ -340,10 +344,10 @@ def test_YCbCr_to_RGB(self): in_int=True, ), np.array([0.25018598, 0.49950072, 0.75040741]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( YCbCr_to_RGB( np.array([150, 99, 175]), in_bits=8, @@ -354,7 +358,7 @@ def test_YCbCr_to_RGB(self): out_int=True, ), np.array([208, 131, 99]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_YCbCr_to_RGB(self): @@ -370,19 +374,19 @@ def test_n_dimensional_YCbCr_to_RGB(self): RGB = np.reshape(RGB, (4, 3)) YCbCr = np.tile(YCbCr, 4) YCbCr = np.reshape(YCbCr, (4, 3)) - np.testing.assert_array_almost_equal(YCbCr_to_RGB(YCbCr), RGB) + np.testing.assert_allclose(YCbCr_to_RGB(YCbCr), RGB) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 3)) YCbCr = np.tile(YCbCr, 4) YCbCr = np.reshape(YCbCr, (4, 4, 3)) - np.testing.assert_array_almost_equal(YCbCr_to_RGB(YCbCr), RGB) + np.testing.assert_allclose(YCbCr_to_RGB(YCbCr), RGB) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 4, 3)) YCbCr = np.tile(YCbCr, 4) YCbCr = np.reshape(YCbCr, (4, 4, 4, 3)) - np.testing.assert_array_almost_equal(YCbCr_to_RGB(YCbCr), RGB) + np.testing.assert_allclose(YCbCr_to_RGB(YCbCr), RGB) def test_domain_range_scale_YCbCr_to_RGB(self): """ @@ -396,8 +400,10 @@ def test_domain_range_scale_YCbCr_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - YCbCr_to_RGB(YCbCr * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + YCbCr_to_RGB(YCbCr * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -421,13 +427,13 @@ class TestRGB_to_YcCbcCrc(unittest.TestCase): def test_RGB_to_YcCbcCrc(self): """Test :func:`colour.models.rgb.ycbcr.RGB_to_YcCbcCrc` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_YcCbcCrc(np.array([0.45620519, 0.03081071, 0.04091952])), np.array([0.37020379, 0.41137200, 0.77704674]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_YcCbcCrc( np.array([0.18, 0.18, 0.18]), out_bits=10, @@ -436,7 +442,7 @@ def test_RGB_to_YcCbcCrc(self): is_12_bits_system=False, ), np.array([422, 512, 512]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_RGB_to_YcCbcCrc(self): @@ -452,24 +458,24 @@ def test_n_dimensional_RGB_to_YcCbcCrc(self): RGB = np.reshape(RGB, (4, 3)) YcCbcCrc = np.tile(YcCbcCrc, 4) YcCbcCrc = np.reshape(YcCbcCrc, (4, 3)) - np.testing.assert_array_almost_equal( - RGB_to_YcCbcCrc(RGB), YcCbcCrc, decimal=7 + np.testing.assert_allclose( + RGB_to_YcCbcCrc(RGB), YcCbcCrc, atol=TOLERANCE_ABSOLUTE_TESTS ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 3)) YcCbcCrc = np.tile(YcCbcCrc, 4) YcCbcCrc = np.reshape(YcCbcCrc, (4, 4, 3)) - np.testing.assert_array_almost_equal( - RGB_to_YcCbcCrc(RGB), YcCbcCrc, decimal=7 + np.testing.assert_allclose( + RGB_to_YcCbcCrc(RGB), YcCbcCrc, atol=TOLERANCE_ABSOLUTE_TESTS ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 4, 3)) YcCbcCrc = np.tile(YcCbcCrc, 4) YcCbcCrc = np.reshape(YcCbcCrc, (4, 4, 4, 3)) - np.testing.assert_array_almost_equal( - RGB_to_YcCbcCrc(RGB), YcCbcCrc, decimal=7 + np.testing.assert_allclose( + RGB_to_YcCbcCrc(RGB), YcCbcCrc, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_RGB_to_YcCbcCrc(self): @@ -484,8 +490,10 @@ def test_domain_range_scale_RGB_to_YcCbcCrc(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - RGB_to_YcCbcCrc(RGB * factor), YcCbcCrc * factor, decimal=7 + np.testing.assert_allclose( + RGB_to_YcCbcCrc(RGB * factor), + YcCbcCrc * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -509,13 +517,13 @@ class TestYcCbcCrc_to_RGB(unittest.TestCase): def test_YcCbcCrc_to_RGB(self): """Test :func:`colour.models.rgb.ycbcr.YCbCr_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( YcCbcCrc_to_RGB(np.array([0.37020379, 0.41137200, 0.77704674])), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( YcCbcCrc_to_RGB( np.array([1689, 2048, 2048]), in_bits=12, @@ -524,7 +532,7 @@ def test_YcCbcCrc_to_RGB(self): is_12_bits_system=True, ), np.array([0.18009037, 0.18009037, 0.18009037]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_YcCbcCrc_to_RGB(self): @@ -540,24 +548,24 @@ def test_n_dimensional_YcCbcCrc_to_RGB(self): RGB = np.reshape(RGB, (4, 3)) YcCbcCrc = np.tile(YcCbcCrc, 4) YcCbcCrc = np.reshape(YcCbcCrc, (4, 3)) - np.testing.assert_array_almost_equal( - YcCbcCrc_to_RGB(YcCbcCrc), RGB, decimal=7 + np.testing.assert_allclose( + YcCbcCrc_to_RGB(YcCbcCrc), RGB, atol=TOLERANCE_ABSOLUTE_TESTS ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 3)) YcCbcCrc = np.tile(YcCbcCrc, 4) YcCbcCrc = np.reshape(YcCbcCrc, (4, 4, 3)) - np.testing.assert_array_almost_equal( - YcCbcCrc_to_RGB(YcCbcCrc), RGB, decimal=7 + np.testing.assert_allclose( + YcCbcCrc_to_RGB(YcCbcCrc), RGB, atol=TOLERANCE_ABSOLUTE_TESTS ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 4, 3)) YcCbcCrc = np.tile(YcCbcCrc, 4) YcCbcCrc = np.reshape(YcCbcCrc, (4, 4, 4, 3)) - np.testing.assert_array_almost_equal( - YcCbcCrc_to_RGB(YcCbcCrc), RGB, decimal=7 + np.testing.assert_allclose( + YcCbcCrc_to_RGB(YcCbcCrc), RGB, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_YcCbcCrc_to_RGB(self): @@ -572,8 +580,10 @@ def test_domain_range_scale_YcCbcCrc_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - YcCbcCrc_to_RGB(YcCbcCrc * factor), RGB * factor, decimal=7 + np.testing.assert_allclose( + YcCbcCrc_to_RGB(YcCbcCrc * factor), + RGB * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/tests/test_ycocg.py b/colour/models/rgb/tests/test_ycocg.py index 2b72596a41..05630a2a83 100644 --- a/colour/models/rgb/tests/test_ycocg.py +++ b/colour/models/rgb/tests/test_ycocg.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.rgb.ycocg` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb import RGB_to_YCoCg, YCoCg_to_RGB from colour.utilities import ignore_numpy_errors @@ -58,19 +60,25 @@ def test_n_dimensional_RGB_to_YCoCg(self): RGB = np.reshape(RGB, (4, 3)) YCoCg = np.tile(YCoCg, 4) YCoCg = np.reshape(YCoCg, (4, 3)) - np.testing.assert_array_equal(RGB_to_YCoCg(RGB), YCoCg) + np.testing.assert_allclose( + RGB_to_YCoCg(RGB), YCoCg, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 3)) YCoCg = np.tile(YCoCg, 4) YCoCg = np.reshape(YCoCg, (4, 4, 3)) - np.testing.assert_array_equal(RGB_to_YCoCg(RGB), YCoCg) + np.testing.assert_allclose( + RGB_to_YCoCg(RGB), YCoCg, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 4, 3)) YCoCg = np.tile(YCoCg, 4) YCoCg = np.reshape(YCoCg, (4, 4, 4, 3)) - np.testing.assert_array_equal(RGB_to_YCoCg(RGB), YCoCg) + np.testing.assert_allclose( + RGB_to_YCoCg(RGB), YCoCg, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_RGB_to_YCoCg(self): @@ -121,19 +129,25 @@ def test_n_dimensional_YCoCg_to_RGB(self): RGB = np.reshape(RGB, (4, 3)) YCoCg = np.tile(YCoCg, 4) YCoCg = np.reshape(YCoCg, (4, 3)) - np.testing.assert_array_equal(YCoCg_to_RGB(YCoCg), RGB) + np.testing.assert_allclose( + YCoCg_to_RGB(YCoCg), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 3)) YCoCg = np.tile(YCoCg, 4) YCoCg = np.reshape(YCoCg, (4, 4, 3)) - np.testing.assert_array_equal(YCoCg_to_RGB(YCoCg), RGB) + np.testing.assert_allclose( + YCoCg_to_RGB(YCoCg), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) RGB = np.tile(RGB, 4) RGB = np.reshape(RGB, (4, 4, 4, 3)) YCoCg = np.tile(YCoCg, 4) YCoCg = np.reshape(YCoCg, (4, 4, 4, 3)) - np.testing.assert_array_equal(YCoCg_to_RGB(YCoCg), RGB) + np.testing.assert_allclose( + YCoCg_to_RGB(YCoCg), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_YCoCg_to_RGB(self): diff --git a/colour/models/rgb/transfer_functions/__init__.py b/colour/models/rgb/transfer_functions/__init__.py index 7e45700389..0d0f021a9f 100644 --- a/colour/models/rgb/transfer_functions/__init__.py +++ b/colour/models/rgb/transfer_functions/__init__.py @@ -5,7 +5,16 @@ ArrayLike, NDArrayFloat, NDArrayInt, - Literal, + LiteralLogEncoding, + LiteralLogDecoding, + LiteralOETF, + LiteralOETFInverse, + LiteralEOTF, + LiteralEOTFInverse, + LiteralCCTFEncoding, + LiteralCCTFDecoding, + LiteralOOTF, + LiteralOOTFInverse, Union, ) from colour.utilities import ( @@ -25,6 +34,10 @@ log_encoding_ACEScct, log_decoding_ACEScct, ) +from .apple_log_profile import ( + log_encoding_AppleLogProfile, + log_decoding_AppleLogProfile, +) from .arib_std_b67 import oetf_ARIBSTDB67, oetf_inverse_ARIBSTDB67 from .arri import ( log_encoding_ARRILogC3, @@ -168,6 +181,7 @@ "log_encoding_ACEScct", "log_decoding_ACEScct", ] +__all__ += ["log_encoding_AppleLogProfile", "log_decoding_AppleLogProfile"] __all__ += [ "oetf_ARIBSTDB67", "oetf_inverse_ARIBSTDB67", @@ -368,6 +382,7 @@ "ACEScc": log_encoding_ACEScc, "ACEScct": log_encoding_ACEScct, "ACESproxy": log_encoding_ACESproxy, + "Apple Log Profile": log_encoding_AppleLogProfile, "ARRI LogC3": log_encoding_ARRILogC3, "ARRI LogC4": log_encoding_ARRILogC4, "Canon Log 2": log_encoding_CanonLog2, @@ -404,41 +419,7 @@ def log_encoding( value: ArrayLike, - function: Union[ - Literal[ - "ACEScc", - "ACEScct", - "ACESproxy", - "ARRI LogC3", - "ARRI LogC4", - "Canon Log 2", - "Canon Log 3", - "Canon Log", - "Cineon", - "D-Log", - "ERIMM RGB", - "F-Log", - "F-Log2", - "Filmic Pro 6", - "L-Log", - "Log2", - "Log3G10", - "Log3G12", - "N-Log", - "PLog", - "Panalog", - "Protune", - "REDLog", - "REDLogFilm", - "S-Log", - "S-Log2", - "S-Log3", - "T-Log", - "V-Log", - "ViperLog", - ], - str, - ] = "Cineon", + function: Union[LiteralLogEncoding, str] = "Cineon", **kwargs: Any ) -> Union[NDArrayFloat, NDArrayInt]: """ @@ -458,6 +439,7 @@ def log_encoding( {:func:`colour.models.log_encoding_ACEScc`, :func:`colour.models.log_encoding_ACEScct`, :func:`colour.models.log_encoding_ACESproxy`, + :func:`colour.models.log_encoding_AppleLogProfile`, :func:`colour.models.log_encoding_ARRILogC3`, :func:`colour.models.log_encoding_ARRILogC4`, :func:`colour.models.log_encoding_CanonLog2`, @@ -521,6 +503,7 @@ def log_encoding( "ACEScc": log_decoding_ACEScc, "ACEScct": log_decoding_ACEScct, "ACESproxy": log_decoding_ACESproxy, + "Apple Log Profile": log_decoding_AppleLogProfile, "ARRI LogC3": log_decoding_ARRILogC3, "ARRI LogC4": log_decoding_ARRILogC4, "Canon Log 2": log_decoding_CanonLog2, @@ -557,41 +540,7 @@ def log_encoding( def log_decoding( value: Union[ArrayLike, ArrayLike], - function: Union[ - Literal[ - "ACEScc", - "ACEScct", - "ACESproxy", - "ARRI LogC3", - "ARRI LogC4", - "Canon Log 2", - "Canon Log 3", - "Canon Log", - "Cineon", - "D-Log", - "ERIMM RGB", - "F-Log", - "F-Log2", - "Filmic Pro 6", - "L-Log", - "Log2", - "Log3G10", - "Log3G12", - "N-Log", - "PLog", - "Panalog", - "Protune", - "REDLog", - "REDLogFilm", - "S-Log", - "S-Log2", - "S-Log3", - "T-Log", - "V-Log", - "ViperLog", - ], - str, - ] = "Cineon", + function: Union[LiteralLogDecoding, str] = "Cineon", **kwargs: Any ) -> NDArrayFloat: """ @@ -611,6 +560,7 @@ def log_decoding( {:func:`colour.models.log_decoding_ACEScc`, :func:`colour.models.log_decoding_ACEScct`, :func:`colour.models.log_decoding_ACESproxy`, + :func:`colour.models.log_decoding_AppleLogProfile`, :func:`colour.models.log_decoding_ARRILogC3`, :func:`colour.models.log_decoding_ARRILogC4`, :func:`colour.models.log_decoding_CanonLog2`, @@ -703,23 +653,7 @@ def log_decoding( def oetf( value: ArrayLike, - function: Union[ - Literal[ - "ARIB STD-B67", - "Blackmagic Film Generation 5", - "DaVinci Intermediate", - "ITU-R BT.2020", - "ITU-R BT.2100 HLG", - "ITU-R BT.2100 PQ", - "ITU-R BT.601", - "ITU-R BT.709", - "ITU-T H.273 Log", - "ITU-T H.273 Log Sqrt", - "ITU-T H.273 IEC 61966-2", - "SMPTE 240M", - ], - str, - ] = "ITU-R BT.709", + function: Union[LiteralOETF, str] = "ITU-R BT.709", **kwargs: Any ) -> NDArrayFloat: """ @@ -794,22 +728,7 @@ def oetf( def oetf_inverse( value: ArrayLike, - function: Union[ - Literal[ - "ARIB STD-B67", - "Blackmagic Film Generation 5", - "DaVinci Intermediate", - "ITU-R BT.2020", - "ITU-R BT.2100 HLG", - "ITU-R BT.2100 PQ", - "ITU-R BT.601", - "ITU-R BT.709", - "ITU-T H.273 Log", - "ITU-T H.273 Log Sqrt", - "ITU-T H.273 IEC 61966-2", - ], - str, - ] = "ITU-R BT.709", + function: Union[LiteralOETFInverse, str] = "ITU-R BT.709", **kwargs: Any ) -> NDArrayFloat: """ @@ -884,20 +803,7 @@ def oetf_inverse( def eotf( value: Union[ArrayLike, ArrayLike], - function: Union[ - Literal[ - "DCDM", - "DICOM GSDF", - "ITU-R BT.1886", - "ITU-R BT.2100 HLG", - "ITU-R BT.2100 PQ", - "ITU-T H.273 ST.428-1", - "SMPTE 240M", - "ST 2084", - "sRGB", - ], - str, - ] = "ITU-R BT.1886", + function: Union[LiteralEOTF, str] = "ITU-R BT.1886", **kwargs: Any ) -> NDArrayFloat: """ @@ -968,19 +874,7 @@ def eotf( def eotf_inverse( value: ArrayLike, - function: Union[ - Literal[ - "DCDM", - "DICOM GSDF", - "ITU-R BT.1886", - "ITU-R BT.2100 HLG", - "ITU-R BT.2100 PQ", - "ITU-T H.273 ST.428-1", - "ST 2084", - "sRGB", - ], - str, - ] = "ITU-R BT.1886", + function: Union[LiteralEOTFInverse, str] = "ITU-R BT.1886", **kwargs ) -> Union[NDArrayFloat, NDArrayInt]: """ @@ -1079,60 +973,7 @@ def eotf_inverse( def cctf_encoding( value: ArrayLike, - function: Union[ - Literal[ - "ACEScc", - "ACEScct", - "ACESproxy", - "ARRI LogC3", - "ARRI LogC4", - "ARIB STD-B67", - "Blackmagic Film Generation 5", - "Canon Log 2", - "Canon Log 3", - "Canon Log", - "Cineon", - "D-Log", - "DCDM", - "DICOM GSDF", - "DaVinci Intermediate", - "ERIMM RGB", - "F-Log", - "F-Log2", - "Filmic Pro 6", - "Gamma 2.2", - "Gamma 2.4", - "Gamma 2.6", - "ITU-R BT.1886", - "ITU-R BT.2020", - "ITU-R BT.2100 HLG", - "ITU-R BT.2100 PQ", - "ITU-R BT.601", - "ITU-R BT.709", - "Log2", - "Log3G10", - "Log3G12", - "N-Log", - "PLog", - "Panalog", - "ProPhoto RGB", - "Protune", - "REDLog", - "REDLogFilm", - "RIMM RGB", - "ROMM RGB", - "S-Log", - "S-Log2", - "S-Log3", - "SMPTE 240M", - "ST 2084", - "T-Log", - "V-Log", - "ViperLog", - "sRGB", - ], - str, - ] = "sRGB", + function: Union[LiteralCCTFEncoding, str] = "sRGB", **kwargs: Any ) -> Union[NDArrayFloat, NDArrayInt]: """ @@ -1236,60 +1077,7 @@ def cctf_encoding( def cctf_decoding( value: Union[ArrayLike, ArrayLike], - function: Union[ - Literal[ - "ACEScc", - "ACEScct", - "ACESproxy", - "ARRI LogC3", - "ARRI LogC4", - "ARIB STD-B67", - "Blackmagic Film Generation 5", - "Canon Log 2", - "Canon Log 3", - "Canon Log", - "Cineon", - "D-Log", - "DCDM", - "DICOM GSDF", - "DaVinci Intermediate", - "ERIMM RGB", - "F-Log", - "F-Log2", - "Filmic Pro 6", - "Gamma 2.2", - "Gamma 2.4", - "Gamma 2.6", - "ITU-R BT.1886", - "ITU-R BT.2020", - "ITU-R BT.2100 HLG", - "ITU-R BT.2100 PQ", - "ITU-R BT.601", - "ITU-R BT.709", - "Log2", - "Log3G10", - "Log3G12", - "N-Log", - "PLog", - "Panalog", - "ProPhoto RGB", - "Protune", - "REDLog", - "REDLogFilm", - "RIMM RGB", - "ROMM RGB", - "S-Log", - "S-Log2", - "S-Log3", - "SMPTE 240M", - "ST 2084", - "T-Log", - "V-Log", - "ViperLog", - "sRGB", - ], - str, - ] = "sRGB", + function: Union[LiteralCCTFDecoding, str] = "sRGB", **kwargs: Any ) -> NDArrayFloat: """ @@ -1377,9 +1165,7 @@ def cctf_decoding( def ootf( value: ArrayLike, - function: Union[ - Literal["ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ"], str - ] = "ITU-R BT.2100 PQ", + function: Union[LiteralOOTF, str] = "ITU-R BT.2100 PQ", **kwargs: Any ) -> NDArrayFloat: """ @@ -1437,9 +1223,7 @@ def ootf( def ootf_inverse( value: ArrayLike, - function: Union[ - Literal["ITU-R BT.2100 HLG", "ITU-R BT.2100 PQ"], str - ] = "ITU-R BT.2100 PQ", + function: Union[LiteralOOTFInverse, str] = "ITU-R BT.2100 PQ", **kwargs: Any ) -> NDArrayFloat: """ diff --git a/colour/models/rgb/transfer_functions/aces.py b/colour/models/rgb/transfer_functions/aces.py index 9b59e7f5f1..c35d18a6cf 100644 --- a/colour/models/rgb/transfer_functions/aces.py +++ b/colour/models/rgb/transfer_functions/aces.py @@ -51,7 +51,7 @@ import numpy as np -from colour.hints import ArrayLike, NDArrayFloat, NDArrayInt, Literal +from colour.hints import ArrayLike, Literal, NDArrayFloat, NDArrayInt from colour.utilities import ( Structure, as_float, diff --git a/colour/models/rgb/transfer_functions/apple_log_profile.py b/colour/models/rgb/transfer_functions/apple_log_profile.py new file mode 100644 index 0000000000..d755e6d6f8 --- /dev/null +++ b/colour/models/rgb/transfer_functions/apple_log_profile.py @@ -0,0 +1,198 @@ +""" +Apple Log Profile Log Encoding +============================== + +Defines the *Apple Log Profile* log encoding: + +- :func:`colour.models.log_encoding_AppleLogProfile` +- :func:`colour.models.log_decoding_AppleLogProfile` + +References +---------- +- :cite:`AppleInc.2023` : Apple Inc. (2023). Apple Log Profile White Paper. + https://developer.apple.com/download/all/?q=Apple%20log%20profile +- :cite:`TheAcademyofMotionPictureArtsandSciences2023` : The Academy of + Motion Picture Arts and Sciences. (2023). IDT.Apple.AppleLog_BT2020.ctl. + Retrieved December 17, 2023, from + https://github.com/ampas/aces-dev/blob/\ +528c78fe2c0f4e7eb322581e98aba05de79466cb/transforms/ctl/idt/vendorSupplied/\ +apple/IDT.Apple.AppleLog_BT2020.ctl + +""" + +from __future__ import annotations + +import numpy as np + +from colour.hints import ArrayLike, NDArrayFloat +from colour.utilities import Structure, as_float, from_range_1, to_domain_1 + +__author__ = "Colour Developers" +__copyright__ = "Copyright 2013 Colour Developers" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" +__maintainer__ = "Colour Developers" +__email__ = "colour-developers@colour-science.org" +__status__ = "Production" + +__all__ = [ + "CONSTANTS_APPLE_LOG_PROFILE", + "log_encoding_AppleLogProfile", + "log_decoding_AppleLogProfile", +] + +CONSTANTS_APPLE_LOG_PROFILE: Structure = Structure( + R_0=-0.05641088, + R_t=0.01, + sigma=47.28711236, + beta=0.00964052, + gamma=0.08550479, + delta=0.69336945, +) +"""*Apple Log Profile* constants.""" + + +def log_encoding_AppleLogProfile( + R: ArrayLike, + constants: Structure = CONSTANTS_APPLE_LOG_PROFILE, +) -> NDArrayFloat: + """ + Define the *Apple Log Profile* log encoding curve. + + Parameters + ---------- + R + Linear reflection data :math`R`. + constants + *Apple Log Profile* constants. + + Returns + ------- + :class:`numpy.ndarray` + *Apple Log Profile* captured pixel value :math:`P` + + References + ---------- + :cite:`AppleInc.2023`, :cite:`TheAcademyofMotionPictureArtsandSciences2023` + + Notes + ----- + - The scene reflection signal :math:`R` captured by the camera is + represented using a floating point encoding. The :math:`R` value of + 0.18 corresponds to the signal produced by an 18% reflectance; + reference gray chart. + + +------------+-----------------------+---------------+ + | **Domain** | **Scale - Reference** | **Scale - 1** | + +============+=======================+===============+ + | ``R`` | [0, 1] | [0, 1] | + +------------+-----------------------+---------------+ + + +------------+-----------------------+---------------+ + | **Range** | **Scale - Reference** | **Scale - 1** | + +============+=======================+===============+ + | ``P`` | [0, 1] | [0, 1] | + +------------+-----------------------+---------------+ + + Examples + -------- + >>> log_encoding_AppleLogProfile(0.18) # doctest: +ELLIPSIS + 0.4882724... + """ + + R = to_domain_1(R) + + R_0 = constants.R_0 + R_t = constants.R_t + sigma = constants.sigma + beta = constants.beta + gamma = constants.gamma + delta = constants.delta + + P = np.select( + [ + R >= R_t, # noqa: SIM300 + np.logical_and(R_0 <= R, R < R_t), # noqa: SIM300 + R < R_0, + ], + [ + gamma * np.log2(R + beta) + delta, + sigma * (R - R_0) ** 2, + 0, + ], + ) + + return as_float(from_range_1(P)) + + +def log_decoding_AppleLogProfile( + P: ArrayLike, + constants: Structure = CONSTANTS_APPLE_LOG_PROFILE, +) -> NDArrayFloat: + """ + Define the *Apple Log Profile* log decoding curve. + + Parameters + ---------- + P + *Apple Log Profile* captured pixel value :math:`P` + constants + *Apple Log Profile* constants. + + Returns + ------- + :class:`numpy.ndarray` + Linear reflection data :math`R`. + + + References + ---------- + :cite:`AppleInc.2023`, :cite:`TheAcademyofMotionPictureArtsandSciences2023` + + Notes + ----- + - The captured pixel :math:`P` value is using a floating point encoding + normalized to the [0, 1] range. + + +------------+-----------------------+---------------+ + | **Domain** | **Scale - Reference** | **Scale - 1** | + +============+=======================+===============+ + | ``P`` | [0, 1] | [0, 1] | + +------------+-----------------------+---------------+ + + +------------+-----------------------+---------------+ + | **Range** | **Scale - Reference** | **Scale - 1** | + +============+=======================+===============+ + | ``R`` | [0, 1] | [0, 1] | + +------------+-----------------------+---------------+ + + Examples + -------- + >>> log_decoding_AppleLogProfile(0.48827245852686763) # doctest: +ELLIPSIS + 0.1800000... + """ + + P = to_domain_1(P) + + R_0 = constants.R_0 + R_t = constants.R_t + sigma = constants.sigma + beta = constants.beta + gamma = constants.gamma + delta = constants.delta + + P_t = sigma * (R_t - R_0) ** 2 + + R = np.select( + [ + P >= P_t, # noqa: SIM300 + np.logical_and(0 <= P, P < P_t), # noqa: SIM300 + P < 0, + ], + [ + 2 ** ((P - delta) / gamma) - beta, + np.sqrt(P / sigma) + R_0, + R_0, + ], + ) + + return as_float(from_range_1(R)) diff --git a/colour/models/rgb/transfer_functions/arri.py b/colour/models/rgb/transfer_functions/arri.py index 2b36f16861..81e5ad812d 100644 --- a/colour/models/rgb/transfer_functions/arri.py +++ b/colour/models/rgb/transfer_functions/arri.py @@ -21,7 +21,7 @@ import numpy as np -from colour.hints import ArrayLike, NDArrayFloat, Literal +from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import ( CanonicalMapping, Structure, diff --git a/colour/models/rgb/transfer_functions/common.py b/colour/models/rgb/transfer_functions/common.py index 1386fecbb3..2aedcc85af 100644 --- a/colour/models/rgb/transfer_functions/common.py +++ b/colour/models/rgb/transfer_functions/common.py @@ -10,7 +10,7 @@ import numpy as np from colour.hints import ArrayLike, NDArrayReal -from colour.utilities import as_float, as_int, as_float_array, as_int_array +from colour.utilities import as_float, as_float_array, as_int, as_int_array __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/models/rgb/transfer_functions/dcdm.py b/colour/models/rgb/transfer_functions/dcdm.py index c71c90bd7b..efd51935cd 100644 --- a/colour/models/rgb/transfer_functions/dcdm.py +++ b/colour/models/rgb/transfer_functions/dcdm.py @@ -25,7 +25,7 @@ from colour.algebra import spow from colour.hints import ArrayLike, NDArrayFloat, NDArrayReal -from colour.utilities import as_float_array, as_float, as_int +from colour.utilities import as_float, as_float_array, as_int __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/models/rgb/transfer_functions/exponent.py b/colour/models/rgb/transfer_functions/exponent.py index 06acff254b..61f7ed5b37 100644 --- a/colour/models/rgb/transfer_functions/exponent.py +++ b/colour/models/rgb/transfer_functions/exponent.py @@ -18,7 +18,6 @@ from __future__ import annotations - from colour.algebra import sdiv, sdiv_mode from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.utilities import ( diff --git a/colour/models/rgb/transfer_functions/gamma.py b/colour/models/rgb/transfer_functions/gamma.py index b4d6d131f0..d330eefa16 100644 --- a/colour/models/rgb/transfer_functions/gamma.py +++ b/colour/models/rgb/transfer_functions/gamma.py @@ -13,8 +13,8 @@ import numpy as np from colour.algebra import spow -from colour.hints import ArrayLike, NDArrayFloat, Literal -from colour.utilities import as_float_array, as_float, validate_method +from colour.hints import ArrayLike, Literal, NDArrayFloat +from colour.utilities import as_float, as_float_array, validate_method __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/models/rgb/transfer_functions/itur_bt_2100.py b/colour/models/rgb/transfer_functions/itur_bt_2100.py index 36dc79fbde..e939cac4fa 100644 --- a/colour/models/rgb/transfer_functions/itur_bt_2100.py +++ b/colour/models/rgb/transfer_functions/itur_bt_2100.py @@ -59,11 +59,11 @@ from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.models.rgb.transfer_functions import ( eotf_BT1886, - eotf_ST2084, eotf_inverse_BT1886, + eotf_inverse_ST2084, + eotf_ST2084, oetf_ARIBSTDB67, oetf_BT709, - eotf_inverse_ST2084, oetf_inverse_ARIBSTDB67, oetf_inverse_BT709, ) diff --git a/colour/models/rgb/transfer_functions/itut_h_273.py b/colour/models/rgb/transfer_functions/itut_h_273.py index 653b999fff..ef6d2cbf58 100644 --- a/colour/models/rgb/transfer_functions/itut_h_273.py +++ b/colour/models/rgb/transfer_functions/itut_h_273.py @@ -29,8 +29,8 @@ from colour.algebra import spow from colour.models.rgb.transfer_functions import ( - eotf_inverse_DCDM, eotf_DCDM, + eotf_inverse_DCDM, eotf_inverse_sRGB, eotf_sRGB, ) diff --git a/colour/models/rgb/transfer_functions/log.py b/colour/models/rgb/transfer_functions/log.py index 57e18fc33b..d90f41fd5e 100644 --- a/colour/models/rgb/transfer_functions/log.py +++ b/colour/models/rgb/transfer_functions/log.py @@ -42,8 +42,8 @@ from colour.algebra import sdiv, sdiv_mode from colour.hints import ( ArrayLike, - NDArrayFloat, Literal, + NDArrayFloat, cast, ) from colour.utilities import ( diff --git a/colour/models/rgb/transfer_functions/red.py b/colour/models/rgb/transfer_functions/red.py index da93d8cc90..c0a857634b 100644 --- a/colour/models/rgb/transfer_functions/red.py +++ b/colour/models/rgb/transfer_functions/red.py @@ -38,10 +38,10 @@ import numpy as np -from colour.hints import ArrayLike, NDArrayFloat, Literal +from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.models.rgb.transfer_functions import ( - log_encoding_Cineon, log_decoding_Cineon, + log_encoding_Cineon, ) from colour.utilities import ( CanonicalMapping, diff --git a/colour/models/rgb/transfer_functions/st_2084.py b/colour/models/rgb/transfer_functions/st_2084.py index 6c1f77f7a9..e82710c1f3 100644 --- a/colour/models/rgb/transfer_functions/st_2084.py +++ b/colour/models/rgb/transfer_functions/st_2084.py @@ -26,7 +26,7 @@ from colour.algebra import spow from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import Structure, as_float_array, as_float +from colour.utilities import Structure, as_float, as_float_array __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/models/rgb/transfer_functions/tests/test__init__.py b/colour/models/rgb/transfer_functions/tests/test__init__.py index ec522e89dd..e17efcfa9b 100644 --- a/colour/models/rgb/transfer_functions/tests/test__init__.py +++ b/colour/models/rgb/transfer_functions/tests/test__init__.py @@ -3,22 +3,24 @@ :mod:`colour.models.rgb.transfer_functions.common` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( CCTF_DECODINGS, CCTF_ENCODINGS, - EOTFS, EOTF_INVERSES, + EOTFS, LOG_DECODINGS, LOG_ENCODINGS, - OETFS, OETF_INVERSES, - OOTFS, + OETFS, OOTF_INVERSES, - cctf_encoding, + OOTFS, cctf_decoding, + cctf_encoding, ) from colour.utilities import ColourUsageWarning @@ -100,7 +102,7 @@ def test_transfer_functions(self): "Filmic Pro 6", ) - decimals = {"D-Log": 1, "F-Log": 4, "L-Log": 4, "N-Log": 3} + tolerance = {"D-Log": 0.1, "F-Log": 5e-4, "L-Log": 5e-4, "N-Log": 5e-3} reciprocal_mappings = [ (LOG_ENCODINGS, LOG_DECODINGS), @@ -130,8 +132,10 @@ def test_transfer_functions(self): samples_e = CCTF_ENCODINGS[name](samples_r) samples_d = CCTF_DECODINGS[name](samples_e) - np.testing.assert_array_almost_equal( - samples_r, samples_d, decimal=decimals.get(name, 7) + np.testing.assert_allclose( + samples_r, + samples_d, + atol=tolerance.get(name, TOLERANCE_ABSOLUTE_TESTS), ) diff --git a/colour/models/rgb/transfer_functions/tests/test_aces.py b/colour/models/rgb/transfer_functions/tests/test_aces.py index cdc4a6fd2e..00d7138aa2 100644 --- a/colour/models/rgb/transfer_functions/tests/test_aces.py +++ b/colour/models/rgb/transfer_functions/tests/test_aces.py @@ -3,16 +3,18 @@ module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_ACESproxy, + log_decoding_ACEScc, + log_decoding_ACEScct, log_decoding_ACESproxy, log_encoding_ACEScc, - log_decoding_ACEScc, log_encoding_ACEScct, - log_decoding_ACEScct, + log_encoding_ACESproxy, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -45,20 +47,28 @@ def test_log_encoding_ACESproxy(self): log_encoding_ACESproxy` definition. """ - self.assertAlmostEqual( - log_encoding_ACESproxy(0.0), 0.062561094819159, places=7 + np.testing.assert_allclose( + log_encoding_ACESproxy(0.0), + 0.062561094819159, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ACESproxy(0.18), 0.416422287390029, places=7 + np.testing.assert_allclose( + log_encoding_ACESproxy(0.18), + 0.416422287390029, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ACESproxy(0.18, 12), 0.416361416361416, places=7 + np.testing.assert_allclose( + log_encoding_ACESproxy(0.18, 12), + 0.416361416361416, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ACESproxy(1.0), 0.537634408602151, places=7 + np.testing.assert_allclose( + log_encoding_ACESproxy(1.0), + 0.537634408602151, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(log_encoding_ACESproxy(0.18, out_int=True), 426) @@ -74,20 +84,26 @@ def test_n_dimensional_log_encoding_ACESproxy(self): lin_AP1 = np.tile(lin_AP1, 6) ACESproxy = np.tile(ACESproxy, 6) - np.testing.assert_array_almost_equal( - log_encoding_ACESproxy(lin_AP1), ACESproxy, decimal=7 + np.testing.assert_allclose( + log_encoding_ACESproxy(lin_AP1), + ACESproxy, + atol=TOLERANCE_ABSOLUTE_TESTS, ) lin_AP1 = np.reshape(lin_AP1, (2, 3)) ACESproxy = np.reshape(ACESproxy, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ACESproxy(lin_AP1), ACESproxy, decimal=7 + np.testing.assert_allclose( + log_encoding_ACESproxy(lin_AP1), + ACESproxy, + atol=TOLERANCE_ABSOLUTE_TESTS, ) lin_AP1 = np.reshape(lin_AP1, (2, 3, 1)) ACESproxy = np.reshape(ACESproxy, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ACESproxy(lin_AP1), ACESproxy, decimal=7 + np.testing.assert_allclose( + log_encoding_ACESproxy(lin_AP1), + ACESproxy, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_encoding_ACESproxy(self): @@ -102,10 +118,10 @@ def test_domain_range_scale_log_encoding_ACESproxy(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_ACESproxy(lin_AP1 * factor), ACESproxy * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -137,35 +153,30 @@ def test_log_decoding_ACESproxy(self): log_decoding_ACESproxy(0.062561094819159), 0.0, atol=0.01, - rtol=0.01, ) np.testing.assert_allclose( log_decoding_ACESproxy(0.416422287390029), 0.18, atol=0.01, - rtol=0.01, ) np.testing.assert_allclose( log_decoding_ACESproxy(0.416361416361416, 12), 0.18, atol=0.01, - rtol=0.01, ) np.testing.assert_allclose( log_decoding_ACESproxy(0.537634408602151), 1.0, atol=0.01, - rtol=0.01, ) np.testing.assert_allclose( log_decoding_ACESproxy(426, in_int=True), 0.18, atol=0.01, - rtol=0.01, ) def test_n_dimensional_log_decoding_ACESproxy(self): @@ -179,20 +190,26 @@ def test_n_dimensional_log_decoding_ACESproxy(self): ACESproxy = np.tile(ACESproxy, 6) lin_AP1 = np.tile(lin_AP1, 6) - np.testing.assert_array_almost_equal( - log_decoding_ACESproxy(ACESproxy), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACESproxy(ACESproxy), + lin_AP1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) ACESproxy = np.reshape(ACESproxy, (2, 3)) lin_AP1 = np.reshape(lin_AP1, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ACESproxy(ACESproxy), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACESproxy(ACESproxy), + lin_AP1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) ACESproxy = np.reshape(ACESproxy, (2, 3, 1)) lin_AP1 = np.reshape(lin_AP1, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ACESproxy(ACESproxy), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACESproxy(ACESproxy), + lin_AP1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_decoding_ACESproxy(self): @@ -207,10 +224,10 @@ def test_domain_range_scale_log_decoding_ACESproxy(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_ACESproxy(ACESproxy * factor), lin_AP1 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -237,16 +254,22 @@ def test_log_encoding_ACEScc(self): log_encoding_ACEScc` definition. """ - self.assertAlmostEqual( - log_encoding_ACEScc(0.0), -0.358447488584475, places=7 + np.testing.assert_allclose( + log_encoding_ACEScc(0.0), + -0.358447488584475, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ACEScc(0.18), 0.413588402492442, places=7 + np.testing.assert_allclose( + log_encoding_ACEScc(0.18), + 0.413588402492442, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ACEScc(1.0), 0.554794520547945, places=7 + np.testing.assert_allclose( + log_encoding_ACEScc(1.0), + 0.554794520547945, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_ACEScc(self): @@ -260,20 +283,20 @@ def test_n_dimensional_log_encoding_ACEScc(self): lin_AP1 = np.tile(lin_AP1, 6) ACEScc = np.tile(ACEScc, 6) - np.testing.assert_array_almost_equal( - log_encoding_ACEScc(lin_AP1), ACEScc, decimal=7 + np.testing.assert_allclose( + log_encoding_ACEScc(lin_AP1), ACEScc, atol=TOLERANCE_ABSOLUTE_TESTS ) lin_AP1 = np.reshape(lin_AP1, (2, 3)) ACEScc = np.reshape(ACEScc, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ACEScc(lin_AP1), ACEScc, decimal=7 + np.testing.assert_allclose( + log_encoding_ACEScc(lin_AP1), ACEScc, atol=TOLERANCE_ABSOLUTE_TESTS ) lin_AP1 = np.reshape(lin_AP1, (2, 3, 1)) ACEScc = np.reshape(ACEScc, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ACEScc(lin_AP1), ACEScc, decimal=7 + np.testing.assert_allclose( + log_encoding_ACEScc(lin_AP1), ACEScc, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_ACEScc(self): @@ -288,10 +311,10 @@ def test_domain_range_scale_log_encoding_ACEScc(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_ACEScc(lin_AP1 * factor), ACEScc * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -318,16 +341,22 @@ def test_log_decoding_ACEScc(self): log_decoding_ACEScc` definition. """ - self.assertAlmostEqual( - log_decoding_ACEScc(-0.358447488584475), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_ACEScc(-0.358447488584475), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ACEScc(0.413588402492442), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_ACEScc(0.413588402492442), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ACEScc(0.554794520547945), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_ACEScc(0.554794520547945), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_ACEScc(self): @@ -341,20 +370,20 @@ def test_n_dimensional_log_decoding_ACEScc(self): ACEScc = np.tile(ACEScc, 6) lin_AP1 = np.tile(lin_AP1, 6) - np.testing.assert_array_almost_equal( - log_decoding_ACEScc(ACEScc), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACEScc(ACEScc), lin_AP1, atol=TOLERANCE_ABSOLUTE_TESTS ) ACEScc = np.reshape(ACEScc, (2, 3)) lin_AP1 = np.reshape(lin_AP1, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ACEScc(ACEScc), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACEScc(ACEScc), lin_AP1, atol=TOLERANCE_ABSOLUTE_TESTS ) ACEScc = np.reshape(ACEScc, (2, 3, 1)) lin_AP1 = np.reshape(lin_AP1, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ACEScc(ACEScc), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACEScc(ACEScc), lin_AP1, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_ACEScc(self): @@ -369,10 +398,10 @@ def test_domain_range_scale_log_decoding_ACEScc(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_ACEScc(ACEScc * factor), lin_AP1 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -399,16 +428,22 @@ def test_log_encoding_ACEScct(self): log_encoding_ACEScct` definition. """ - self.assertAlmostEqual( - log_encoding_ACEScct(0.0), 0.072905534195835495, places=7 + np.testing.assert_allclose( + log_encoding_ACEScct(0.0), + 0.072905534195835495, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ACEScct(0.18), 0.413588402492442, places=7 + np.testing.assert_allclose( + log_encoding_ACEScct(0.18), + 0.413588402492442, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ACEScct(1.0), 0.554794520547945, places=7 + np.testing.assert_allclose( + log_encoding_ACEScct(1.0), + 0.554794520547945, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_ACEScct(self): @@ -422,20 +457,26 @@ def test_n_dimensional_log_encoding_ACEScct(self): lin_AP1 = np.tile(lin_AP1, 6) ACEScct = np.tile(ACEScct, 6) - np.testing.assert_array_almost_equal( - log_encoding_ACEScct(lin_AP1), ACEScct, decimal=7 + np.testing.assert_allclose( + log_encoding_ACEScct(lin_AP1), + ACEScct, + atol=TOLERANCE_ABSOLUTE_TESTS, ) lin_AP1 = np.reshape(lin_AP1, (2, 3)) ACEScct = np.reshape(ACEScct, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ACEScct(lin_AP1), ACEScct, decimal=7 + np.testing.assert_allclose( + log_encoding_ACEScct(lin_AP1), + ACEScct, + atol=TOLERANCE_ABSOLUTE_TESTS, ) lin_AP1 = np.reshape(lin_AP1, (2, 3, 1)) ACEScct = np.reshape(ACEScct, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ACEScct(lin_AP1), ACEScct, decimal=7 + np.testing.assert_allclose( + log_encoding_ACEScct(lin_AP1), + ACEScct, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_encoding_ACEScct(self): @@ -450,10 +491,10 @@ def test_domain_range_scale_log_encoding_ACEScct(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_ACEScct(lin_AP1 * factor), ACEScct * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_ACEScc_equivalency_log_encoding_ACEScct(self): @@ -466,8 +507,10 @@ def test_ACEScc_equivalency_log_encoding_ACEScct(self): """ equiv = np.linspace(0.0078125, 222.86094420380761, 100) - np.testing.assert_array_almost_equal( - log_encoding_ACEScct(equiv), log_encoding_ACEScc(equiv), decimal=7 + np.testing.assert_allclose( + log_encoding_ACEScct(equiv), + log_encoding_ACEScc(equiv), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -494,16 +537,22 @@ def test_log_decoding_ACEScct(self): log_decoding_ACEScct` definition. """ - self.assertAlmostEqual( - log_decoding_ACEScct(0.072905534195835495), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_ACEScct(0.072905534195835495), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ACEScct(0.41358840249244228), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_ACEScct(0.41358840249244228), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ACEScct(0.554794520547945), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_ACEScct(0.554794520547945), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_ACEScct(self): @@ -517,20 +566,26 @@ def test_n_dimensional_log_decoding_ACEScct(self): ACEScct = np.tile(ACEScct, 6) lin_AP1 = np.tile(lin_AP1, 6) - np.testing.assert_array_almost_equal( - log_decoding_ACEScct(ACEScct), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACEScct(ACEScct), + lin_AP1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) ACEScct = np.reshape(ACEScct, (2, 3)) lin_AP1 = np.reshape(lin_AP1, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ACEScct(ACEScct), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACEScct(ACEScct), + lin_AP1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) ACEScct = np.reshape(ACEScct, (2, 3, 1)) lin_AP1 = np.reshape(lin_AP1, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ACEScct(ACEScct), lin_AP1, decimal=7 + np.testing.assert_allclose( + log_decoding_ACEScct(ACEScct), + lin_AP1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_decoding_ACEScct(self): @@ -545,10 +600,10 @@ def test_domain_range_scale_log_decoding_ACEScct(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_ACEScct(ACEScc * factor), lin_AP1 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_ACEScc_equivalency_log_decoding_ACEScct(self): @@ -561,8 +616,10 @@ def test_ACEScc_equivalency_log_decoding_ACEScct(self): """ equiv = np.linspace(0.15525114155251146, 1.0, 100) - np.testing.assert_array_almost_equal( - log_decoding_ACEScct(equiv), log_decoding_ACEScc(equiv), decimal=7 + np.testing.assert_allclose( + log_decoding_ACEScct(equiv), + log_decoding_ACEScc(equiv), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_apple_log_profile.py b/colour/models/rgb/transfer_functions/tests/test_apple_log_profile.py new file mode 100644 index 0000000000..27d29587b3 --- /dev/null +++ b/colour/models/rgb/transfer_functions/tests/test_apple_log_profile.py @@ -0,0 +1,193 @@ +""" +Define the unit tests for the :mod:`colour.models.rgb.transfer_functions.\ +apple_log_profile` module. +""" + +import unittest + +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models.rgb.transfer_functions import ( + log_decoding_AppleLogProfile, + log_encoding_AppleLogProfile, +) +from colour.utilities import domain_range_scale, ignore_numpy_errors + +__author__ = "Colour Developers" +__copyright__ = "Copyright 2013 Colour Developers" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" +__maintainer__ = "Colour Developers" +__email__ = "colour-developers@colour-science.org" +__status__ = "Production" + +__all__ = [ + "TestLogEncoding_AppleLogProfile", + "TestLogDecoding_AppleLogProfile", +] + + +class TestLogEncoding_AppleLogProfile(unittest.TestCase): + """ + Define :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_encoding_AppleLogProfile` definition unit tests methods. + """ + + def test_log_encoding_AppleLogProfile(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_encoding_AppleLogProfile` definition. + """ + + self.assertAlmostEqual( + log_encoding_AppleLogProfile(0.0), 0.150476452300913, places=7 + ) + + self.assertAlmostEqual( + log_encoding_AppleLogProfile(0.18), 0.488272458526868, places=7 + ) + + self.assertAlmostEqual( + log_encoding_AppleLogProfile(1.0), 0.694552983055191, places=7 + ) + + def test_n_dimensional_log_encoding_DLog(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_encoding_AppleLogProfile` definition n-dimensional arrays support. + """ + + R = 0.18 + P = log_encoding_AppleLogProfile(R) + + R = np.tile(R, 6) + P = np.tile(P, 6) + np.testing.assert_allclose( + log_encoding_AppleLogProfile(R), P, atol=TOLERANCE_ABSOLUTE_TESTS + ) + + R = np.reshape(R, (2, 3)) + P = np.reshape(P, (2, 3)) + np.testing.assert_allclose( + log_encoding_AppleLogProfile(R), P, atol=TOLERANCE_ABSOLUTE_TESTS + ) + + R = np.reshape(R, (2, 3, 1)) + P = np.reshape(P, (2, 3, 1)) + np.testing.assert_allclose( + log_encoding_AppleLogProfile(R), P, atol=TOLERANCE_ABSOLUTE_TESTS + ) + + def test_domain_range_scale_log_encoding_DLog(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_encoding_AppleLogProfile` definition domain and range scale support. + """ + + R = 0.18 + P = log_encoding_AppleLogProfile(R) + + d_r = (("reference", 1), ("1", 1), ("100", 100)) + for scale, factor in d_r: + with domain_range_scale(scale): + np.testing.assert_allclose( + log_encoding_AppleLogProfile(R * factor), + P * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + @ignore_numpy_errors + def test_nan_log_encoding_DLog(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_encoding_AppleLogProfile` definition nan support. + """ + + log_encoding_AppleLogProfile( + np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) + ) + + +class TestLogDecoding_AppleLogProfile(unittest.TestCase): + """ + Define :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_decoding_AppleLogProfile` definition unit tests methods. + """ + + def test_log_decoding_AppleLogProfile(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_decoding_AppleLogProfile` definition. + """ + + self.assertAlmostEqual( + log_decoding_AppleLogProfile(0.150476452300913), 0.0, places=7 + ) + + self.assertAlmostEqual( + log_decoding_AppleLogProfile(0.488272458526868), 0.18, places=6 + ) + + self.assertAlmostEqual( + log_decoding_AppleLogProfile(0.694552983055191), 1.0, places=6 + ) + + def test_n_dimensional_log_decoding_DLog(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_decoding_AppleLogProfile` definition n-dimensional arrays support. + """ + + P = 0.398764556189331 + R = log_decoding_AppleLogProfile(P) + + P = np.tile(P, 6) + R = np.tile(R, 6) + np.testing.assert_allclose( + log_decoding_AppleLogProfile(P), R, atol=TOLERANCE_ABSOLUTE_TESTS + ) + + P = np.reshape(P, (2, 3)) + R = np.reshape(R, (2, 3)) + np.testing.assert_allclose( + log_decoding_AppleLogProfile(P), R, atol=TOLERANCE_ABSOLUTE_TESTS + ) + + P = np.reshape(P, (2, 3, 1)) + R = np.reshape(R, (2, 3, 1)) + np.testing.assert_allclose( + log_decoding_AppleLogProfile(P), R, atol=TOLERANCE_ABSOLUTE_TESTS + ) + + def test_domain_range_scale_log_decoding_DLog(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_decoding_AppleLogProfile` definition domain and range scale support. + """ + + P = 0.398764556189331 + R = log_decoding_AppleLogProfile(P) + + d_r = (("reference", 1), ("1", 1), ("100", 100)) + for scale, factor in d_r: + with domain_range_scale(scale): + np.testing.assert_allclose( + log_decoding_AppleLogProfile(P * factor), + R * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) + + @ignore_numpy_errors + def test_nan_log_decoding_DLog(self): + """ + Test :func:`colour.models.rgb.transfer_functions.apple_log_profile.\ +log_decoding_AppleLogProfile` definition nan support. + """ + + log_decoding_AppleLogProfile( + np.array([-1.0, 0.0, 1.0, -np.inf, np.inf, np.nan]) + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/colour/models/rgb/transfer_functions/tests/test_arib_std_b67.py b/colour/models/rgb/transfer_functions/tests/test_arib_std_b67.py index 94453c3e86..0a0e173756 100644 --- a/colour/models/rgb/transfer_functions/tests/test_arib_std_b67.py +++ b/colour/models/rgb/transfer_functions/tests/test_arib_std_b67.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.arib_std_b67` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( oetf_ARIBSTDB67, oetf_inverse_ARIBSTDB67, @@ -37,18 +39,28 @@ def test_oetf_ARIBSTDB67(self): oetf_ARIBSTDB67` definition. """ - self.assertAlmostEqual(oetf_ARIBSTDB67(-0.25), -0.25, places=7) + np.testing.assert_allclose( + oetf_ARIBSTDB67(-0.25), -0.25, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_ARIBSTDB67(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_ARIBSTDB67(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_ARIBSTDB67(0.18), 0.212132034355964, places=7 + np.testing.assert_allclose( + oetf_ARIBSTDB67(0.18), + 0.212132034355964, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_ARIBSTDB67(1.0), 0.5, places=7) + np.testing.assert_allclose( + oetf_ARIBSTDB67(1.0), 0.5, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_ARIBSTDB67(64.0), 1.302858098046995, places=7 + np.testing.assert_allclose( + oetf_ARIBSTDB67(64.0), + 1.302858098046995, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_ARIBSTDB67(self): @@ -62,20 +74,20 @@ def test_n_dimensional_oetf_ARIBSTDB67(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - oetf_ARIBSTDB67(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_ARIBSTDB67(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_ARIBSTDB67(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_ARIBSTDB67(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_ARIBSTDB67(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_ARIBSTDB67(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_ARIBSTDB67(self): @@ -90,8 +102,10 @@ def test_domain_range_scale_oetf_ARIBSTDB67(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_ARIBSTDB67(E * factor), E_p * factor, decimal=7 + np.testing.assert_allclose( + oetf_ARIBSTDB67(E * factor), + E_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -116,18 +130,30 @@ def test_oetf_inverse_ARIBSTDB67(self): oetf_inverse_ARIBSTDB67` definition. """ - self.assertAlmostEqual(oetf_inverse_ARIBSTDB67(-0.25), -0.25, places=7) + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(-0.25), + -0.25, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - self.assertAlmostEqual(oetf_inverse_ARIBSTDB67(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_ARIBSTDB67(0.212132034355964), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(0.212132034355964), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_ARIBSTDB67(0.5), 1.0, places=7) + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(0.5), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_ARIBSTDB67(1.302858098046995), 64.0, places=7 + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(1.302858098046995), + 64.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_inverse_ARIBSTDB67(self): @@ -141,20 +167,20 @@ def test_n_dimensional_oetf_inverse_ARIBSTDB67(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_ARIBSTDB67(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_ARIBSTDB67(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_ARIBSTDB67(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_ARIBSTDB67(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_ARIBSTDB67(self): @@ -169,10 +195,10 @@ def test_domain_range_scale_oetf_inverse_ARIBSTDB67(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( oetf_inverse_ARIBSTDB67(E_p * factor), E * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_arri.py b/colour/models/rgb/transfer_functions/tests/test_arri.py index 084d942403..cbb02b119d 100644 --- a/colour/models/rgb/transfer_functions/tests/test_arri.py +++ b/colour/models/rgb/transfer_functions/tests/test_arri.py @@ -3,14 +3,16 @@ :mod:`colour.models.rgb.transfer_functions.arri` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_ARRILogC3, log_decoding_ARRILogC3, - log_encoding_ARRILogC4, log_decoding_ARRILogC4, + log_encoding_ARRILogC3, + log_encoding_ARRILogC4, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -41,16 +43,22 @@ def test_log_encoding_ARRILogC3(self): log_encoding_ARRILogC3` definition. """ - self.assertAlmostEqual( - log_encoding_ARRILogC3(0.0), 0.092809000000000, places=7 + np.testing.assert_allclose( + log_encoding_ARRILogC3(0.0), + 0.092809000000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ARRILogC3(0.18), 0.391006832034084, places=7 + np.testing.assert_allclose( + log_encoding_ARRILogC3(0.18), + 0.391006832034084, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ARRILogC3(1.0), 0.570631558120417, places=7 + np.testing.assert_allclose( + log_encoding_ARRILogC3(1.0), + 0.570631558120417, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_ARRILogC3(self): @@ -64,20 +72,20 @@ def test_n_dimensional_log_encoding_ARRILogC3(self): x = np.tile(x, 6) t = np.tile(t, 6) - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC3(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC3(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) t = np.reshape(t, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC3(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC3(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) t = np.reshape(t, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC3(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC3(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_ARRILogC3(self): @@ -92,8 +100,10 @@ def test_domain_range_scale_log_encoding_ARRILogC3(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC3(x * factor), t * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC3(x * factor), + t * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -120,14 +130,22 @@ def test_log_decoding_ARRILogC3(self): log_decoding_ARRILogC3` definition. """ - self.assertAlmostEqual(log_decoding_ARRILogC3(0.092809), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_ARRILogC3(0.092809), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - self.assertAlmostEqual( - log_decoding_ARRILogC3(0.391006832034084), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_ARRILogC3(0.391006832034084), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ARRILogC3(0.570631558120417), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_ARRILogC3(0.570631558120417), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_ARRILogC3(self): @@ -141,20 +159,20 @@ def test_n_dimensional_log_decoding_ARRILogC3(self): t = np.tile(t, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC3(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC3(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) t = np.reshape(t, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC3(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC3(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) t = np.reshape(t, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC3(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC3(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_ARRILogC3(self): @@ -169,8 +187,10 @@ def test_domain_range_scale_log_decoding_ARRILogC3(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC3(t * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC3(t * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -197,16 +217,22 @@ def test_log_encoding_ARRILogC4(self): log_encoding_ARRILogC4` definition. """ - self.assertAlmostEqual( - log_encoding_ARRILogC4(0.0), 0.092864125122190, places=7 + np.testing.assert_allclose( + log_encoding_ARRILogC4(0.0), + 0.092864125122190, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ARRILogC4(0.18), 0.278395836548265, places=7 + np.testing.assert_allclose( + log_encoding_ARRILogC4(0.18), + 0.278395836548265, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ARRILogC4(1.0), 0.427519364835306, places=7 + np.testing.assert_allclose( + log_encoding_ARRILogC4(1.0), + 0.427519364835306, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_ARRILogC4(self): @@ -220,20 +246,20 @@ def test_n_dimensional_log_encoding_ARRILogC4(self): x = np.tile(x, 6) t = np.tile(t, 6) - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC4(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC4(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) t = np.reshape(t, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC4(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC4(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) t = np.reshape(t, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC4(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC4(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_ARRILogC4(self): @@ -248,8 +274,10 @@ def test_domain_range_scale_log_encoding_ARRILogC4(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_ARRILogC4(x * factor), t * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_ARRILogC4(x * factor), + t * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -276,16 +304,22 @@ def test_log_decoding_ARRILogC4(self): log_decoding_ARRILogC4` definition. """ - self.assertAlmostEqual( - log_decoding_ARRILogC4(0.092864125122190), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_ARRILogC4(0.092864125122190), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ARRILogC4(0.278395836548265), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_ARRILogC4(0.278395836548265), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ARRILogC4(0.427519364835306), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_ARRILogC4(0.427519364835306), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_ARRILogC4(self): @@ -299,20 +333,20 @@ def test_n_dimensional_log_decoding_ARRILogC4(self): t = np.tile(t, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC4(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC4(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) t = np.reshape(t, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC4(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC4(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) t = np.reshape(t, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC4(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC4(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_ARRILogC4(self): @@ -327,8 +361,10 @@ def test_domain_range_scale_log_decoding_ARRILogC4(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_ARRILogC4(t * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_ARRILogC4(t * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_blackmagic_design.py b/colour/models/rgb/transfer_functions/tests/test_blackmagic_design.py index ed7d430c94..a0ff544456 100644 --- a/colour/models/rgb/transfer_functions/tests/test_blackmagic_design.py +++ b/colour/models/rgb/transfer_functions/tests/test_blackmagic_design.py @@ -3,9 +3,11 @@ blackmagic_design` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( oetf_BlackmagicFilmGeneration5, oetf_inverse_BlackmagicFilmGeneration5, @@ -37,24 +39,34 @@ def test_oetf_BlackmagicFilmGeneration5(self): blackmagic_design.oetf_BlackmagicFilmGeneration5` definition. """ - self.assertAlmostEqual( - oetf_BlackmagicFilmGeneration5(0.0), 0.092465753424658, places=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(0.0), + 0.092465753424658, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_BlackmagicFilmGeneration5(0.18), 0.383561643835617, places=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(0.18), + 0.383561643835617, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_BlackmagicFilmGeneration5(1.0), 0.530489624957305, places=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(1.0), + 0.530489624957305, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_BlackmagicFilmGeneration5(100.0), 0.930339851899973, places=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(100.0), + 0.930339851899973, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_BlackmagicFilmGeneration5(222.86), 0.999999631713769, places=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(222.86), + 0.999999631713769, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_BlackmagicFilmGeneration5(self): @@ -69,20 +81,20 @@ def test_n_dimensional_oetf_BlackmagicFilmGeneration5(self): L = np.tile(L, 6) V = np.tile(V, 6) - np.testing.assert_array_almost_equal( - oetf_BlackmagicFilmGeneration5(L), V, decimal=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3)) V = np.reshape(V, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_BlackmagicFilmGeneration5(L), V, decimal=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3, 1)) V = np.reshape(V, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_BlackmagicFilmGeneration5(L), V, decimal=7 + np.testing.assert_allclose( + oetf_BlackmagicFilmGeneration5(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_BlackmagicFilmGeneration5(self): @@ -98,10 +110,10 @@ def test_domain_range_scale_oetf_BlackmagicFilmGeneration5(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( oetf_BlackmagicFilmGeneration5(L * factor), V * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -129,34 +141,34 @@ def test_oetf_inverse_BlackmagicFilmGeneration5(self): blackmagic_design.oetf_inverse_BlackmagicFilmGeneration5` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( oetf_inverse_BlackmagicFilmGeneration5(0.092465753424658), 0.0, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( oetf_inverse_BlackmagicFilmGeneration5(0.383561643835617), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( oetf_inverse_BlackmagicFilmGeneration5(0.530489624957305), 1.0, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( oetf_inverse_BlackmagicFilmGeneration5(0.930339851899973), 100.0, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( oetf_inverse_BlackmagicFilmGeneration5(0.999999631713769), 222.86, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_inverse_BlackmagicFilmGeneration5(self): @@ -171,20 +183,26 @@ def test_n_dimensional_oetf_inverse_BlackmagicFilmGeneration5(self): V = np.tile(V, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_BlackmagicFilmGeneration5(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BlackmagicFilmGeneration5(V), + L, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V = np.reshape(V, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_BlackmagicFilmGeneration5(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BlackmagicFilmGeneration5(V), + L, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V = np.reshape(V, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_BlackmagicFilmGeneration5(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BlackmagicFilmGeneration5(V), + L, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_oetf_inverse_BlackmagicFilmGeneration5(self): @@ -200,10 +218,10 @@ def test_domain_range_scale_oetf_inverse_BlackmagicFilmGeneration5(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( oetf_inverse_BlackmagicFilmGeneration5(V * factor), L * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_canon.py b/colour/models/rgb/transfer_functions/tests/test_canon.py index ac256dd385..c382665b79 100644 --- a/colour/models/rgb/transfer_functions/tests/test_canon.py +++ b/colour/models/rgb/transfer_functions/tests/test_canon.py @@ -3,24 +3,25 @@ :mod:`colour.models.rgb.transfer_functions.canon` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions.canon import ( - log_encoding_CanonLog_v1, + log_decoding_CanonLog2_v1, + log_decoding_CanonLog2_v1_2, + log_decoding_CanonLog3_v1, + log_decoding_CanonLog3_v1_2, log_decoding_CanonLog_v1, - log_encoding_CanonLog_v1_2, log_decoding_CanonLog_v1_2, log_encoding_CanonLog2_v1, - log_decoding_CanonLog2_v1, log_encoding_CanonLog2_v1_2, - log_decoding_CanonLog2_v1_2, log_encoding_CanonLog3_v1, - log_decoding_CanonLog3_v1, log_encoding_CanonLog3_v1_2, - log_decoding_CanonLog3_v1_2, + log_encoding_CanonLog_v1, + log_encoding_CanonLog_v1_2, ) - from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -58,36 +59,46 @@ def test_log_encoding_CanonLog_v1(self): log_encoding_CanonLog_v1` definition. """ - self.assertAlmostEqual( - log_encoding_CanonLog_v1(-0.1), -0.023560122781997, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(-0.1), + -0.023560122781997, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1(0.0), 0.125122480156403, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(0.0), + 0.125122480156403, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1(0.18), 0.343389651726069, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(0.18), + 0.343389651726069, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1(0.18, 12), 0.343138084215647, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(0.18, 12), + 0.343138084215647, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog_v1(0.18, 10, False), 0.327953896935809, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog_v1(0.18, 10, False, False), 0.312012855550395, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1(1.0), 0.618775485598649, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(1.0), + 0.618775485598649, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_CanonLog_v1(self): @@ -101,20 +112,20 @@ def test_n_dimensional_log_encoding_CanonLog_v1(self): x = np.tile(x, 6) clog = np.tile(clog, 6) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog_v1(x), clog, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(x), clog, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) clog = np.reshape(clog, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog_v1(x), clog, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(x), clog, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) clog = np.reshape(clog, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog_v1(x), clog, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1(x), clog, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_CanonLog_v1(self): @@ -129,10 +140,10 @@ def test_domain_range_scale_log_encoding_CanonLog_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_CanonLog_v1(x * factor), clog * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -159,36 +170,46 @@ def test_log_decoding_CanonLog_v1(self): log_decoding_CanonLog_v1` definition. """ - self.assertAlmostEqual( - log_decoding_CanonLog_v1(-0.023560122781997), -0.1, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(-0.023560122781997), + -0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1(0.125122480156403), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(0.125122480156403), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1(0.343389651726069), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(0.343389651726069), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1(0.343138084215647, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(0.343138084215647, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog_v1(0.327953896935809, 10, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog_v1(0.312012855550395, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1(0.618775485598649), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(0.618775485598649), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_CanonLog_v1(self): @@ -202,20 +223,20 @@ def test_n_dimensional_log_decoding_CanonLog_v1(self): clog = np.tile(clog, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog_v1(clog), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(clog), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog = np.reshape(clog, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog_v1(clog), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(clog), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog = np.reshape(clog, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog_v1(clog), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1(clog), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_CanonLog_v1(self): @@ -230,10 +251,10 @@ def test_domain_range_scale_log_decoding_CanonLog_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_CanonLog_v1(clog * factor), x * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -260,36 +281,46 @@ def test_log_encoding_CanonLog_v1_2(self): log_encoding_CanonLog_v1_2` definition. """ - self.assertAlmostEqual( - log_encoding_CanonLog_v1_2(-0.1), -0.023560121389098, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(-0.1), + -0.023560121389098, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1_2(0.0), 0.125122480000000, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(0.0), + 0.125122480000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1_2(0.18), 0.343389649295280, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(0.18), + 0.343389649295280, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1_2(0.18, 12), 0.343389649295281, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(0.18, 12), + 0.343389649295281, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog_v1_2(0.18, 10, False), 0.327953894097114, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog_v1_2(0.18, 10, False, False), 0.312012852877809, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog_v1_2(1.0), 0.618775480298287, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(1.0), + 0.618775480298287, + atol=TOLERANCE_ABSOLUTE_TESTS, ) samples = np.linspace(0, 1, 10000) @@ -297,15 +328,13 @@ def test_log_encoding_CanonLog_v1_2(self): np.testing.assert_allclose( log_encoding_CanonLog_v1(samples), log_encoding_CanonLog_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_encoding_CanonLog_v1(samples), log_encoding_CanonLog_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -313,14 +342,12 @@ def test_log_encoding_CanonLog_v1_2(self): log_encoding_CanonLog_v1_2( samples, out_normalised_code_value=False ), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_encoding_CanonLog_v1(samples, in_reflection=False), log_encoding_CanonLog_v1_2(samples, in_reflection=False), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_CanonLog_v1_2(self): @@ -334,20 +361,20 @@ def test_n_dimensional_log_encoding_CanonLog_v1_2(self): x = np.tile(x, 6) clog = np.tile(clog, 6) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog_v1_2(x), clog, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(x), clog, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) clog = np.reshape(clog, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog_v1_2(x), clog, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(x), clog, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) clog = np.reshape(clog, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog_v1_2(x), clog, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog_v1_2(x), clog, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_CanonLog_v1_2(self): @@ -362,10 +389,10 @@ def test_domain_range_scale_log_encoding_CanonLog_v1_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_CanonLog_v1_2(x * factor), clog * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -392,36 +419,46 @@ def test_log_decoding_CanonLog_v1_2(self): log_decoding_CanonLog_v1_2` definition. """ - self.assertAlmostEqual( - log_decoding_CanonLog_v1_2(-0.023560121389098), -0.1, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(-0.023560121389098), + -0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1_2(0.125122480000000), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(0.125122480000000), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1_2(0.343389649295280), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(0.343389649295280), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1_2(0.343389649295281, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(0.343389649295281, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog_v1_2(0.327953894097114, 10, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog_v1_2(0.312012852877809, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog_v1_2(0.618775480298287), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(0.618775480298287), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) samples = np.linspace(0, 1, 10000) @@ -429,15 +466,13 @@ def test_log_decoding_CanonLog_v1_2(self): np.testing.assert_allclose( log_decoding_CanonLog_v1(samples), log_decoding_CanonLog_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_decoding_CanonLog_v1(samples), log_decoding_CanonLog_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -445,14 +480,12 @@ def test_log_decoding_CanonLog_v1_2(self): log_decoding_CanonLog_v1_2( samples, in_normalised_code_value=False ), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_decoding_CanonLog_v1(samples, out_reflection=False), log_decoding_CanonLog_v1_2(samples, out_reflection=False), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_CanonLog_v1_2(self): @@ -466,20 +499,20 @@ def test_n_dimensional_log_decoding_CanonLog_v1_2(self): clog = np.tile(clog, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog_v1_2(clog), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(clog), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog = np.reshape(clog, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog_v1_2(clog), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(clog), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog = np.reshape(clog, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog_v1_2(clog), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog_v1_2(clog), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_CanonLog_v1_2(self): @@ -494,10 +527,10 @@ def test_domain_range_scale_log_decoding_CanonLog_v1_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_CanonLog_v1_2(clog * factor), x * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -524,36 +557,46 @@ def test_log_encoding_CanonLog2_v1(self): log_encoding_CanonLog2_v1` definition. """ - self.assertAlmostEqual( - log_encoding_CanonLog2_v1(-0.1), -0.155370131996824, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(-0.1), + -0.155370131996824, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1(0.0), 0.092864125247312, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(0.0), + 0.092864125247312, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1(0.18), 0.398254694983167, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(0.18), + 0.398254694983167, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1(0.18, 12), 0.397962933301861, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(0.18, 12), + 0.397962933301861, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog2_v1(0.18, 10, False), 0.392025745397009, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog2_v1(0.18, 10, False, False), 0.379864582222983, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1(1.0), 0.573229282897641, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(1.0), + 0.573229282897641, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_CanonLog2_v1(self): @@ -567,20 +610,20 @@ def test_n_dimensional_log_encoding_CanonLog2_v1(self): x = np.tile(x, 6) clog2 = np.tile(clog2, 6) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog2_v1(x), clog2, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(x), clog2, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) clog2 = np.reshape(clog2, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog2_v1(x), clog2, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(x), clog2, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) clog2 = np.reshape(clog2, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog2_v1(x), clog2, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1(x), clog2, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_CanonLog2_v1(self): @@ -595,10 +638,10 @@ def test_domain_range_scale_log_encoding_CanonLog2_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_CanonLog2_v1(x * factor), clog2 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -625,36 +668,46 @@ def test_log_decoding_CanonLog2_v1(self): log_decoding_CanonLog2_v1` definition. """ - self.assertAlmostEqual( - log_decoding_CanonLog2_v1(-0.155370131996824), -0.1, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(-0.155370131996824), + -0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1(0.092864125247312), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(0.092864125247312), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1(0.398254694983167), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(0.398254694983167), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1(0.397962933301861, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(0.397962933301861, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog2_v1(0.392025745397009, 10, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog2_v1(0.379864582222983, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1(0.573229282897641), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(0.573229282897641), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_CanonLog2_v1(self): @@ -668,20 +721,20 @@ def test_n_dimensional_log_decoding_CanonLog2_v1(self): clog2 = np.tile(clog2, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog2_v1(clog2), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(clog2), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog2 = np.reshape(clog2, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog2_v1(clog2), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(clog2), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog2 = np.reshape(clog2, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog2_v1(clog2), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1(clog2), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_CanonLog2_v1(self): @@ -696,10 +749,10 @@ def test_domain_range_scale_log_decoding_CanonLog2_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_CanonLog2_v1(clog * factor), x * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -726,36 +779,46 @@ def test_log_encoding_CanonLog2_v1_2(self): log_encoding_CanonLog2_v1_2` definition. """ - self.assertAlmostEqual( - log_encoding_CanonLog2_v1_2(-0.1), -0.155370130476722, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(-0.1), + -0.155370130476722, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1_2(0.0), 0.092864125000000, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(0.0), + 0.092864125000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1_2(0.18), 0.398254692561492, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(0.18), + 0.398254692561492, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1_2(0.18, 12), 0.398254692561492, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(0.18, 12), + 0.398254692561492, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog2_v1_2(0.18, 10, False), 0.392025742568957, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog2_v1_2(0.18, 10, False, False), 0.379864579481518, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog2_v1_2(1.0), 0.573229279230156, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(1.0), + 0.573229279230156, + atol=TOLERANCE_ABSOLUTE_TESTS, ) samples = np.linspace(0, 1, 10000) @@ -763,15 +826,13 @@ def test_log_encoding_CanonLog2_v1_2(self): np.testing.assert_allclose( log_encoding_CanonLog2_v1(samples), log_encoding_CanonLog2_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_encoding_CanonLog2_v1(samples), log_encoding_CanonLog2_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -781,14 +842,12 @@ def test_log_encoding_CanonLog2_v1_2(self): log_encoding_CanonLog2_v1_2( samples, out_normalised_code_value=False ), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_encoding_CanonLog2_v1(samples, in_reflection=False), log_encoding_CanonLog2_v1_2(samples, in_reflection=False), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_CanonLog2_v1_2(self): @@ -802,20 +861,26 @@ def test_n_dimensional_log_encoding_CanonLog2_v1_2(self): x = np.tile(x, 6) clog2 = np.tile(clog2, 6) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog2_v1_2(x), clog2, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(x), + clog2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) x = np.reshape(x, (2, 3)) clog2 = np.reshape(clog2, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog2_v1_2(x), clog2, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(x), + clog2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) x = np.reshape(x, (2, 3, 1)) clog2 = np.reshape(clog2, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog2_v1_2(x), clog2, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog2_v1_2(x), + clog2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_encoding_CanonLog2_v1_2(self): @@ -830,10 +895,10 @@ def test_domain_range_scale_log_encoding_CanonLog2_v1_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_CanonLog2_v1_2(x * factor), clog2 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -860,36 +925,46 @@ def test_log_decoding_CanonLog2_v1_2(self): log_decoding_CanonLog2_v1_2` definition. """ - self.assertAlmostEqual( - log_decoding_CanonLog2_v1_2(-0.155370130476722), -0.1, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(-0.155370130476722), + -0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1_2(0.092864125000000), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(0.092864125000000), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1_2(0.398254692561492), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(0.398254692561492), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1_2(0.398254692561492, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(0.398254692561492, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog2_v1_2(0.392025742568957, 10, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog2_v1_2(0.379864579481518, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog2_v1_2(0.573229279230156), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(0.573229279230156), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) samples = np.linspace(0, 1, 10000) @@ -897,15 +972,13 @@ def test_log_decoding_CanonLog2_v1_2(self): np.testing.assert_allclose( log_decoding_CanonLog_v1(samples), log_decoding_CanonLog_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_decoding_CanonLog_v1(samples), log_decoding_CanonLog_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -913,14 +986,12 @@ def test_log_decoding_CanonLog2_v1_2(self): log_decoding_CanonLog_v1_2( samples, in_normalised_code_value=False ), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_decoding_CanonLog_v1(samples, out_reflection=False), log_decoding_CanonLog_v1_2(samples, out_reflection=False), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_CanonLog2_v1_2(self): @@ -934,20 +1005,26 @@ def test_n_dimensional_log_decoding_CanonLog2_v1_2(self): clog2 = np.tile(clog2, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog2_v1_2(clog2), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(clog2), + x, + atol=TOLERANCE_ABSOLUTE_TESTS, ) clog2 = np.reshape(clog2, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog2_v1_2(clog2), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(clog2), + x, + atol=TOLERANCE_ABSOLUTE_TESTS, ) clog2 = np.reshape(clog2, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog2_v1_2(clog2), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog2_v1_2(clog2), + x, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_decoding_CanonLog2_v1_2(self): @@ -962,10 +1039,10 @@ def test_domain_range_scale_log_decoding_CanonLog2_v1_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_CanonLog2_v1_2(clog * factor), x * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -992,36 +1069,46 @@ def test_log_encoding_CanonLog3_v1(self): log_encoding_CanonLog3_v1` definition. """ - self.assertAlmostEqual( - log_encoding_CanonLog3_v1(-0.1), -0.028494506076432, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(-0.1), + -0.028494506076432, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1(0.0), 0.125122189869013, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(0.0), + 0.125122189869013, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1(0.18), 0.343389369388687, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(0.18), + 0.343389369388687, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1(0.18, 12), 0.343137802085105, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(0.18, 12), + 0.343137802085105, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog3_v1(0.18, 10, False), 0.327953567219893, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog3_v1(0.18, 10, False, False), 0.313436005886328, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1(1.0), 0.580277796238604, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(1.0), + 0.580277796238604, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_CanonLog3_v1(self): @@ -1035,20 +1122,20 @@ def test_n_dimensional_log_encoding_CanonLog3_v1(self): x = np.tile(x, 6) clog3 = np.tile(clog3, 6) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog3_v1(x), clog3, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(x), clog3, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) clog3 = np.reshape(clog3, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog3_v1(x), clog3, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(x), clog3, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) clog3 = np.reshape(clog3, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog3_v1(x), clog3, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1(x), clog3, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_CanonLog3_v1(self): @@ -1063,10 +1150,10 @@ def test_domain_range_scale_log_encoding_CanonLog3_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_CanonLog3_v1(x * factor), clog3 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1093,36 +1180,46 @@ def test_log_decoding_CanonLog3_v1(self): log_decoding_CanonLog3_v1` definition. """ - self.assertAlmostEqual( - log_decoding_CanonLog3_v1(-0.028494506076432), -0.1, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(-0.028494506076432), + -0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1(0.125122189869013), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(0.125122189869013), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1(0.343389369388687), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(0.343389369388687), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1(0.343137802085105, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(0.343137802085105, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog3_v1(0.327953567219893, 10, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog3_v1(0.313436005886328, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1(0.580277796238604), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(0.580277796238604), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_CanonLog3_v1(self): @@ -1136,20 +1233,20 @@ def test_n_dimensional_log_decoding_CanonLog3_v1(self): clog3 = np.tile(clog3, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog3_v1(clog3), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(clog3), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog3 = np.reshape(clog3, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog3_v1(clog3), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(clog3), x, atol=TOLERANCE_ABSOLUTE_TESTS ) clog3 = np.reshape(clog3, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog3_v1(clog3), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1(clog3), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_CanonLog3_v1(self): @@ -1164,10 +1261,10 @@ def test_domain_range_scale_log_decoding_CanonLog3_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_CanonLog3_v1(clog * factor), x * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1194,36 +1291,46 @@ def test_log_encoding_CanonLog3_v1_2(self): log_encoding_CanonLog3_v1_2` definition. """ - self.assertAlmostEqual( - log_encoding_CanonLog3_v1_2(-0.1), -0.028494507620494, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(-0.1), + -0.028494507620494, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1_2(0.0), 0.125122189999999, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(0.0), + 0.125122189999999, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1_2(0.18), 0.343389370373936, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(0.18), + 0.343389370373936, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1_2(0.18, 12), 0.343389370373936, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(0.18, 12), + 0.343389370373936, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog3_v1_2(0.18, 10, False), 0.327953568370475, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_CanonLog3_v1_2(0.18, 10, False, False), 0.313436007221221, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_CanonLog3_v1_2(1.0), 0.580277794216371, places=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(1.0), + 0.580277794216371, + atol=TOLERANCE_ABSOLUTE_TESTS, ) samples = np.linspace(0, 1, 10000) @@ -1231,15 +1338,13 @@ def test_log_encoding_CanonLog3_v1_2(self): np.testing.assert_allclose( log_encoding_CanonLog3_v1(samples), log_encoding_CanonLog3_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_encoding_CanonLog3_v1(samples), log_encoding_CanonLog3_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -1249,14 +1354,12 @@ def test_log_encoding_CanonLog3_v1_2(self): log_encoding_CanonLog3_v1_2( samples, out_normalised_code_value=False ), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_encoding_CanonLog3_v1(samples, in_reflection=False), log_encoding_CanonLog3_v1_2(samples, in_reflection=False), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_CanonLog3_v1_2(self): @@ -1270,20 +1373,26 @@ def test_n_dimensional_log_encoding_CanonLog3_v1_2(self): x = np.tile(x, 6) clog3 = np.tile(clog3, 6) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog3_v1_2(x), clog3, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(x), + clog3, + atol=TOLERANCE_ABSOLUTE_TESTS, ) x = np.reshape(x, (2, 3)) clog3 = np.reshape(clog3, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog3_v1_2(x), clog3, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(x), + clog3, + atol=TOLERANCE_ABSOLUTE_TESTS, ) x = np.reshape(x, (2, 3, 1)) clog3 = np.reshape(clog3, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_CanonLog3_v1_2(x), clog3, decimal=7 + np.testing.assert_allclose( + log_encoding_CanonLog3_v1_2(x), + clog3, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_encoding_CanonLog3_v1_2(self): @@ -1298,10 +1407,10 @@ def test_domain_range_scale_log_encoding_CanonLog3_v1_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_CanonLog3_v1_2(x * factor), clog3 * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1328,36 +1437,46 @@ def test_log_decoding_CanonLog3_v1_2(self): log_decoding_CanonLog3_v1_2` definition. """ - self.assertAlmostEqual( - log_decoding_CanonLog3_v1_2(-0.028494507620494), -0.1, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(-0.028494507620494), + -0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1_2(0.125122189999999), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(0.125122189999999), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1_2(0.343389370373936), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(0.343389370373936), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1_2(0.343389370373936, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(0.343389370373936, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog3_v1_2(0.327953568370475, 10, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_CanonLog3_v1_2(0.313436007221221, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_CanonLog3_v1_2(0.580277794216371), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(0.580277794216371), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) samples = np.linspace(0, 1, 10000) @@ -1365,15 +1484,13 @@ def test_log_decoding_CanonLog3_v1_2(self): np.testing.assert_allclose( log_decoding_CanonLog3_v1(samples), log_decoding_CanonLog3_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_decoding_CanonLog3_v1(samples), log_decoding_CanonLog3_v1_2(samples), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -1381,14 +1498,12 @@ def test_log_decoding_CanonLog3_v1_2(self): log_decoding_CanonLog3_v1_2( samples, in_normalised_code_value=False ), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_decoding_CanonLog3_v1(samples, out_reflection=False), log_decoding_CanonLog3_v1_2(samples, out_reflection=False), - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_CanonLog3_v1_2(self): @@ -1402,20 +1517,26 @@ def test_n_dimensional_log_decoding_CanonLog3_v1_2(self): clog3 = np.tile(clog3, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog3_v1_2(clog3), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(clog3), + x, + atol=TOLERANCE_ABSOLUTE_TESTS, ) clog3 = np.reshape(clog3, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog3_v1_2(clog3), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(clog3), + x, + atol=TOLERANCE_ABSOLUTE_TESTS, ) clog3 = np.reshape(clog3, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_CanonLog3_v1_2(clog3), x, decimal=7 + np.testing.assert_allclose( + log_decoding_CanonLog3_v1_2(clog3), + x, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_log_decoding_CanonLog3_v1_2(self): @@ -1430,10 +1551,10 @@ def test_domain_range_scale_log_decoding_CanonLog3_v1_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_CanonLog3_v1_2(clog * factor), x * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_cineon.py b/colour/models/rgb/transfer_functions/tests/test_cineon.py index b28fda6b89..7b06586154 100644 --- a/colour/models/rgb/transfer_functions/tests/test_cineon.py +++ b/colour/models/rgb/transfer_functions/tests/test_cineon.py @@ -3,12 +3,14 @@ :mod:`colour.models.rgb.transfer_functions.cineon` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_Cineon, log_decoding_Cineon, + log_encoding_Cineon, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,16 +39,22 @@ def test_log_encoding_Cineon(self): log_encoding_Cineon` definition. """ - self.assertAlmostEqual( - log_encoding_Cineon(0.0), 0.092864125122190, places=7 + np.testing.assert_allclose( + log_encoding_Cineon(0.0), + 0.092864125122190, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Cineon(0.18), 0.457319613085418, places=7 + np.testing.assert_allclose( + log_encoding_Cineon(0.18), + 0.457319613085418, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Cineon(1.0), 0.669599217986315, places=7 + np.testing.assert_allclose( + log_encoding_Cineon(1.0), + 0.669599217986315, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_Cineon(self): @@ -60,20 +68,20 @@ def test_n_dimensional_log_encoding_Cineon(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Cineon(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Cineon(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Cineon(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Cineon(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Cineon(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Cineon(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Cineon(self): @@ -88,8 +96,10 @@ def test_domain_range_scale_log_encoding_Cineon(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Cineon(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Cineon(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -116,16 +126,22 @@ def test_log_decoding_Cineon(self): log_decoding_Cineon` definition. """ - self.assertAlmostEqual( - log_decoding_Cineon(0.092864125122190), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_Cineon(0.092864125122190), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Cineon(0.457319613085418), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Cineon(0.457319613085418), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Cineon(0.669599217986315), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_Cineon(0.669599217986315), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_Cineon(self): @@ -139,20 +155,20 @@ def test_n_dimensional_log_decoding_Cineon(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Cineon(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Cineon(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Cineon(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Cineon(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Cineon(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Cineon(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Cineon(self): @@ -167,8 +183,10 @@ def test_domain_range_scale_log_decoding_Cineon(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Cineon(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Cineon(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_common.py b/colour/models/rgb/transfer_functions/tests/test_common.py index 2fadad024f..409bb03ab2 100644 --- a/colour/models/rgb/transfer_functions/tests/test_common.py +++ b/colour/models/rgb/transfer_functions/tests/test_common.py @@ -3,13 +3,15 @@ :mod:`colour.models.rgb.transfer_functions.common` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( CV_range, - legal_to_full, full_to_legal, + legal_to_full, ) from colour.utilities import ignore_numpy_errors @@ -47,10 +49,10 @@ def test_CV_range(self): CV_range(8, False, True), np.array([0, 255]) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CV_range(8, True, False), np.array([0.06274510, 0.92156863]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_array_equal( @@ -65,10 +67,10 @@ def test_CV_range(self): CV_range(10, False, True), np.array([0, 1023]) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CV_range(10, True, False), np.array([0.06256109, 0.91886608]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_array_equal( @@ -88,21 +90,25 @@ def test_legal_to_full(self): definition. """ - self.assertAlmostEqual(legal_to_full(64 / 1023), 0.0) + np.testing.assert_allclose(legal_to_full(64 / 1023), 0.0) - self.assertAlmostEqual(legal_to_full(940 / 1023), 1.0) + np.testing.assert_allclose(legal_to_full(940 / 1023), 1.0) - self.assertAlmostEqual(legal_to_full(64 / 1023, out_int=True), 0) + np.testing.assert_allclose(legal_to_full(64 / 1023, out_int=True), 0) - self.assertAlmostEqual(legal_to_full(940 / 1023, out_int=True), 1023) + np.testing.assert_allclose( + legal_to_full(940 / 1023, out_int=True), 1023 + ) - self.assertAlmostEqual(legal_to_full(64, in_int=True), 0.0) + np.testing.assert_allclose(legal_to_full(64, in_int=True), 0.0) - self.assertAlmostEqual(legal_to_full(940, in_int=True), 1.0) + np.testing.assert_allclose(legal_to_full(940, in_int=True), 1.0) - self.assertAlmostEqual(legal_to_full(64, in_int=True, out_int=True), 0) + np.testing.assert_allclose( + legal_to_full(64, in_int=True, out_int=True), 0 + ) - self.assertAlmostEqual( + np.testing.assert_allclose( legal_to_full(940, in_int=True, out_int=True), 1023 ) @@ -117,20 +123,20 @@ def test_n_dimensional_legal_to_full(self): CV_l = np.tile(CV_l, 6) CV_f = np.tile(CV_f, 6) - np.testing.assert_array_almost_equal( - legal_to_full(CV_l, 10), CV_f, decimal=7 + np.testing.assert_allclose( + legal_to_full(CV_l, 10), CV_f, atol=TOLERANCE_ABSOLUTE_TESTS ) CV_l = np.reshape(CV_l, (2, 3)) CV_f = np.reshape(CV_f, (2, 3)) - np.testing.assert_array_almost_equal( - legal_to_full(CV_l, 10), CV_f, decimal=7 + np.testing.assert_allclose( + legal_to_full(CV_l, 10), CV_f, atol=TOLERANCE_ABSOLUTE_TESTS ) CV_l = np.reshape(CV_l, (2, 3, 1)) CV_f = np.reshape(CV_f, (2, 3, 1)) - np.testing.assert_array_almost_equal( - legal_to_full(CV_l, 10), CV_f, decimal=7 + np.testing.assert_allclose( + legal_to_full(CV_l, 10), CV_f, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -155,25 +161,27 @@ def test_full_to_legal(self): definition. """ - self.assertAlmostEqual(full_to_legal(0.0), 0.062561094819159) + np.testing.assert_allclose(full_to_legal(0.0), 0.062561094819159) - self.assertAlmostEqual(full_to_legal(1.0), 0.918866080156403) + np.testing.assert_allclose(full_to_legal(1.0), 0.918866080156403) - self.assertAlmostEqual(full_to_legal(0.0, out_int=True), 64) + np.testing.assert_allclose(full_to_legal(0.0, out_int=True), 64) - self.assertAlmostEqual(full_to_legal(1.0, out_int=True), 940) + np.testing.assert_allclose(full_to_legal(1.0, out_int=True), 940) - self.assertAlmostEqual( + np.testing.assert_allclose( full_to_legal(0, in_int=True), 0.062561094819159 ) - self.assertAlmostEqual( + np.testing.assert_allclose( full_to_legal(1023, in_int=True), 0.918866080156403 ) - self.assertAlmostEqual(full_to_legal(0, in_int=True, out_int=True), 64) + np.testing.assert_allclose( + full_to_legal(0, in_int=True, out_int=True), 64 + ) - self.assertAlmostEqual( + np.testing.assert_allclose( full_to_legal(1023, in_int=True, out_int=True), 940 ) @@ -188,20 +196,20 @@ def test_n_dimensional_full_to_legal(self): CF_f = np.tile(CF_f, 6) CV_l = np.tile(CV_l, 6) - np.testing.assert_array_almost_equal( - full_to_legal(CF_f, 10), CV_l, decimal=7 + np.testing.assert_allclose( + full_to_legal(CF_f, 10), CV_l, atol=TOLERANCE_ABSOLUTE_TESTS ) CF_f = np.reshape(CF_f, (2, 3)) CV_l = np.reshape(CV_l, (2, 3)) - np.testing.assert_array_almost_equal( - full_to_legal(CF_f, 10), CV_l, decimal=7 + np.testing.assert_allclose( + full_to_legal(CF_f, 10), CV_l, atol=TOLERANCE_ABSOLUTE_TESTS ) CF_f = np.reshape(CF_f, (2, 3, 1)) CV_l = np.reshape(CV_l, (2, 3, 1)) - np.testing.assert_array_almost_equal( - full_to_legal(CF_f, 10), CV_l, decimal=7 + np.testing.assert_allclose( + full_to_legal(CF_f, 10), CV_l, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_davinci_intermediate.py b/colour/models/rgb/transfer_functions/tests/test_davinci_intermediate.py index 44ca99edf0..e51c0d335b 100644 --- a/colour/models/rgb/transfer_functions/tests/test_davinci_intermediate.py +++ b/colour/models/rgb/transfer_functions/tests/test_davinci_intermediate.py @@ -3,9 +3,11 @@ davinci_intermediate` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( oetf_DaVinciIntermediate, oetf_inverse_DaVinciIntermediate, @@ -37,22 +39,32 @@ def test_oetf_DaVinciIntermediate(self): davinci_intermediate.oetf_DaVinciIntermediate` definition. """ - self.assertAlmostEqual( - oetf_DaVinciIntermediate(-0.01), -0.104442685500000, places=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(-0.01), + -0.104442685500000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_DaVinciIntermediate(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_DaVinciIntermediate(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_DaVinciIntermediate(0.18), 0.336043272384855, places=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(0.18), + 0.336043272384855, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_DaVinciIntermediate(1.0), 0.513837441116225, places=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(1.0), + 0.513837441116225, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_DaVinciIntermediate(100.0), 0.999999987016872, places=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(100.0), + 0.999999987016872, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_DaVinciIntermediate(self): @@ -67,20 +79,20 @@ def test_n_dimensional_oetf_DaVinciIntermediate(self): L = np.tile(L, 6) V = np.tile(V, 6) - np.testing.assert_array_almost_equal( - oetf_DaVinciIntermediate(L), V, decimal=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3)) V = np.reshape(V, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_DaVinciIntermediate(L), V, decimal=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3, 1)) V = np.reshape(V, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_DaVinciIntermediate(L), V, decimal=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_DaVinciIntermediate(self): @@ -96,8 +108,10 @@ def test_domain_range_scale_oetf_DaVinciIntermediate(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_DaVinciIntermediate(L * factor), V * factor, decimal=7 + np.testing.assert_allclose( + oetf_DaVinciIntermediate(L * factor), + V * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -125,28 +139,34 @@ def test_oetf_inverse_DaVinciIntermediate(self): davinci_intermediate.oetf_inverse_DaVinciIntermediate` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( oetf_inverse_DaVinciIntermediate(-0.104442685500000), -0.01, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_DaVinciIntermediate(0.0), 0.0, places=7 + np.testing.assert_allclose( + oetf_inverse_DaVinciIntermediate(0.0), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_DaVinciIntermediate(0.336043272384855), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_DaVinciIntermediate(0.336043272384855), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_DaVinciIntermediate(0.513837441116225), 1.0, places=7 + np.testing.assert_allclose( + oetf_inverse_DaVinciIntermediate(0.513837441116225), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( oetf_inverse_DaVinciIntermediate(0.999999987016872), 100.0, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_inverse_DaVinciIntermediate(self): @@ -161,20 +181,26 @@ def test_n_dimensional_oetf_inverse_DaVinciIntermediate(self): V = np.tile(V, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_DaVinciIntermediate(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_DaVinciIntermediate(V), + L, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V = np.reshape(V, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_DaVinciIntermediate(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_DaVinciIntermediate(V), + L, + atol=TOLERANCE_ABSOLUTE_TESTS, ) V = np.reshape(V, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_DaVinciIntermediate(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_DaVinciIntermediate(V), + L, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_oetf_inverse_DaVinciIntermediate(self): @@ -190,10 +216,10 @@ def test_domain_range_scale_oetf_inverse_DaVinciIntermediate(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( oetf_inverse_DaVinciIntermediate(V * factor), L * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_dcdm.py b/colour/models/rgb/transfer_functions/tests/test_dcdm.py index 1ec45be6e0..f4f5fea48c 100644 --- a/colour/models/rgb/transfer_functions/tests/test_dcdm.py +++ b/colour/models/rgb/transfer_functions/tests/test_dcdm.py @@ -3,10 +3,12 @@ module. """ -import numpy as np import unittest -from colour.models.rgb.transfer_functions import eotf_inverse_DCDM, eotf_DCDM +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models.rgb.transfer_functions import eotf_DCDM, eotf_inverse_DCDM from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -34,11 +36,17 @@ def test_eotf_inverse_DCDM(self): dcdm.eotf_inverse_DCDM` definition. """ - self.assertAlmostEqual(eotf_inverse_DCDM(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_inverse_DCDM(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_inverse_DCDM(0.18), 0.11281861, places=7) + np.testing.assert_allclose( + eotf_inverse_DCDM(0.18), 0.11281861, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_inverse_DCDM(1.0), 0.21817973, places=7) + np.testing.assert_allclose( + eotf_inverse_DCDM(1.0), 0.21817973, atol=TOLERANCE_ABSOLUTE_TESTS + ) self.assertEqual(eotf_inverse_DCDM(0.18, out_int=True), 462) @@ -53,20 +61,20 @@ def test_n_dimensional_eotf_inverse_DCDM(self): XYZ = np.tile(XYZ, 6) XYZ_p = np.tile(XYZ_p, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_DCDM(XYZ), XYZ_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DCDM(XYZ), XYZ_p, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3)) XYZ_p = np.reshape(XYZ_p, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_DCDM(XYZ), XYZ_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DCDM(XYZ), XYZ_p, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 1)) XYZ_p = np.reshape(XYZ_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_DCDM(XYZ), XYZ_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DCDM(XYZ), XYZ_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_DCDM(self): @@ -81,8 +89,10 @@ def test_domain_range_scale_eotf_inverse_DCDM(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_inverse_DCDM(XYZ * factor), XYZ_p * factor, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DCDM(XYZ * factor), + XYZ_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -107,14 +117,20 @@ def test_eotf_DCDM(self): definition. """ - self.assertAlmostEqual(eotf_DCDM(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_DCDM(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_DCDM(0.11281861), 0.18, places=7) + np.testing.assert_allclose( + eotf_DCDM(0.11281861), 0.18, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_DCDM(0.21817973), 1.0, places=7) + np.testing.assert_allclose( + eotf_DCDM(0.21817973), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) np.testing.assert_allclose( - eotf_DCDM(462, in_int=True), 0.18, atol=0.00001, rtol=0.00001 + eotf_DCDM(462, in_int=True), 0.18, atol=1e-5 ) def test_n_dimensional_eotf_DCDM(self): @@ -128,15 +144,21 @@ def test_n_dimensional_eotf_DCDM(self): XYZ_p = np.tile(XYZ_p, 6) XYZ = np.tile(XYZ, 6) - np.testing.assert_array_almost_equal(eotf_DCDM(XYZ_p), XYZ, decimal=7) + np.testing.assert_allclose( + eotf_DCDM(XYZ_p), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) XYZ_p = np.reshape(XYZ_p, (2, 3)) XYZ = np.reshape(XYZ, (2, 3)) - np.testing.assert_array_almost_equal(eotf_DCDM(XYZ_p), XYZ, decimal=7) + np.testing.assert_allclose( + eotf_DCDM(XYZ_p), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) XYZ_p = np.reshape(XYZ_p, (2, 3, 1)) XYZ = np.reshape(XYZ, (2, 3, 1)) - np.testing.assert_array_almost_equal(eotf_DCDM(XYZ_p), XYZ, decimal=7) + np.testing.assert_allclose( + eotf_DCDM(XYZ_p), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_eotf_DCDM(self): """ @@ -150,8 +172,10 @@ def test_domain_range_scale_eotf_DCDM(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_DCDM(XYZ_p * factor), XYZ * factor, decimal=7 + np.testing.assert_allclose( + eotf_DCDM(XYZ_p * factor), + XYZ * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_dicom_gsdf.py b/colour/models/rgb/transfer_functions/tests/test_dicom_gsdf.py index 5d2b18d0d0..68acc94735 100644 --- a/colour/models/rgb/transfer_functions/tests/test_dicom_gsdf.py +++ b/colour/models/rgb/transfer_functions/tests/test_dicom_gsdf.py @@ -3,12 +3,14 @@ :mod:`colour.models.rgb.transfer_functions.dicom_gsdf` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - eotf_inverse_DICOMGSDF, eotf_DICOMGSDF, + eotf_inverse_DICOMGSDF, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,20 +39,28 @@ def test_eotf_inverse_DICOMGSDF(self): eotf_inverse_DICOMGSDF` definition. """ - self.assertAlmostEqual( - eotf_inverse_DICOMGSDF(0.05), 0.001007281350787, places=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(0.05), + 0.001007281350787, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_DICOMGSDF(130.0662), 0.500486263438448, places=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(130.0662), + 0.500486263438448, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_DICOMGSDF(4000), 1.000160314715578, places=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(4000), + 1.000160314715578, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_DICOMGSDF(130.0662, out_int=True), 512, places=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(130.0662, out_int=True), + 512, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_inverse_DICOMGSDF(self): @@ -64,20 +74,20 @@ def test_n_dimensional_eotf_inverse_DICOMGSDF(self): L = np.tile(L, 6) J = np.tile(J, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_DICOMGSDF(L), J, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(L), J, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3)) J = np.reshape(J, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_DICOMGSDF(L), J, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(L), J, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3, 1)) J = np.reshape(J, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_DICOMGSDF(L), J, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(L), J, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_DICOMGSDF(self): @@ -92,8 +102,10 @@ def test_domain_range_scale_eotf_inverse_DICOMGSDF(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_inverse_DICOMGSDF(L * factor), J * factor, decimal=7 + np.testing.assert_allclose( + eotf_inverse_DICOMGSDF(L * factor), + J * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -120,20 +132,28 @@ def test_eotf_DICOMGSDF(self): eotf_DICOMGSDF` definition. """ - self.assertAlmostEqual( - eotf_DICOMGSDF(0.001007281350787), 0.050143440671692, places=7 + np.testing.assert_allclose( + eotf_DICOMGSDF(0.001007281350787), + 0.050143440671692, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_DICOMGSDF(0.500486263438448), 130.062864706476550, places=7 + np.testing.assert_allclose( + eotf_DICOMGSDF(0.500486263438448), + 130.062864706476550, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_DICOMGSDF(1.000160314715578), 3997.586161113322300, places=7 + np.testing.assert_allclose( + eotf_DICOMGSDF(1.000160314715578), + 3997.586161113322300, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_DICOMGSDF(512, in_int=True), 130.065284012159790, places=7 + np.testing.assert_allclose( + eotf_DICOMGSDF(512, in_int=True), + 130.065284012159790, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_DICOMGSDF(self): @@ -147,15 +167,21 @@ def test_n_dimensional_eotf_DICOMGSDF(self): J = np.tile(J, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal(eotf_DICOMGSDF(J), L, decimal=7) + np.testing.assert_allclose( + eotf_DICOMGSDF(J), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) J = np.reshape(J, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal(eotf_DICOMGSDF(J), L, decimal=7) + np.testing.assert_allclose( + eotf_DICOMGSDF(J), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) J = np.reshape(J, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal(eotf_DICOMGSDF(J), L, decimal=7) + np.testing.assert_allclose( + eotf_DICOMGSDF(J), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_eotf_DICOMGSDF(self): """ @@ -169,8 +195,10 @@ def test_domain_range_scale_eotf_DICOMGSDF(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_DICOMGSDF(J * factor), L * factor, decimal=7 + np.testing.assert_allclose( + eotf_DICOMGSDF(J * factor), + L * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_dji_d_log.py b/colour/models/rgb/transfer_functions/tests/test_dji_d_log.py index 639b2e3094..2866414a22 100644 --- a/colour/models/rgb/transfer_functions/tests/test_dji_d_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_dji_d_log.py @@ -3,12 +3,14 @@ dji_d_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_DJIDLog, log_decoding_DJIDLog, + log_encoding_DJIDLog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,13 +39,19 @@ def test_log_encoding_DJIDLog(self): log_encoding_DJIDLog` definition. """ - self.assertAlmostEqual(log_encoding_DJIDLog(0.0), 0.0929, places=7) + np.testing.assert_allclose( + log_encoding_DJIDLog(0.0), 0.0929, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_DJIDLog(0.18), 0.398764556189331, places=7 + np.testing.assert_allclose( + log_encoding_DJIDLog(0.18), + 0.398764556189331, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_encoding_DJIDLog(1.0), 0.584555, places=7) + np.testing.assert_allclose( + log_encoding_DJIDLog(1.0), 0.584555, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_log_encoding_DLog(self): """ @@ -56,20 +64,20 @@ def test_n_dimensional_log_encoding_DLog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_DJIDLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_DJIDLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_DJIDLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_DJIDLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_DJIDLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_DJIDLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_DLog(self): @@ -84,8 +92,10 @@ def test_domain_range_scale_log_encoding_DLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_DJIDLog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_DJIDLog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -112,13 +122,17 @@ def test_log_decoding_DJIDLog(self): log_decoding_DJIDLog` definition. """ - self.assertAlmostEqual(log_decoding_DJIDLog(0.0929), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_DJIDLog(0.0929), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_DJIDLog(0.398764556189331), 0.18, places=6 + np.testing.assert_allclose( + log_decoding_DJIDLog(0.398764556189331), 0.18, atol=1e-6 ) - self.assertAlmostEqual(log_decoding_DJIDLog(0.584555), 1.0, places=6) + np.testing.assert_allclose( + log_decoding_DJIDLog(0.584555), 1.0, atol=1e-6 + ) def test_n_dimensional_log_decoding_DLog(self): """ @@ -131,20 +145,20 @@ def test_n_dimensional_log_decoding_DLog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_DJIDLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_DJIDLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_DJIDLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_DJIDLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_DJIDLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_DJIDLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_DLog(self): @@ -159,8 +173,10 @@ def test_domain_range_scale_log_decoding_DLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_DJIDLog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_DJIDLog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_exponent.py b/colour/models/rgb/transfer_functions/tests/test_exponent.py index ff862f1630..d13dbbbd54 100644 --- a/colour/models/rgb/transfer_functions/tests/test_exponent.py +++ b/colour/models/rgb/transfer_functions/tests/test_exponent.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.exponent` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( exponent_function_basic, exponent_function_monitor_curve, @@ -39,58 +41,76 @@ def test_exponent_function_basic(self): a = 0.18 a_p = 0.0229932049927 - self.assertAlmostEqual(exponent_function_basic(a, 2.2), a_p, places=7) + np.testing.assert_allclose( + exponent_function_basic(a, 2.2), a_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - exponent_function_basic(a, 2.2, "basicMirrorFwd"), a_p, places=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_function_basic(a, 2.2, "basicPassThruFwd"), a_p, places=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = 0.0229932049927 a_p = 0.18 - self.assertAlmostEqual( - exponent_function_basic(a, 2.2, "basicRev"), a_p, places=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_function_basic(a, 2.2, "basicMirrorRev"), a_p, places=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_function_basic(a, 2.2, "basicPassThruRev"), a_p, places=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = -0.18 - self.assertAlmostEqual(exponent_function_basic(a, 2.2), 0.0, places=7) + np.testing.assert_allclose( + exponent_function_basic(a, 2.2), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_basic(a, 2.2, "basicMirrorFwd"), -0.0229932049927, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_basic(a, 2.2, "basicPassThruFwd"), -0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = -0.0229932049927 - self.assertAlmostEqual( - exponent_function_basic(a, 2.2, "basicRev"), 0.0, places=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicRev"), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_function_basic(a, 2.2, "basicMirrorRev"), -0.18, places=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorRev"), + -0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_basic(a, 2.2, "basicPassThruRev"), -0.0229932049927, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_exponent_function_basic(self): @@ -104,38 +124,50 @@ def test_n_dimensional_exponent_function_basic(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicMirrorFwd"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicPassThruFwd"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicMirrorFwd"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicPassThruFwd"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicMirrorFwd"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicPassThruFwd"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruFwd"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = 0.0229932049927 @@ -143,38 +175,56 @@ def test_n_dimensional_exponent_function_basic(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicMirrorRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicPassThruRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicMirrorRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicPassThruRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicMirrorRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicMirrorRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - exponent_function_basic(a, 2.2, "basicPassThruRev"), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_basic(a, 2.2, "basicPassThruRev"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -203,62 +253,64 @@ def test_exponent_function_monitor_curve(self): a = 0.18 a_p = 0.0232240466001 - self.assertAlmostEqual( - exponent_function_monitor_curve(a, 2.2, 0.001), a_p, places=7 + np.testing.assert_allclose( + exponent_function_monitor_curve(a, 2.2, 0.001), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorFwd" ), a_p, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = 0.0232240466001 a_p = 0.18 - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_monitor_curve(a, 2.2, 0.001, "monCurveRev"), a_p, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorRev" ), a_p, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = -0.18 - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_monitor_curve(a, 2.2, 0.001), -0.000205413951, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorFwd" ), -0.0232240466001, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = -0.000205413951 - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_monitor_curve(a, 2.2, 0.001, "monCurveRev"), -0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorRev" ), -0.0201036111565, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_exponent_function_monitor_curve(self): @@ -272,41 +324,47 @@ def test_n_dimensional_exponent_function_monitor_curve(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - exponent_function_monitor_curve(a, 2.2, 0.001), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_monitor_curve(a, 2.2, 0.001), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorFwd" ), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - exponent_function_monitor_curve(a, 2.2, 0.001), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_monitor_curve(a, 2.2, 0.001), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorFwd" ), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - exponent_function_monitor_curve(a, 2.2, 0.001), a_p, decimal=7 + np.testing.assert_allclose( + exponent_function_monitor_curve(a, 2.2, 0.001), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorFwd" ), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = 0.0232240466001 @@ -314,47 +372,47 @@ def test_n_dimensional_exponent_function_monitor_curve(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve(a, 2.2, 0.001, "monCurveRev"), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorRev" ), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve(a, 2.2, 0.001, "monCurveRev"), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorRev" ), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve(a, 2.2, 0.001, "monCurveRev"), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_function_monitor_curve( a, 2.2, 0.001, "monCurveMirrorRev" ), a_p, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_filmic_pro.py b/colour/models/rgb/transfer_functions/tests/test_filmic_pro.py index e984e8aa56..8705b89a64 100644 --- a/colour/models/rgb/transfer_functions/tests/test_filmic_pro.py +++ b/colour/models/rgb/transfer_functions/tests/test_filmic_pro.py @@ -3,12 +3,14 @@ :mod:`colour.models.rgb.transfer_functions.filmic_pro` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_FilmicPro6, log_decoding_FilmicPro6, + log_encoding_FilmicPro6, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,14 +39,22 @@ def test_log_encoding_FilmicPro6(self): log_encoding_FilmicPro6` definition. """ - self.assertAlmostEqual(log_encoding_FilmicPro6(0.0), -np.inf, places=7) + np.testing.assert_allclose( + log_encoding_FilmicPro6(0.0), + -np.inf, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - self.assertAlmostEqual( - log_encoding_FilmicPro6(0.18), 0.606634519924703, places=7 + np.testing.assert_allclose( + log_encoding_FilmicPro6(0.18), + 0.606634519924703, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FilmicPro6(1.0), 1.000000819999999, places=7 + np.testing.assert_allclose( + log_encoding_FilmicPro6(1.0), + 1.000000819999999, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_FilmicPro6(self): @@ -58,20 +68,20 @@ def test_n_dimensional_log_encoding_FilmicPro6(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_FilmicPro6(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_FilmicPro6(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_FilmicPro6(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_FilmicPro6(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_FilmicPro6(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_FilmicPro6(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_FilmicPro6(self): @@ -86,8 +96,10 @@ def test_domain_range_scale_log_encoding_FilmicPro6(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_FilmicPro6(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_FilmicPro6(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -116,12 +128,16 @@ def test_log_decoding_FilmicPro6(self): np.testing.assert_array_equal(log_decoding_FilmicPro6(-np.inf), 0.0) - self.assertAlmostEqual( - log_decoding_FilmicPro6(0.606634519924703), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FilmicPro6(0.606634519924703), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FilmicPro6(1.000000819999999), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_FilmicPro6(1.000000819999999), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_FilmicPro6(self): @@ -135,20 +151,20 @@ def test_n_dimensional_log_decoding_FilmicPro6(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_FilmicPro6(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_FilmicPro6(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_FilmicPro6(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_FilmicPro6(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_FilmicPro6(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_FilmicPro6(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_FilmicPro6(self): @@ -163,8 +179,10 @@ def test_domain_range_scale_log_decoding_FilmicPro6(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_FilmicPro6(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_FilmicPro6(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_filmlight_t_log.py b/colour/models/rgb/transfer_functions/tests/test_filmlight_t_log.py index 47c4cd2cfe..979a1d95d3 100644 --- a/colour/models/rgb/transfer_functions/tests/test_filmlight_t_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_filmlight_t_log.py @@ -3,12 +3,14 @@ filmlight_t_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_FilmLightTLog, log_decoding_FilmLightTLog, + log_encoding_FilmLightTLog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,16 +39,22 @@ def test_log_encoding_FilmLightTLog(self): log_encoding_FilmLightTLog` definition. """ - self.assertAlmostEqual( - log_encoding_FilmLightTLog(0.0), 0.075, places=7 + np.testing.assert_allclose( + log_encoding_FilmLightTLog(0.0), + 0.075, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FilmLightTLog(0.18), 0.396567801298332, places=7 + np.testing.assert_allclose( + log_encoding_FilmLightTLog(0.18), + 0.396567801298332, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FilmLightTLog(1.0), 0.552537881005859, places=7 + np.testing.assert_allclose( + log_encoding_FilmLightTLog(1.0), + 0.552537881005859, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_TLog(self): @@ -60,20 +68,20 @@ def test_n_dimensional_log_encoding_TLog(self): x = np.tile(x, 6) t = np.tile(t, 6) - np.testing.assert_array_almost_equal( - log_encoding_FilmLightTLog(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_FilmLightTLog(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) t = np.reshape(t, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_FilmLightTLog(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_FilmLightTLog(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) t = np.reshape(t, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_FilmLightTLog(x), t, decimal=7 + np.testing.assert_allclose( + log_encoding_FilmLightTLog(x), t, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_TLog(self): @@ -88,10 +96,10 @@ def test_domain_range_scale_log_encoding_TLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_encoding_FilmLightTLog(x * factor), t * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -118,16 +126,22 @@ def test_log_decoding_FilmLightTLog(self): log_decoding_FilmLightTLog` definition. """ - self.assertAlmostEqual( - log_decoding_FilmLightTLog(0.075), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_FilmLightTLog(0.075), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FilmLightTLog(0.396567801298332), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FilmLightTLog(0.396567801298332), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FilmLightTLog(0.552537881005859), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_FilmLightTLog(0.552537881005859), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_TLog(self): @@ -141,20 +155,20 @@ def test_n_dimensional_log_decoding_TLog(self): t = np.tile(t, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_FilmLightTLog(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_FilmLightTLog(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) t = np.reshape(t, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_FilmLightTLog(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_FilmLightTLog(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) t = np.reshape(t, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_FilmLightTLog(t), x, decimal=7 + np.testing.assert_allclose( + log_decoding_FilmLightTLog(t), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_TLog(self): @@ -169,10 +183,10 @@ def test_domain_range_scale_log_decoding_TLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( log_decoding_FilmLightTLog(t * factor), x * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_fujifilm_f_log.py b/colour/models/rgb/transfer_functions/tests/test_fujifilm_f_log.py index b04dacb36c..74f718abc6 100644 --- a/colour/models/rgb/transfer_functions/tests/test_fujifilm_f_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_fujifilm_f_log.py @@ -3,14 +3,16 @@ fujifilm_f_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_FLog, log_decoding_FLog, - log_encoding_FLog2, log_decoding_FLog2, + log_encoding_FLog, + log_encoding_FLog2, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -41,30 +43,40 @@ def test_log_encoding_FLog(self): log_encoding_FLog` definition. """ - self.assertAlmostEqual( - log_encoding_FLog(0.0), 0.092864000000000, places=7 + np.testing.assert_allclose( + log_encoding_FLog(0.0), + 0.092864000000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog(0.18), 0.459318458661621, places=7 + np.testing.assert_allclose( + log_encoding_FLog(0.18), + 0.459318458661621, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog(0.18, 12), 0.459318458661621, places=7 + np.testing.assert_allclose( + log_encoding_FLog(0.18, 12), + 0.459318458661621, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog(0.18, 10, False), 0.463336510514656, places=7 + np.testing.assert_allclose( + log_encoding_FLog(0.18, 10, False), + 0.463336510514656, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_FLog(0.18, 10, False, False), 0.446590337236003, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog(1.0), 0.704996409216428, places=7 + np.testing.assert_allclose( + log_encoding_FLog(1.0), + 0.704996409216428, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_FLog(self): @@ -78,20 +90,20 @@ def test_n_dimensional_log_encoding_FLog(self): L_in = np.tile(L_in, 6) V_out = np.tile(V_out, 6) - np.testing.assert_array_almost_equal( - log_encoding_FLog(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_FLog(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) L_in = np.reshape(L_in, (2, 3)) V_out = np.reshape(V_out, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_FLog(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_FLog(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) L_in = np.reshape(L_in, (2, 3, 1)) V_out = np.reshape(V_out, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_FLog(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_FLog(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_FLog(self): @@ -106,8 +118,10 @@ def test_domain_range_scale_log_encoding_FLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_FLog(L_in * factor), V_out * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_FLog(L_in * factor), + V_out * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -132,30 +146,40 @@ def test_log_decoding_FLog(self): log_decoding_FLog` definition. """ - self.assertAlmostEqual( - log_decoding_FLog(0.092864000000000), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_FLog(0.092864000000000), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog(0.459318458661621), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FLog(0.459318458661621), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog(0.459318458661621, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FLog(0.459318458661621, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog(0.463336510514656, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FLog(0.463336510514656, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_FLog(0.446590337236003, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog(0.704996409216428), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_FLog(0.704996409216428), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_FLog(self): @@ -169,20 +193,20 @@ def test_n_dimensional_log_decoding_FLog(self): V_out = np.tile(V_out, 6) L_in = np.tile(L_in, 6) - np.testing.assert_array_almost_equal( - log_decoding_FLog(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_FLog(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) V_out = np.reshape(V_out, (2, 3)) L_in = np.reshape(L_in, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_FLog(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_FLog(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) V_out = np.reshape(V_out, (2, 3, 1)) L_in = np.reshape(L_in, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_FLog(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_FLog(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_FLog(self): @@ -197,8 +221,10 @@ def test_domain_range_scale_log_decoding_FLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_FLog(V_out * factor), L_in * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_FLog(V_out * factor), + L_in * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -223,30 +249,40 @@ def test_log_encoding_FLog2(self): log_encoding_FLog2` definition. """ - self.assertAlmostEqual( - log_encoding_FLog2(0.0), 0.092864000000000, places=7 + np.testing.assert_allclose( + log_encoding_FLog2(0.0), + 0.092864000000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog2(0.18), 0.39100724189123, places=7 + np.testing.assert_allclose( + log_encoding_FLog2(0.18), + 0.39100724189123, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog2(0.18, 12), 0.39100724189123, places=7 + np.testing.assert_allclose( + log_encoding_FLog2(0.18, 12), + 0.39100724189123, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog2(0.18, 10, False), 0.383562110108137, places=7 + np.testing.assert_allclose( + log_encoding_FLog2(0.18, 10, False), + 0.383562110108137, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_FLog2(0.18, 10, False, False), 0.371293971820387, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_FLog2(1.0), 0.568219370444443, places=7 + np.testing.assert_allclose( + log_encoding_FLog2(1.0), + 0.568219370444443, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_FLog2(self): @@ -260,20 +296,20 @@ def test_n_dimensional_log_encoding_FLog2(self): L_in = np.tile(L_in, 6) V_out = np.tile(V_out, 6) - np.testing.assert_almost_equal( - log_encoding_FLog2(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_FLog2(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) L_in = np.reshape(L_in, (2, 3)) V_out = np.reshape(V_out, (2, 3)) - np.testing.assert_almost_equal( - log_encoding_FLog2(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_FLog2(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) L_in = np.reshape(L_in, (2, 3, 1)) V_out = np.reshape(V_out, (2, 3, 1)) - np.testing.assert_almost_equal( - log_encoding_FLog2(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_FLog2(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_FLog2(self): @@ -288,10 +324,8 @@ def test_domain_range_scale_log_encoding_FLog2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_almost_equal( - log_encoding_FLog2(L_in * factor), - V_out * factor, - decimal=7, + np.testing.assert_array_equal( + log_encoding_FLog2(L_in * factor), V_out * factor ) @ignore_numpy_errors @@ -316,30 +350,40 @@ def test_log_decoding_FLog2(self): log_decoding_FLog2` definition. """ - self.assertAlmostEqual( - log_decoding_FLog2(0.092864000000000), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_FLog2(0.092864000000000), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog2(0.391007241891230), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FLog2(0.391007241891230), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog2(0.391007241891230, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FLog2(0.391007241891230, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog2(0.383562110108137, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_FLog2(0.383562110108137, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_FLog2(0.371293971820387, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_FLog2(0.568219370444443), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_FLog2(0.568219370444443), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_FLog2(self): @@ -353,20 +397,20 @@ def test_n_dimensional_log_decoding_FLog2(self): V_out = np.tile(V_out, 6) L_in = np.tile(L_in, 6) - np.testing.assert_almost_equal( - log_decoding_FLog2(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_FLog2(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) V_out = np.reshape(V_out, (2, 3)) L_in = np.reshape(L_in, (2, 3)) - np.testing.assert_almost_equal( - log_decoding_FLog2(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_FLog2(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) V_out = np.reshape(V_out, (2, 3, 1)) L_in = np.reshape(L_in, (2, 3, 1)) - np.testing.assert_almost_equal( - log_decoding_FLog2(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_FLog2(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_FLog2(self): @@ -381,10 +425,9 @@ def test_domain_range_scale_log_decoding_FLog2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_almost_equal( + np.testing.assert_array_equal( log_decoding_FLog2(V_out * factor), L_in * factor, - decimal=7, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_gamma.py b/colour/models/rgb/transfer_functions/tests/test_gamma.py index 16d14d9e8c..4430b604c4 100644 --- a/colour/models/rgb/transfer_functions/tests/test_gamma.py +++ b/colour/models/rgb/transfer_functions/tests/test_gamma.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.gamma` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import gamma_function from colour.utilities import ignore_numpy_errors @@ -33,45 +35,65 @@ def test_gamma_function(self): gamma_function` definition. """ - self.assertAlmostEqual(gamma_function(0.0, 2.2), 0.0, places=7) + np.testing.assert_allclose( + gamma_function(0.0, 2.2), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - gamma_function(0.18, 2.2), 0.022993204992707, places=7 + np.testing.assert_allclose( + gamma_function(0.18, 2.2), + 0.022993204992707, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function(0.022993204992707, 1.0 / 2.2), 0.18, places=7 + np.testing.assert_allclose( + gamma_function(0.022993204992707, 1.0 / 2.2), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function(-0.18, 2.0), 0.0323999999999998, places=7 + np.testing.assert_allclose( + gamma_function(-0.18, 2.0), + 0.0323999999999998, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_array_equal(gamma_function(-0.18, 2.2), np.nan) - self.assertAlmostEqual( - gamma_function(-0.18, 2.2, "Mirror"), -0.022993204992707, places=7 + np.testing.assert_allclose( + gamma_function(-0.18, 2.2, "Mirror"), + -0.022993204992707, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function(-0.18, 2.2, "Preserve"), -0.18, places=7 + np.testing.assert_allclose( + gamma_function(-0.18, 2.2, "Preserve"), + -0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function(-0.18, 2.2, "Clamp"), 0, places=7 + np.testing.assert_allclose( + gamma_function(-0.18, 2.2, "Clamp"), + 0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_array_equal(gamma_function(-0.18, -2.2), np.nan) - self.assertAlmostEqual( - gamma_function(0.0, -2.2, "Mirror"), 0.0, places=7 + np.testing.assert_allclose( + gamma_function(0.0, -2.2, "Mirror"), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function(0.0, 2.2, "Preserve"), 0.0, places=7 + np.testing.assert_allclose( + gamma_function(0.0, 2.2, "Preserve"), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(gamma_function(0.0, 2.2, "Clamp"), 0, places=7) + np.testing.assert_allclose( + gamma_function(0.0, 2.2, "Clamp"), 0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_gamma_function(self): """ @@ -84,92 +106,108 @@ def test_n_dimensional_gamma_function(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = -0.18 a_p = -0.022993204992707 - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Mirror"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Mirror"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Mirror"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Mirror"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Mirror"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Mirror"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Mirror"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Mirror"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = -0.18 a_p = -0.18 - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Preserve"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Preserve"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Preserve"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Preserve"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Preserve"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Preserve"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Preserve"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Preserve"), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = -0.18 a_p = 0.0 - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Clamp"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Clamp"), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Clamp"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Clamp"), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Clamp"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Clamp"), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - gamma_function(a, 2.2, "Clamp"), a_p, decimal=7 + np.testing.assert_allclose( + gamma_function(a, 2.2, "Clamp"), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_gopro.py b/colour/models/rgb/transfer_functions/tests/test_gopro.py index 99b0b04317..0852a7b7fe 100644 --- a/colour/models/rgb/transfer_functions/tests/test_gopro.py +++ b/colour/models/rgb/transfer_functions/tests/test_gopro.py @@ -3,12 +3,14 @@ :mod:`colour.models.rgb.transfer_functions.gopro` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_Protune, log_decoding_Protune, + log_encoding_Protune, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,13 +39,19 @@ def test_log_encoding_Protune(self): log_encoding_Protune` definition. """ - self.assertAlmostEqual(log_encoding_Protune(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_encoding_Protune(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_Protune(0.18), 0.645623486803636, places=7 + np.testing.assert_allclose( + log_encoding_Protune(0.18), + 0.645623486803636, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_encoding_Protune(1.0), 1.0, places=7) + np.testing.assert_allclose( + log_encoding_Protune(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_log_encoding_Protune(self): """ @@ -56,20 +64,20 @@ def test_n_dimensional_log_encoding_Protune(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Protune(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Protune(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Protune(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Protune(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Protune(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Protune(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Protune(self): @@ -84,8 +92,10 @@ def test_domain_range_scale_log_encoding_Protune(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Protune(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Protune(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -112,13 +122,19 @@ def test_log_decoding_Protune(self): log_decoding_Protune` definition. """ - self.assertAlmostEqual(log_decoding_Protune(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_Protune(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_Protune(0.645623486803636), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Protune(0.645623486803636), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_decoding_Protune(1.0), 1.0, places=7) + np.testing.assert_allclose( + log_decoding_Protune(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_log_decoding_Protune(self): """ @@ -131,20 +147,20 @@ def test_n_dimensional_log_decoding_Protune(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Protune(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Protune(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Protune(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Protune(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Protune(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Protune(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Protune(self): @@ -159,8 +175,10 @@ def test_domain_range_scale_log_decoding_Protune(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Protune(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Protune(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_itur_bt_1361.py b/colour/models/rgb/transfer_functions/tests/test_itur_bt_1361.py index 35f14825fc..c45121ba4e 100644 --- a/colour/models/rgb/transfer_functions/tests/test_itur_bt_1361.py +++ b/colour/models/rgb/transfer_functions/tests/test_itur_bt_1361.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.itur_bt_1361` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( oetf_BT1361, oetf_inverse_BT1361, @@ -37,17 +39,29 @@ def test_oetf_BT1361(self): oetf_BT1361` definition. """ - self.assertAlmostEqual( - oetf_BT1361(-0.18), -0.212243985492969, places=7 + np.testing.assert_allclose( + oetf_BT1361(-0.18), + -0.212243985492969, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_BT1361(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_BT1361(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT1361(0.015), 0.067500000000000, places=7) + np.testing.assert_allclose( + oetf_BT1361(0.015), + 0.067500000000000, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - self.assertAlmostEqual(oetf_BT1361(0.18), 0.409007728864150, places=7) + np.testing.assert_allclose( + oetf_BT1361(0.18), 0.409007728864150, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT1361(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_BT1361(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_BT1361(self): """ @@ -60,15 +74,21 @@ def test_n_dimensional_oetf_BT1361(self): L = np.tile(L, 6) V = np.tile(V, 6) - np.testing.assert_array_almost_equal(oetf_BT1361(L), V, decimal=7) + np.testing.assert_allclose( + oetf_BT1361(L), V, atol=TOLERANCE_ABSOLUTE_TESTS + ) L = np.reshape(L, (2, 3)) V = np.reshape(V, (2, 3)) - np.testing.assert_array_almost_equal(oetf_BT1361(L), V, decimal=7) + np.testing.assert_allclose( + oetf_BT1361(L), V, atol=TOLERANCE_ABSOLUTE_TESTS + ) L = np.reshape(L, (2, 3, 1)) V = np.reshape(V, (2, 3, 1)) - np.testing.assert_array_almost_equal(oetf_BT1361(L), V, decimal=7) + np.testing.assert_allclose( + oetf_BT1361(L), V, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_oetf_BT1361(self): """ @@ -82,8 +102,10 @@ def test_domain_range_scale_oetf_BT1361(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_BT1361(L * factor), V * factor, decimal=7 + np.testing.assert_allclose( + oetf_BT1361(L * factor), + V * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -108,21 +130,31 @@ def test_oetf_inverse_BT1361(self): oetf_inverse_BT1361` definition. """ - self.assertAlmostEqual( - oetf_inverse_BT1361(-0.212243985492969), -0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_BT1361(-0.212243985492969), + -0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_BT1361(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT1361(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_BT1361(0.067500000000000), 0.015, places=7 + np.testing.assert_allclose( + oetf_inverse_BT1361(0.067500000000000), + 0.015, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_BT1361(0.409007728864150), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_BT1361(0.409007728864150), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_BT1361(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT1361(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_inverse_BT1361(self): """ @@ -135,20 +167,20 @@ def test_n_dimensional_oetf_inverse_BT1361(self): V = np.tile(V, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_BT1361(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT1361(V), L, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT1361(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT1361(V), L, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT1361(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT1361(V), L, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_BT1361(self): @@ -163,8 +195,10 @@ def test_domain_range_scale_oetf_inverse_BT1361(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_inverse_BT1361(V * factor), L * factor, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT1361(V * factor), + L * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_itur_bt_1886.py b/colour/models/rgb/transfer_functions/tests/test_itur_bt_1886.py index 08b48c8b53..e94e977b6b 100644 --- a/colour/models/rgb/transfer_functions/tests/test_itur_bt_1886.py +++ b/colour/models/rgb/transfer_functions/tests/test_itur_bt_1886.py @@ -3,12 +3,14 @@ :mod:`colour.models.rgb.transfer_functions.itur_bt_1886` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - eotf_inverse_BT1886, eotf_BT1886, + eotf_inverse_BT1886, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,13 +39,19 @@ def test_eotf_inverse_BT1886(self): eotf_inverse_BT1886` definition. """ - self.assertAlmostEqual(eotf_inverse_BT1886(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_inverse_BT1886(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_inverse_BT1886(0.016317514686316), 0.18, places=7 + np.testing.assert_allclose( + eotf_inverse_BT1886(0.016317514686316), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(eotf_inverse_BT1886(1.0), 1.0, places=7) + np.testing.assert_allclose( + eotf_inverse_BT1886(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_inverse_BT1886(self): """ @@ -56,20 +64,20 @@ def test_n_dimensional_eotf_inverse_BT1886(self): L = np.tile(L, 6) V = np.tile(V, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_BT1886(L), V, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT1886(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3)) V = np.reshape(V, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT1886(L), V, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT1886(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3, 1)) V = np.reshape(V, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT1886(L), V, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT1886(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_BT1886(self): @@ -84,8 +92,10 @@ def test_domain_range_scale_eotf_inverse_BT1886(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_inverse_BT1886(L * factor), V * factor, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT1886(L * factor), + V * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -112,11 +122,17 @@ def test_eotf_BT1886(self): eotf_BT1886` definition. """ - self.assertAlmostEqual(eotf_BT1886(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_BT1886(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_BT1886(0.18), 0.016317514686316, places=7) + np.testing.assert_allclose( + eotf_BT1886(0.18), 0.016317514686316, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_BT1886(1.0), 1.0, places=7) + np.testing.assert_allclose( + eotf_BT1886(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_BT1886(self): """ @@ -129,15 +145,21 @@ def test_n_dimensional_eotf_BT1886(self): V = np.tile(V, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal(eotf_BT1886(V), L, decimal=7) + np.testing.assert_allclose( + eotf_BT1886(V), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) V = np.reshape(V, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal(eotf_BT1886(V), L, decimal=7) + np.testing.assert_allclose( + eotf_BT1886(V), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) V = np.reshape(V, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal(eotf_BT1886(V), L, decimal=7) + np.testing.assert_allclose( + eotf_BT1886(V), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_eotf_BT1886(self): """ @@ -151,8 +173,10 @@ def test_domain_range_scale_eotf_BT1886(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_BT1886(V * factor), L * factor, decimal=7 + np.testing.assert_allclose( + eotf_BT1886(V * factor), + L * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_itur_bt_2020.py b/colour/models/rgb/transfer_functions/tests/test_itur_bt_2020.py index 3744a8fe67..212314d6b9 100644 --- a/colour/models/rgb/transfer_functions/tests/test_itur_bt_2020.py +++ b/colour/models/rgb/transfer_functions/tests/test_itur_bt_2020.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.itur_bt_2020` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( oetf_BT2020, oetf_inverse_BT2020, @@ -37,11 +39,17 @@ def test_oetf_BT2020(self): oetf_BT2020` definition. """ - self.assertAlmostEqual(oetf_BT2020(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_BT2020(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT2020(0.18), 0.409007728864150, places=7) + np.testing.assert_allclose( + oetf_BT2020(0.18), 0.409007728864150, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT2020(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_BT2020(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_BT2020(self): """ @@ -54,15 +62,21 @@ def test_n_dimensional_oetf_BT2020(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal(oetf_BT2020(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_BT2020(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal(oetf_BT2020(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_BT2020(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal(oetf_BT2020(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_BT2020(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_oetf_BT2020(self): """ @@ -76,8 +90,10 @@ def test_domain_range_scale_oetf_BT2020(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_BT2020(E * factor), E_p * factor, decimal=7 + np.testing.assert_allclose( + oetf_BT2020(E * factor), + E_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -102,13 +118,19 @@ def test_oetf_inverse_BT2020(self): oetf_inverse_BT2020` definition. """ - self.assertAlmostEqual(oetf_inverse_BT2020(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT2020(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_BT2020(0.409007728864150), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_BT2020(0.409007728864150), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_BT2020(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT2020(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_inverse_BT2020(self): """ @@ -121,20 +143,20 @@ def test_n_dimensional_oetf_inverse_BT2020(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2020(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2020(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2020(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2020(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2020(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2020(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_BT2020(self): @@ -149,8 +171,10 @@ def test_domain_range_scale_oetf_inverse_BT2020(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_inverse_BT2020(E_p * factor), E * factor, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2020(E_p * factor), + E * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_itur_bt_2100.py b/colour/models/rgb/transfer_functions/tests/test_itur_bt_2100.py index 4522d038a3..e713c899a0 100644 --- a/colour/models/rgb/transfer_functions/tests/test_itur_bt_2100.py +++ b/colour/models/rgb/transfer_functions/tests/test_itur_bt_2100.py @@ -3,32 +3,32 @@ :mod:`colour.models.rgb.transfer_functions.itur_bt_2100` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - oetf_BT2100_PQ, - oetf_inverse_BT2100_PQ, eotf_BT2100_PQ, eotf_inverse_BT2100_PQ, - ootf_BT2100_PQ, - ootf_inverse_BT2100_PQ, oetf_BT2100_HLG, + oetf_BT2100_PQ, oetf_inverse_BT2100_HLG, + oetf_inverse_BT2100_PQ, + ootf_BT2100_PQ, + ootf_inverse_BT2100_PQ, ) from colour.models.rgb.transfer_functions.itur_bt_2100 import ( eotf_BT2100_HLG_1, eotf_BT2100_HLG_2, eotf_inverse_BT2100_HLG_1, eotf_inverse_BT2100_HLG_2, + gamma_function_BT2100_HLG, ootf_BT2100_HLG_1, ootf_BT2100_HLG_2, ootf_inverse_BT2100_HLG_1, ootf_inverse_BT2100_HLG_2, ) -from colour.models.rgb.transfer_functions.itur_bt_2100 import ( - gamma_function_BT2100_HLG, -) from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -71,16 +71,22 @@ def test_oetf_BT2100_PQ(self): oetf_BT2100_PQ` definition. """ - self.assertAlmostEqual( - oetf_BT2100_PQ(0.0), 0.000000730955903, places=7 + np.testing.assert_allclose( + oetf_BT2100_PQ(0.0), + 0.000000730955903, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_BT2100_PQ(0.1), 0.724769816665726, places=7 + np.testing.assert_allclose( + oetf_BT2100_PQ(0.1), + 0.724769816665726, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_BT2100_PQ(1.0), 0.999999934308041, places=7 + np.testing.assert_allclose( + oetf_BT2100_PQ(1.0), + 0.999999934308041, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_BT2100_PQ(self): @@ -94,15 +100,21 @@ def test_n_dimensional_oetf_BT2100_PQ(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal(oetf_BT2100_PQ(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_BT2100_PQ(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal(oetf_BT2100_PQ(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_BT2100_PQ(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal(oetf_BT2100_PQ(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_BT2100_PQ(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_oetf_BT2100_PQ(self): """ @@ -116,8 +128,10 @@ def test_domain_range_scale_oetf_BT2100_PQ(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_BT2100_PQ(E * factor), E_p * factor, decimal=7 + np.testing.assert_allclose( + oetf_BT2100_PQ(E * factor), + E_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -142,16 +156,22 @@ def test_oetf_inverse_BT2100_PQ(self): oetf_inverse_BT2100_PQ` definition. """ - self.assertAlmostEqual( - oetf_inverse_BT2100_PQ(0.000000730955903), 0.0, places=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_PQ(0.000000730955903), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_BT2100_PQ(0.724769816665726), 0.1, places=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_PQ(0.724769816665726), + 0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_BT2100_PQ(0.999999934308041), 1.0, places=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_PQ(0.999999934308041), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_inverse_BT2100_PQ(self): @@ -165,20 +185,20 @@ def test_n_dimensional_oetf_inverse_BT2100_PQ(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2100_PQ(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_PQ(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2100_PQ(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_PQ(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2100_PQ(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_PQ(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_BT2100_PQ(self): @@ -193,8 +213,10 @@ def test_domain_range_scale_oetf_inverse_BT2100_PQ(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_inverse_BT2100_PQ(E_p * factor), E * factor, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_PQ(E_p * factor), + E * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -221,13 +243,19 @@ def test_eotf_BT2100_PQ(self): eotf_BT2100_PQ` definition. """ - self.assertAlmostEqual(eotf_BT2100_PQ(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_BT2100_PQ(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_BT2100_PQ(0.724769816665726), 779.98836083408537, places=7 + np.testing.assert_allclose( + eotf_BT2100_PQ(0.724769816665726), + 779.98836083408537, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(eotf_BT2100_PQ(1.0), 10000.0, places=7) + np.testing.assert_allclose( + eotf_BT2100_PQ(1.0), 10000.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_BT2100_PQ(self): """ @@ -240,20 +268,20 @@ def test_n_dimensional_eotf_BT2100_PQ(self): E_p = np.tile(E_p, 6) F_D = np.tile(F_D, 6) - np.testing.assert_array_almost_equal( - eotf_BT2100_PQ(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_PQ(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) F_D = np.reshape(F_D, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_BT2100_PQ(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_PQ(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) F_D = np.reshape(F_D, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_BT2100_PQ(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_PQ(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_BT2100_PQ(self): @@ -268,8 +296,10 @@ def test_domain_range_scale_eotf_BT2100_PQ(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_BT2100_PQ(E_p * factor), F_D * factor, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_PQ(E_p * factor), + F_D * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -294,17 +324,21 @@ def test_eotf_inverse_BT2100_PQ(self): eotf_inverse_BT2100_PQ` definition. """ - self.assertAlmostEqual( - eotf_inverse_BT2100_PQ(0.0), 0.000000730955903, places=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_PQ(0.0), + 0.000000730955903, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( eotf_inverse_BT2100_PQ(779.98836083408537), 0.724769816665726, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(eotf_inverse_BT2100_PQ(10000.0), 1.0, places=7) + np.testing.assert_allclose( + eotf_inverse_BT2100_PQ(10000.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_inverse_BT2100_PQ(self): """ @@ -317,20 +351,20 @@ def test_n_dimensional_eotf_inverse_BT2100_PQ(self): F_D = np.tile(F_D, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_PQ(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_PQ(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_PQ(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_PQ(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_PQ(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_PQ(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_BT2100_PQ(self): @@ -345,10 +379,10 @@ def test_domain_range_scale_eotf_inverse_BT2100_PQ(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( eotf_inverse_BT2100_PQ(F_D * factor), E_p * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -375,14 +409,20 @@ def test_ootf_BT2100_PQ(self): ootf_BT2100_PQ` definition. """ - self.assertAlmostEqual(ootf_BT2100_PQ(0.0), 0.0, places=7) + np.testing.assert_allclose( + ootf_BT2100_PQ(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - ootf_BT2100_PQ(0.1), 779.98836083411584, places=7 + np.testing.assert_allclose( + ootf_BT2100_PQ(0.1), + 779.98836083411584, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - ootf_BT2100_PQ(1.0), 9999.993723673924300, places=7 + np.testing.assert_allclose( + ootf_BT2100_PQ(1.0), + 9999.993723673924300, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ootf_BT2100_PQ(self): @@ -396,15 +436,21 @@ def test_n_dimensional_ootf_BT2100_PQ(self): E = np.tile(E, 6) F_D = np.tile(F_D, 6) - np.testing.assert_array_almost_equal(ootf_BT2100_PQ(E), F_D, decimal=7) + np.testing.assert_allclose( + ootf_BT2100_PQ(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3)) F_D = np.reshape(F_D, (2, 3)) - np.testing.assert_array_almost_equal(ootf_BT2100_PQ(E), F_D, decimal=7) + np.testing.assert_allclose( + ootf_BT2100_PQ(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3, 1)) F_D = np.reshape(F_D, (2, 3, 1)) - np.testing.assert_array_almost_equal(ootf_BT2100_PQ(E), F_D, decimal=7) + np.testing.assert_allclose( + ootf_BT2100_PQ(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_ootf_BT2100_PQ(self): """ @@ -418,8 +464,10 @@ def test_domain_range_scale_ootf_BT2100_PQ(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ootf_BT2100_PQ(E * factor), F_D * factor, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_PQ(E * factor), + F_D * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -444,14 +492,20 @@ def test_ootf_inverse_BT2100_PQ(self): ootf_inverse_BT2100_PQ` definition. """ - self.assertAlmostEqual(ootf_inverse_BT2100_PQ(0.0), 0.0, places=7) + np.testing.assert_allclose( + ootf_inverse_BT2100_PQ(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - ootf_inverse_BT2100_PQ(779.98836083411584), 0.1, places=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_PQ(779.98836083411584), + 0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - ootf_inverse_BT2100_PQ(9999.993723673924300), 1.0, places=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_PQ(9999.993723673924300), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ootf_inverse_BT2100_PQ(self): @@ -465,20 +519,20 @@ def test_n_dimensional_ootf_inverse_BT2100_PQ(self): F_D = np.tile(F_D, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_PQ(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_PQ(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_PQ(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_PQ(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_PQ(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_PQ(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ootf_inverse_BT2100_PQ(self): @@ -493,8 +547,10 @@ def test_domain_range_scale_ootf_inverse_BT2100_PQ(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_PQ(F_D * factor), E * factor, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_PQ(F_D * factor), + E * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -521,20 +577,28 @@ def test_gamma_function_BT2100_HLG(self): gamma_function_BT2100_HLG` definition. """ - self.assertAlmostEqual( - gamma_function_BT2100_HLG(1000.0), 1.2, places=7 + np.testing.assert_allclose( + gamma_function_BT2100_HLG(1000.0), + 1.2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function_BT2100_HLG(2000.0), 1.326432598178872, places=7 + np.testing.assert_allclose( + gamma_function_BT2100_HLG(2000.0), + 1.326432598178872, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function_BT2100_HLG(4000.0), 1.452865196357744, places=7 + np.testing.assert_allclose( + gamma_function_BT2100_HLG(4000.0), + 1.452865196357744, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gamma_function_BT2100_HLG(10000.0), 1.619999999999999, places=7 + np.testing.assert_allclose( + gamma_function_BT2100_HLG(10000.0), + 1.619999999999999, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -550,14 +614,20 @@ def test_oetf_BT2100_HLG(self): oetf_BT2100_HLG` definition. """ - self.assertAlmostEqual(oetf_BT2100_HLG(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_BT2100_HLG(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_BT2100_HLG(0.18 / 12), 0.212132034355964, places=7 + np.testing.assert_allclose( + oetf_BT2100_HLG(0.18 / 12), + 0.212132034355964, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_BT2100_HLG(1.0), 0.999999995536569, places=7 + np.testing.assert_allclose( + oetf_BT2100_HLG(1.0), + 0.999999995536569, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_BT2100_HLG(self): @@ -571,20 +641,20 @@ def test_n_dimensional_oetf_BT2100_HLG(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - oetf_BT2100_HLG(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_BT2100_HLG(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_BT2100_HLG(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_BT2100_HLG(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_BT2100_HLG(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_BT2100_HLG(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_BT2100_HLG(self): @@ -599,8 +669,10 @@ def test_domain_range_scale_oetf_BT2100_HLG(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_BT2100_HLG(E * factor), E_p * factor, decimal=7 + np.testing.assert_allclose( + oetf_BT2100_HLG(E * factor), + E_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -625,14 +697,20 @@ def test_oetf_inverse_BT2100_HLG(self): oetf_inverse_BT2100_HLG` definition. """ - self.assertAlmostEqual(oetf_inverse_BT2100_HLG(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT2100_HLG(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_BT2100_HLG(0.212132034355964), 0.18 / 12, places=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_HLG(0.212132034355964), + 0.18 / 12, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_BT2100_HLG(0.999999995536569), 1.0, places=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_HLG(0.999999995536569), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_inverse_BT2100_HLG(self): @@ -646,20 +724,20 @@ def test_n_dimensional_oetf_inverse_BT2100_HLG(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2100_HLG(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_HLG(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2100_HLG(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_HLG(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT2100_HLG(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT2100_HLG(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_BT2100_HLG(self): @@ -674,10 +752,10 @@ def test_domain_range_scale_oetf_inverse_BT2100_HLG(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( oetf_inverse_BT2100_HLG(E_p * factor), E * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -704,20 +782,26 @@ def test_eotf_BT2100_HLG_1(self): eotf_BT2100_HLG_1` definition. """ - self.assertAlmostEqual(eotf_BT2100_HLG_1(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_BT2100_HLG_1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_BT2100_HLG_1(0.212132034355964), 6.476039825649814, places=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(0.212132034355964), + 6.476039825649814, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_BT2100_HLG_1(1.0), 1000.000032321769100, places=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(1.0), + 1000.000032321769100, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( eotf_BT2100_HLG_1(0.212132034355964, 0.001, 10000, 1.4), 27.96039175299561, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_BT2100_HLG_1(self): @@ -731,44 +815,44 @@ def test_n_dimensional_eotf_BT2100_HLG_1(self): E_p = np.tile(E_p, 6) F_D = np.tile(F_D, 6) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) F_D = np.reshape(F_D, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) F_D = np.reshape(F_D, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (6, 1)) F_D = np.reshape(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.array([0.25, 0.50, 0.75]) F_D = np.array([12.49759413, 49.99037650, 158.94693786]) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.tile(E_p, (6, 1)) F_D = np.tile(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 3)) F_D = np.reshape(F_D, (2, 3, 3)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_BT2100_HLG_1(self): @@ -783,8 +867,10 @@ def test_domain_range_scale_eotf_BT2100_HLG_1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_1(E_p * factor), F_D * factor, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_1(E_p * factor), + F_D * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -809,20 +895,26 @@ def test_eotf_BT2100_HLG_2(self): eotf_BT2100_HLG_2` definition. """ - self.assertAlmostEqual(eotf_BT2100_HLG_2(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_BT2100_HLG_2(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_BT2100_HLG_2(0.212132034355964), 6.476039825649814, places=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(0.212132034355964), + 6.476039825649814, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_BT2100_HLG_2(1.0), 1000.000032321769100, places=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(1.0), + 1000.000032321769100, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( eotf_BT2100_HLG_2(0.212132034355964, 0.001, 10000, 1.4), 29.581261576946076, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_BT2100_HLG_2(self): @@ -836,44 +928,44 @@ def test_n_dimensional_eotf_BT2100_HLG_2(self): E_p = np.tile(E_p, 6) F_D = np.tile(F_D, 6) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) F_D = np.reshape(F_D, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) F_D = np.reshape(F_D, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (6, 1)) F_D = np.reshape(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.array([0.25, 0.50, 0.75]) F_D = np.array([12.49759413, 49.99037650, 158.94693786]) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.tile(E_p, (6, 1)) F_D = np.tile(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 3)) F_D = np.reshape(F_D, (2, 3, 3)) - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p), F_D, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_BT2100_HLG_2(self): @@ -888,8 +980,10 @@ def test_domain_range_scale_eotf_BT2100_HLG_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_BT2100_HLG_2(E_p * factor), F_D * factor, decimal=7 + np.testing.assert_allclose( + eotf_BT2100_HLG_2(E_p * factor), + F_D * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -914,22 +1008,26 @@ def test_eotf_inverse_BT2100_HLG_1(self): eotf_inverse_BT2100_HLG_1` definition. """ - self.assertAlmostEqual(eotf_inverse_BT2100_HLG_1(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( + np.testing.assert_allclose( eotf_inverse_BT2100_HLG_1(6.476039825649814), 0.212132034355964, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_BT2100_HLG_1(1000.000032321769100), 1.0, places=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(1000.000032321769100), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( eotf_inverse_BT2100_HLG_1(27.96039175299561, 0.001, 10000, 1.4), 0.212132034355964, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_inverse_BT2100_HLG_1(self): @@ -943,44 +1041,44 @@ def test_n_dimensional_eotf_inverse_BT2100_HLG_1(self): F_D = np.tile(F_D, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_1(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_1(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_1(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (6, 1)) E_p = np.reshape(E_p, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_1(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.array([12.49759413, 49.99037650, 158.94693786]) E_p = np.array([0.25, 0.50, 0.75]) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_1(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.tile(F_D, (6, 1)) E_p = np.tile(E_p, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_1(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 3)) E_p = np.reshape(E_p, (2, 3, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_1(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_1(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_BT2100_HLG_1(self): @@ -995,10 +1093,10 @@ def test_domain_range_scale_eotf_inverse_BT2100_HLG_1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( eotf_inverse_BT2100_HLG_1(F_D * factor), E_p * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1025,22 +1123,26 @@ def test_eotf_inverse_BT2100_HLG_2(self): eotf_inverse_BT2100_HLG_2` definition. """ - self.assertAlmostEqual(eotf_inverse_BT2100_HLG_2(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( + np.testing.assert_allclose( eotf_inverse_BT2100_HLG_2(6.476039825649814), 0.212132034355964, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_BT2100_HLG_2(1000.000032321769100), 1.0, places=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(1000.000032321769100), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( eotf_inverse_BT2100_HLG_2(29.581261576946076, 0.001, 10000, 1.4), 0.212132034355964, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_inverse_BT2100_HLG_2(self): @@ -1054,44 +1156,44 @@ def test_n_dimensional_eotf_inverse_BT2100_HLG_2(self): F_D = np.tile(F_D, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_2(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_2(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_2(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (6, 1)) E_p = np.reshape(E_p, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_2(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.array([12.49759413, 49.99037650, 158.94693786]) E_p = np.array([0.25, 0.50, 0.75]) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_2(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.tile(F_D, (6, 1)) E_p = np.tile(E_p, (6, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_2(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 3)) E_p = np.reshape(E_p, (2, 3, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_BT2100_HLG_2(F_D), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_BT2100_HLG_2(F_D), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_BT2100_HLG_2(self): @@ -1106,10 +1208,10 @@ def test_domain_range_scale_eotf_inverse_BT2100_HLG_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( eotf_inverse_BT2100_HLG_2(F_D * factor), E_p * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1136,18 +1238,24 @@ def test_ootf_BT2100_HLG_1(self): ootf_BT2100_HLG_1` definition. """ - self.assertAlmostEqual(ootf_BT2100_HLG_1(0.0), 0.0, places=7) + np.testing.assert_allclose( + ootf_BT2100_HLG_1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - ootf_BT2100_HLG_1(0.1), 63.095734448019336, places=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(0.1), + 63.095734448019336, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(ootf_BT2100_HLG_1(1.0), 1000.0, places=7) + np.testing.assert_allclose( + ootf_BT2100_HLG_1(1.0), 1000.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( + np.testing.assert_allclose( ootf_BT2100_HLG_1(0.1, 0.001, 10000, 1.4), 398.108130742780300, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.array( @@ -1162,7 +1270,7 @@ def test_ootf_BT2100_HLG_1(self): [51.320396090100672, -51.320396090100672, 51.320396090100672], ], ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ootf_BT2100_HLG_1( np.array( [ @@ -1174,7 +1282,7 @@ def test_ootf_BT2100_HLG_1(self): ) ), a, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ootf_BT2100_HLG_1(self): @@ -1188,44 +1296,44 @@ def test_n_dimensional_ootf_BT2100_HLG_1(self): E = np.tile(E, 6) F_D = np.tile(F_D, 6) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) F_D = np.reshape(F_D, (2, 3)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) F_D = np.reshape(F_D, (2, 3, 1)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (6, 1)) F_D = np.reshape(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.array([0.25, 0.50, 0.75]) F_D = np.array([213.01897444, 426.03794887, 639.05692331]) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.tile(E, (6, 1)) F_D = np.tile(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 3)) F_D = np.reshape(F_D, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ootf_BT2100_HLG_1(self): @@ -1240,8 +1348,10 @@ def test_domain_range_scale_ootf_BT2100_HLG_1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E * factor), F_D * factor, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E * factor), + F_D * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1266,16 +1376,24 @@ def test_ootf_BT2100_HLG_2(self): ootf_BT2100_HLG_2` definition. """ - self.assertAlmostEqual(ootf_BT2100_HLG_2(0.0), 0.0, places=7) + np.testing.assert_allclose( + ootf_BT2100_HLG_2(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - ootf_BT2100_HLG_2(0.1), 63.095734448019336, places=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(0.1), + 63.095734448019336, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(ootf_BT2100_HLG_2(1.0), 1000.0, places=7) + np.testing.assert_allclose( + ootf_BT2100_HLG_2(1.0), 1000.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - ootf_BT2100_HLG_2(0.1, 10000, 1.4), 398.107170553497380, places=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(0.1, 10000, 1.4), + 398.107170553497380, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.array( @@ -1290,7 +1408,7 @@ def test_ootf_BT2100_HLG_2(self): [51.320396090100672, -51.320396090100672, 51.320396090100672], ], ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ootf_BT2100_HLG_2( np.array( [ @@ -1302,7 +1420,7 @@ def test_ootf_BT2100_HLG_2(self): ) ), a, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ootf_BT2100_HLG_2(self): @@ -1316,44 +1434,44 @@ def test_n_dimensional_ootf_BT2100_HLG_2(self): E = np.tile(E, 6) F_D = np.tile(F_D, 6) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_2(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) F_D = np.reshape(F_D, (2, 3)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_2(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) F_D = np.reshape(F_D, (2, 3, 1)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_2(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (6, 1)) F_D = np.reshape(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_2(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.array([0.25, 0.50, 0.75]) F_D = np.array([213.01897444, 426.03794887, 639.05692331]) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_2(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.tile(E, (6, 1)) F_D = np.tile(F_D, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_2(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 3)) F_D = np.reshape(F_D, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_2(E), F_D, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_2(E), F_D, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ootf_BT2100_HLG_2(self): @@ -1368,8 +1486,10 @@ def test_domain_range_scale_ootf_BT2100_HLG_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ootf_BT2100_HLG_1(E * factor), F_D * factor, decimal=7 + np.testing.assert_allclose( + ootf_BT2100_HLG_1(E * factor), + F_D * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1394,20 +1514,26 @@ def test_ootf_inverse_BT2100_HLG_1(self): ootf_inverse_BT2100_HLG_1` definition. """ - self.assertAlmostEqual(ootf_inverse_BT2100_HLG_1(0.0), 0.0, places=7) + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - ootf_inverse_BT2100_HLG_1(63.095734448019336), 0.1, places=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(63.095734448019336), + 0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - ootf_inverse_BT2100_HLG_1(1000.0), 1.0, places=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(1000.0), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( ootf_inverse_BT2100_HLG_1(398.108130742780300, 0.001, 10000, 1.4), 0.1, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.array( @@ -1422,7 +1548,7 @@ def test_ootf_inverse_BT2100_HLG_1(self): [51.320396090100672, -51.320396090100672, 51.320396090100672], ] ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ootf_inverse_BT2100_HLG_1(a), np.array( [ @@ -1432,7 +1558,7 @@ def test_ootf_inverse_BT2100_HLG_1(self): [0.1, -0.1, 0.1], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ootf_inverse_BT2100_HLG_1(self): @@ -1446,44 +1572,44 @@ def test_n_dimensional_ootf_inverse_BT2100_HLG_1(self): F_D = np.tile(F_D, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_1(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_1(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_1(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (6, 1)) E = np.reshape(E, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_1(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.array([213.01897444, 426.03794887, 639.05692331]) E = np.array([0.25, 0.50, 0.75]) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_1(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.tile(F_D, (6, 1)) E = np.tile(E, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_1(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 3)) E = np.reshape(E, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_1(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_1(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ootf_inverse_BT2100_HLG_1(self): @@ -1498,10 +1624,10 @@ def test_domain_range_scale_ootf_inverse_BT2100_HLG_1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ootf_inverse_BT2100_HLG_1(F_D * factor), E * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1528,20 +1654,26 @@ def test_ootf_inverse_BT2100_HLG_2(self): ootf_inverse_BT2100_HLG_2` definition. """ - self.assertAlmostEqual(ootf_inverse_BT2100_HLG_2(0.0), 0.0, places=7) + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - ootf_inverse_BT2100_HLG_2(63.095734448019336), 0.1, places=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(63.095734448019336), + 0.1, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - ootf_inverse_BT2100_HLG_2(1000.0), 1.0, places=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(1000.0), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( ootf_inverse_BT2100_HLG_2(398.107170553497380, 10000, 1.4), 0.1, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.array( @@ -1556,7 +1688,7 @@ def test_ootf_inverse_BT2100_HLG_2(self): [51.320396090100672, -51.320396090100672, 51.320396090100672], ] ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ootf_inverse_BT2100_HLG_2(a), np.array( [ @@ -1566,7 +1698,7 @@ def test_ootf_inverse_BT2100_HLG_2(self): [0.1, -0.1, 0.1], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ootf_inverse_BT2100_HLG_2(self): @@ -1580,44 +1712,44 @@ def test_n_dimensional_ootf_inverse_BT2100_HLG_2(self): F_D = np.tile(F_D, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_2(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_2(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_2(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (6, 1)) E = np.reshape(E, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_2(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.array([213.01897444, 426.03794887, 639.05692331]) E = np.array([0.25, 0.50, 0.75]) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_2(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.tile(F_D, (6, 1)) E = np.tile(E, (6, 1)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_2(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) F_D = np.reshape(F_D, (2, 3, 3)) E = np.reshape(E, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ootf_inverse_BT2100_HLG_2(F_D), E, decimal=7 + np.testing.assert_allclose( + ootf_inverse_BT2100_HLG_2(F_D), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ootf_inverse_BT2100_HLG_2(self): @@ -1632,10 +1764,10 @@ def test_domain_range_scale_ootf_inverse_BT2100_HLG_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ootf_inverse_BT2100_HLG_2(F_D * factor), E * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_itur_bt_601.py b/colour/models/rgb/transfer_functions/tests/test_itur_bt_601.py index 41bf25eb88..b73263959b 100644 --- a/colour/models/rgb/transfer_functions/tests/test_itur_bt_601.py +++ b/colour/models/rgb/transfer_functions/tests/test_itur_bt_601.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.itur_bt_601` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import oetf_BT601, oetf_inverse_BT601 from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -34,13 +36,21 @@ def test_oetf_BT601(self): oetf_BT601` definition. """ - self.assertAlmostEqual(oetf_BT601(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_BT601(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT601(0.015), 0.067500000000000, places=7) + np.testing.assert_allclose( + oetf_BT601(0.015), 0.067500000000000, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT601(0.18), 0.409007728864150, places=7) + np.testing.assert_allclose( + oetf_BT601(0.18), 0.409007728864150, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT601(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_BT601(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_BT601(self): """ @@ -53,15 +63,21 @@ def test_n_dimensional_oetf_BT601(self): L = np.tile(L, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal(oetf_BT601(L), E, decimal=7) + np.testing.assert_allclose( + oetf_BT601(L), E, atol=TOLERANCE_ABSOLUTE_TESTS + ) L = np.reshape(L, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal(oetf_BT601(L), E, decimal=7) + np.testing.assert_allclose( + oetf_BT601(L), E, atol=TOLERANCE_ABSOLUTE_TESTS + ) L = np.reshape(L, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal(oetf_BT601(L), E, decimal=7) + np.testing.assert_allclose( + oetf_BT601(L), E, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_oetf_BT601(self): """ @@ -75,8 +91,10 @@ def test_domain_range_scale_oetf_BT601(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_BT601(L * factor), E * factor, decimal=7 + np.testing.assert_allclose( + oetf_BT601(L * factor), + E * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -101,17 +119,25 @@ def test_oetf_inverse_BT601(self): oetf_inverse_BT601` definition. """ - self.assertAlmostEqual(oetf_inverse_BT601(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT601(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_BT601(0.067500000000000), 0.015, places=7 + np.testing.assert_allclose( + oetf_inverse_BT601(0.067500000000000), + 0.015, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_BT601(0.409007728864150), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_BT601(0.409007728864150), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_BT601(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT601(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_inverse_BT601(self): """ @@ -124,20 +150,20 @@ def test_n_dimensional_oetf_inverse_BT601(self): E = np.tile(E, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_BT601(E), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT601(E), L, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT601(E), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT601(E), L, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT601(E), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT601(E), L, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_BT601(self): @@ -152,8 +178,10 @@ def test_domain_range_scale_oetf_inverse_BT601(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_inverse_BT601(E * factor), L * factor, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT601(E * factor), + L * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_itur_bt_709.py b/colour/models/rgb/transfer_functions/tests/test_itur_bt_709.py index fe239e3912..d5a2f31ad6 100644 --- a/colour/models/rgb/transfer_functions/tests/test_itur_bt_709.py +++ b/colour/models/rgb/transfer_functions/tests/test_itur_bt_709.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.itur_bt_709` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import oetf_BT709, oetf_inverse_BT709 from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -34,13 +36,21 @@ def test_oetf_BT709(self): oetf_BT709` definition. """ - self.assertAlmostEqual(oetf_BT709(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_BT709(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT709(0.015), 0.067500000000000, places=7) + np.testing.assert_allclose( + oetf_BT709(0.015), 0.067500000000000, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT709(0.18), 0.409007728864150, places=7) + np.testing.assert_allclose( + oetf_BT709(0.18), 0.409007728864150, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(oetf_BT709(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_BT709(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_BT709(self): """ @@ -53,15 +63,21 @@ def test_n_dimensional_oetf_BT709(self): L = np.tile(L, 6) V = np.tile(V, 6) - np.testing.assert_array_almost_equal(oetf_BT709(L), V, decimal=7) + np.testing.assert_allclose( + oetf_BT709(L), V, atol=TOLERANCE_ABSOLUTE_TESTS + ) L = np.reshape(L, (2, 3)) V = np.reshape(V, (2, 3)) - np.testing.assert_array_almost_equal(oetf_BT709(L), V, decimal=7) + np.testing.assert_allclose( + oetf_BT709(L), V, atol=TOLERANCE_ABSOLUTE_TESTS + ) L = np.reshape(L, (2, 3, 1)) V = np.reshape(V, (2, 3, 1)) - np.testing.assert_array_almost_equal(oetf_BT709(L), V, decimal=7) + np.testing.assert_allclose( + oetf_BT709(L), V, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_oetf_BT709(self): """ @@ -75,8 +91,10 @@ def test_domain_range_scale_oetf_BT709(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_BT709(L * factor), V * factor, decimal=7 + np.testing.assert_allclose( + oetf_BT709(L * factor), + V * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -101,17 +119,25 @@ def test_oetf_inverse_BT709(self): oetf_inverse_BT709` definition. """ - self.assertAlmostEqual(oetf_inverse_BT709(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT709(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_BT709(0.067500000000000), 0.015, places=7 + np.testing.assert_allclose( + oetf_inverse_BT709(0.067500000000000), + 0.015, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_BT709(0.409007728864150), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_BT709(0.409007728864150), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_BT709(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_inverse_BT709(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_inverse_BT709(self): """ @@ -124,20 +150,20 @@ def test_n_dimensional_oetf_inverse_BT709(self): V = np.tile(V, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_BT709(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT709(V), L, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT709(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT709(V), L, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_BT709(V), L, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT709(V), L, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_BT709(self): @@ -152,8 +178,10 @@ def test_domain_range_scale_oetf_inverse_BT709(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_inverse_BT709(V * factor), L * factor, decimal=7 + np.testing.assert_allclose( + oetf_inverse_BT709(V * factor), + L * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_itut_h_273.py b/colour/models/rgb/transfer_functions/tests/test_itut_h_273.py index d2465b9ccd..ad00a662c9 100644 --- a/colour/models/rgb/transfer_functions/tests/test_itut_h_273.py +++ b/colour/models/rgb/transfer_functions/tests/test_itut_h_273.py @@ -3,18 +3,20 @@ :mod:`colour.models.rgb.transfer_functions.itut_h_273` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( + eotf_H273_ST428_1, + eotf_inverse_H273_ST428_1, + oetf_H273_IEC61966_2, oetf_H273_Log, - oetf_inverse_H273_Log, oetf_H273_LogSqrt, - oetf_inverse_H273_LogSqrt, - oetf_H273_IEC61966_2, oetf_inverse_H273_IEC61966_2, - eotf_inverse_H273_ST428_1, - eotf_H273_ST428_1, + oetf_inverse_H273_Log, + oetf_inverse_H273_LogSqrt, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -49,13 +51,19 @@ def test_oetf_H273_Log(self): oetf_H273_Log` definition. """ - self.assertAlmostEqual(oetf_H273_Log(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_H273_Log(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_H273_Log(0.18), 0.627636252551653, places=7 + np.testing.assert_allclose( + oetf_H273_Log(0.18), + 0.627636252551653, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_H273_Log(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_H273_Log(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_H273_Log(self): """ @@ -68,15 +76,21 @@ def test_n_dimensional_oetf_H273_Log(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal(oetf_H273_Log(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_H273_Log(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal(oetf_H273_Log(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_H273_Log(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal(oetf_H273_Log(E), E_p, decimal=7) + np.testing.assert_allclose( + oetf_H273_Log(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_oetf_H273_Log(self): """ @@ -90,8 +104,10 @@ def test_domain_range_scale_oetf_H273_Log(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_H273_Log(E * factor), E_p * factor, decimal=7 + np.testing.assert_allclose( + oetf_H273_Log(E * factor), + E_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -118,13 +134,19 @@ def test_oetf_inverse_H273_Log(self): # NOTE: The function is unfortunately clamped and cannot roundtrip # properly. - self.assertAlmostEqual(oetf_inverse_H273_Log(0.0), 0.01, places=7) + np.testing.assert_allclose( + oetf_inverse_H273_Log(0.0), 0.01, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_inverse_H273_Log(0.627636252551653), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_H273_Log(0.627636252551653), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_H273_Log(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_inverse_H273_Log(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_inverse_H273_Log(self): """ @@ -137,20 +159,20 @@ def test_n_dimensional_oetf_inverse_H273_Log(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_Log(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_Log(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_Log(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_Log(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_Log(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_Log(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_H273_Log(self): @@ -165,8 +187,10 @@ def test_domain_range_scale_oetf_inverse_H273_Log(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_inverse_H273_Log(E_p * factor), E * factor, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_Log(E_p * factor), + E * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -193,13 +217,19 @@ def test_oetf_H273_LogSqrt(self): oetf_H273_LogSqrt` definition. """ - self.assertAlmostEqual(oetf_H273_LogSqrt(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_H273_LogSqrt(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_H273_LogSqrt(0.18), 0.702109002041322, places=7 + np.testing.assert_allclose( + oetf_H273_LogSqrt(0.18), + 0.702109002041322, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_H273_LogSqrt(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_H273_LogSqrt(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_H273_LogSqrt(self): """ @@ -212,20 +242,20 @@ def test_n_dimensional_oetf_H273_LogSqrt(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - oetf_H273_LogSqrt(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_H273_LogSqrt(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_H273_LogSqrt(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_H273_LogSqrt(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_H273_LogSqrt(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_H273_LogSqrt(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_H273_LogSqrt(self): @@ -240,8 +270,10 @@ def test_domain_range_scale_oetf_H273_LogSqrt(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_H273_LogSqrt(E * factor), E_p * factor, decimal=7 + np.testing.assert_allclose( + oetf_H273_LogSqrt(E * factor), + E_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -268,15 +300,21 @@ def test_oetf_inverse_H273_LogSqrt(self): # NOTE: The function is unfortunately clamped and cannot roundtrip # properly. - self.assertAlmostEqual( - oetf_inverse_H273_LogSqrt(0.0), 0.003162277660168, places=7 + np.testing.assert_allclose( + oetf_inverse_H273_LogSqrt(0.0), + 0.003162277660168, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_H273_LogSqrt(0.702109002041322), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_H273_LogSqrt(0.702109002041322), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_inverse_H273_LogSqrt(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_inverse_H273_LogSqrt(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_inverse_H273_LogSqrt(self): """ @@ -289,20 +327,20 @@ def test_n_dimensional_oetf_inverse_H273_LogSqrt(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_LogSqrt(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_LogSqrt(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_LogSqrt(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_LogSqrt(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_LogSqrt(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_LogSqrt(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_H273_LogSqrt(self): @@ -317,10 +355,10 @@ def test_domain_range_scale_oetf_inverse_H273_LogSqrt(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( oetf_inverse_H273_LogSqrt(E_p * factor), E * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -347,17 +385,25 @@ def test_oetf_H273_IEC61966_2(self): oetf_H273_IEC61966_2` definition. """ - self.assertAlmostEqual( - oetf_H273_IEC61966_2(-0.18), -0.461356129500442, places=7 + np.testing.assert_allclose( + oetf_H273_IEC61966_2(-0.18), + -0.461356129500442, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_H273_IEC61966_2(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_H273_IEC61966_2(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_H273_IEC61966_2(0.18), 0.461356129500442, places=7 + np.testing.assert_allclose( + oetf_H273_IEC61966_2(0.18), + 0.461356129500442, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_H273_IEC61966_2(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_H273_IEC61966_2(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_H273_IEC61966_2(self): """ @@ -370,20 +416,20 @@ def test_n_dimensional_oetf_H273_IEC61966_2(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - oetf_H273_IEC61966_2(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_H273_IEC61966_2(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_H273_IEC61966_2(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_H273_IEC61966_2(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_H273_IEC61966_2(E), E_p, decimal=7 + np.testing.assert_allclose( + oetf_H273_IEC61966_2(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_H273_IEC61966_2(self): @@ -398,8 +444,10 @@ def test_domain_range_scale_oetf_H273_IEC61966_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_H273_IEC61966_2(E * factor), E_p * factor, decimal=7 + np.testing.assert_allclose( + oetf_H273_IEC61966_2(E * factor), + E_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -426,20 +474,28 @@ def test_oetf_inverse_H273_IEC61966_2(self): oetf_inverse_H273_IEC61966_2` definition. """ - self.assertAlmostEqual( - oetf_inverse_H273_IEC61966_2(-0.461356129500442), -0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_H273_IEC61966_2(-0.461356129500442), + -0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_H273_IEC61966_2(0.0), 0.0, places=7 + np.testing.assert_allclose( + oetf_inverse_H273_IEC61966_2(0.0), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_H273_IEC61966_2(0.461356129500442), 0.18, places=7 + np.testing.assert_allclose( + oetf_inverse_H273_IEC61966_2(0.461356129500442), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_inverse_H273_IEC61966_2(1.0), 1.0, places=7 + np.testing.assert_allclose( + oetf_inverse_H273_IEC61966_2(1.0), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_oetf_inverse_H273_IEC61966_2(self): @@ -453,20 +509,20 @@ def test_n_dimensional_oetf_inverse_H273_IEC61966_2(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_IEC61966_2(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_IEC61966_2(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_IEC61966_2(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_IEC61966_2(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_inverse_H273_IEC61966_2(E_p), E, decimal=7 + np.testing.assert_allclose( + oetf_inverse_H273_IEC61966_2(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_inverse_H273_IEC61966_2(self): @@ -481,10 +537,10 @@ def test_domain_range_scale_oetf_inverse_H273_IEC61966_2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( oetf_inverse_H273_IEC61966_2(E_p * factor), E * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -511,14 +567,20 @@ def test_eotf_inverse_H273_ST428_1(self): eotf_inverse_H273_ST428_1` definition. """ - self.assertAlmostEqual(eotf_inverse_H273_ST428_1(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_inverse_H273_ST428_1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_inverse_H273_ST428_1(0.18), 0.500048337717236, places=7 + np.testing.assert_allclose( + eotf_inverse_H273_ST428_1(0.18), + 0.500048337717236, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_H273_ST428_1(1.0), 0.967042675317934, places=7 + np.testing.assert_allclose( + eotf_inverse_H273_ST428_1(1.0), + 0.967042675317934, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_inverse_H273_ST428_1(self): @@ -532,20 +594,20 @@ def test_n_dimensional_eotf_inverse_H273_ST428_1(self): E = np.tile(E, 6) E_p = np.tile(E_p, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_H273_ST428_1(E), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_H273_ST428_1(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3)) E_p = np.reshape(E_p, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_H273_ST428_1(E), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_H273_ST428_1(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) E = np.reshape(E, (2, 3, 1)) E_p = np.reshape(E_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_H273_ST428_1(E), E_p, decimal=7 + np.testing.assert_allclose( + eotf_inverse_H273_ST428_1(E), E_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_H273_ST428_1(self): @@ -560,10 +622,10 @@ def test_domain_range_scale_eotf_inverse_H273_ST428_1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( eotf_inverse_H273_ST428_1(E * factor), E_p * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -590,14 +652,20 @@ def test_eotf_H273_ST428_1(self): eotf_H273_ST428_1` definition. """ - self.assertAlmostEqual(eotf_H273_ST428_1(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_H273_ST428_1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_H273_ST428_1(0.500048337717236), 0.18, places=7 + np.testing.assert_allclose( + eotf_H273_ST428_1(0.500048337717236), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_H273_ST428_1(0.967042675317934), 1.0, places=7 + np.testing.assert_allclose( + eotf_H273_ST428_1(0.967042675317934), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_eotf_H273_ST428_1(self): @@ -611,20 +679,20 @@ def test_n_dimensional_eotf_H273_ST428_1(self): E_p = np.tile(E_p, 6) E = np.tile(E, 6) - np.testing.assert_array_almost_equal( - eotf_H273_ST428_1(E_p), E, decimal=7 + np.testing.assert_allclose( + eotf_H273_ST428_1(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3)) E = np.reshape(E, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_H273_ST428_1(E_p), E, decimal=7 + np.testing.assert_allclose( + eotf_H273_ST428_1(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) E_p = np.reshape(E_p, (2, 3, 1)) E = np.reshape(E, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_H273_ST428_1(E_p), E, decimal=7 + np.testing.assert_allclose( + eotf_H273_ST428_1(E_p), E, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_H273_ST428_1(self): @@ -639,8 +707,10 @@ def test_domain_range_scale_eotf_H273_ST428_1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_H273_ST428_1(E_p * factor), E * factor, decimal=7 + np.testing.assert_allclose( + eotf_H273_ST428_1(E_p * factor), + E * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_leica_l_log.py b/colour/models/rgb/transfer_functions/tests/test_leica_l_log.py index 483d2b35fa..ebf30f638a 100644 --- a/colour/models/rgb/transfer_functions/tests/test_leica_l_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_leica_l_log.py @@ -3,12 +3,14 @@ leica_l_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_LLog, log_decoding_LLog, + log_encoding_LLog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,30 +39,40 @@ def test_log_encoding_LLog(self): log_encoding_LLog` definition. """ - self.assertAlmostEqual( - log_encoding_LLog(0.0), 0.089999999999999, places=7 + np.testing.assert_allclose( + log_encoding_LLog(0.0), + 0.089999999999999, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_LLog(0.18), 0.435313904043927, places=7 + np.testing.assert_allclose( + log_encoding_LLog(0.18), + 0.435313904043927, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_LLog(0.18, 12), 0.435313904043927, places=7 + np.testing.assert_allclose( + log_encoding_LLog(0.18, 12), + 0.435313904043927, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_LLog(0.18, 10, False), 0.4353037943344028, places=7 + np.testing.assert_allclose( + log_encoding_LLog(0.18, 10, False), + 0.4353037943344028, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_LLog(0.18, 10, False, False), 0.421586960452824, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_LLog(1.0), 0.631797439630121, places=7 + np.testing.assert_allclose( + log_encoding_LLog(1.0), + 0.631797439630121, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_LLog(self): @@ -74,20 +86,20 @@ def test_n_dimensional_log_encoding_LLog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_encoding_LLog(y), x, decimal=7 + np.testing.assert_allclose( + log_encoding_LLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_LLog(y), x, decimal=7 + np.testing.assert_allclose( + log_encoding_LLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_LLog(y), x, decimal=7 + np.testing.assert_allclose( + log_encoding_LLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_LLog(self): @@ -102,8 +114,10 @@ def test_domain_range_scale_log_encoding_LLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_LLog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_LLog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -128,30 +142,40 @@ def test_log_decoding_LLog(self): log_decoding_LLog` definition. """ - self.assertAlmostEqual( - log_decoding_LLog(0.089999999999999), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_LLog(0.089999999999999), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_LLog(0.435313904043927), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_LLog(0.435313904043927), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_LLog(0.435313904043927, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_LLog(0.435313904043927, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_LLog(0.4353037943344028, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_LLog(0.4353037943344028, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_LLog(0.421586960452824, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_LLog(0.631797439630121), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_LLog(0.631797439630121), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_LLog(self): @@ -165,20 +189,20 @@ def test_n_dimensional_log_decoding_LLog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_decoding_LLog(x), y, decimal=7 + np.testing.assert_allclose( + log_decoding_LLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_LLog(x), y, decimal=7 + np.testing.assert_allclose( + log_decoding_LLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_LLog(x), y, decimal=7 + np.testing.assert_allclose( + log_decoding_LLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_LLog(self): @@ -193,8 +217,10 @@ def test_domain_range_scale_log_decoding_LLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_LLog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_LLog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_linear.py b/colour/models/rgb/transfer_functions/tests/test_linear.py index 7278869a38..d18f7c0568 100644 --- a/colour/models/rgb/transfer_functions/tests/test_linear.py +++ b/colour/models/rgb/transfer_functions/tests/test_linear.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.linear` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import linear_function from colour.utilities import ignore_numpy_errors @@ -50,20 +52,20 @@ def test_n_dimensional_linear_function(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - linear_function(a), a_p, decimal=7 + np.testing.assert_allclose( + linear_function(a), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - linear_function(a), a_p, decimal=7 + np.testing.assert_allclose( + linear_function(a), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - linear_function(a), a_p, decimal=7 + np.testing.assert_allclose( + linear_function(a), a_p, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_log.py b/colour/models/rgb/transfer_functions/tests/test_log.py index bba7a8963c..7a8f4f74f0 100644 --- a/colour/models/rgb/transfer_functions/tests/test_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_log.py @@ -3,15 +3,17 @@ :mod:`colour.models.rgb.transfer_functions.log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( + log_decoding_Log2, + log_encoding_Log2, logarithmic_function_basic, - logarithmic_function_quasilog, logarithmic_function_camera, - log_encoding_Log2, - log_decoding_Log2, + logarithmic_function_quasilog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -43,38 +45,40 @@ def test_logarithmic_function_basic(self): logarithmic_function_basic` definition. """ - self.assertAlmostEqual( - logarithmic_function_basic(0.18), -2.473931188332412, places=7 + np.testing.assert_allclose( + logarithmic_function_basic(0.18), + -2.473931188332412, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_basic(-2.473931188332412, "antiLog2"), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_basic(0.18, "log10"), -0.744727494896694, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_basic(-0.744727494896694, "antiLog10"), 0.179999999999999, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_basic(0.18, "logB", 3), -1.560876795007312, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_basic(-1.560876795007312, "antiLogB", 3), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_logarithmic_function_basic(self): @@ -91,20 +95,26 @@ def test_n_dimensional_logarithmic_function_basic(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - logarithmic_function_basic(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_basic(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - logarithmic_function_basic(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_basic(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - logarithmic_function_basic(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_basic(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -132,86 +142,88 @@ def test_logarithmic_function_quasilog(self): logarithmic_function_quasilog` definition. """ - self.assertAlmostEqual( - logarithmic_function_quasilog(0.18), -2.473931188332412, places=7 + np.testing.assert_allclose( + logarithmic_function_quasilog(0.18), + -2.473931188332412, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog(-2.473931188332412, "logToLin"), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog(0.18, "linToLog", 10), -0.744727494896694, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog(-0.744727494896694, "logToLin", 10), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog(0.18, "linToLog", 10, 0.75), -0.558545621172520, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog( -0.558545621172520, "logToLin", 10, 0.75 ), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog(0.18, "linToLog", 10, 0.75, 0.75), -0.652249673628745, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog( -0.652249673628745, "logToLin", 10, 0.75, 0.75 ), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog( 0.18, "linToLog", 10, 0.75, 0.75, 0.001 ), -0.651249673628745, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog( -0.651249673628745, "logToLin", 10, 0.75, 0.75, 0.001 ), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog( 0.18, "linToLog", 10, 0.75, 0.75, 0.001, 0.01 ), -0.627973998323769, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_quasilog( -0.627973998323769, "logToLin", 10, 0.75, 0.75, 0.001, 0.01 ), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_logarithmic_function_quasilog(self): @@ -228,20 +240,26 @@ def test_n_dimensional_logarithmic_function_quasilog(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - logarithmic_function_quasilog(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_quasilog(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - logarithmic_function_quasilog(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_quasilog(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - logarithmic_function_quasilog(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_quasilog(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -269,127 +287,127 @@ def test_logarithmic_function_camera(self): logarithmic_function_camera` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(0, "cameraLinToLog"), -9.08655123066369, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(-9.08655123066369, "cameraLogToLin"), 0.000000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(0.18, "cameraLinToLog"), -2.473931188332412, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(-2.473931188332412, "cameraLogToLin"), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(1, "cameraLinToLog"), 0.000000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(0, "cameraLogToLin"), 1.000000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(0.18, "cameraLinToLog", 10), -0.744727494896693, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( -0.744727494896693, "cameraLogToLin", 10 ), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera(0.18, "cameraLinToLog", 10, 0.25), -0.186181873724173, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( -0.186181873724173, "cameraLogToLin", 10, 0.25 ), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.18, "cameraLinToLog", 10, 0.25, 0.95 ), -0.191750972401961, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( -0.191750972401961, "cameraLogToLin", 10, 0.25, 0.95 ), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.18, "cameraLinToLog", 10, 0.25, 0.95, 0.6 ), 0.408249027598038, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.408249027598038, "cameraLogToLin", 10, 0.25, 0.95, 0.6 ), 0.179999999999999, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.18, "cameraLinToLog", 10, 0.25, 0.95, 0.6, 0.01 ), 0.414419643717296, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.414419643717296, "cameraLogToLin", 10, 0.25, 0.95, 0.6, 0.01 ), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.005, "cameraLinToLog", 10, 0.25, 0.95, 0.6, 0.01, 0.01 ), 0.146061232468316, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.146061232468316, "cameraLogToLin", @@ -401,18 +419,18 @@ def test_logarithmic_function_camera(self): 0.01, ), 0.005000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.005, "cameraLinToLog", 10, 0.25, 0.95, 0.6, 0.01, 0.01, 6 ), 0.142508652840630, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( logarithmic_function_camera( 0.142508652840630, "cameraLogToLin", @@ -425,7 +443,7 @@ def test_logarithmic_function_camera(self): 6, ), 0.005000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_logarithmic_function_camera(self): @@ -442,20 +460,26 @@ def test_n_dimensional_logarithmic_function_camera(self): a = np.tile(a, 6) a_p = np.tile(a_p, 6) - np.testing.assert_array_almost_equal( - logarithmic_function_camera(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_camera(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3)) a_p = np.reshape(a_p, (2, 3)) - np.testing.assert_array_almost_equal( - logarithmic_function_camera(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_camera(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 1)) a_p = np.reshape(a_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - logarithmic_function_camera(a, style), a_p, decimal=7 + np.testing.assert_allclose( + logarithmic_function_camera(a, style), + a_p, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -483,28 +507,36 @@ def test_log_encoding_Log2(self): log_encoding_Log2` definition. """ - self.assertAlmostEqual(log_encoding_Log2(0.0), -np.inf, places=7) + np.testing.assert_allclose( + log_encoding_Log2(0.0), -np.inf, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(log_encoding_Log2(0.18), 0.5, places=7) + np.testing.assert_allclose( + log_encoding_Log2(0.18), 0.5, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_Log2(1.0), 0.690302399102493, places=7 + np.testing.assert_allclose( + log_encoding_Log2(1.0), + 0.690302399102493, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Log2(0.18, 0.12), 0.544997115440089, places=7 + np.testing.assert_allclose( + log_encoding_Log2(0.18, 0.12), + 0.544997115440089, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_Log2(0.18, 0.12, 2**-10), 0.089857490719529, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_Log2(0.18, 0.12, 2**-10, 2**10), 0.000570299311674, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_Log2(self): @@ -518,20 +550,20 @@ def test_n_dimensional_log_encoding_Log2(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Log2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Log2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Log2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Log2(self): @@ -546,8 +578,10 @@ def test_domain_range_scale_log_encoding_Log2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Log2(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Log2(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -572,30 +606,38 @@ def test_log_decoding_Log2(self): log_decoding_Log2` definition. """ - self.assertAlmostEqual( - log_decoding_Log2(0.0), 0.001988737822087, places=7 + np.testing.assert_allclose( + log_decoding_Log2(0.0), + 0.001988737822087, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_decoding_Log2(0.5), 0.18, places=7) + np.testing.assert_allclose( + log_decoding_Log2(0.5), 0.18, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_Log2(0.690302399102493), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_Log2(0.690302399102493), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Log2(0.544997115440089, 0.12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Log2(0.544997115440089, 0.12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_Log2(0.089857490719529, 0.12, 2**-10), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_Log2(0.000570299311674, 0.12, 2**-10, 2**10), 0.180000000000000, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_Log2(self): @@ -609,20 +651,20 @@ def test_n_dimensional_log_decoding_Log2(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Log2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Log2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Log2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Log2(self): @@ -637,8 +679,10 @@ def test_domain_range_scale_log_decoding_Log2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Log2(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Log2(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_nikon_n_log.py b/colour/models/rgb/transfer_functions/tests/test_nikon_n_log.py index eb37baf310..55f4b869c3 100644 --- a/colour/models/rgb/transfer_functions/tests/test_nikon_n_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_nikon_n_log.py @@ -3,12 +3,14 @@ nikon_n_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_NLog, log_decoding_NLog, + log_encoding_NLog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,30 +39,40 @@ def test_log_encoding_NLog(self): log_encoding_NLog` definition. """ - self.assertAlmostEqual( - log_encoding_NLog(0.0), 0.124372627896372, places=7 + np.testing.assert_allclose( + log_encoding_NLog(0.0), + 0.124372627896372, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_NLog(0.18), 0.363667770117139, places=7 + np.testing.assert_allclose( + log_encoding_NLog(0.18), + 0.363667770117139, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_NLog(0.18, 12), 0.363667770117139, places=7 + np.testing.assert_allclose( + log_encoding_NLog(0.18, 12), + 0.363667770117139, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_NLog(0.18, 10, False), 0.351634850262366, places=7 + np.testing.assert_allclose( + log_encoding_NLog(0.18, 10, False), + 0.351634850262366, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_NLog(0.18, 10, False, False), 0.337584957293328, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_NLog(1.0), 0.605083088954056, places=7 + np.testing.assert_allclose( + log_encoding_NLog(1.0), + 0.605083088954056, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_NLog(self): @@ -74,20 +86,20 @@ def test_n_dimensional_log_encoding_NLog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_encoding_NLog(y), x, decimal=7 + np.testing.assert_allclose( + log_encoding_NLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_NLog(y), x, decimal=7 + np.testing.assert_allclose( + log_encoding_NLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_NLog(y), x, decimal=7 + np.testing.assert_allclose( + log_encoding_NLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_NLog(self): @@ -102,8 +114,10 @@ def test_domain_range_scale_log_encoding_NLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_NLog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_NLog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -128,30 +142,40 @@ def test_log_decoding_NLog(self): log_decoding_NLog` definition. """ - self.assertAlmostEqual( - log_decoding_NLog(0.124372627896372), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_NLog(0.124372627896372), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_NLog(0.363667770117139), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_NLog(0.363667770117139), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_NLog(0.363667770117139, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_NLog(0.363667770117139, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_NLog(0.351634850262366, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_NLog(0.351634850262366, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_NLog(0.337584957293328, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_NLog(0.605083088954056), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_NLog(0.605083088954056), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_NLog(self): @@ -165,20 +189,20 @@ def test_n_dimensional_log_decoding_NLog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_decoding_NLog(x), y, decimal=7 + np.testing.assert_allclose( + log_decoding_NLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_NLog(x), y, decimal=7 + np.testing.assert_allclose( + log_decoding_NLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_NLog(x), y, decimal=7 + np.testing.assert_allclose( + log_decoding_NLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_NLog(self): @@ -193,8 +217,10 @@ def test_domain_range_scale_log_decoding_NLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_NLog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_NLog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_panalog.py b/colour/models/rgb/transfer_functions/tests/test_panalog.py index 3a81dcb796..a2eebe75ac 100644 --- a/colour/models/rgb/transfer_functions/tests/test_panalog.py +++ b/colour/models/rgb/transfer_functions/tests/test_panalog.py @@ -3,12 +3,14 @@ :mod:`colour.models.rgb.transfer_functions.panalog` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_Panalog, log_decoding_Panalog, + log_encoding_Panalog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,16 +39,22 @@ def test_log_encoding_Panalog(self): log_encoding_Panalog` definition. """ - self.assertAlmostEqual( - log_encoding_Panalog(0.0), 0.062561094819159, places=7 + np.testing.assert_allclose( + log_encoding_Panalog(0.0), + 0.062561094819159, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Panalog(0.18), 0.374576791382298, places=7 + np.testing.assert_allclose( + log_encoding_Panalog(0.18), + 0.374576791382298, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Panalog(1.0), 0.665689149560117, places=7 + np.testing.assert_allclose( + log_encoding_Panalog(1.0), + 0.665689149560117, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_Panalog(self): @@ -60,20 +68,20 @@ def test_n_dimensional_log_encoding_Panalog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Panalog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Panalog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Panalog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Panalog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Panalog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Panalog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Panalog(self): @@ -88,8 +96,10 @@ def test_domain_range_scale_log_encoding_Panalog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Panalog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Panalog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -116,16 +126,22 @@ def test_log_decoding_Panalog(self): log_decoding_Panalog` definition. """ - self.assertAlmostEqual( - log_decoding_Panalog(0.062561094819159), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_Panalog(0.062561094819159), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Panalog(0.374576791382298), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Panalog(0.374576791382298), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Panalog(0.665689149560117), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_Panalog(0.665689149560117), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_Panalog(self): @@ -139,20 +155,20 @@ def test_n_dimensional_log_decoding_Panalog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Panalog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Panalog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Panalog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Panalog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Panalog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Panalog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Panalog(self): @@ -167,8 +183,10 @@ def test_domain_range_scale_log_decoding_Panalog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Panalog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Panalog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py b/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py index 17956660db..8c8d3bc31a 100644 --- a/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py +++ b/colour/models/rgb/transfer_functions/tests/test_panasonic_vlog.py @@ -3,12 +3,14 @@ panasonic_v_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_VLog, log_decoding_VLog, + log_encoding_VLog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,28 +39,38 @@ def test_log_encoding_VLog(self): log_encoding_VLog` definition. """ - self.assertAlmostEqual(log_encoding_VLog(0.0), 0.125, places=7) + np.testing.assert_allclose( + log_encoding_VLog(0.0), 0.125, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_VLog(0.18), 0.423311448760136, places=7 + np.testing.assert_allclose( + log_encoding_VLog(0.18), + 0.423311448760136, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_VLog(0.18, 12), 0.423311448760136, places=7 + np.testing.assert_allclose( + log_encoding_VLog(0.18, 12), + 0.423311448760136, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_VLog(0.18, 10, False), 0.421287228403675, places=7 + np.testing.assert_allclose( + log_encoding_VLog(0.18, 10, False), + 0.421287228403675, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_VLog(0.18, 10, False, False), 0.409009628526078, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_VLog(1.0), 0.599117700158146, places=7 + np.testing.assert_allclose( + log_encoding_VLog(1.0), + 0.599117700158146, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_VLog(self): @@ -72,20 +84,20 @@ def test_n_dimensional_log_encoding_VLog(self): L_in = np.tile(L_in, 6) V_out = np.tile(V_out, 6) - np.testing.assert_array_almost_equal( - log_encoding_VLog(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_VLog(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) L_in = np.reshape(L_in, (2, 3)) V_out = np.reshape(V_out, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_VLog(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_VLog(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) L_in = np.reshape(L_in, (2, 3, 1)) V_out = np.reshape(V_out, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_VLog(L_in), V_out, decimal=7 + np.testing.assert_allclose( + log_encoding_VLog(L_in), V_out, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_VLog(self): @@ -100,8 +112,10 @@ def test_domain_range_scale_log_encoding_VLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_VLog(L_in * factor), V_out * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_VLog(L_in * factor), + V_out * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -126,28 +140,38 @@ def test_log_decoding_VLog(self): log_decoding_VLog` definition. """ - self.assertAlmostEqual(log_decoding_VLog(0.125), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_VLog(0.125), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_VLog(0.423311448760136), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_VLog(0.423311448760136), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_VLog(0.423311448760136, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_VLog(0.423311448760136, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_VLog(0.421287228403675, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_VLog(0.421287228403675, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_VLog(0.409009628526078, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_VLog(0.599117700158146), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_VLog(0.599117700158146), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_VLog(self): @@ -161,20 +185,20 @@ def test_n_dimensional_log_decoding_VLog(self): V_out = np.tile(V_out, 6) L_in = np.tile(L_in, 6) - np.testing.assert_array_almost_equal( - log_decoding_VLog(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_VLog(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) V_out = np.reshape(V_out, (2, 3)) L_in = np.reshape(L_in, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_VLog(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_VLog(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) V_out = np.reshape(V_out, (2, 3, 1)) L_in = np.reshape(L_in, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_VLog(V_out), L_in, decimal=7 + np.testing.assert_allclose( + log_decoding_VLog(V_out), L_in, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_VLog(self): @@ -189,8 +213,10 @@ def test_domain_range_scale_log_decoding_VLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_VLog(V_out * factor), L_in * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_VLog(V_out * factor), + L_in * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_pivoted_log.py b/colour/models/rgb/transfer_functions/tests/test_pivoted_log.py index dc3a35745b..81a16222ab 100644 --- a/colour/models/rgb/transfer_functions/tests/test_pivoted_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_pivoted_log.py @@ -3,12 +3,14 @@ pivoted_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_PivotedLog, log_decoding_PivotedLog, + log_encoding_PivotedLog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,14 +39,22 @@ def test_log_encoding_PivotedLog(self): log_encoding_PivotedLog` definition. """ - self.assertAlmostEqual(log_encoding_PivotedLog(0.0), -np.inf, places=7) + np.testing.assert_allclose( + log_encoding_PivotedLog(0.0), + -np.inf, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - self.assertAlmostEqual( - log_encoding_PivotedLog(0.18), 0.434995112414467, places=7 + np.testing.assert_allclose( + log_encoding_PivotedLog(0.18), + 0.434995112414467, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_PivotedLog(1.0), 0.653390272208219, places=7 + np.testing.assert_allclose( + log_encoding_PivotedLog(1.0), + 0.653390272208219, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_PivotedLog(self): @@ -58,20 +68,20 @@ def test_n_dimensional_log_encoding_PivotedLog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_PivotedLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_PivotedLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_PivotedLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_PivotedLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_PivotedLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_PivotedLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_PivotedLog(self): @@ -86,8 +96,10 @@ def test_domain_range_scale_log_encoding_PivotedLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_PivotedLog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_PivotedLog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -114,14 +126,22 @@ def test_log_decoding_PivotedLog(self): log_decoding_PivotedLog` definition. """ - self.assertAlmostEqual(log_decoding_PivotedLog(-np.inf), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_PivotedLog(-np.inf), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) - self.assertAlmostEqual( - log_decoding_PivotedLog(0.434995112414467), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_PivotedLog(0.434995112414467), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_PivotedLog(0.653390272208219), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_PivotedLog(0.653390272208219), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_PivotedLog(self): @@ -135,20 +155,20 @@ def test_n_dimensional_log_decoding_PivotedLog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_PivotedLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_PivotedLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_PivotedLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_PivotedLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_PivotedLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_PivotedLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_PivotedLog(self): @@ -163,8 +183,10 @@ def test_domain_range_scale_log_decoding_PivotedLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_PivotedLog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_PivotedLog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_red.py b/colour/models/rgb/transfer_functions/tests/test_red.py index 07be4e4365..186a1f3a71 100644 --- a/colour/models/rgb/transfer_functions/tests/test_red.py +++ b/colour/models/rgb/transfer_functions/tests/test_red.py @@ -3,24 +3,26 @@ :mod:`colour.models.rgb.transfer_functions.red` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_REDLog, + log_decoding_Log3G12, log_decoding_REDLog, - log_encoding_REDLogFilm, log_decoding_REDLogFilm, log_encoding_Log3G12, - log_decoding_Log3G12, + log_encoding_REDLog, + log_encoding_REDLogFilm, ) from colour.models.rgb.transfer_functions.red import ( - log_encoding_Log3G10_v1, log_decoding_Log3G10_v1, - log_encoding_Log3G10_v2, log_decoding_Log3G10_v2, - log_encoding_Log3G10_v3, log_decoding_Log3G10_v3, + log_encoding_Log3G10_v1, + log_encoding_Log3G10_v2, + log_encoding_Log3G10_v3, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -59,13 +61,19 @@ def test_log_encoding_REDLog(self): log_encoding_REDLog` definition. """ - self.assertAlmostEqual(log_encoding_REDLog(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_encoding_REDLog(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_REDLog(0.18), 0.637621845988175, places=7 + np.testing.assert_allclose( + log_encoding_REDLog(0.18), + 0.637621845988175, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_encoding_REDLog(1.0), 1.0, places=7) + np.testing.assert_allclose( + log_encoding_REDLog(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_log_encoding_REDLog(self): """ @@ -78,20 +86,20 @@ def test_n_dimensional_log_encoding_REDLog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_REDLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_REDLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_REDLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_REDLog(self): @@ -106,8 +114,10 @@ def test_domain_range_scale_log_encoding_REDLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_REDLog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -134,13 +144,19 @@ def test_log_decoding_REDLog(self): log_decoding_REDLog` definition. """ - self.assertAlmostEqual(log_decoding_REDLog(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_REDLog(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_REDLog(0.637621845988175), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_REDLog(0.637621845988175), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_decoding_REDLog(1.0), 1.0, places=7) + np.testing.assert_allclose( + log_decoding_REDLog(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_log_decoding_REDLog(self): """ @@ -153,20 +169,20 @@ def test_n_dimensional_log_decoding_REDLog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_REDLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_REDLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_REDLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_REDLog(self): @@ -181,8 +197,10 @@ def test_domain_range_scale_log_decoding_REDLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_REDLog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -209,16 +227,22 @@ def test_log_encoding_REDLogFilm(self): log_encoding_REDLogFilm` definition. """ - self.assertAlmostEqual( - log_encoding_REDLogFilm(0.0), 0.092864125122190, places=7 + np.testing.assert_allclose( + log_encoding_REDLogFilm(0.0), + 0.092864125122190, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_REDLogFilm(0.18), 0.457319613085418, places=7 + np.testing.assert_allclose( + log_encoding_REDLogFilm(0.18), + 0.457319613085418, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_REDLogFilm(1.0), 0.669599217986315, places=7 + np.testing.assert_allclose( + log_encoding_REDLogFilm(1.0), + 0.669599217986315, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_REDLogFilm(self): @@ -232,20 +256,20 @@ def test_n_dimensional_log_encoding_REDLogFilm(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_REDLogFilm(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLogFilm(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_REDLogFilm(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLogFilm(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_REDLogFilm(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLogFilm(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_REDLogFilm(self): @@ -260,8 +284,10 @@ def test_domain_range_scale_log_encoding_REDLogFilm(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_REDLogFilm(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_REDLogFilm(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -288,16 +314,22 @@ def test_log_decoding_REDLogFilm(self): log_decoding_REDLogFilm` definition. """ - self.assertAlmostEqual( - log_decoding_REDLogFilm(0.092864125122190), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_REDLogFilm(0.092864125122190), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_REDLogFilm(0.457319613085418), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_REDLogFilm(0.457319613085418), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_REDLogFilm(0.669599217986315), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_REDLogFilm(0.669599217986315), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_REDLogFilm(self): @@ -311,20 +343,20 @@ def test_n_dimensional_log_decoding_REDLogFilm(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_REDLogFilm(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLogFilm(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_REDLogFilm(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLogFilm(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_REDLogFilm(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLogFilm(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_REDLogFilm(self): @@ -339,8 +371,10 @@ def test_domain_range_scale_log_decoding_REDLogFilm(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_REDLogFilm(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_REDLogFilm(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -367,14 +401,20 @@ def test_log_encoding_Log3G10_v1(self): log_encoding_Log3G10_v1` definition. """ - self.assertAlmostEqual( - log_encoding_Log3G10_v1(-1.0), -0.496483569056003, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v1(-1.0), + -0.496483569056003, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_encoding_Log3G10_v1(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_encoding_Log3G10_v1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_Log3G10_v1(0.18), 0.333333644207707, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v1(0.18), + 0.333333644207707, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_Log3G10_v1(self): @@ -388,20 +428,20 @@ def test_n_dimensional_log_encoding_Log3G10_v1(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v1(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v1(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v1(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v1(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v1(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v1(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Log3G10_v1(self): @@ -416,8 +456,10 @@ def test_domain_range_scale_log_encoding_Log3G10_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v1(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v1(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -444,14 +486,20 @@ def test_log_decoding_Log3G10_v1(self): log_decoding_Log3G10_v1` definition. """ - self.assertAlmostEqual( - log_decoding_Log3G10_v1(-0.496483569056003), -1.0, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v1(-0.496483569056003), + -1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_decoding_Log3G10_v1(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_Log3G10_v1(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_Log3G10_v1(0.333333644207707), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v1(0.333333644207707), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_Log3G10_v1(self): @@ -465,20 +513,20 @@ def test_n_dimensional_log_decoding_Log3G10_v1(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v1(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v1(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v1(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v1(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v1(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v1(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Log3G10_v1(self): @@ -493,8 +541,10 @@ def test_domain_range_scale_log_decoding_Log3G10_v1(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v1(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v1(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -521,16 +571,22 @@ def test_log_encoding_Log3G10_v2(self): log_encoding_Log3G10_v2` definition. """ - self.assertAlmostEqual( - log_encoding_Log3G10_v2(-1.0), -0.491512777522511, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v2(-1.0), + -0.491512777522511, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Log3G10_v2(0.0), 0.091551487714745, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v2(0.0), + 0.091551487714745, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Log3G10_v2(0.18), 0.333332912025992, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v2(0.18), + 0.333332912025992, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_Log3G10_v2(self): @@ -544,20 +600,20 @@ def test_n_dimensional_log_encoding_Log3G10_v2(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Log3G10_v2(self): @@ -572,8 +628,10 @@ def test_domain_range_scale_log_encoding_Log3G10_v2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v2(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v2(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -600,16 +658,22 @@ def test_log_decoding_Log3G10_v2(self): log_decoding_Log3G10_v2` definition. """ - self.assertAlmostEqual( - log_decoding_Log3G10_v2(-0.491512777522511), -1.0, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v2(-0.491512777522511), + -1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Log3G10_v2(0.091551487714745), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v2(0.091551487714745), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Log3G10_v2(0.333332912025992), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v2(0.333332912025992), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_Log3G10_v2(self): @@ -623,20 +687,20 @@ def test_n_dimensional_log_decoding_Log3G10_v2(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Log3G10_v2(self): @@ -651,8 +715,10 @@ def test_domain_range_scale_log_decoding_Log3G10_v2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v2(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v2(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -679,16 +745,22 @@ def test_log_encoding_Log3G10_v3(self): log_encoding_Log3G10_v3` definition. """ - self.assertAlmostEqual( - log_encoding_Log3G10_v3(-1.0), -15.040773, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v3(-1.0), + -15.040773, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Log3G10_v3(0.0), 0.091551487714745, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v3(0.0), + 0.091551487714745, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Log3G10_v3(0.18), 0.333332912025992, places=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v3(0.18), + 0.333332912025992, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_Log3G10_v3(self): @@ -702,20 +774,20 @@ def test_n_dimensional_log_encoding_Log3G10_v3(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v3(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v3(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v3(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v3(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v3(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v3(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Log3G10_v3(self): @@ -730,8 +802,10 @@ def test_domain_range_scale_log_encoding_Log3G10_v3(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Log3G10_v3(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G10_v3(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -758,16 +832,22 @@ def test_log_decoding_Log3G10_v3(self): log_decoding_Log3G10_v3` definition. """ - self.assertAlmostEqual( - log_decoding_Log3G10_v3(-15.040773), -1.0, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v3(-15.040773), + -1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Log3G10_v3(0.091551487714745), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v3(0.091551487714745), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Log3G10_v3(0.333332912025992), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v3(0.333332912025992), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_Log3G10_v3(self): @@ -781,20 +861,20 @@ def test_n_dimensional_log_decoding_Log3G10_v3(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v3(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v3(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v3(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v3(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v3(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v3(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Log3G10_v3(self): @@ -809,8 +889,10 @@ def test_domain_range_scale_log_decoding_Log3G10_v3(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Log3G10_v3(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G10_v3(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -837,18 +919,26 @@ def test_log_encoding_Log3G12(self): log_encoding_Log3G12` definition. """ - self.assertAlmostEqual(log_encoding_Log3G12(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_encoding_Log3G12(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_Log3G12(0.18), 0.333332662015923, places=7 + np.testing.assert_allclose( + log_encoding_Log3G12(0.18), + 0.333332662015923, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Log3G12(1.0), 0.469991923234319, places=7 + np.testing.assert_allclose( + log_encoding_Log3G12(1.0), + 0.469991923234319, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_Log3G12(0.18 * 2**12), 0.999997986792394, places=7 + np.testing.assert_allclose( + log_encoding_Log3G12(0.18 * 2**12), + 0.999997986792394, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_Log3G12(self): @@ -862,20 +952,20 @@ def test_n_dimensional_log_encoding_Log3G12(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_Log3G12(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G12(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G12(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G12(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_Log3G12(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G12(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_Log3G12(self): @@ -890,8 +980,10 @@ def test_domain_range_scale_log_encoding_Log3G12(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_Log3G12(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_Log3G12(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -918,18 +1010,26 @@ def test_log_decoding_Log3G12(self): log_decoding_Log3G12` definition. """ - self.assertAlmostEqual(log_decoding_Log3G12(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_Log3G12(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_Log3G12(0.333332662015923), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_Log3G12(0.333332662015923), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Log3G12(0.469991923234319), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_Log3G12(0.469991923234319), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_Log3G12(1.0), 737.29848406719, places=7 + np.testing.assert_allclose( + log_decoding_Log3G12(1.0), + 737.29848406719, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_Log3G12(self): @@ -943,20 +1043,20 @@ def test_n_dimensional_log_decoding_Log3G12(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_Log3G12(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G12(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G12(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G12(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_Log3G12(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G12(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_Log3G12(self): @@ -971,8 +1071,10 @@ def test_domain_range_scale_log_decoding_Log3G12(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_Log3G12(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_Log3G12(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_rimm_romm_rgb.py b/colour/models/rgb/transfer_functions/tests/test_rimm_romm_rgb.py index 5bf7b68d63..4dab824f3e 100644 --- a/colour/models/rgb/transfer_functions/tests/test_rimm_romm_rgb.py +++ b/colour/models/rgb/transfer_functions/tests/test_rimm_romm_rgb.py @@ -3,16 +3,18 @@ :mod:`colour.models.rgb.transfer_functions.rimm_romm_rgb` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - cctf_encoding_ROMMRGB, + cctf_decoding_RIMMRGB, cctf_decoding_ROMMRGB, cctf_encoding_RIMMRGB, - cctf_decoding_RIMMRGB, - log_encoding_ERIMMRGB, + cctf_encoding_ROMMRGB, log_decoding_ERIMMRGB, + log_encoding_ERIMMRGB, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -45,13 +47,19 @@ def test_cctf_encoding_ROMMRGB(self): cctf_encoding_ROMMRGB` definition. """ - self.assertAlmostEqual(cctf_encoding_ROMMRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + cctf_encoding_ROMMRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - cctf_encoding_ROMMRGB(0.18), 0.385711424751138, places=7 + np.testing.assert_allclose( + cctf_encoding_ROMMRGB(0.18), + 0.385711424751138, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(cctf_encoding_ROMMRGB(1.0), 1.0, places=7) + np.testing.assert_allclose( + cctf_encoding_ROMMRGB(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) self.assertEqual(cctf_encoding_ROMMRGB(0.18, out_int=True), 98) @@ -70,20 +78,20 @@ def test_n_dimensional_cctf_encoding_ROMMRGB(self): X = np.tile(X, 6) X_ROMM = np.tile(X_ROMM, 6) - np.testing.assert_array_almost_equal( - cctf_encoding_ROMMRGB(X), X_ROMM, decimal=7 + np.testing.assert_allclose( + cctf_encoding_ROMMRGB(X), X_ROMM, atol=TOLERANCE_ABSOLUTE_TESTS ) X = np.reshape(X, (2, 3)) X_ROMM = np.reshape(X_ROMM, (2, 3)) - np.testing.assert_array_almost_equal( - cctf_encoding_ROMMRGB(X), X_ROMM, decimal=7 + np.testing.assert_allclose( + cctf_encoding_ROMMRGB(X), X_ROMM, atol=TOLERANCE_ABSOLUTE_TESTS ) X = np.reshape(X, (2, 3, 1)) X_ROMM = np.reshape(X_ROMM, (2, 3, 1)) - np.testing.assert_array_almost_equal( - cctf_encoding_ROMMRGB(X), X_ROMM, decimal=7 + np.testing.assert_allclose( + cctf_encoding_ROMMRGB(X), X_ROMM, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_cctf_encoding_ROMMRGB(self): @@ -98,8 +106,10 @@ def test_domain_range_scale_cctf_encoding_ROMMRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - cctf_encoding_ROMMRGB(X * factor), X_p * factor, decimal=7 + np.testing.assert_allclose( + cctf_encoding_ROMMRGB(X * factor), + X_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -126,26 +136,30 @@ def test_cctf_decoding_ROMMRGB(self): cctf_decoding_ROMMRGB` definition. """ - self.assertAlmostEqual(cctf_decoding_ROMMRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + cctf_decoding_ROMMRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - cctf_decoding_ROMMRGB(0.385711424751138), 0.18, places=7 + np.testing.assert_allclose( + cctf_decoding_ROMMRGB(0.385711424751138), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(cctf_decoding_ROMMRGB(1.0), 1.0, places=7) + np.testing.assert_allclose( + cctf_decoding_ROMMRGB(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) np.testing.assert_allclose( cctf_decoding_ROMMRGB(98, in_int=True), 0.18, - atol=0.001, - rtol=0.001, + atol=0.01, ) np.testing.assert_allclose( cctf_decoding_ROMMRGB(1579, bit_depth=12, in_int=True), 0.18, atol=0.001, - rtol=0.001, ) def test_n_dimensional_cctf_decoding_ROMMRGB(self): @@ -159,20 +173,20 @@ def test_n_dimensional_cctf_decoding_ROMMRGB(self): X_p = np.tile(X_p, 6) X = np.tile(X, 6) - np.testing.assert_array_almost_equal( - cctf_decoding_ROMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + cctf_decoding_ROMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) X_p = np.reshape(X_p, (2, 3)) X = np.reshape(X, (2, 3)) - np.testing.assert_array_almost_equal( - cctf_decoding_ROMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + cctf_decoding_ROMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) X_p = np.reshape(X_p, (2, 3, 1)) X = np.reshape(X, (2, 3, 1)) - np.testing.assert_array_almost_equal( - cctf_decoding_ROMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + cctf_decoding_ROMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_cctf_decoding_ROMMRGB(self): @@ -187,8 +201,10 @@ def test_domain_range_scale_cctf_decoding_ROMMRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - cctf_decoding_ROMMRGB(X_p * factor), X * factor, decimal=7 + np.testing.assert_allclose( + cctf_decoding_ROMMRGB(X_p * factor), + X * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -215,14 +231,20 @@ def test_cctf_encoding_RIMMRGB(self): cctf_encoding_RIMMRGB` definition. """ - self.assertAlmostEqual(cctf_encoding_RIMMRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + cctf_encoding_RIMMRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - cctf_encoding_RIMMRGB(0.18), 0.291673732475746, places=7 + np.testing.assert_allclose( + cctf_encoding_RIMMRGB(0.18), + 0.291673732475746, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - cctf_encoding_RIMMRGB(1.0), 0.713125234297525, places=7 + np.testing.assert_allclose( + cctf_encoding_RIMMRGB(1.0), + 0.713125234297525, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(cctf_encoding_RIMMRGB(0.18, out_int=True), 74) @@ -242,20 +264,20 @@ def test_n_dimensional_cctf_encoding_RIMMRGB(self): X = np.tile(X, 6) X_p = np.tile(X_p, 6) - np.testing.assert_array_almost_equal( - cctf_encoding_RIMMRGB(X), X_p, decimal=7 + np.testing.assert_allclose( + cctf_encoding_RIMMRGB(X), X_p, atol=TOLERANCE_ABSOLUTE_TESTS ) X = np.reshape(X, (2, 3)) X_p = np.reshape(X_p, (2, 3)) - np.testing.assert_array_almost_equal( - cctf_encoding_RIMMRGB(X), X_p, decimal=7 + np.testing.assert_allclose( + cctf_encoding_RIMMRGB(X), X_p, atol=TOLERANCE_ABSOLUTE_TESTS ) X = np.reshape(X, (2, 3, 1)) X_p = np.reshape(X_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - cctf_encoding_RIMMRGB(X), X_p, decimal=7 + np.testing.assert_allclose( + cctf_encoding_RIMMRGB(X), X_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_cctf_encoding_RIMMRGB(self): @@ -270,8 +292,10 @@ def test_domain_range_scale_cctf_encoding_RIMMRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - cctf_encoding_RIMMRGB(X * factor), X_p * factor, decimal=7 + np.testing.assert_allclose( + cctf_encoding_RIMMRGB(X * factor), + X_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -298,28 +322,32 @@ def test_cctf_decoding_RIMMRGB(self): cctf_decoding_RIMMRGB` definition. """ - self.assertAlmostEqual(cctf_decoding_RIMMRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + cctf_decoding_RIMMRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - cctf_decoding_RIMMRGB(0.291673732475746), 0.18, places=7 + np.testing.assert_allclose( + cctf_decoding_RIMMRGB(0.291673732475746), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - cctf_decoding_RIMMRGB(0.713125234297525), 1.0, places=7 + np.testing.assert_allclose( + cctf_decoding_RIMMRGB(0.713125234297525), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( cctf_decoding_RIMMRGB(74, in_int=True), 0.18, atol=0.005, - rtol=0.005, ) np.testing.assert_allclose( cctf_decoding_RIMMRGB(1194, bit_depth=12, in_int=True), 0.18, atol=0.005, - rtol=0.005, ) def test_n_dimensional_cctf_decoding_RIMMRGB(self): @@ -333,20 +361,20 @@ def test_n_dimensional_cctf_decoding_RIMMRGB(self): X_p = np.tile(X_p, 6) X = np.tile(X, 6) - np.testing.assert_array_almost_equal( - cctf_decoding_RIMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + cctf_decoding_RIMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) X_p = np.reshape(X_p, (2, 3)) X = np.reshape(X, (2, 3)) - np.testing.assert_array_almost_equal( - cctf_decoding_RIMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + cctf_decoding_RIMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) X_p = np.reshape(X_p, (2, 3, 1)) X = np.reshape(X, (2, 3, 1)) - np.testing.assert_array_almost_equal( - cctf_decoding_RIMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + cctf_decoding_RIMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_cctf_decoding_RIMMRGB(self): @@ -361,8 +389,10 @@ def test_domain_range_scale_cctf_decoding_RIMMRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - cctf_decoding_RIMMRGB(X_p * factor), X * factor, decimal=7 + np.testing.assert_allclose( + cctf_decoding_RIMMRGB(X_p * factor), + X * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -389,14 +419,20 @@ def test_log_encoding_ERIMMRGB(self): log_encoding_ERIMMRGB` definition. """ - self.assertAlmostEqual(log_encoding_ERIMMRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_encoding_ERIMMRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_ERIMMRGB(0.18), 0.410052389492129, places=7 + np.testing.assert_allclose( + log_encoding_ERIMMRGB(0.18), + 0.410052389492129, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_ERIMMRGB(1.0), 0.545458327405113, places=7 + np.testing.assert_allclose( + log_encoding_ERIMMRGB(1.0), + 0.545458327405113, + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual(log_encoding_ERIMMRGB(0.18, out_int=True), 105) @@ -416,20 +452,20 @@ def test_n_dimensional_log_encoding_ERIMMRGB(self): X = np.tile(X, 6) X_p = np.tile(X_p, 6) - np.testing.assert_array_almost_equal( - log_encoding_ERIMMRGB(X), X_p, decimal=7 + np.testing.assert_allclose( + log_encoding_ERIMMRGB(X), X_p, atol=TOLERANCE_ABSOLUTE_TESTS ) X = np.reshape(X, (2, 3)) X_p = np.reshape(X_p, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ERIMMRGB(X), X_p, decimal=7 + np.testing.assert_allclose( + log_encoding_ERIMMRGB(X), X_p, atol=TOLERANCE_ABSOLUTE_TESTS ) X = np.reshape(X, (2, 3, 1)) X_p = np.reshape(X_p, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ERIMMRGB(X), X_p, decimal=7 + np.testing.assert_allclose( + log_encoding_ERIMMRGB(X), X_p, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_ERIMMRGB(self): @@ -444,8 +480,10 @@ def test_domain_range_scale_log_encoding_ERIMMRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_ERIMMRGB(X * factor), X_p * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_ERIMMRGB(X * factor), + X_p * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -472,28 +510,32 @@ def test_log_decoding_ERIMMRGB(self): log_decoding_ERIMMRGB` definition. """ - self.assertAlmostEqual(log_decoding_ERIMMRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_ERIMMRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_ERIMMRGB(0.410052389492129), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_ERIMMRGB(0.410052389492129), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_ERIMMRGB(0.545458327405113), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_ERIMMRGB(0.545458327405113), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( log_decoding_ERIMMRGB(105, in_int=True), 0.18, atol=0.005, - rtol=0.005, ) np.testing.assert_allclose( log_decoding_ERIMMRGB(1679, bit_depth=12, in_int=True), 0.18, atol=0.005, - rtol=0.005, ) def test_n_dimensional_log_decoding_ERIMMRGB(self): @@ -507,20 +549,20 @@ def test_n_dimensional_log_decoding_ERIMMRGB(self): X_p = np.tile(X_p, 6) X = np.tile(X, 6) - np.testing.assert_array_almost_equal( - log_decoding_ERIMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + log_decoding_ERIMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) X_p = np.reshape(X_p, (2, 3)) X = np.reshape(X, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ERIMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + log_decoding_ERIMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) X_p = np.reshape(X_p, (2, 3, 1)) X = np.reshape(X, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ERIMMRGB(X_p), X, decimal=7 + np.testing.assert_allclose( + log_decoding_ERIMMRGB(X_p), X, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_ERIMMRGB(self): @@ -535,8 +577,10 @@ def test_domain_range_scale_log_decoding_ERIMMRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_ERIMMRGB(X_p * factor), X * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_ERIMMRGB(X_p * factor), + X * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_smpte_240m.py b/colour/models/rgb/transfer_functions/tests/test_smpte_240m.py index 6e76194e27..d23b9f541a 100644 --- a/colour/models/rgb/transfer_functions/tests/test_smpte_240m.py +++ b/colour/models/rgb/transfer_functions/tests/test_smpte_240m.py @@ -3,10 +3,12 @@ :mod:`colour.models.rgb.transfer_functions.smpte_240m` module. """ -import numpy as np import unittest -from colour.models.rgb.transfer_functions import oetf_SMPTE240M, eotf_SMPTE240M +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models.rgb.transfer_functions import eotf_SMPTE240M, oetf_SMPTE240M from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -34,17 +36,25 @@ def test_oetf_SMPTE240M(self): oetf_SMPTE240M` definition. """ - self.assertAlmostEqual(oetf_SMPTE240M(0.0), 0.0, places=7) + np.testing.assert_allclose( + oetf_SMPTE240M(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - oetf_SMPTE240M(0.02), 0.080000000000000, places=7 + np.testing.assert_allclose( + oetf_SMPTE240M(0.02), + 0.080000000000000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - oetf_SMPTE240M(0.18), 0.402285796753870, places=7 + np.testing.assert_allclose( + oetf_SMPTE240M(0.18), + 0.402285796753870, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(oetf_SMPTE240M(1.0), 1.0, places=7) + np.testing.assert_allclose( + oetf_SMPTE240M(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_oetf_SMPTE240M(self): """ @@ -57,20 +67,20 @@ def test_n_dimensional_oetf_SMPTE240M(self): L_c = np.tile(L_c, 6) V_c = np.tile(V_c, 6) - np.testing.assert_array_almost_equal( - oetf_SMPTE240M(L_c), V_c, decimal=7 + np.testing.assert_allclose( + oetf_SMPTE240M(L_c), V_c, atol=TOLERANCE_ABSOLUTE_TESTS ) L_c = np.reshape(L_c, (2, 3)) V_c = np.reshape(V_c, (2, 3)) - np.testing.assert_array_almost_equal( - oetf_SMPTE240M(L_c), V_c, decimal=7 + np.testing.assert_allclose( + oetf_SMPTE240M(L_c), V_c, atol=TOLERANCE_ABSOLUTE_TESTS ) L_c = np.reshape(L_c, (2, 3, 1)) V_c = np.reshape(V_c, (2, 3, 1)) - np.testing.assert_array_almost_equal( - oetf_SMPTE240M(L_c), V_c, decimal=7 + np.testing.assert_allclose( + oetf_SMPTE240M(L_c), V_c, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_oetf_SMPTE240M(self): @@ -85,8 +95,10 @@ def test_domain_range_scale_oetf_SMPTE240M(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - oetf_SMPTE240M(L_c * factor), V_c * factor, decimal=7 + np.testing.assert_allclose( + oetf_SMPTE240M(L_c * factor), + V_c * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -111,17 +123,25 @@ def test_eotf_SMPTE240M(self): eotf_SMPTE240M` definition. """ - self.assertAlmostEqual(eotf_SMPTE240M(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_SMPTE240M(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_SMPTE240M(0.080000000000000), 0.02, places=7 + np.testing.assert_allclose( + eotf_SMPTE240M(0.080000000000000), + 0.02, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_SMPTE240M(0.402285796753870), 0.18, places=7 + np.testing.assert_allclose( + eotf_SMPTE240M(0.402285796753870), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(eotf_SMPTE240M(1.0), 1.0, places=7) + np.testing.assert_allclose( + eotf_SMPTE240M(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_SMPTE240M(self): """ @@ -134,20 +154,20 @@ def test_n_dimensional_eotf_SMPTE240M(self): V_r = np.tile(V_r, 6) L_r = np.tile(L_r, 6) - np.testing.assert_array_almost_equal( - eotf_SMPTE240M(V_r), L_r, decimal=7 + np.testing.assert_allclose( + eotf_SMPTE240M(V_r), L_r, atol=TOLERANCE_ABSOLUTE_TESTS ) V_r = np.reshape(V_r, (2, 3)) L_r = np.reshape(L_r, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_SMPTE240M(V_r), L_r, decimal=7 + np.testing.assert_allclose( + eotf_SMPTE240M(V_r), L_r, atol=TOLERANCE_ABSOLUTE_TESTS ) V_r = np.reshape(V_r, (2, 3, 1)) L_r = np.reshape(L_r, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_SMPTE240M(V_r), L_r, decimal=7 + np.testing.assert_allclose( + eotf_SMPTE240M(V_r), L_r, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_SMPTE240M(self): @@ -162,8 +182,10 @@ def test_domain_range_scale_eotf_SMPTE240M(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_SMPTE240M(V_r * factor), L_r * factor, decimal=7 + np.testing.assert_allclose( + eotf_SMPTE240M(V_r * factor), + L_r * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_sony.py b/colour/models/rgb/transfer_functions/tests/test_sony.py index d296b0925c..3b247b3f00 100644 --- a/colour/models/rgb/transfer_functions/tests/test_sony.py +++ b/colour/models/rgb/transfer_functions/tests/test_sony.py @@ -3,16 +3,18 @@ :mod:`colour.models.rgb.transfer_functions.sony` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_SLog, log_decoding_SLog, - log_encoding_SLog2, log_decoding_SLog2, - log_encoding_SLog3, log_decoding_SLog3, + log_encoding_SLog, + log_encoding_SLog2, + log_encoding_SLog3, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -45,30 +47,40 @@ def test_log_encoding_SLog(self): log_encoding_SLog` definition. """ - self.assertAlmostEqual( - log_encoding_SLog(0.0), 0.088251291513446, places=7 + np.testing.assert_allclose( + log_encoding_SLog(0.0), + 0.088251291513446, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog(0.18), 0.384970815928670, places=7 + np.testing.assert_allclose( + log_encoding_SLog(0.18), + 0.384970815928670, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog(0.18, 12), 0.384688786026891, places=7 + np.testing.assert_allclose( + log_encoding_SLog(0.18, 12), + 0.384688786026891, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog(0.18, 10, False), 0.376512722254600, places=7 + np.testing.assert_allclose( + log_encoding_SLog(0.18, 10, False), + 0.376512722254600, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_SLog(0.18, 10, False, False), 0.359987846422154, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog(1.0), 0.638551684622532, places=7 + np.testing.assert_allclose( + log_encoding_SLog(1.0), + 0.638551684622532, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_SLog(self): @@ -82,20 +94,20 @@ def test_n_dimensional_log_encoding_SLog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_SLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_SLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_SLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_SLog(self): @@ -110,8 +122,10 @@ def test_domain_range_scale_log_encoding_SLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_SLog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -136,30 +150,40 @@ def test_log_decoding_SLog(self): log_decoding_SLog` definition. """ - self.assertAlmostEqual( - log_decoding_SLog(0.088251291513446), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_SLog(0.088251291513446), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog(0.384970815928670), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog(0.384970815928670), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog(0.384688786026891, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog(0.384688786026891, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog(0.376512722254600, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog(0.376512722254600, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_SLog(0.359987846422154, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog(0.638551684622532), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_SLog(0.638551684622532), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_SLog(self): @@ -173,20 +197,20 @@ def test_n_dimensional_log_decoding_SLog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_SLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_SLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_SLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_SLog(self): @@ -201,8 +225,10 @@ def test_domain_range_scale_log_decoding_SLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_SLog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -227,30 +253,40 @@ def test_log_encoding_SLog2(self): log_encoding_SLog2` definition. """ - self.assertAlmostEqual( - log_encoding_SLog2(0.0), 0.088251291513446, places=7 + np.testing.assert_allclose( + log_encoding_SLog2(0.0), + 0.088251291513446, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog2(0.18), 0.339532524633774, places=7 + np.testing.assert_allclose( + log_encoding_SLog2(0.18), + 0.339532524633774, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog2(0.18, 12), 0.339283782857486, places=7 + np.testing.assert_allclose( + log_encoding_SLog2(0.18, 12), + 0.339283782857486, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog2(0.18, 10, False), 0.323449512215013, places=7 + np.testing.assert_allclose( + log_encoding_SLog2(0.18, 10, False), + 0.323449512215013, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_SLog2(0.18, 10, False, False), 0.307980741258647, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog2(1.0), 0.585091059564112, places=7 + np.testing.assert_allclose( + log_encoding_SLog2(1.0), + 0.585091059564112, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_SLog2(self): @@ -264,20 +300,20 @@ def test_n_dimensional_log_encoding_SLog2(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_SLog2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_SLog2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_SLog2(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog2(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_SLog2(self): @@ -292,8 +328,10 @@ def test_domain_range_scale_log_encoding_SLog2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_SLog2(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog2(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -318,30 +356,40 @@ def test_log_decoding_SLog2(self): log_decoding_SLog2` definition. """ - self.assertAlmostEqual( - log_decoding_SLog2(0.088251291513446), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_SLog2(0.088251291513446), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog2(0.339532524633774), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog2(0.339532524633774), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog2(0.339283782857486, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog2(0.339283782857486, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog2(0.323449512215013, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog2(0.323449512215013, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_SLog2(0.307980741258647, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog2(0.585091059564112), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_SLog2(0.585091059564112), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_SLog2(self): @@ -355,20 +403,20 @@ def test_n_dimensional_log_decoding_SLog2(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_SLog2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_SLog2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_SLog2(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog2(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_SLog2(self): @@ -383,8 +431,10 @@ def test_domain_range_scale_log_decoding_SLog2(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_SLog2(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog2(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -409,30 +459,40 @@ def test_log_encoding_SLog3(self): log_encoding_SLog3` definition. """ - self.assertAlmostEqual( - log_encoding_SLog3(0.0), 0.092864125122190, places=7 + np.testing.assert_allclose( + log_encoding_SLog3(0.0), + 0.092864125122190, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog3(0.18), 0.41055718475073, places=7 + np.testing.assert_allclose( + log_encoding_SLog3(0.18), + 0.41055718475073, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog3(0.18, 12), 0.410557184750733, places=7 + np.testing.assert_allclose( + log_encoding_SLog3(0.18, 12), + 0.410557184750733, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog3(0.18, 10, False), 0.406392694063927, places=7 + np.testing.assert_allclose( + log_encoding_SLog3(0.18, 10, False), + 0.406392694063927, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_encoding_SLog3(0.18, 10, False, False), 0.393489294768447, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_encoding_SLog3(1.0), 0.596027343690123, places=7 + np.testing.assert_allclose( + log_encoding_SLog3(1.0), + 0.596027343690123, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_encoding_SLog3(self): @@ -446,20 +506,20 @@ def test_n_dimensional_log_encoding_SLog3(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_SLog3(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog3(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_SLog3(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog3(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_SLog3(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog3(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_SLog3(self): @@ -474,8 +534,10 @@ def test_domain_range_scale_log_encoding_SLog3(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_SLog3(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_SLog3(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -500,30 +562,40 @@ def test_log_decoding_SLog3(self): log_decoding_SLog3` definition. """ - self.assertAlmostEqual( - log_decoding_SLog3(0.092864125122190), 0.0, places=7 + np.testing.assert_allclose( + log_decoding_SLog3(0.092864125122190), + 0.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog3(0.41055718475073), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog3(0.41055718475073), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog3(0.410557184750733, 12), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog3(0.410557184750733, 12), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog3(0.406392694063927, 10, False), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_SLog3(0.406392694063927, 10, False), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( log_decoding_SLog3(0.393489294768447, 10, False, False), 0.18, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - log_decoding_SLog3(0.596027343690123), 1.0, places=7 + np.testing.assert_allclose( + log_decoding_SLog3(0.596027343690123), + 1.0, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_log_decoding_SLog3(self): @@ -537,20 +609,20 @@ def test_n_dimensional_log_decoding_SLog3(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_SLog3(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog3(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_SLog3(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog3(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_SLog3(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog3(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_SLog3(self): @@ -565,8 +637,10 @@ def test_domain_range_scale_log_decoding_SLog3(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_SLog3(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_SLog3(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_srgb.py b/colour/models/rgb/transfer_functions/tests/test_srgb.py index 8792434bf6..99c336a7c4 100644 --- a/colour/models/rgb/transfer_functions/tests/test_srgb.py +++ b/colour/models/rgb/transfer_functions/tests/test_srgb.py @@ -3,9 +3,11 @@ module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import eotf_inverse_sRGB, eotf_sRGB from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -34,13 +36,19 @@ def test_eotf_inverse_sRGB(self): eotf_inverse_sRGB` definition. """ - self.assertAlmostEqual(eotf_inverse_sRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_inverse_sRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - eotf_inverse_sRGB(0.18), 0.461356129500442, places=7 + np.testing.assert_allclose( + eotf_inverse_sRGB(0.18), + 0.461356129500442, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(eotf_inverse_sRGB(1.0), 1.0, places=7) + np.testing.assert_allclose( + eotf_inverse_sRGB(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_inverse_sRGB(self): """ @@ -53,20 +61,20 @@ def test_n_dimensional_eotf_inverse_sRGB(self): L = np.tile(L, 6) V = np.tile(V, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_sRGB(L), V, decimal=7 + np.testing.assert_allclose( + eotf_inverse_sRGB(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3)) V = np.reshape(V, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_sRGB(L), V, decimal=7 + np.testing.assert_allclose( + eotf_inverse_sRGB(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) L = np.reshape(L, (2, 3, 1)) V = np.reshape(V, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_sRGB(L), V, decimal=7 + np.testing.assert_allclose( + eotf_inverse_sRGB(L), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_sRGB(self): @@ -81,8 +89,10 @@ def test_domain_range_scale_eotf_inverse_sRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_inverse_sRGB(L * factor), V * factor, decimal=7 + np.testing.assert_allclose( + eotf_inverse_sRGB(L * factor), + V * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -107,11 +117,17 @@ def test_eotf_sRGB(self): eotf_sRGB` definition. """ - self.assertAlmostEqual(eotf_sRGB(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_sRGB(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_sRGB(0.461356129500442), 0.18, places=7) + np.testing.assert_allclose( + eotf_sRGB(0.461356129500442), 0.18, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_sRGB(1.0), 1.0, places=7) + np.testing.assert_allclose( + eotf_sRGB(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_sRGB(self): """ @@ -124,15 +140,21 @@ def test_n_dimensional_eotf_sRGB(self): V = np.tile(V, 6) L = np.tile(L, 6) - np.testing.assert_array_almost_equal(eotf_sRGB(V), L, decimal=7) + np.testing.assert_allclose( + eotf_sRGB(V), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) V = np.reshape(V, (2, 3)) L = np.reshape(L, (2, 3)) - np.testing.assert_array_almost_equal(eotf_sRGB(V), L, decimal=7) + np.testing.assert_allclose( + eotf_sRGB(V), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) V = np.reshape(V, (2, 3, 1)) L = np.reshape(L, (2, 3, 1)) - np.testing.assert_array_almost_equal(eotf_sRGB(V), L, decimal=7) + np.testing.assert_allclose( + eotf_sRGB(V), L, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_eotf_sRGB(self): """ @@ -146,8 +168,10 @@ def test_domain_range_scale_eotf_sRGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_sRGB(V * factor), L * factor, decimal=7 + np.testing.assert_allclose( + eotf_sRGB(V * factor), + L * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_st_2084.py b/colour/models/rgb/transfer_functions/tests/test_st_2084.py index 9786f62f36..de7b742f0c 100644 --- a/colour/models/rgb/transfer_functions/tests/test_st_2084.py +++ b/colour/models/rgb/transfer_functions/tests/test_st_2084.py @@ -3,9 +3,11 @@ :mod:`colour.models.rgb.transfer_functions.st_2084` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( eotf_inverse_ST2084, eotf_ST2084, @@ -37,19 +39,27 @@ def test_eotf_inverse_ST2084(self): eotf_inverse_ST2084` definition. """ - self.assertAlmostEqual( - eotf_inverse_ST2084(0.0), 0.000000730955903, places=7 + np.testing.assert_allclose( + eotf_inverse_ST2084(0.0), + 0.000000730955903, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_ST2084(100), 0.508078421517399, places=7 + np.testing.assert_allclose( + eotf_inverse_ST2084(100), + 0.508078421517399, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - eotf_inverse_ST2084(400), 0.652578597563067, places=7 + np.testing.assert_allclose( + eotf_inverse_ST2084(400), + 0.652578597563067, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(eotf_inverse_ST2084(5000, 5000), 1.0, places=7) + np.testing.assert_allclose( + eotf_inverse_ST2084(5000, 5000), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_inverse_ST2084(self): """ @@ -62,20 +72,20 @@ def test_n_dimensional_eotf_inverse_ST2084(self): C = np.tile(C, 6) N = np.tile(N, 6) - np.testing.assert_array_almost_equal( - eotf_inverse_ST2084(C), N, decimal=7 + np.testing.assert_allclose( + eotf_inverse_ST2084(C), N, atol=TOLERANCE_ABSOLUTE_TESTS ) C = np.reshape(C, (2, 3)) N = np.reshape(N, (2, 3)) - np.testing.assert_array_almost_equal( - eotf_inverse_ST2084(C), N, decimal=7 + np.testing.assert_allclose( + eotf_inverse_ST2084(C), N, atol=TOLERANCE_ABSOLUTE_TESTS ) C = np.reshape(C, (2, 3, 1)) N = np.reshape(N, (2, 3, 1)) - np.testing.assert_array_almost_equal( - eotf_inverse_ST2084(C), N, decimal=7 + np.testing.assert_allclose( + eotf_inverse_ST2084(C), N, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_eotf_inverse_ST2084(self): @@ -90,8 +100,10 @@ def test_domain_range_scale_eotf_inverse_ST2084(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_inverse_ST2084(C * factor), N * factor, decimal=7 + np.testing.assert_allclose( + eotf_inverse_ST2084(C * factor), + N * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -118,13 +130,21 @@ def test_eotf_ST2084(self): eotf_ST2084` definition. """ - self.assertAlmostEqual(eotf_ST2084(0.0), 0.0, places=7) + np.testing.assert_allclose( + eotf_ST2084(0.0), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_ST2084(0.508078421517399), 100, places=7) + np.testing.assert_allclose( + eotf_ST2084(0.508078421517399), 100, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_ST2084(0.652578597563067), 400, places=7) + np.testing.assert_allclose( + eotf_ST2084(0.652578597563067), 400, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(eotf_ST2084(1.0, 5000), 5000.0, places=7) + np.testing.assert_allclose( + eotf_ST2084(1.0, 5000), 5000.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_eotf_ST2084(self): """ @@ -137,15 +157,21 @@ def test_n_dimensional_eotf_ST2084(self): N = np.tile(N, 6) C = np.tile(C, 6) - np.testing.assert_array_almost_equal(eotf_ST2084(N), C, decimal=7) + np.testing.assert_allclose( + eotf_ST2084(N), C, atol=TOLERANCE_ABSOLUTE_TESTS + ) N = np.reshape(N, (2, 3)) C = np.reshape(C, (2, 3)) - np.testing.assert_array_almost_equal(eotf_ST2084(N), C, decimal=7) + np.testing.assert_allclose( + eotf_ST2084(N), C, atol=TOLERANCE_ABSOLUTE_TESTS + ) N = np.reshape(N, (2, 3, 1)) C = np.reshape(C, (2, 3, 1)) - np.testing.assert_array_almost_equal(eotf_ST2084(N), C, decimal=7) + np.testing.assert_allclose( + eotf_ST2084(N), C, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_eotf_ST2084(self): """ @@ -159,8 +185,10 @@ def test_domain_range_scale_eotf_ST2084(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - eotf_ST2084(N * factor), C * factor, decimal=7 + np.testing.assert_allclose( + eotf_ST2084(N * factor), + C * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/rgb/transfer_functions/tests/test_viper_log.py b/colour/models/rgb/transfer_functions/tests/test_viper_log.py index 13f4913cfd..d858005a29 100644 --- a/colour/models/rgb/transfer_functions/tests/test_viper_log.py +++ b/colour/models/rgb/transfer_functions/tests/test_viper_log.py @@ -3,12 +3,14 @@ :mod:`colour.models.rgb.transfer_functions.viper_log` module. """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models.rgb.transfer_functions import ( - log_encoding_ViperLog, log_decoding_ViperLog, + log_encoding_ViperLog, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,13 +39,19 @@ def test_log_encoding_ViperLog(self): log_encoding_ViperLog` definition. """ - self.assertAlmostEqual(log_encoding_ViperLog(0.0), -np.inf, places=7) + np.testing.assert_allclose( + log_encoding_ViperLog(0.0), -np.inf, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_encoding_ViperLog(0.18), 0.636008067010413, places=7 + np.testing.assert_allclose( + log_encoding_ViperLog(0.18), + 0.636008067010413, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_encoding_ViperLog(1.0), 1.0, places=7) + np.testing.assert_allclose( + log_encoding_ViperLog(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_log_encoding_ViperLog(self): """ @@ -56,20 +64,20 @@ def test_n_dimensional_log_encoding_ViperLog(self): x = np.tile(x, 6) y = np.tile(y, 6) - np.testing.assert_array_almost_equal( - log_encoding_ViperLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_ViperLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3)) y = np.reshape(y, (2, 3)) - np.testing.assert_array_almost_equal( - log_encoding_ViperLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_ViperLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) x = np.reshape(x, (2, 3, 1)) y = np.reshape(y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_encoding_ViperLog(x), y, decimal=7 + np.testing.assert_allclose( + log_encoding_ViperLog(x), y, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_encoding_ViperLog(self): @@ -84,8 +92,10 @@ def test_domain_range_scale_log_encoding_ViperLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_encoding_ViperLog(x * factor), y * factor, decimal=7 + np.testing.assert_allclose( + log_encoding_ViperLog(x * factor), + y * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -112,13 +122,19 @@ def test_log_decoding_ViperLog(self): log_decoding_ViperLog` definition. """ - self.assertAlmostEqual(log_decoding_ViperLog(-np.inf), 0.0, places=7) + np.testing.assert_allclose( + log_decoding_ViperLog(-np.inf), 0.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - log_decoding_ViperLog(0.636008067010413), 0.18, places=7 + np.testing.assert_allclose( + log_decoding_ViperLog(0.636008067010413), + 0.18, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual(log_decoding_ViperLog(1.0), 1.0, places=7) + np.testing.assert_allclose( + log_decoding_ViperLog(1.0), 1.0, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_n_dimensional_log_decoding_ViperLog(self): """ @@ -131,20 +147,20 @@ def test_n_dimensional_log_decoding_ViperLog(self): y = np.tile(y, 6) x = np.tile(x, 6) - np.testing.assert_array_almost_equal( - log_decoding_ViperLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ViperLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3)) x = np.reshape(x, (2, 3)) - np.testing.assert_array_almost_equal( - log_decoding_ViperLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ViperLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) y = np.reshape(y, (2, 3, 1)) x = np.reshape(x, (2, 3, 1)) - np.testing.assert_array_almost_equal( - log_decoding_ViperLog(y), x, decimal=7 + np.testing.assert_allclose( + log_decoding_ViperLog(y), x, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_log_decoding_ViperLog(self): @@ -159,8 +175,10 @@ def test_domain_range_scale_log_decoding_ViperLog(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - log_decoding_ViperLog(y * factor), x * factor, decimal=7 + np.testing.assert_allclose( + log_decoding_ViperLog(y * factor), + x * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_cam02_ucs.py b/colour/models/tests/test_cam02_ucs.py index 06e99d6914..6cd650871a 100644 --- a/colour/models/tests/test_cam02_ucs.py +++ b/colour/models/tests/test_cam02_ucs.py @@ -1,35 +1,37 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.cam02_ucs` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.appearance import ( - CAM_KWARGS_CIECAM02_sRGB, VIEWING_CONDITIONS_CIECAM02, + CAM_KWARGS_CIECAM02_sRGB, XYZ_to_CIECAM02, ) -from colour.models.cam02_ucs import ( - COEFFICIENTS_UCS_LUO2006, - JMh_CIECAM02_to_UCS_Luo2006, - UCS_Luo2006_to_JMh_CIECAM02, - XYZ_to_UCS_Luo2006, - UCS_Luo2006_to_XYZ, -) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - JMh_CIECAM02_to_CAM02LCD, CAM02LCD_to_JMh_CIECAM02, - JMh_CIECAM02_to_CAM02SCD, + CAM02LCD_to_XYZ, CAM02SCD_to_JMh_CIECAM02, - JMh_CIECAM02_to_CAM02UCS, + CAM02SCD_to_XYZ, CAM02UCS_to_JMh_CIECAM02, + CAM02UCS_to_XYZ, + JMh_CIECAM02_to_CAM02LCD, + JMh_CIECAM02_to_CAM02SCD, + JMh_CIECAM02_to_CAM02UCS, XYZ_to_CAM02LCD, - CAM02LCD_to_XYZ, XYZ_to_CAM02SCD, - CAM02SCD_to_XYZ, XYZ_to_CAM02UCS, - CAM02UCS_to_XYZ, +) +from colour.models.cam02_ucs import ( + COEFFICIENTS_UCS_LUO2006, + JMh_CIECAM02_to_UCS_Luo2006, + UCS_Luo2006_to_JMh_CIECAM02, + UCS_Luo2006_to_XYZ, + XYZ_to_UCS_Luo2006, ) from colour.utilities import attest, domain_range_scale, ignore_numpy_errors @@ -74,52 +76,52 @@ def test_JMh_CIECAM02_to_UCS_Luo2006(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( self._JMh, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), np.array([54.90433134, -0.08450395, -0.06854831]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( self._JMh, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), JMh_CIECAM02_to_CAM02LCD(self._JMh), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( self._JMh, COEFFICIENTS_UCS_LUO2006["CAM02-SCD"] ), np.array([54.90433134, -0.08436178, -0.06843298]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( self._JMh, COEFFICIENTS_UCS_LUO2006["CAM02-SCD"] ), JMh_CIECAM02_to_CAM02SCD(self._JMh), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( self._JMh, COEFFICIENTS_UCS_LUO2006["CAM02-UCS"] ), np.array([54.90433134, -0.08442362, -0.06848314]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( self._JMh, COEFFICIENTS_UCS_LUO2006["CAM02-UCS"] ), JMh_CIECAM02_to_CAM02UCS(self._JMh), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_JMh_CIECAM02_to_UCS_Luo2006(self): @@ -135,22 +137,22 @@ def test_n_dimensional_JMh_CIECAM02_to_UCS_Luo2006(self): JMh = np.tile(JMh, (6, 1)) Jpapbp = np.tile(Jpapbp, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( JMh, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), Jpapbp, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) JMh = np.reshape(JMh, (2, 3, 3)) Jpapbp = np.reshape(Jpapbp, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( JMh, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), Jpapbp, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_JMh_CIECAM02_to_UCS_Luo2006(self): @@ -171,12 +173,12 @@ def test_domain_range_scale_JMh_CIECAM02_to_UCS_Luo2006(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JMh_CIECAM02_to_UCS_Luo2006( JMh * factor_a, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), Jpapbp * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -205,16 +207,16 @@ def test_UCS_Luo2006_to_JMh_CIECAM02(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]), COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], ), np.array([41.73109113, 0.10873867, 219.04843202]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]), COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], @@ -222,19 +224,19 @@ def test_UCS_Luo2006_to_JMh_CIECAM02(self): CAM02LCD_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]) ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]), COEFFICIENTS_UCS_LUO2006["CAM02-SCD"], ), np.array([41.73109113, 0.10892212, 219.04843202]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]), COEFFICIENTS_UCS_LUO2006["CAM02-SCD"], @@ -242,19 +244,19 @@ def test_UCS_Luo2006_to_JMh_CIECAM02(self): CAM02SCD_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]) ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]), COEFFICIENTS_UCS_LUO2006["CAM02-UCS"], ), np.array([41.73109113, 0.10884218, 219.04843202]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]), COEFFICIENTS_UCS_LUO2006["CAM02-UCS"], @@ -262,7 +264,7 @@ def test_UCS_Luo2006_to_JMh_CIECAM02(self): CAM02UCS_to_JMh_CIECAM02( np.array([54.90433134, -0.08442362, -0.06848314]) ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_UCS_Luo2006_to_JMh_CIECAM02(self): @@ -278,22 +280,22 @@ def test_n_dimensional_UCS_Luo2006_to_JMh_CIECAM02(self): Jpapbp = np.tile(Jpapbp, (6, 1)) JMh = np.tile(JMh, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( Jpapbp, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), JMh, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Jpapbp = np.reshape(Jpapbp, (2, 3, 3)) JMh = np.reshape(JMh, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( Jpapbp, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"] ), JMh, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_UCS_Luo2006_to_JMh_CIECAM02(self): @@ -314,13 +316,13 @@ def test_domain_range_scale_UCS_Luo2006_to_JMh_CIECAM02(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_JMh_CIECAM02( Jpapbp * factor_a, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], ), JMh * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -346,58 +348,58 @@ class TestXYZ_to_UCS_Luo2006(unittest.TestCase): def test_XYZ_to_UCS_Luo2006(self): """Test :func:`colour.models.cam02_ucs.XYZ_to_UCS_Luo2006` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006( np.array([0.20654008, 0.12197225, 0.05136952]), COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], ), np.array([46.61386154, 39.35760236, 15.96730435]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006( np.array([0.20654008, 0.12197225, 0.05136952]), COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], ), XYZ_to_CAM02LCD(np.array([0.20654008, 0.12197225, 0.05136952])), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006( np.array([0.20654008, 0.12197225, 0.05136952]), COEFFICIENTS_UCS_LUO2006["CAM02-SCD"], ), np.array([46.61386154, 25.62879882, 10.39755489]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006( np.array([0.20654008, 0.12197225, 0.05136952]), COEFFICIENTS_UCS_LUO2006["CAM02-SCD"], ), XYZ_to_CAM02SCD(np.array([0.20654008, 0.12197225, 0.05136952])), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006( np.array([0.20654008, 0.12197225, 0.05136952]), COEFFICIENTS_UCS_LUO2006["CAM02-UCS"], ), np.array([46.61386154, 29.88310013, 12.12351683]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006( np.array([0.20654008, 0.12197225, 0.05136952]), COEFFICIENTS_UCS_LUO2006["CAM02-UCS"], ), XYZ_to_CAM02UCS(np.array([0.20654008, 0.12197225, 0.05136952])), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_UCS_Luo2006(self): @@ -411,18 +413,18 @@ def test_n_dimensional_XYZ_to_UCS_Luo2006(self): XYZ = np.tile(XYZ, (6, 1)) Jpapbp = np.tile(Jpapbp, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006(XYZ, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"]), Jpapbp, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) Jpapbp = np.reshape(Jpapbp, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006(XYZ, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"]), Jpapbp, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_UCS_Luo2006(self): @@ -438,14 +440,14 @@ def test_domain_range_scale_XYZ_to_UCS_Luo2006(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS_Luo2006( XYZ * factor_a, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], XYZ_w=XYZ_w * factor_a, ), Jpapbp * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -469,58 +471,58 @@ class TestUCS_Luo2006_to_XYZ(unittest.TestCase): def test_UCS_Luo2006_to_XYZ(self): """Test :func:`colour.models.cam02_ucs.UCS_Luo2006_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ( np.array([46.61386154, 39.35760236, 15.96730435]), COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ( np.array([46.61386154, 39.35760236, 15.96730435]), COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], ), CAM02LCD_to_XYZ(np.array([46.61386154, 39.35760236, 15.96730435])), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ( np.array([46.61386154, 39.35760236, 15.96730435]), COEFFICIENTS_UCS_LUO2006["CAM02-SCD"], ), np.array([0.28264475, 0.11036927, 0.00824593]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ( np.array([46.61386154, 39.35760236, 15.96730435]), COEFFICIENTS_UCS_LUO2006["CAM02-SCD"], ), CAM02SCD_to_XYZ(np.array([46.61386154, 39.35760236, 15.96730435])), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ( np.array([46.61386154, 39.35760236, 15.96730435]), COEFFICIENTS_UCS_LUO2006["CAM02-UCS"], ), np.array([0.24229809, 0.11573005, 0.02517649]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ( np.array([46.61386154, 39.35760236, 15.96730435]), COEFFICIENTS_UCS_LUO2006["CAM02-UCS"], ), CAM02UCS_to_XYZ(np.array([46.61386154, 39.35760236, 15.96730435])), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_UCS_Luo2006_to_XYZ(self): @@ -534,18 +536,18 @@ def test_n_dimensional_UCS_Luo2006_to_XYZ(self): Jpapbp = np.tile(Jpapbp, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ(Jpapbp, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"]), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Jpapbp = np.reshape(Jpapbp, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ(Jpapbp, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"]), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_UCS_Luo2006_to_XYZ(self): @@ -561,14 +563,14 @@ def test_domain_range_scale_UCS_Luo2006_to_XYZ(self): d_r = (("reference", 1, 1, 1), ("1", 0.01, 1, 1), ("100", 1, 100, 100)) for scale, factor_a, factor_b, factor_c in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_Luo2006_to_XYZ( Jpapbp * factor_a, COEFFICIENTS_UCS_LUO2006["CAM02-LCD"], XYZ_w=XYZ_w * factor_c, ), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_cam16_ucs.py b/colour/models/tests/test_cam16_ucs.py index 21e9ad8377..93988d37fd 100644 --- a/colour/models/tests/test_cam16_ucs.py +++ b/colour/models/tests/test_cam16_ucs.py @@ -6,8 +6,8 @@ from colour.models.tests.test_cam02_ucs import ( TestJMh_CIECAM02_to_UCS_Luo2006, TestUCS_Luo2006_to_JMh_CIECAM02, - TestXYZ_to_UCS_Luo2006, TestUCS_Luo2006_to_XYZ, + TestXYZ_to_UCS_Luo2006, ) __author__ = "Colour Developers" diff --git a/colour/models/tests/test_cie_lab.py b/colour/models/tests/test_cie_lab.py index f62fafee33..7da98a5f02 100644 --- a/colour/models/tests/test_cie_lab.py +++ b/colour/models/tests/test_cie_lab.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.cie_lab` module.""" -import numpy as np import unittest from itertools import product -from colour.models import XYZ_to_Lab, Lab_to_XYZ, Lab_to_LCHab, LCHab_to_Lab +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import Lab_to_LCHab, Lab_to_XYZ, LCHab_to_Lab, XYZ_to_Lab from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -32,49 +34,49 @@ class TestXYZ_to_Lab(unittest.TestCase): def test_XYZ_to_Lab(self): """Test :func:`colour.models.cie_lab.XYZ_to_Lab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Lab(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([41.52787529, 52.63858304, 26.92317922]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Lab(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([55.11636304, -41.08791787, 30.91825778]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Lab(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([29.80565520, 20.01830466, -48.34913874]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Lab( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.44757, 0.40745]), ), np.array([41.52787529, 38.48089305, -5.73295122]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Lab( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.34570, 0.35850]), ), np.array([41.52787529, 51.19354174, 19.91843098]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Lab( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.34570, 0.35850, 1.00000]), ), np.array([41.52787529, 51.19354174, 19.91843098]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Lab(self): @@ -89,20 +91,20 @@ def test_n_dimensional_XYZ_to_Lab(self): XYZ = np.tile(XYZ, (6, 1)) Lab = np.tile(Lab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Lab(XYZ, illuminant), Lab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Lab(XYZ, illuminant), Lab, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Lab(XYZ, illuminant), Lab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Lab(XYZ, illuminant), Lab, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) illuminant = np.reshape(illuminant, (2, 3, 2)) Lab = np.reshape(Lab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_Lab(XYZ, illuminant), Lab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Lab(XYZ, illuminant), Lab, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_Lab(self): @@ -118,10 +120,10 @@ def test_domain_range_scale_XYZ_to_Lab(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Lab(XYZ * factor_a, illuminant), Lab * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -142,49 +144,49 @@ class TestLab_to_XYZ(unittest.TestCase): def test_Lab_to_XYZ(self): """Test :func:`colour.models.cie_lab.Lab_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_XYZ(np.array([41.52787529, 52.63858304, 26.92317922])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_XYZ(np.array([55.11636304, -41.08791787, 30.91825778])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_XYZ(np.array([29.80565520, 20.01830466, -48.34913874])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_XYZ( np.array([41.52787529, 38.48089305, -5.73295122]), np.array([0.44757, 0.40745]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_XYZ( np.array([41.52787529, 51.19354174, 19.91843098]), np.array([0.34570, 0.35850]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_XYZ( np.array([41.52787529, 51.19354174, 19.91843098]), np.array([0.34570, 0.35850, 1.00000]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Lab_to_XYZ(self): @@ -199,20 +201,20 @@ def test_n_dimensional_Lab_to_XYZ(self): Lab = np.tile(Lab, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - Lab_to_XYZ(Lab, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + Lab_to_XYZ(Lab, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - Lab_to_XYZ(Lab, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + Lab_to_XYZ(Lab, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab = np.reshape(Lab, (2, 3, 3)) illuminant = np.reshape(illuminant, (2, 3, 2)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Lab_to_XYZ(Lab, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + Lab_to_XYZ(Lab, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Lab_to_XYZ(self): @@ -228,10 +230,10 @@ def test_domain_range_scale_Lab_to_XYZ(self): d_r = (("reference", 1, 1), ("1", 0.01, 1), ("100", 1, 100)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_XYZ(Lab * factor_a, illuminant), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -252,22 +254,22 @@ class TestLab_to_LCHab(unittest.TestCase): def test_Lab_to_LCHab(self): """Test :func:`colour.models.cie_lab.Lab_to_LCHab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_LCHab(np.array([41.52787529, 52.63858304, 26.92317922])), np.array([41.52787529, 59.12425901, 27.08848784]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_LCHab(np.array([55.11636304, -41.08791787, 30.91825778])), np.array([55.11636304, 51.42135412, 143.03889556]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_LCHab(np.array([29.80565520, 20.01830466, -48.34913874])), np.array([29.80565520, 52.32945383, 292.49133666]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Lab_to_LCHab(self): @@ -281,14 +283,14 @@ def test_n_dimensional_Lab_to_LCHab(self): Lab = np.tile(Lab, (6, 1)) LCHab = np.tile(LCHab, (6, 1)) - np.testing.assert_array_almost_equal( - Lab_to_LCHab(Lab), LCHab, decimal=7 + np.testing.assert_allclose( + Lab_to_LCHab(Lab), LCHab, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab = np.reshape(Lab, (2, 3, 3)) LCHab = np.reshape(LCHab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Lab_to_LCHab(Lab), LCHab, decimal=7 + np.testing.assert_allclose( + Lab_to_LCHab(Lab), LCHab, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Lab_to_LCHab(self): @@ -307,8 +309,10 @@ def test_domain_range_scale_Lab_to_LCHab(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - Lab_to_LCHab(Lab * factor_a), LCHab * factor_b, decimal=7 + np.testing.assert_allclose( + Lab_to_LCHab(Lab * factor_a), + LCHab * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -332,22 +336,22 @@ class TestLCHab_to_Lab(unittest.TestCase): def test_LCHab_to_Lab(self): """Test :func:`colour.models.cie_lab.LCHab_to_Lab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_Lab(np.array([41.52787529, 59.12425901, 27.08848784])), np.array([41.52787529, 52.63858304, 26.92317922]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_Lab(np.array([55.11636304, 51.42135412, 143.03889556])), np.array([55.11636304, -41.08791787, 30.91825778]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_Lab(np.array([29.80565520, 52.32945383, 292.49133666])), np.array([29.80565520, 20.01830466, -48.34913874]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_LCHab_to_Lab(self): @@ -361,14 +365,14 @@ def test_n_dimensional_LCHab_to_Lab(self): LCHab = np.tile(LCHab, (6, 1)) Lab = np.tile(Lab, (6, 1)) - np.testing.assert_array_almost_equal( - LCHab_to_Lab(LCHab), Lab, decimal=7 + np.testing.assert_allclose( + LCHab_to_Lab(LCHab), Lab, atol=TOLERANCE_ABSOLUTE_TESTS ) LCHab = np.reshape(LCHab, (2, 3, 3)) Lab = np.reshape(Lab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - LCHab_to_Lab(LCHab), Lab, decimal=7 + np.testing.assert_allclose( + LCHab_to_Lab(LCHab), Lab, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_LCHab_to_Lab(self): @@ -387,8 +391,10 @@ def test_domain_range_scale_LCHab_to_Lab(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - LCHab_to_Lab(LCHab * factor_a), Lab * factor_b, decimal=7 + np.testing.assert_allclose( + LCHab_to_Lab(LCHab * factor_a), + Lab * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_cie_luv.py b/colour/models/tests/test_cie_luv.py index 742611b128..78028ce7ac 100644 --- a/colour/models/tests/test_cie_luv.py +++ b/colour/models/tests/test_cie_luv.py @@ -1,19 +1,21 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.cie_luv` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - XYZ_to_Luv, - Luv_to_XYZ, + LCHuv_to_Luv, + Luv_to_LCHuv, Luv_to_uv, - uv_to_Luv, + Luv_to_XYZ, Luv_uv_to_xy, + XYZ_to_Luv, + uv_to_Luv, xy_to_Luv_uv, - Luv_to_LCHuv, - LCHuv_to_Luv, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -45,49 +47,49 @@ class TestXYZ_to_Luv(unittest.TestCase): def test_XYZ_to_Luv(self): """Test :func:`colour.models.cie_luv.XYZ_to_Luv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Luv(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([41.52787529, 96.83626054, 17.75210149]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Luv(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([55.11636304, -37.59308176, 44.13768458]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Luv(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([29.80565520, -10.96316802, -65.06751860]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Luv( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.44757, 0.40745]), ), np.array([41.52787529, 65.45180940, -12.46626977]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Luv( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.34570, 0.35850]), ), np.array([41.52787529, 90.70925962, 7.08455273]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Luv( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.34570, 0.35850, 1.00000]), ), np.array([41.52787529, 90.70925962, 7.08455273]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Luv(self): @@ -102,20 +104,20 @@ def test_n_dimensional_XYZ_to_Luv(self): XYZ = np.tile(XYZ, (6, 1)) Luv = np.tile(Luv, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Luv(XYZ, illuminant), Luv, decimal=7 + np.testing.assert_allclose( + XYZ_to_Luv(XYZ, illuminant), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Luv(XYZ, illuminant), Luv, decimal=7 + np.testing.assert_allclose( + XYZ_to_Luv(XYZ, illuminant), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) illuminant = np.reshape(illuminant, (2, 3, 2)) Luv = np.reshape(Luv, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_Luv(XYZ, illuminant), Luv, decimal=7 + np.testing.assert_allclose( + XYZ_to_Luv(XYZ, illuminant), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_Luv(self): @@ -131,10 +133,10 @@ def test_domain_range_scale_XYZ_to_Luv(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Luv(XYZ * factor_a, illuminant), Luv * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -155,49 +157,49 @@ class TestLuv_to_XYZ(unittest.TestCase): def test_Luv_to_XYZ(self): """Test :func:`colour.models.cie_luv.Luv_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_XYZ(np.array([41.52787529, 96.83626054, 17.75210149])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_XYZ(np.array([55.11636304, -37.59308176, 44.13768458])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_XYZ(np.array([29.80565520, -10.96316802, -65.06751860])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_XYZ( np.array([41.52787529, 65.45180940, -12.46626977]), np.array([0.44757, 0.40745]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_XYZ( np.array([41.52787529, 90.70925962, 7.08455273]), np.array([0.34570, 0.35850]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_XYZ( np.array([41.52787529, 90.70925962, 7.08455273]), np.array([0.34570, 0.35850, 1.00000]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Luv_to_XYZ(self): @@ -212,20 +214,20 @@ def test_n_dimensional_Luv_to_XYZ(self): Luv = np.tile(Luv, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - Luv_to_XYZ(Luv, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + Luv_to_XYZ(Luv, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - Luv_to_XYZ(Luv, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + Luv_to_XYZ(Luv, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Luv = np.reshape(Luv, (2, 3, 3)) illuminant = np.reshape(illuminant, (2, 3, 2)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Luv_to_XYZ(Luv, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + Luv_to_XYZ(Luv, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Luv_to_XYZ(self): @@ -241,10 +243,10 @@ def test_domain_range_scale_Luv_to_XYZ(self): d_r = (("reference", 1, 1), ("1", 0.01, 1), ("100", 1, 100)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_XYZ(Luv * factor_a, illuminant), XYZ * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -265,49 +267,49 @@ class TestLuv_to_uv(unittest.TestCase): def test_Luv_to_uv(self): """Test :func:`colour.models.cie_luv.Luv_to_uv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_uv(np.array([41.52787529, 96.83626054, 17.75210149])), np.array([0.37720213, 0.50120264]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_uv(np.array([55.11636304, -37.59308176, 44.13768458])), np.array([0.14536327, 0.52992069]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_uv(np.array([29.80565520, -10.96316802, -65.06751860])), np.array([0.16953603, 0.30039234]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_uv( np.array([41.52787529, 65.45180940, -12.46626977]), np.array([0.44757, 0.40745]), ), np.array([0.37720213, 0.50120264]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_uv( np.array([41.52787529, 90.70925962, 7.08455273]), np.array([0.34570, 0.35850]), ), np.array([0.37720213, 0.50120264]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_uv( np.array([41.52787529, 90.70925962, 7.08455273]), np.array([0.34570, 0.35850, 1.00000]), ), np.array([0.37720213, 0.50120264]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Luv_to_uv(self): @@ -322,20 +324,20 @@ def test_n_dimensional_Luv_to_uv(self): Luv = np.tile(Luv, (6, 1)) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal( - Luv_to_uv(Luv, illuminant), uv, decimal=7 + np.testing.assert_allclose( + Luv_to_uv(Luv, illuminant), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - Luv_to_uv(Luv, illuminant), uv, decimal=7 + np.testing.assert_allclose( + Luv_to_uv(Luv, illuminant), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) Luv = np.reshape(Luv, (2, 3, 3)) illuminant = np.reshape(illuminant, (2, 3, 2)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - Luv_to_uv(Luv, illuminant), uv, decimal=7 + np.testing.assert_allclose( + Luv_to_uv(Luv, illuminant), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Luv_to_uv(self): @@ -351,8 +353,10 @@ def test_domain_range_scale_Luv_to_uv(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - Luv_to_uv(Luv * factor, illuminant), uv, decimal=7 + np.testing.assert_allclose( + Luv_to_uv(Luv * factor, illuminant), + uv, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -373,55 +377,55 @@ class Testuv_to_Luv(unittest.TestCase): def test_uv_to_Luv(self): """Test :func:`colour.models.cie_luv.uv_to_Luv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv(np.array([0.37720213, 0.50120264])), np.array([100.00000000, 233.18376036, 42.74743858]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv(np.array([0.14536327, 0.52992069])), np.array([100.00000000, -68.20675764, 80.08090358]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv(np.array([0.16953603, 0.30039234])), np.array([100.00000000, -36.78216964, -218.3059514]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv( np.array([0.37720213, 0.50120264]), np.array([0.44757, 0.40745]), ), np.array([100.00000000, 157.60933976, -30.01903705]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv( np.array([0.37720213, 0.50120264]), np.array([0.34570, 0.35850]), ), np.array([100.00000000, 218.42981284, 17.05975609]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv( np.array([0.37720213, 0.50120264]), np.array([0.34570, 0.35850, 1.00000]), ), np.array([100.00000000, 218.42981284, 17.05975609]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv(np.array([0.37720213, 0.50120264]), Y=0.18), np.array([49.49610761, 115.41688496, -243.29048251]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_uv_to_Luv(self): @@ -436,20 +440,20 @@ def test_n_dimensional_uv_to_Luv(self): uv = np.tile(uv, (6, 1)) Luv = np.tile(Luv, (6, 1)) - np.testing.assert_array_almost_equal( - uv_to_Luv(uv, illuminant), Luv, decimal=7 + np.testing.assert_allclose( + uv_to_Luv(uv, illuminant), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - uv_to_Luv(uv, illuminant), Luv, decimal=7 + np.testing.assert_allclose( + uv_to_Luv(uv, illuminant), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) uv = np.reshape(uv, (2, 3, 2)) illuminant = np.reshape(illuminant, (2, 3, 2)) Luv = np.reshape(Luv, (2, 3, 3)) - np.testing.assert_array_almost_equal( - uv_to_Luv(uv, illuminant), Luv, decimal=7 + np.testing.assert_allclose( + uv_to_Luv(uv, illuminant), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_uv_to_Luv(self): @@ -466,10 +470,10 @@ def test_domain_range_scale_uv_to_Luv(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_Luv(uv, illuminant, Y * factor_a), Luv * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -490,22 +494,22 @@ class TestLuv_uv_to_xy(unittest.TestCase): def test_Luv_uv_to_xy(self): """Test :func:`colour.models.cie_luv.Luv_uv_to_xy` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_uv_to_xy(np.array([0.37720213, 0.50120264])), np.array([0.54369558, 0.32107944]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_uv_to_xy(np.array([0.14536327, 0.52992069])), np.array([0.29777734, 0.48246445]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_uv_to_xy(np.array([0.16953603, 0.30039234])), np.array([0.18582824, 0.14633764]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Luv_uv_to_xy(self): @@ -519,11 +523,15 @@ def test_n_dimensional_Luv_uv_to_xy(self): uv = np.tile(uv, (6, 1)) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal(Luv_uv_to_xy(uv), xy, decimal=7) + np.testing.assert_allclose( + Luv_uv_to_xy(uv), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) uv = np.reshape(uv, (2, 3, 2)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal(Luv_uv_to_xy(uv), xy, decimal=7) + np.testing.assert_allclose( + Luv_uv_to_xy(uv), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_Luv_uv_to_xy(self): @@ -546,22 +554,22 @@ class TestXy_to_Luv_uv(unittest.TestCase): def test_xy_to_Luv_uv(self): """Test :func:`colour.models.cie_luv.xy_to_Luv_uv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_Luv_uv(np.array([0.54369558, 0.32107944])), np.array([0.37720213, 0.50120264]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_Luv_uv(np.array([0.29777734, 0.48246445])), np.array([0.14536327, 0.52992069]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_Luv_uv(np.array([0.18582824, 0.14633764])), np.array([0.16953603, 0.30039234]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_Luv_uv(self): @@ -575,11 +583,15 @@ def test_n_dimensional_xy_to_Luv_uv(self): xy = np.tile(xy, (6, 1)) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal(xy_to_Luv_uv(xy), uv, decimal=7) + np.testing.assert_allclose( + xy_to_Luv_uv(xy), uv, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal(xy_to_Luv_uv(xy), uv, decimal=7) + np.testing.assert_allclose( + xy_to_Luv_uv(xy), uv, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_xy_to_Luv_uv(self): @@ -602,22 +614,22 @@ class TestLuv_to_LCHuv(unittest.TestCase): def test_Luv_to_LCHuv(self): """Test :func:`colour.models.cie_luv.Luv_to_LCHuv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_LCHuv(np.array([41.52787529, 96.83626054, 17.75210149])), np.array([41.52787529, 98.44997950, 10.38816348]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_LCHuv(np.array([55.11636304, -37.59308176, 44.13768458])), np.array([55.11636304, 57.97736624, 130.42180076]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Luv_to_LCHuv(np.array([29.80565520, -10.96316802, -65.06751860])), np.array([29.80565520, 65.98464238, 260.43611196]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Luv_to_LCHuv(self): @@ -631,14 +643,14 @@ def test_n_dimensional_Luv_to_LCHuv(self): Luv = np.tile(Luv, (6, 1)) LCHuv = np.tile(LCHuv, (6, 1)) - np.testing.assert_array_almost_equal( - Luv_to_LCHuv(Luv), LCHuv, decimal=7 + np.testing.assert_allclose( + Luv_to_LCHuv(Luv), LCHuv, atol=TOLERANCE_ABSOLUTE_TESTS ) Luv = np.reshape(Luv, (2, 3, 3)) LCHuv = np.reshape(LCHuv, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Luv_to_LCHuv(Luv), LCHuv, decimal=7 + np.testing.assert_allclose( + Luv_to_LCHuv(Luv), LCHuv, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Luv_to_LCHuv(self): @@ -657,8 +669,10 @@ def test_domain_range_scale_Luv_to_LCHuv(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - Luv_to_LCHuv(Luv * factor_a), LCHuv * factor_b, decimal=7 + np.testing.assert_allclose( + Luv_to_LCHuv(Luv * factor_a), + LCHuv * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -682,22 +696,22 @@ class TestLCHuv_to_Luv(unittest.TestCase): def test_LCHuv_to_Luv(self): """Test :func:`colour.models.cie_luv.LCHuv_to_Luv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHuv_to_Luv(np.array([41.52787529, 98.44997950, 10.38816348])), np.array([41.52787529, 96.83626054, 17.75210149]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHuv_to_Luv(np.array([55.11636304, 57.97736624, 130.42180076])), np.array([55.11636304, -37.59308176, 44.13768458]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHuv_to_Luv(np.array([29.80565520, 65.98464238, 260.43611196])), np.array([29.80565520, -10.96316802, -65.06751860]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_LCHuv_to_Luv(self): @@ -711,14 +725,14 @@ def test_n_dimensional_LCHuv_to_Luv(self): Luv = np.tile(Luv, (6, 1)) LCHuv = np.tile(LCHuv, (6, 1)) - np.testing.assert_array_almost_equal( - LCHuv_to_Luv(LCHuv), Luv, decimal=7 + np.testing.assert_allclose( + LCHuv_to_Luv(LCHuv), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) Luv = np.reshape(Luv, (2, 3, 3)) LCHuv = np.reshape(LCHuv, (2, 3, 3)) - np.testing.assert_array_almost_equal( - LCHuv_to_Luv(LCHuv), Luv, decimal=7 + np.testing.assert_allclose( + LCHuv_to_Luv(LCHuv), Luv, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_LCHuv_to_Lab(self): @@ -737,8 +751,10 @@ def test_domain_range_scale_LCHuv_to_Lab(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - LCHuv_to_Luv(LCHuv * factor_a), Luv * factor_b, decimal=7 + np.testing.assert_allclose( + LCHuv_to_Luv(LCHuv * factor_a), + Luv * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_cie_ucs.py b/colour/models/tests/test_cie_ucs.py index 510ad57c46..57c63fd74a 100644 --- a/colour/models/tests/test_cie_ucs.py +++ b/colour/models/tests/test_cie_ucs.py @@ -1,16 +1,18 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.cie_ucs` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - XYZ_to_UCS, - UCS_to_XYZ, UCS_to_uv, - uv_to_UCS, + UCS_to_XYZ, UCS_uv_to_xy, + XYZ_to_UCS, + uv_to_UCS, xy_to_UCS_uv, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -41,22 +43,22 @@ class TestXYZ_to_UCS(unittest.TestCase): def test_XYZ_to_UCS(self): """Test :func:`colour.models.cie_ucs.XYZ_to_UCS` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.13769339, 0.12197225, 0.10537310]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.09481340, 0.23042768, 0.32701033]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UCS(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([0.05212520, 0.06157201, 0.19376075]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_UCS(self): @@ -70,11 +72,15 @@ def test_n_dimensional_XYZ_to_UCS(self): UCS = np.tile(UCS, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal(XYZ_to_UCS(XYZ), UCS, decimal=7) + np.testing.assert_allclose( + XYZ_to_UCS(XYZ), UCS, atol=TOLERANCE_ABSOLUTE_TESTS + ) UCS = np.reshape(UCS, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal(XYZ_to_UCS(XYZ), UCS, decimal=7) + np.testing.assert_allclose( + XYZ_to_UCS(XYZ), UCS, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_XYZ_to_UCS(self): """ @@ -88,8 +94,10 @@ def test_domain_range_scale_XYZ_to_UCS(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_UCS(XYZ * factor), UCS * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_UCS(XYZ * factor), + UCS * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -110,22 +118,22 @@ class TestUCS_to_XYZ(unittest.TestCase): def test_UCS_to_XYZ(self): """Test :func:`colour.models.cie_ucs.UCS_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_to_XYZ(np.array([0.13769339, 0.12197225, 0.10537310])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_to_XYZ(np.array([0.09481340, 0.23042768, 0.32701033])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_to_XYZ(np.array([0.05212520, 0.06157201, 0.19376075])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_UCS_to_XYZ(self): @@ -139,11 +147,15 @@ def test_n_dimensional_UCS_to_XYZ(self): UCS = np.tile(UCS, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal(UCS_to_XYZ(UCS), XYZ, decimal=7) + np.testing.assert_allclose( + UCS_to_XYZ(UCS), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) UCS = np.reshape(UCS, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal(UCS_to_XYZ(UCS), XYZ, decimal=7) + np.testing.assert_allclose( + UCS_to_XYZ(UCS), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_UCS_to_XYZ(self): """ @@ -157,8 +169,10 @@ def test_domain_range_scale_UCS_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - UCS_to_XYZ(UCS * factor), XYZ * factor, decimal=7 + np.testing.assert_allclose( + UCS_to_XYZ(UCS * factor), + XYZ * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -179,22 +193,22 @@ class TestUCS_to_uv(unittest.TestCase): def test_UCS_to_uv(self): """Test :func:`colour.models.cie_ucs.UCS_to_uv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_to_uv(np.array([0.13769339, 0.12197225, 0.10537310])), np.array([0.37720213, 0.33413508]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_to_uv(np.array([0.09481340, 0.23042768, 0.32701033])), np.array([0.14536327, 0.35328046]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_to_uv(np.array([0.05212520, 0.06157201, 0.19376075])), np.array([0.16953602, 0.20026156]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_UCS_to_uv(self): @@ -208,11 +222,15 @@ def test_n_dimensional_UCS_to_uv(self): UCS = np.tile(UCS, (6, 1)) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal(UCS_to_uv(UCS), uv, decimal=7) + np.testing.assert_allclose( + UCS_to_uv(UCS), uv, atol=TOLERANCE_ABSOLUTE_TESTS + ) UCS = np.reshape(UCS, (2, 3, 3)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal(UCS_to_uv(UCS), uv, decimal=7) + np.testing.assert_allclose( + UCS_to_uv(UCS), uv, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_UCS_to_uv(self): """ @@ -226,8 +244,8 @@ def test_domain_range_scale_UCS_to_uv(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - UCS_to_uv(UCS * factor), uv, decimal=7 + np.testing.assert_allclose( + UCS_to_uv(UCS * factor), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -248,28 +266,28 @@ class Testuv_to_UCS(unittest.TestCase): def test_uv_to_UCS(self): """Test :func:`colour.models.cie_ucs.uv_to_UCS` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_UCS(np.array([0.37720213, 0.33413508])), np.array([1.12889114, 1.00000000, 0.86391046]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_UCS(np.array([0.14536327, 0.35328046])), np.array([0.41146705, 1.00000000, 1.41914520]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_UCS(np.array([0.16953602, 0.20026156])), np.array([0.84657295, 1.00000000, 3.14689659]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_UCS(np.array([0.37720213, 0.33413508]), V=0.18), np.array([0.20320040, 0.18000000, 0.15550388]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_uv_to_UCS(self): @@ -283,11 +301,15 @@ def test_n_dimensional_uv_to_UCS(self): uv = np.tile(uv, (6, 1)) UCS = np.tile(UCS, (6, 1)) - np.testing.assert_array_almost_equal(uv_to_UCS(uv), UCS, decimal=7) + np.testing.assert_allclose( + uv_to_UCS(uv), UCS, atol=TOLERANCE_ABSOLUTE_TESTS + ) uv = np.reshape(uv, (2, 3, 2)) UCS = np.reshape(UCS, (2, 3, 3)) - np.testing.assert_array_almost_equal(uv_to_UCS(uv), UCS, decimal=7) + np.testing.assert_allclose( + uv_to_UCS(uv), UCS, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_uv_to_UCS(self): """ @@ -302,8 +324,10 @@ def test_domain_range_scale_uv_to_UCS(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - uv_to_UCS(uv, V * factor), UCS * factor, decimal=7 + np.testing.assert_allclose( + uv_to_UCS(uv, V * factor), + UCS * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -324,22 +348,22 @@ class TestUCS_uv_to_xy(unittest.TestCase): def test_UCS_uv_to_xy(self): """Test :func:`colour.models.cie_ucs.UCS_uv_to_xy` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_uv_to_xy(np.array([0.37720213, 0.33413508])), np.array([0.54369555, 0.32107941]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_uv_to_xy(np.array([0.14536327, 0.35328046])), np.array([0.29777734, 0.48246445]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UCS_uv_to_xy(np.array([0.16953602, 0.20026156])), np.array([0.18582823, 0.14633764]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_UCS_uv_to_xy(self): @@ -353,11 +377,15 @@ def test_n_dimensional_UCS_uv_to_xy(self): uv = np.tile(uv, (6, 1)) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal(UCS_uv_to_xy(uv), xy, decimal=7) + np.testing.assert_allclose( + UCS_uv_to_xy(uv), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) uv = np.reshape(uv, (2, 3, 2)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal(UCS_uv_to_xy(uv), xy, decimal=7) + np.testing.assert_allclose( + UCS_uv_to_xy(uv), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_UCS_uv_to_xy(self): @@ -380,22 +408,22 @@ class TestXy_to_UCS_uv(unittest.TestCase): def test_xy_to_UCS_uv(self): """Test :func:`colour.models.cie_ucs.xy_to_UCS_uv` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_UCS_uv(np.array([0.54369555, 0.32107941])), np.array([0.37720213, 0.33413508]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_UCS_uv(np.array([0.29777734, 0.48246445])), np.array([0.14536327, 0.35328046]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_UCS_uv(np.array([0.18582823, 0.14633764])), np.array([0.16953602, 0.20026156]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_UCS_uv(self): @@ -409,11 +437,15 @@ def test_n_dimensional_xy_to_UCS_uv(self): xy = np.tile(xy, (6, 1)) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal(xy_to_UCS_uv(xy), uv, decimal=7) + np.testing.assert_allclose( + xy_to_UCS_uv(xy), uv, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal(xy_to_UCS_uv(xy), uv, decimal=7) + np.testing.assert_allclose( + xy_to_UCS_uv(xy), uv, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_xy_to_UCS_uv(self): diff --git a/colour/models/tests/test_cie_uvw.py b/colour/models/tests/test_cie_uvw.py index 17b80ec59d..60cf4142b6 100644 --- a/colour/models/tests/test_cie_uvw.py +++ b/colour/models/tests/test_cie_uvw.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.cie_uvw` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import UVW_to_XYZ, XYZ_to_UVW from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -30,49 +32,49 @@ class TestXYZ_to_UVW(unittest.TestCase): def test_XYZ_to_UVW(self): """Test :func:`colour.models.cie_uvw.XYZ_to_UVW` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UVW(np.array([0.20654008, 0.12197225, 0.05136952]) * 100), np.array([94.55035725, 11.55536523, 40.54757405]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UVW(np.array([0.14222010, 0.23042768, 0.10495772]) * 100), np.array([-36.92762376, 28.90425105, 54.14071478]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UVW(np.array([0.07818780, 0.06157201, 0.28099326]) * 100), np.array([-10.60111550, -41.94580000, 28.82134002]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UVW( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, np.array([0.44757, 0.40745]), ), np.array([63.90676310, -8.11466183, 40.54757405]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UVW( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, np.array([0.34570, 0.35850]), ), np.array([88.56798946, 4.61154385, 40.54757405]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UVW( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, np.array([0.34570, 0.35850, 1.00000]), ), np.array([88.56798946, 4.61154385, 40.54757405]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_UVW(self): @@ -87,20 +89,20 @@ def test_n_dimensional_XYZ_to_UVW(self): XYZ = np.tile(XYZ, (6, 1)) UVW = np.tile(UVW, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_UVW(XYZ, illuminant), UVW, decimal=7 + np.testing.assert_allclose( + XYZ_to_UVW(XYZ, illuminant), UVW, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_UVW(XYZ, illuminant), UVW, decimal=7 + np.testing.assert_allclose( + XYZ_to_UVW(XYZ, illuminant), UVW, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) illuminant = np.reshape(illuminant, (2, 3, 2)) UVW = np.reshape(UVW, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_UVW(XYZ, illuminant), UVW, decimal=7 + np.testing.assert_allclose( + XYZ_to_UVW(XYZ, illuminant), UVW, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_UVW(self): @@ -116,10 +118,10 @@ def test_domain_range_scale_XYZ_to_UVW(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_UVW(XYZ * factor, illuminant), UVW * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -140,49 +142,49 @@ class TestUVW_to_XYZ(unittest.TestCase): def test_UVW_to_XYZ(self): """Test :func:`colour.models.cie_uvw.UVW_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UVW_to_XYZ(np.array([94.55035725, 11.55536523, 40.54757405])), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UVW_to_XYZ(np.array([-36.92762376, 28.90425105, 54.14071478])), np.array([0.14222010, 0.23042768, 0.10495772]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UVW_to_XYZ(np.array([-10.60111550, -41.94580000, 28.82134002])), np.array([0.07818780, 0.06157201, 0.28099326]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UVW_to_XYZ( np.array([63.90676310, -8.11466183, 40.54757405]), np.array([0.44757, 0.40745]), ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UVW_to_XYZ( np.array([88.56798946, 4.61154385, 40.54757405]), np.array([0.34570, 0.35850]), ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UVW_to_XYZ( np.array([88.56798946, 4.61154385, 40.54757405]), np.array([0.34570, 0.35850, 1.00000]), ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_UVW_to_XYZ(self): @@ -197,20 +199,20 @@ def test_n_dimensional_UVW_to_XYZ(self): XYZ = np.tile(XYZ, (6, 1)) UVW = np.tile(UVW, (6, 1)) - np.testing.assert_array_almost_equal( - UVW_to_XYZ(UVW, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + UVW_to_XYZ(UVW, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) illuminant = np.tile(illuminant, (6, 1)) - np.testing.assert_array_almost_equal( - UVW_to_XYZ(UVW, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + UVW_to_XYZ(UVW, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) illuminant = np.reshape(illuminant, (2, 3, 2)) UVW = np.reshape(UVW, (2, 3, 3)) - np.testing.assert_array_almost_equal( - UVW_to_XYZ(UVW, illuminant), XYZ, decimal=7 + np.testing.assert_allclose( + UVW_to_XYZ(UVW, illuminant), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_UVW_to_XYZ(self): @@ -226,10 +228,10 @@ def test_domain_range_scale_UVW_to_XYZ(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( UVW_to_XYZ(UVW * factor, illuminant), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_cie_xyy.py b/colour/models/tests/test_cie_xyy.py index c676a14919..5f418a4383 100644 --- a/colour/models/tests/test_cie_xyy.py +++ b/colour/models/tests/test_cie_xyy.py @@ -1,17 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.cie_xyy` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( + XYZ_to_xy, XYZ_to_xyY, - xyY_to_XYZ, xy_to_xyY, - xyY_to_xy, xy_to_XYZ, - XYZ_to_xy, + xyY_to_xy, + xyY_to_XYZ, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -41,31 +43,31 @@ class TestXYZ_to_xyY(unittest.TestCase): def test_XYZ_to_xyY(self): """Test :func:`colour.models.cie_xyy.XYZ_to_xyY` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xyY(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.54369557, 0.32107944, 0.12197225]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xyY(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.29777735, 0.48246446, 0.23042768]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xyY(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([0.18582823, 0.14633764, 0.06157201]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xyY(np.array([0.00000000, 0.00000000, 1.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xyY( np.array( [ @@ -82,7 +84,7 @@ def test_XYZ_to_xyY(self): [0.00000000, 1.00000000, 1.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_xyY(self): @@ -96,11 +98,15 @@ def test_n_dimensional_XYZ_to_xyY(self): XYZ = np.tile(XYZ, (6, 1)) xyY = np.tile(xyY, (6, 1)) - np.testing.assert_array_almost_equal(XYZ_to_xyY(XYZ), xyY, decimal=7) + np.testing.assert_allclose( + XYZ_to_xyY(XYZ), xyY, atol=TOLERANCE_ABSOLUTE_TESTS + ) XYZ = np.reshape(XYZ, (2, 3, 3)) xyY = np.reshape(xyY, (2, 3, 3)) - np.testing.assert_array_almost_equal(XYZ_to_xyY(XYZ), xyY, decimal=7) + np.testing.assert_allclose( + XYZ_to_xyY(XYZ), xyY, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_XYZ_to_xyY(self): """ @@ -120,8 +126,10 @@ def test_domain_range_scale_XYZ_to_xyY(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_xyY(XYZ * factor_a), xyY * factor_b, decimal=7 + np.testing.assert_allclose( + XYZ_to_xyY(XYZ * factor_a), + xyY * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -142,31 +150,31 @@ class TestxyY_to_XYZ(unittest.TestCase): def test_xyY_to_XYZ(self): """Test :func:`colour.models.cie_xyy.xyY_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_XYZ(np.array([0.54369557, 0.32107944, 0.12197225])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_XYZ(np.array([0.29777735, 0.48246446, 0.23042768])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_XYZ(np.array([0.18582823, 0.14633764, 0.06157201])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_XYZ(np.array([0.34567, 0.3585, 0.00000000])), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_XYZ( np.array( [ @@ -183,7 +191,7 @@ def test_xyY_to_XYZ(self): [0.00000000, 1.00000000, 0.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xyY_to_XYZ(self): @@ -197,11 +205,15 @@ def test_n_dimensional_xyY_to_XYZ(self): xyY = np.tile(xyY, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal(xyY_to_XYZ(xyY), XYZ, decimal=7) + np.testing.assert_allclose( + xyY_to_XYZ(xyY), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) xyY = np.reshape(xyY, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal(xyY_to_XYZ(xyY), XYZ, decimal=7) + np.testing.assert_allclose( + xyY_to_XYZ(xyY), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_xyY_to_XYZ(self): """ @@ -221,8 +233,10 @@ def test_domain_range_scale_xyY_to_XYZ(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - xyY_to_XYZ(xyY * factor_a), XYZ * factor_b, decimal=7 + np.testing.assert_allclose( + xyY_to_XYZ(xyY * factor_a), + XYZ * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -243,28 +257,28 @@ class TestxyY_to_xy(unittest.TestCase): def test_xyY_to_xy(self): """Test :func:`colour.models.cie_xyy.xyY_to_xy` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_xy(np.array([0.54369557, 0.32107944, 0.12197225])), np.array([0.54369557, 0.32107944]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_xy(np.array([0.29777735, 0.48246446, 0.23042768])), np.array([0.29777735, 0.48246446]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_xy(np.array([0.18582823, 0.14633764, 0.06157201])), np.array([0.18582823, 0.14633764]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xyY_to_xy(np.array([0.31270, 0.32900])), np.array([0.31270000, 0.32900000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xyY_to_xy(self): @@ -278,11 +292,15 @@ def test_n_dimensional_xyY_to_xy(self): xyY = np.tile(xyY, (6, 1)) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal(xyY_to_xy(xyY), xy, decimal=7) + np.testing.assert_allclose( + xyY_to_xy(xyY), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) xyY = np.reshape(xyY, (2, 3, 3)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal(xyY_to_xy(xyY), xy, decimal=7) + np.testing.assert_allclose( + xyY_to_xy(xyY), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_xyY_to_xy(self): """ @@ -302,8 +320,10 @@ def test_domain_range_scale_xyY_to_xy(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - xyY_to_xy(xyY * factor_a), xy * factor_b, decimal=7 + np.testing.assert_allclose( + xyY_to_xy(xyY * factor_a), + xy * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -324,34 +344,34 @@ class Testxy_to_xyY(unittest.TestCase): def test_xy_to_xyY(self): """Test :func:`colour.models.cie_xyy.xy_to_xyY` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_xyY(np.array([0.54369557, 0.32107944])), np.array([0.54369557, 0.32107944, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_xyY(np.array([0.29777735, 0.48246446])), np.array([0.29777735, 0.48246446, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_xyY(np.array([0.18582823, 0.14633764])), np.array([0.18582823, 0.14633764, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_xyY(np.array([0.31270000, 0.32900000, 1.00000000])), np.array([0.31270000, 0.32900000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_xyY(np.array([0.31270000, 0.32900000]), 100), np.array([0.31270000, 0.32900000, 100.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_xyY(self): @@ -365,11 +385,15 @@ def test_n_dimensional_xy_to_xyY(self): xy = np.tile(xy, (6, 1)) xyY = np.tile(xyY, (6, 1)) - np.testing.assert_array_almost_equal(xy_to_xyY(xy), xyY, decimal=7) + np.testing.assert_allclose( + xy_to_xyY(xy), xyY, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) xyY = np.reshape(xyY, (2, 3, 3)) - np.testing.assert_array_almost_equal(xy_to_xyY(xy), xyY, decimal=7) + np.testing.assert_allclose( + xy_to_xyY(xy), xyY, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_xy_to_xyY(self): """ @@ -393,8 +417,10 @@ def test_domain_range_scale_xy_to_xyY(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - xy_to_xyY(xy * factor_a), xyY * factor_b, decimal=7 + np.testing.assert_allclose( + xy_to_xyY(xy * factor_a), + xyY * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -415,28 +441,28 @@ class TestXYZ_to_xy(unittest.TestCase): def test_XYZ_to_xy(self): """Test :func:`colour.models.cie_xyy.XYZ_to_xy` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xy(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.54369557, 0.32107944]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xy(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.29777735, 0.48246446]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xy(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([0.18582823, 0.14633764]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_xy(np.array([0.00000000, 0.00000000, 0.00000000])), np.array([0.00000000, 0.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_xy(self): @@ -450,11 +476,15 @@ def test_n_dimensional_XYZ_to_xy(self): XYZ = np.tile(XYZ, (6, 1)) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal(XYZ_to_xy(XYZ), xy, decimal=7) + np.testing.assert_allclose( + XYZ_to_xy(XYZ), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) XYZ = np.reshape(XYZ, (2, 3, 3)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal(XYZ_to_xy(XYZ), xy, decimal=7) + np.testing.assert_allclose( + XYZ_to_xy(XYZ), xy, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_XYZ_to_xy(self): """ @@ -470,8 +500,8 @@ def test_domain_range_scale_XYZ_to_xy(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_xy(XYZ * factor), xy, decimal=7 + np.testing.assert_allclose( + XYZ_to_xy(XYZ * factor), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -492,28 +522,28 @@ class Testxy_to_XYZ(unittest.TestCase): def test_xy_to_XYZ(self): """Test :func:`colour.models.cie_xyy.xy_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_XYZ(np.array([0.54369557, 0.32107944])), np.array([1.69333661, 1.00000000, 0.42115742]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_XYZ(np.array([0.29777735, 0.48246446])), np.array([0.61720059, 1.00000000, 0.45549094]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_XYZ(np.array([0.18582823, 0.14633764])), np.array([1.26985942, 1.00000000, 4.56365245]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_to_XYZ(np.array([0.31270000, 0.32900000])), np.array([0.95045593, 1.00000000, 1.08905775]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_XYZ(self): @@ -527,11 +557,15 @@ def test_n_dimensional_xy_to_XYZ(self): xy = np.tile(xy, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal(xy_to_XYZ(xy), XYZ, decimal=7) + np.testing.assert_allclose( + xy_to_XYZ(xy), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) xy = np.reshape(xy, (2, 3, 2)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal(xy_to_XYZ(xy), XYZ, decimal=7) + np.testing.assert_allclose( + xy_to_XYZ(xy), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_xy_to_XYZ(self): """ @@ -551,8 +585,10 @@ def test_domain_range_scale_xy_to_XYZ(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - xy_to_XYZ(xy * factor_a), XYZ * factor_b, decimal=7 + np.testing.assert_allclose( + xy_to_XYZ(xy * factor_a), + XYZ * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_common.py b/colour/models/tests/test_common.py index de7a18a569..696dec0e52 100644 --- a/colour/models/tests/test_common.py +++ b/colour/models/tests/test_common.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.common` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import Iab_to_XYZ, Jab_to_JCh, JCh_to_Jab, XYZ_to_Iab from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -32,22 +34,22 @@ class TestJab_to_JCh(unittest.TestCase): def test_Jab_to_JCh(self): """Test :func:`colour.models.common.Jab_to_JCh` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Jab_to_JCh(np.array([41.52787529, 52.63858304, 26.92317922])), np.array([41.52787529, 59.12425901, 27.08848784]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Jab_to_JCh(np.array([55.11636304, -41.08791787, 30.91825778])), np.array([55.11636304, 51.42135412, 143.03889556]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Jab_to_JCh(np.array([29.80565520, 20.01830466, -48.34913874])), np.array([29.80565520, 52.32945383, 292.49133666]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Jab_to_JCh(self): @@ -61,11 +63,15 @@ def test_n_dimensional_Jab_to_JCh(self): Lab = np.tile(Lab, (6, 1)) LCHab = np.tile(LCHab, (6, 1)) - np.testing.assert_array_almost_equal(Jab_to_JCh(Lab), LCHab, decimal=7) + np.testing.assert_allclose( + Jab_to_JCh(Lab), LCHab, atol=TOLERANCE_ABSOLUTE_TESTS + ) Lab = np.reshape(Lab, (2, 3, 3)) LCHab = np.reshape(LCHab, (2, 3, 3)) - np.testing.assert_array_almost_equal(Jab_to_JCh(Lab), LCHab, decimal=7) + np.testing.assert_allclose( + Jab_to_JCh(Lab), LCHab, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_Jab_to_JCh(self): """ @@ -83,8 +89,10 @@ def test_domain_range_scale_Jab_to_JCh(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - Jab_to_JCh(Lab * factor_a), LCHab * factor_b, decimal=7 + np.testing.assert_allclose( + Jab_to_JCh(Lab * factor_a), + LCHab * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -105,22 +113,22 @@ class TestJCh_to_Jab(unittest.TestCase): def test_JCh_to_Jab(self): """Test :func:`colour.models.common.JCh_to_Jab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JCh_to_Jab(np.array([41.52787529, 59.12425901, 27.08848784])), np.array([41.52787529, 52.63858304, 26.92317922]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JCh_to_Jab(np.array([55.11636304, 51.42135412, 143.03889556])), np.array([55.11636304, -41.08791787, 30.91825778]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( JCh_to_Jab(np.array([29.80565520, 52.32945383, 292.49133666])), np.array([29.80565520, 20.01830466, -48.34913874]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_JCh_to_Jab(self): @@ -134,11 +142,15 @@ def test_n_dimensional_JCh_to_Jab(self): LCHab = np.tile(LCHab, (6, 1)) Lab = np.tile(Lab, (6, 1)) - np.testing.assert_array_almost_equal(JCh_to_Jab(LCHab), Lab, decimal=7) + np.testing.assert_allclose( + JCh_to_Jab(LCHab), Lab, atol=TOLERANCE_ABSOLUTE_TESTS + ) LCHab = np.reshape(LCHab, (2, 3, 3)) Lab = np.reshape(Lab, (2, 3, 3)) - np.testing.assert_array_almost_equal(JCh_to_Jab(LCHab), Lab, decimal=7) + np.testing.assert_allclose( + JCh_to_Jab(LCHab), Lab, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_JCh_to_Jab(self): """ @@ -156,8 +168,10 @@ def test_domain_range_scale_JCh_to_Jab(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - JCh_to_Jab(LCHab * factor_a), Lab * factor_b, decimal=7 + np.testing.assert_allclose( + JCh_to_Jab(LCHab * factor_a), + Lab * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -194,7 +208,7 @@ def setUp(self): def test_XYZ_to_Iab(self): """Test :func:`colour.models.common.XYZ_to_Iab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Iab( np.array([0.20654008, 0.12197225, 0.05136952]), self.LMS_to_LMS_p, @@ -202,10 +216,10 @@ def test_XYZ_to_Iab(self): self.M_LMS_p_to_Iab, ), np.array([0.38426191, 0.38487306, 0.18886838]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Iab( np.array([0.14222010, 0.23042768, 0.10495772]), self.LMS_to_LMS_p, @@ -213,10 +227,10 @@ def test_XYZ_to_Iab(self): self.M_LMS_p_to_Iab, ), np.array([0.49437481, -0.19251742, 0.18080304]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Iab( np.array([0.07818780, 0.06157201, 0.28099326]), self.LMS_to_LMS_p, @@ -224,7 +238,7 @@ def test_XYZ_to_Iab(self): self.M_LMS_p_to_Iab, ), np.array([0.35167774, -0.07525627, -0.30921279]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Iab(self): @@ -240,22 +254,22 @@ def test_n_dimensional_XYZ_to_Iab(self): XYZ = np.tile(XYZ, (6, 1)) Iab = np.tile(Iab, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Iab( XYZ, self.LMS_to_LMS_p, self.M_XYZ_to_LMS, self.M_LMS_p_to_Iab ), Iab, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) Iab = np.reshape(Iab, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Iab( XYZ, self.LMS_to_LMS_p, self.M_XYZ_to_LMS, self.M_LMS_p_to_Iab ), Iab, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_Iab(self): @@ -272,7 +286,7 @@ def test_domain_range_scale_XYZ_to_Iab(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Iab( XYZ * factor, self.LMS_to_LMS_p, @@ -280,7 +294,7 @@ def test_domain_range_scale_XYZ_to_Iab(self): self.M_LMS_p_to_Iab, ), Iab * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -326,7 +340,7 @@ def setUp(self): def test_Iab_to_XYZ(self): """Test :func:`colour.models.common.Iab_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Iab_to_XYZ( np.array([0.38426191, 0.38487306, 0.18886838]), self.LMS_p_to_LMS, @@ -334,10 +348,10 @@ def test_Iab_to_XYZ(self): self.M_LMS_to_XYZ, ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Iab_to_XYZ( np.array([0.49437481, -0.19251742, 0.18080304]), self.LMS_p_to_LMS, @@ -345,10 +359,10 @@ def test_Iab_to_XYZ(self): self.M_LMS_to_XYZ, ), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Iab_to_XYZ( np.array([0.35167774, -0.07525627, -0.30921279]), self.LMS_p_to_LMS, @@ -356,7 +370,7 @@ def test_Iab_to_XYZ(self): self.M_LMS_to_XYZ, ), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Iab_to_XYZ(self): @@ -372,22 +386,22 @@ def test_n_dimensional_Iab_to_XYZ(self): Iab = np.tile(Iab, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Iab_to_XYZ( Iab, self.LMS_p_to_LMS, self.M_Iab_to_LMS_p, self.M_LMS_to_XYZ ), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Iab = np.reshape(Iab, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Iab_to_XYZ( Iab, self.LMS_p_to_LMS, self.M_Iab_to_LMS_p, self.M_LMS_to_XYZ ), XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_Iab_to_XYZ(self): @@ -404,7 +418,7 @@ def test_domain_range_scale_Iab_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Iab_to_XYZ( Iab * factor, self.LMS_p_to_LMS, @@ -412,7 +426,7 @@ def test_domain_range_scale_Iab_to_XYZ(self): self.M_LMS_to_XYZ, ), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_din99.py b/colour/models/tests/test_din99.py index b79cf85cf1..9a8147cb35 100644 --- a/colour/models/tests/test_din99.py +++ b/colour/models/tests/test_din99.py @@ -1,15 +1,17 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.din99` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - Lab_to_DIN99, DIN99_to_Lab, - XYZ_to_DIN99, DIN99_to_XYZ, + Lab_to_DIN99, + XYZ_to_DIN99, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,49 +39,49 @@ class TestLab_to_DIN99(unittest.TestCase): def test_Lab_to_DIN99(self): """Test :func:`colour.models.din99.Lab_to_DIN99` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99(np.array([41.52787529, 52.63858304, 26.92317922])), np.array([53.22821988, 28.41634656, 3.89839552]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99(np.array([55.11636304, -41.08791787, 30.91825778])), np.array([66.08943912, -17.35290106, 16.09690691]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99(np.array([29.80565520, 20.01830466, -48.34913874])), np.array([40.71533366, 3.48714163, -21.45321411]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99( np.array([41.52787529, 52.63858304, 26.92317922]), method="DIN99b", ), np.array([45.58303137, 34.71824493, 17.61622149]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99( np.array([41.52787529, 52.63858304, 26.92317922]), method="DIN99c", ), np.array([45.40284208, 32.75074741, 15.74603532]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99( np.array([41.52787529, 52.63858304, 26.92317922]), method="DIN99d", ), np.array([45.31204747, 31.42106716, 14.17004652]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Lab_to_DIN99(self): @@ -93,14 +95,14 @@ def test_n_dimensional_Lab_to_DIN99(self): Lab = np.tile(Lab, (6, 1)) Lab_99 = np.tile(Lab_99, (6, 1)) - np.testing.assert_array_almost_equal( - Lab_to_DIN99(Lab), Lab_99, decimal=7 + np.testing.assert_allclose( + Lab_to_DIN99(Lab), Lab_99, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab = np.reshape(Lab, (2, 3, 3)) Lab_99 = np.reshape(Lab_99, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Lab_to_DIN99(Lab), Lab_99, decimal=7 + np.testing.assert_allclose( + Lab_to_DIN99(Lab), Lab_99, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Lab_to_DIN99(self): @@ -118,23 +120,25 @@ def test_domain_range_scale_Lab_to_DIN99(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - Lab_to_DIN99(Lab * factor), Lab_99 * factor, decimal=7 + np.testing.assert_allclose( + Lab_to_DIN99(Lab * factor), + Lab_99 * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99((Lab * factor), method="DIN99b"), Lab_99_b * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99((Lab * factor), method="DIN99c"), Lab_99_c * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Lab_to_DIN99((Lab * factor), method="DIN99d"), Lab_99_d * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -158,49 +162,49 @@ class TestDIN99_to_Lab(unittest.TestCase): def test_DIN99_to_Lab(self): """Test :func:`colour.models.din99.DIN99_to_Lab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab(np.array([53.22821988, 28.41634656, 3.89839552])), np.array([41.52787529, 52.63858304, 26.92317922]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab(np.array([66.08943912, -17.35290106, 16.09690691])), np.array([55.11636304, -41.08791787, 30.91825778]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab(np.array([40.71533366, 3.48714163, -21.45321411])), np.array([29.80565520, 20.01830466, -48.34913874]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab( np.array([45.58303137, 34.71824493, 17.61622149]), method="DIN99b", ), np.array([41.52787529, 52.63858304, 26.92317922]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab( np.array([45.40284208, 32.75074741, 15.74603532]), method="DIN99c", ), np.array([41.52787529, 52.63858304, 26.92317922]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab( np.array([45.31204747, 31.42106716, 14.17004652]), method="DIN99d", ), np.array([41.52787529, 52.63858304, 26.92317922]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_DIN99_to_Lab(self): @@ -214,14 +218,14 @@ def test_n_dimensional_DIN99_to_Lab(self): Lab_99 = np.tile(Lab_99, (6, 1)) Lab = np.tile(Lab, (6, 1)) - np.testing.assert_array_almost_equal( - DIN99_to_Lab(Lab_99), Lab, decimal=7 + np.testing.assert_allclose( + DIN99_to_Lab(Lab_99), Lab, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab_99 = np.reshape(Lab_99, (2, 3, 3)) Lab = np.reshape(Lab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - DIN99_to_Lab(Lab_99), Lab, decimal=7 + np.testing.assert_allclose( + DIN99_to_Lab(Lab_99), Lab, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_DIN99_to_Lab(self): @@ -239,23 +243,25 @@ def test_domain_range_scale_DIN99_to_Lab(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - DIN99_to_Lab(Lab_99 * factor), Lab * factor, decimal=7 + np.testing.assert_allclose( + DIN99_to_Lab(Lab_99 * factor), + Lab * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab((Lab_99 * factor), method="DIN99b"), Lab_b * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab((Lab_99 * factor), method="DIN99c"), Lab_c * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_Lab((Lab_99 * factor), method="DIN99d"), Lab_d * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -279,30 +285,30 @@ class TestXYZ_to_DIN99(unittest.TestCase): def test_XYZ_to_DIN99(self): """Test :func:`colour.models.din99.XYZ_to_DIN99` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_DIN99(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([53.22821988, 28.41634656, 3.89839552]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_DIN99(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([66.08943912, -17.35290106, 16.09690691]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_DIN99(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([40.71533366, 3.48714163, -21.45321411]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_DIN99( np.array([0.20654008, 0.12197225, 0.05136952]), method="DIN99b" ), np.array([45.58303137, 34.71824493, 17.61622149]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_DIN99(self): @@ -316,14 +322,14 @@ def test_n_dimensional_XYZ_to_DIN99(self): XYZ = np.tile(XYZ, (6, 1)) Lab_99 = np.tile(Lab_99, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_DIN99(XYZ), Lab_99, decimal=7 + np.testing.assert_allclose( + XYZ_to_DIN99(XYZ), Lab_99, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) Lab_99 = np.reshape(Lab_99, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_DIN99(XYZ), Lab_99, decimal=7 + np.testing.assert_allclose( + XYZ_to_DIN99(XYZ), Lab_99, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_DIN99(self): @@ -338,8 +344,10 @@ def test_domain_range_scale_XYZ_to_DIN99(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_DIN99(XYZ * factor_a), Lab_99 * factor_b, decimal=7 + np.testing.assert_allclose( + XYZ_to_DIN99(XYZ * factor_a), + Lab_99 * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -360,31 +368,31 @@ class TestDIN99_to_XYZ(unittest.TestCase): def test_DIN99_to_XYZ(self): """Test :func:`colour.models.din99.DIN99_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_XYZ(np.array([53.22821988, 28.41634656, 3.89839552])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_XYZ(np.array([66.08943912, -17.35290106, 16.09690691])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_XYZ(np.array([40.71533366, 3.48714163, -21.45321411])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( DIN99_to_XYZ( np.array([45.58303137, 34.71824493, 17.61622149]), method="DIN99b", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_DIN99_to_XYZ(self): @@ -398,14 +406,14 @@ def test_n_dimensional_DIN99_to_XYZ(self): Lab_99 = np.tile(Lab_99, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - DIN99_to_XYZ(Lab_99), XYZ, decimal=7 + np.testing.assert_allclose( + DIN99_to_XYZ(Lab_99), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Lab_99 = np.reshape(Lab_99, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - DIN99_to_XYZ(Lab_99), XYZ, decimal=7 + np.testing.assert_allclose( + DIN99_to_XYZ(Lab_99), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_DIN99_to_XYZ(self): @@ -420,8 +428,10 @@ def test_domain_range_scale_DIN99_to_XYZ(self): d_r = (("reference", 1, 1), ("1", 0.01, 1), ("100", 1, 100)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - DIN99_to_XYZ(Lab_99 * factor_a), XYZ * factor_b, decimal=7 + np.testing.assert_allclose( + DIN99_to_XYZ(Lab_99 * factor_a), + XYZ * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_hdr_cie_lab.py b/colour/models/tests/test_hdr_cie_lab.py index 55eb1e0e5f..c5a6979f22 100644 --- a/colour/models/tests/test_hdr_cie_lab.py +++ b/colour/models/tests/test_hdr_cie_lab.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.hdr_cie_lab` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import XYZ_to_hdr_CIELab, hdr_CIELab_to_XYZ from colour.models.hdr_cie_lab import exponent_hdr_CIELab from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -35,22 +37,28 @@ def test_exponent_hdr_CIELab(self): definition. """ - self.assertAlmostEqual( - exponent_hdr_CIELab(0.2, 100), 0.473851073746817, places=7 + np.testing.assert_allclose( + exponent_hdr_CIELab(0.2, 100), + 0.473851073746817, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_hdr_CIELab(0.4, 100), 0.656101486726362, places=7 + np.testing.assert_allclose( + exponent_hdr_CIELab(0.4, 100), + 0.656101486726362, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_hdr_CIELab(0.4, 100, method="Fairchild 2010"), 1.326014370643925, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_hdr_CIELab(0.2, 1000), 0.710776610620225, places=7 + np.testing.assert_allclose( + exponent_hdr_CIELab(0.2, 1000), + 0.710776610620225, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_exponent_hdr_CIELab(self): @@ -66,22 +74,28 @@ def test_n_dimensional_exponent_hdr_CIELab(self): Y_s = np.tile(Y_s, 6) Y_abs = np.tile(Y_abs, 6) epsilon = np.tile(epsilon, 6) - np.testing.assert_array_almost_equal( - exponent_hdr_CIELab(Y_s, Y_abs), epsilon, decimal=7 + np.testing.assert_allclose( + exponent_hdr_CIELab(Y_s, Y_abs), + epsilon, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_s = np.reshape(Y_s, (2, 3)) Y_abs = np.reshape(Y_abs, (2, 3)) epsilon = np.reshape(epsilon, (2, 3)) - np.testing.assert_array_almost_equal( - exponent_hdr_CIELab(Y_s, Y_abs), epsilon, decimal=7 + np.testing.assert_allclose( + exponent_hdr_CIELab(Y_s, Y_abs), + epsilon, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_s = np.reshape(Y_s, (2, 3, 1)) Y_abs = np.reshape(Y_abs, (2, 3, 1)) epsilon = np.reshape(epsilon, (2, 3, 1)) - np.testing.assert_array_almost_equal( - exponent_hdr_CIELab(Y_s, Y_abs), epsilon, decimal=7 + np.testing.assert_allclose( + exponent_hdr_CIELab(Y_s, Y_abs), + epsilon, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_exponent_hdr_CIELab(self): @@ -97,10 +111,10 @@ def test_domain_range_scale_exponent_hdr_CIELab(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( exponent_hdr_CIELab(Y_s * factor, Y_abs), epsilon, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -123,45 +137,45 @@ class TestXYZ_to_hdr_CIELab(unittest.TestCase): def test_XYZ_to_hdr_CIELab(self): """Test :func:`colour.models.hdr_cie_lab.XYZ_to_hdr_CIELab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_CIELab(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([51.87002062, 60.47633850, 32.14551912]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_CIELab( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.44757, 0.40745]), ), np.array([51.87002062, 44.49667330, -6.69619196]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_CIELab( np.array([0.20654008, 0.12197225, 0.05136952]), np.array([0.44757, 0.40745]), method="Fairchild 2010", ), np.array([31.99621114, 95.08564341, -14.14047055]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_CIELab( np.array([0.20654008, 0.12197225, 0.05136952]), Y_s=0.5 ), np.array([23.10388654, 59.31425004, 23.69960142]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_CIELab( np.array([0.20654008, 0.12197225, 0.05136952]), Y_abs=1000 ), np.array([29.77261805, 62.58315675, 27.31232673]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_hdr_CIELab(self): @@ -178,15 +192,19 @@ def test_n_dimensional_XYZ_to_hdr_CIELab(self): XYZ = np.tile(XYZ, (6, 1)) Lab_hdr = np.tile(Lab_hdr, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), Lab_hdr, decimal=7 + np.testing.assert_allclose( + XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), + Lab_hdr, + atol=TOLERANCE_ABSOLUTE_TESTS, ) illuminant = np.tile(illuminant, (6, 1)) Y_s = np.tile(Y_s, 6) Y_abs = np.tile(Y_abs, 6) - np.testing.assert_array_almost_equal( - XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), Lab_hdr, decimal=7 + np.testing.assert_allclose( + XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), + Lab_hdr, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) @@ -194,8 +212,10 @@ def test_n_dimensional_XYZ_to_hdr_CIELab(self): Y_s = np.reshape(Y_s, (2, 3)) Y_abs = np.reshape(Y_abs, (2, 3)) Lab_hdr = np.reshape(Lab_hdr, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), Lab_hdr, decimal=7 + np.testing.assert_allclose( + XYZ_to_hdr_CIELab(XYZ, illuminant, Y_s, Y_abs), + Lab_hdr, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_hdr_CIELab(self): @@ -213,12 +233,12 @@ def test_domain_range_scale_XYZ_to_hdr_CIELab(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_CIELab( XYZ * factor_a, illuminant, Y_s * factor_a, Y_abs ), Lab_hdr * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -242,47 +262,47 @@ class TestHdr_CIELab_to_XYZ(unittest.TestCase): def test_hdr_CIELab_to_XYZ(self): """Test :func:`colour.models.hdr_cie_lab.hdr_CIELab_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_CIELab_to_XYZ( np.array([51.87002062, 60.47633850, 32.14551912]) ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_CIELab_to_XYZ( np.array([51.87002062, 44.49667330, -6.69619196]), np.array([0.44757, 0.40745]), ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_CIELab_to_XYZ( np.array([31.99621114, 95.08564341, -14.14047055]), np.array([0.44757, 0.40745]), method="Fairchild 2010", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_CIELab_to_XYZ( np.array([23.10388654, 59.31425004, 23.69960142]), Y_s=0.5 ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_CIELab_to_XYZ( np.array([29.77261805, 62.58315675, 27.31232673]), Y_abs=1000 ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_hdr_CIELab_to_XYZ(self): @@ -299,15 +319,19 @@ def test_n_dimensional_hdr_CIELab_to_XYZ(self): Lab_hdr = np.tile(Lab_hdr, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), XYZ, decimal=7 + np.testing.assert_allclose( + hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) illuminant = np.tile(illuminant, (6, 1)) Y_s = np.tile(Y_s, 6) Y_abs = np.tile(Y_abs, 6) - np.testing.assert_array_almost_equal( - hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), XYZ, decimal=7 + np.testing.assert_allclose( + hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Lab_hdr = np.reshape(Lab_hdr, (2, 3, 3)) @@ -315,8 +339,10 @@ def test_n_dimensional_hdr_CIELab_to_XYZ(self): Y_s = np.reshape(Y_s, (2, 3)) Y_abs = np.reshape(Y_abs, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), XYZ, decimal=7 + np.testing.assert_allclose( + hdr_CIELab_to_XYZ(Lab_hdr, illuminant, Y_s, Y_abs), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_hdr_CIELab_to_XYZ(self): @@ -334,12 +360,12 @@ def test_domain_range_scale_hdr_CIELab_to_XYZ(self): d_r = (("reference", 1, 1, 1), ("1", 0.01, 1, 1), ("100", 1, 100, 100)) for scale, factor_a, factor_b, factor_c in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_CIELab_to_XYZ( Lab_hdr * factor_a, illuminant, Y_s * factor_b, Y_abs ), XYZ * factor_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_hdr_ipt.py b/colour/models/tests/test_hdr_ipt.py index 0c2c9a181f..e187462b48 100644 --- a/colour/models/tests/test_hdr_ipt.py +++ b/colour/models/tests/test_hdr_ipt.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.hdr_ipt` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import XYZ_to_hdr_IPT, hdr_IPT_to_XYZ from colour.models.hdr_ipt import exponent_hdr_IPT from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -32,22 +34,28 @@ class TestExponent_hdr_IPT(unittest.TestCase): def test_exponent_hdr_IPT(self): """Test :func:`colour.models.hdr_ipt.exponent_hdr_IPT` definition.""" - self.assertAlmostEqual( - exponent_hdr_IPT(0.2, 100), 0.482020919845900, places=7 + np.testing.assert_allclose( + exponent_hdr_IPT(0.2, 100), + 0.482020919845900, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_hdr_IPT(0.4, 100), 0.667413581325092, places=7 + np.testing.assert_allclose( + exponent_hdr_IPT(0.4, 100), + 0.667413581325092, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( exponent_hdr_IPT(0.4, 100, method="Fairchild 2010"), 1.219933220992410, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - exponent_hdr_IPT(0.2, 1000), 0.723031379768850, places=7 + np.testing.assert_allclose( + exponent_hdr_IPT(0.2, 1000), + 0.723031379768850, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_exponent_hdr_IPT(self): @@ -63,22 +71,28 @@ def test_n_dimensional_exponent_hdr_IPT(self): Y_s = np.tile(Y_s, 6) Y_abs = np.tile(Y_abs, 6) epsilon = np.tile(epsilon, 6) - np.testing.assert_array_almost_equal( - exponent_hdr_IPT(Y_s, Y_abs), epsilon, decimal=7 + np.testing.assert_allclose( + exponent_hdr_IPT(Y_s, Y_abs), + epsilon, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_s = np.reshape(Y_s, (2, 3)) Y_abs = np.reshape(Y_abs, (2, 3)) epsilon = np.reshape(epsilon, (2, 3)) - np.testing.assert_array_almost_equal( - exponent_hdr_IPT(Y_s, Y_abs), epsilon, decimal=7 + np.testing.assert_allclose( + exponent_hdr_IPT(Y_s, Y_abs), + epsilon, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_s = np.reshape(Y_s, (2, 3, 1)) Y_abs = np.reshape(Y_abs, (2, 3, 1)) epsilon = np.reshape(epsilon, (2, 3, 1)) - np.testing.assert_array_almost_equal( - exponent_hdr_IPT(Y_s, Y_abs), epsilon, decimal=7 + np.testing.assert_allclose( + exponent_hdr_IPT(Y_s, Y_abs), + epsilon, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_exponent_hdr_IPT(self): @@ -94,8 +108,10 @@ def test_domain_range_scale_exponent_hdr_IPT(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - exponent_hdr_IPT(Y_s * factor, Y_abs), epsilon, decimal=7 + np.testing.assert_allclose( + exponent_hdr_IPT(Y_s * factor, Y_abs), + epsilon, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -118,35 +134,35 @@ class TestXYZ_to_hdr_IPT(unittest.TestCase): def test_XYZ_to_hdr_IPT(self): """Test :func:`colour.models.hdr_ipt.XYZ_to_hdr_IPT` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_IPT(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([48.39376346, 42.44990202, 22.01954033]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_IPT( np.array([0.20654008, 0.12197225, 0.05136952]), method="Fairchild 2010", ), np.array([30.02873147, 83.93845061, 34.90287382]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_IPT( np.array([0.20654008, 0.12197225, 0.05136952]), Y_s=0.5 ), np.array([20.75088680, 37.98300971, 16.66974299]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_IPT( np.array([0.07818780, 0.06157201, 0.28099326]), Y_abs=1000 ), np.array([23.83205010, -5.98739209, -32.74311745]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_hdr_IPT(self): @@ -162,22 +178,28 @@ def test_n_dimensional_XYZ_to_hdr_IPT(self): XYZ = np.tile(XYZ, (6, 1)) IPT_hdr = np.tile(IPT_hdr, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs), IPT_hdr, decimal=7 + np.testing.assert_allclose( + XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs), + IPT_hdr, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_s = np.tile(Y_s, 6) Y_abs = np.tile(Y_abs, 6) - np.testing.assert_array_almost_equal( - XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs), IPT_hdr, decimal=7 + np.testing.assert_allclose( + XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs), + IPT_hdr, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) Y_s = np.reshape(Y_s, (2, 3)) Y_abs = np.reshape(Y_abs, (2, 3)) IPT_hdr = np.reshape(IPT_hdr, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs), IPT_hdr, decimal=7 + np.testing.assert_allclose( + XYZ_to_hdr_IPT(XYZ, Y_s, Y_abs), + IPT_hdr, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_hdr_IPT(self): @@ -194,10 +216,10 @@ def test_domain_range_scale_XYZ_to_hdr_IPT(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_hdr_IPT(XYZ * factor_a, Y_s * factor_a, Y_abs), IPT_hdr * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -221,35 +243,35 @@ class TestHdr_IPT_to_XYZ(unittest.TestCase): def test_hdr_IPT_to_XYZ(self): """Test :func:`colour.models.hdr_ipt.hdr_IPT_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_IPT_to_XYZ(np.array([48.39376346, 42.44990202, 22.01954033])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_IPT_to_XYZ( np.array([30.02873147, 83.93845061, 34.90287382]), method="Fairchild 2010", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_IPT_to_XYZ( np.array([20.75088680, 37.98300971, 16.66974299]), Y_s=0.5 ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_IPT_to_XYZ( np.array([23.83205010, -5.98739209, -32.74311745]), Y_abs=1000 ), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_hdr_IPT_to_XYZ(self): @@ -265,22 +287,28 @@ def test_n_dimensional_hdr_IPT_to_XYZ(self): IPT_hdr = np.tile(IPT_hdr, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs), XYZ, decimal=7 + np.testing.assert_allclose( + hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Y_s = np.tile(Y_s, 6) Y_abs = np.tile(Y_abs, 6) - np.testing.assert_array_almost_equal( - hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs), XYZ, decimal=7 + np.testing.assert_allclose( + hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) IPT_hdr = np.reshape(IPT_hdr, (2, 3, 3)) Y_s = np.reshape(Y_s, (2, 3)) Y_abs = np.reshape(Y_abs, (2, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs), XYZ, decimal=7 + np.testing.assert_allclose( + hdr_IPT_to_XYZ(IPT_hdr, Y_s, Y_abs), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_hdr_IPT_to_XYZ(self): @@ -297,10 +325,10 @@ def test_domain_range_scale_hdr_IPT_to_XYZ(self): d_r = (("reference", 1, 1, 1), ("1", 0.01, 1, 1), ("100", 1, 100, 100)) for scale, factor_a, factor_b, factor_c in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( hdr_IPT_to_XYZ(IPT_hdr * factor_a, Y_s * factor_b, Y_abs), XYZ * factor_c, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_hunter_lab.py b/colour/models/tests/test_hunter_lab.py index 3170100807..d57f2c3b95 100644 --- a/colour/models/tests/test_hunter_lab.py +++ b/colour/models/tests/test_hunter_lab.py @@ -1,17 +1,18 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.hunter_lab` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.colorimetry import TVS_ILLUMINANTS_HUNTERLAB +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - XYZ_to_K_ab_HunterLab1966, - XYZ_to_Hunter_Lab, Hunter_Lab_to_XYZ, + XYZ_to_Hunter_Lab, + XYZ_to_K_ab_HunterLab1966, ) - from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -40,28 +41,28 @@ def test_XYZ_to_K_ab_HunterLab1966(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_K_ab_HunterLab1966( np.array([0.20654008, 0.12197225, 0.05136952]) * 100 ), np.array([80.32152090, 14.59816495]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_K_ab_HunterLab1966( np.array([0.14222010, 0.23042768, 0.10495772]) * 100 ), np.array([66.65154834, 20.86664881]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_K_ab_HunterLab1966( np.array([0.07818780, 0.06157201, 0.28099326]) * 100 ), np.array([49.41960269, 34.14235426]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_K_ab_HunterLab1966(self): @@ -75,14 +76,14 @@ def test_n_dimensional_XYZ_to_K_ab_HunterLab1966(self): XYZ = np.tile(XYZ, (6, 1)) K_ab = np.tile(K_ab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_K_ab_HunterLab1966(XYZ), K_ab, decimal=7 + np.testing.assert_allclose( + XYZ_to_K_ab_HunterLab1966(XYZ), K_ab, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) K_ab = np.reshape(K_ab, (2, 3, 2)) - np.testing.assert_array_almost_equal( - XYZ_to_K_ab_HunterLab1966(XYZ), K_ab, decimal=7 + np.testing.assert_allclose( + XYZ_to_K_ab_HunterLab1966(XYZ), K_ab, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -106,61 +107,61 @@ class TestXYZ_to_Hunter_Lab(unittest.TestCase): def test_XYZ_to_Hunter_Lab(self): """Test :func:`colour.models.hunter_lab.XYZ_to_Hunter_Lab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Lab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100 ), np.array([34.92452577, 47.06189858, 14.38615107]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Lab( np.array([0.14222010, 0.23042768, 0.10495772]) * 100 ), np.array([48.00288325, -28.98551622, 18.75564181]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Lab( np.array([0.07818780, 0.06157201, 0.28099326]) * 100 ), np.array([24.81370791, 14.38300039, -53.25539126]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"] A = h_i["A"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Lab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, A.XYZ_n, A.K_ab, ), np.array([34.92452577, 35.04243086, -2.47688619]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) D65 = h_i["D65"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Lab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, D65.XYZ_n, D65.K_ab, ), np.array([34.92452577, 47.06189858, 14.38615107]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Lab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, D65.XYZ_n, K_ab=None, ), np.array([34.92452577, 47.05669614, 14.38385238]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Hunter_Lab(self): @@ -179,22 +180,28 @@ def test_n_dimensional_XYZ_to_Hunter_Lab(self): XYZ = np.tile(XYZ, (6, 1)) Lab = np.tile(Lab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Hunter_Lab(XYZ, XYZ_n, K_ab), Lab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Hunter_Lab(XYZ, XYZ_n, K_ab), + Lab, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_n = np.tile(XYZ_n, (6, 1)) K_ab = np.tile(K_ab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Hunter_Lab(XYZ, XYZ_n, K_ab), Lab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Hunter_Lab(XYZ, XYZ_n, K_ab), + Lab, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) K_ab = np.reshape(K_ab, (2, 3, 2)) Lab = np.reshape(Lab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_Hunter_Lab(XYZ, XYZ_n, K_ab), Lab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Hunter_Lab(XYZ, XYZ_n, K_ab), + Lab, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_Hunter_Lab(self): @@ -214,10 +221,10 @@ def test_domain_range_scale_XYZ_to_Hunter_Lab(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Lab(XYZ * factor, XYZ_n * factor, K_ab), Lab * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -241,61 +248,61 @@ class TestHunter_Lab_to_XYZ(unittest.TestCase): def test_Hunter_Lab_to_XYZ(self): """Test :func:`colour.models.hunter_lab.Hunter_Lab_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Lab_to_XYZ( np.array([34.92452577, 47.06189858, 14.38615107]) ), np.array([20.65400800, 12.19722500, 5.13695200]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Lab_to_XYZ( np.array([48.00288325, -28.98551622, 18.75564181]) ), np.array([14.22201000, 23.04276800, 10.49577200]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Lab_to_XYZ( np.array([24.81370791, 14.38300039, -53.25539126]) ), np.array([7.81878000, 6.15720100, 28.09932601]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"] A = h_i["A"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Lab_to_XYZ( np.array([34.92452577, 35.04243086, -2.47688619]), A.XYZ_n, A.K_ab, ), np.array([20.65400800, 12.19722500, 5.13695200]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) D65 = h_i["D65"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Lab_to_XYZ( np.array([34.92452577, 47.06189858, 14.38615107]), D65.XYZ_n, D65.K_ab, ), np.array([20.65400800, 12.19722500, 5.13695200]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Lab_to_XYZ( np.array([34.92452577, 47.05669614, 14.38385238]), D65.XYZ_n, K_ab=None, ), np.array([20.65400800, 12.19722500, 5.13695200]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Hunter_Lab_to_XYZ(self): @@ -314,22 +321,28 @@ def test_n_dimensional_Hunter_Lab_to_XYZ(self): Lab = np.tile(Lab, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - Hunter_Lab_to_XYZ(Lab, XYZ_n, K_ab), XYZ, decimal=7 + np.testing.assert_allclose( + Hunter_Lab_to_XYZ(Lab, XYZ_n, K_ab), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) K_ab = np.tile(K_ab, (6, 1)) XYZ_n = np.tile(XYZ_n, (6, 1)) - np.testing.assert_array_almost_equal( - Hunter_Lab_to_XYZ(Lab, XYZ_n, K_ab), XYZ, decimal=7 + np.testing.assert_allclose( + Hunter_Lab_to_XYZ(Lab, XYZ_n, K_ab), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) Lab = np.reshape(Lab, (2, 3, 3)) XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) K_ab = np.reshape(K_ab, (2, 3, 2)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Hunter_Lab_to_XYZ(Lab, XYZ_n, K_ab), XYZ, decimal=7 + np.testing.assert_allclose( + Hunter_Lab_to_XYZ(Lab, XYZ_n, K_ab), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_Hunter_Lab_to_XYZ(self): @@ -349,10 +362,10 @@ def test_domain_range_scale_Hunter_Lab_to_XYZ(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Lab_to_XYZ(Lab * factor, XYZ_n * factor, K_ab), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_hunter_rdab.py b/colour/models/tests/test_hunter_rdab.py index 9d92012663..9532a61246 100644 --- a/colour/models/tests/test_hunter_rdab.py +++ b/colour/models/tests/test_hunter_rdab.py @@ -1,13 +1,14 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.hunter_rdab` module.""" -import numpy as np import unittest from itertools import product -from colour.colorimetry import TVS_ILLUMINANTS_HUNTERLAB -from colour.models import XYZ_to_Hunter_Rdab, Hunter_Rdab_to_XYZ +import numpy as np +from colour.colorimetry import TVS_ILLUMINANTS_HUNTERLAB +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import Hunter_Rdab_to_XYZ, XYZ_to_Hunter_Rdab from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -32,61 +33,61 @@ class TestXYZ_to_Hunter_Rdab(unittest.TestCase): def test_XYZ_to_Hunter_Rdab(self): """Test :func:`colour.models.hunter_rdab.XYZ_to_Hunter_Rdab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Rdab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100 ), np.array([12.19722500, 57.12537874, 17.46241341]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Rdab( np.array([0.14222010, 0.23042768, 0.10495772]) * 100 ), np.array([23.04276800, -32.40057474, 20.96542183]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Rdab( np.array([0.07818780, 0.06157201, 0.28099326]) * 100 ), np.array([6.15720100, 18.13400284, -67.14408607]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"] A = h_i["A"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Rdab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, A.XYZ_n, A.K_ab, ), np.array([12.19722500, 42.53572838, -3.00653110]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) D65 = h_i["D65"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Rdab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, D65.XYZ_n, D65.K_ab, ), np.array([12.19722500, 57.12537874, 17.46241341]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Rdab( np.array([0.20654008, 0.12197225, 0.05136952]) * 100, D65.XYZ_n, K_ab=None, ), np.array([12.19722500, 57.11906384, 17.45962317]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Hunter_Rdab(self): @@ -105,22 +106,28 @@ def test_n_dimensional_XYZ_to_Hunter_Rdab(self): XYZ = np.tile(XYZ, (6, 1)) R_d_ab = np.tile(R_d_ab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab), R_d_ab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab), + R_d_ab, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ_n = np.tile(XYZ_n, (6, 1)) K_ab = np.tile(K_ab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab), R_d_ab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab), + R_d_ab, + atol=TOLERANCE_ABSOLUTE_TESTS, ) XYZ = np.reshape(XYZ, (2, 3, 3)) XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) K_ab = np.reshape(K_ab, (2, 3, 2)) R_d_ab = np.reshape(R_d_ab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab), R_d_ab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Hunter_Rdab(XYZ, XYZ_n, K_ab), + R_d_ab, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_XYZ_to_Hunter_Rdab(self): @@ -140,10 +147,10 @@ def test_domain_range_scale_XYZ_to_Hunter_Rdab(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Hunter_Rdab(XYZ * factor, XYZ_n * factor, K_ab), R_d_ab * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -167,61 +174,61 @@ class TestHunter_Rdab_to_XYZ(unittest.TestCase): def test_Hunter_Rdab_to_XYZ(self): """Test :func:`colour.models.hunter_rdab.Hunter_Rdab_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Rdab_to_XYZ( np.array([12.19722500, 57.12537874, 17.46241341]) ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Rdab_to_XYZ( np.array([23.04276800, -32.40057474, 20.96542183]) ), np.array([0.14222010, 0.23042768, 0.10495772]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Rdab_to_XYZ( np.array([6.15720100, 18.13400284, -67.14408607]) ), np.array([0.07818780, 0.06157201, 0.28099326]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) h_i = TVS_ILLUMINANTS_HUNTERLAB["CIE 1931 2 Degree Standard Observer"] A = h_i["A"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Rdab_to_XYZ( np.array([12.19722500, 42.53572838, -3.00653110]), A.XYZ_n, A.K_ab, ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) D65 = h_i["D65"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Rdab_to_XYZ( np.array([12.19722500, 57.12537874, 17.46241341]), D65.XYZ_n, D65.K_ab, ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Rdab_to_XYZ( np.array([12.19722500, 57.11906384, 17.45962317]), D65.XYZ_n, K_ab=None, ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_Hunter_Rdab_to_XYZ(self): @@ -240,22 +247,28 @@ def test_n_dimensional_Hunter_Rdab_to_XYZ(self): R_d_ab = np.tile(R_d_ab, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab), XYZ, decimal=7 + np.testing.assert_allclose( + Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) K_ab = np.tile(K_ab, (6, 1)) XYZ_n = np.tile(XYZ_n, (6, 1)) - np.testing.assert_array_almost_equal( - Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab), XYZ, decimal=7 + np.testing.assert_allclose( + Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) R_d_ab = np.reshape(R_d_ab, (2, 3, 3)) XYZ_n = np.reshape(XYZ_n, (2, 3, 3)) K_ab = np.reshape(K_ab, (2, 3, 2)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab), XYZ, decimal=7 + np.testing.assert_allclose( + Hunter_Rdab_to_XYZ(R_d_ab, XYZ_n, K_ab), + XYZ, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_Hunter_Rdab_to_XYZ(self): @@ -275,10 +288,10 @@ def test_domain_range_scale_Hunter_Rdab_to_XYZ(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Hunter_Rdab_to_XYZ(R_d_ab * factor, XYZ_n * factor, K_ab), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_icacb.py b/colour/models/tests/test_icacb.py index 4e0300a438..7f4860f56c 100644 --- a/colour/models/tests/test_icacb.py +++ b/colour/models/tests/test_icacb.py @@ -1,12 +1,14 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.hunter_rdab` module.""" +import unittest from itertools import product + import numpy as np -import unittest -from colour.models import XYZ_to_ICaCb, ICaCb_to_XYZ -from colour.utilities import ignore_numpy_errors, domain_range_scale +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import ICaCb_to_XYZ, XYZ_to_ICaCb +from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -30,28 +32,28 @@ class TestXYZ_to_ICaCb(unittest.TestCase): def test_XYZ_to_ICaCb(self): """Test :func:`colour.models.icacb.XYZ_to_ICaCb` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICaCb(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.06875297, 0.05753352, 0.02081548]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICaCb(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.08666353, -0.02479011, 0.03099396]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICaCb(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([0.05102472, -0.00965461, -0.05150706]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ICaCb(np.array([0.00000000, 0.00000000, 1.00000000])), np.array([1702.0656419, 14738.00583456, 1239.66837927]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_ICaCb(self): @@ -65,14 +67,14 @@ def test_n_dimensional_XYZ_to_ICaCb(self): XYZ = np.tile(XYZ, (6, 1)) ICaCb = np.tile(ICaCb, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_ICaCb(XYZ), ICaCb, decimal=7 + np.testing.assert_allclose( + XYZ_to_ICaCb(XYZ), ICaCb, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) ICaCb = np.reshape(ICaCb, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_ICaCb(XYZ), ICaCb, decimal=7 + np.testing.assert_allclose( + XYZ_to_ICaCb(XYZ), ICaCb, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_ICaCb(self): @@ -87,8 +89,10 @@ def test_domain_range_scale_XYZ_to_ICaCb(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_ICaCb(XYZ * factor), ICaCb * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_ICaCb(XYZ * factor), + ICaCb * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -106,30 +110,30 @@ class TestICaCb_to_XYZ(unittest.TestCase): def test_XYZ_to_ICaCb(self): """Test :func:`colour.models.icacb.ICaCb_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICaCb_to_XYZ(np.array([0.06875297, 0.05753352, 0.02081548])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICaCb_to_XYZ(np.array([0.08666353, -0.02479011, 0.03099396])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICaCb_to_XYZ(np.array([0.05102472, -0.00965461, -0.05150706])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ICaCb_to_XYZ( np.array([1702.0656419, 14738.00583456, 1239.66837927]) ), np.array([0.00000000, 0.00000000, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_ICaCb_to_XYZ(self): @@ -143,14 +147,14 @@ def test_n_dimensional_ICaCb_to_XYZ(self): ICaCb = np.tile(ICaCb, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - ICaCb_to_XYZ(ICaCb), XYZ, decimal=7 + np.testing.assert_allclose( + ICaCb_to_XYZ(ICaCb), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) ICaCb = np.reshape(ICaCb, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ICaCb_to_XYZ(ICaCb), XYZ, decimal=7 + np.testing.assert_allclose( + ICaCb_to_XYZ(ICaCb), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_ICaCb_to_XYZ(self): @@ -165,8 +169,10 @@ def test_domain_range_scale_ICaCb_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - ICaCb_to_XYZ(ICaCb * factor), XYZ * factor, decimal=7 + np.testing.assert_allclose( + ICaCb_to_XYZ(ICaCb * factor), + XYZ * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_igpgtg.py b/colour/models/tests/test_igpgtg.py index f0d68706f4..df131f10e6 100644 --- a/colour/models/tests/test_igpgtg.py +++ b/colour/models/tests/test_igpgtg.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.igpgtg` module.""" -import numpy as np import unittest from itertools import product -from colour.models import XYZ_to_IgPgTg, IgPgTg_to_XYZ +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import IgPgTg_to_XYZ, XYZ_to_IgPgTg from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -30,22 +32,22 @@ class TestXYZ_to_IgPgTg(unittest.TestCase): def test_XYZ_to_IgPgTg(self): """Test :func:`colour.models.igpgtg.XYZ_to_IgPgTg` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IgPgTg(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.42421258, 0.18632491, 0.10689223]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IgPgTg(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.50912820, -0.14804331, 0.11921472]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IgPgTg(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([0.29095152, -0.04057508, -0.18220795]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_IgPgTg(self): @@ -59,14 +61,14 @@ def test_n_dimensional_XYZ_to_IgPgTg(self): XYZ = np.tile(XYZ, (6, 1)) IgPgTg = np.tile(IgPgTg, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_IgPgTg(XYZ), IgPgTg, decimal=7 + np.testing.assert_allclose( + XYZ_to_IgPgTg(XYZ), IgPgTg, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) IgPgTg = np.reshape(IgPgTg, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_IgPgTg(XYZ), IgPgTg, decimal=7 + np.testing.assert_allclose( + XYZ_to_IgPgTg(XYZ), IgPgTg, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_IgPgTg(self): @@ -81,8 +83,10 @@ def test_domain_range_scale_XYZ_to_IgPgTg(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_IgPgTg(XYZ * factor), IgPgTg * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_IgPgTg(XYZ * factor), + IgPgTg * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -106,22 +110,22 @@ class TestIgPgTg_to_XYZ(unittest.TestCase): def test_IgPgTg_to_XYZ(self): """Test :func:`colour.models.igpgtg.IgPgTg_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IgPgTg_to_XYZ(np.array([0.42421258, 0.18632491, 0.10689223])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IgPgTg_to_XYZ(np.array([0.50912820, -0.14804331, 0.11921472])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IgPgTg_to_XYZ(np.array([0.29095152, -0.04057508, -0.18220795])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_IgPgTg_to_XYZ(self): @@ -135,14 +139,14 @@ def test_n_dimensional_IgPgTg_to_XYZ(self): IgPgTg = np.tile(IgPgTg, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - IgPgTg_to_XYZ(IgPgTg), XYZ, decimal=7 + np.testing.assert_allclose( + IgPgTg_to_XYZ(IgPgTg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) IgPgTg = np.reshape(IgPgTg, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - IgPgTg_to_XYZ(IgPgTg), XYZ, decimal=7 + np.testing.assert_allclose( + IgPgTg_to_XYZ(IgPgTg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_IgPgTg_to_XYZ(self): @@ -157,8 +161,10 @@ def test_domain_range_scale_IgPgTg_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - IgPgTg_to_XYZ(IgPgTg * factor), XYZ * factor, decimal=7 + np.testing.assert_allclose( + IgPgTg_to_XYZ(IgPgTg * factor), + XYZ * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_ipt.py b/colour/models/tests/test_ipt.py index db026a6aee..54efb6b252 100644 --- a/colour/models/tests/test_ipt.py +++ b/colour/models/tests/test_ipt.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.ipt` module.""" -import numpy as np import unittest from itertools import product -from colour.models import XYZ_to_IPT, IPT_to_XYZ, IPT_hue_angle +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import IPT_hue_angle, IPT_to_XYZ, XYZ_to_IPT from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -28,22 +30,22 @@ class TestXYZ_to_IPT(unittest.TestCase): def test_XYZ_to_IPT(self): """Test :func:`colour.models.ipt.XYZ_to_IPT` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IPT(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.38426191, 0.38487306, 0.18886838]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IPT(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.49437481, -0.19251742, 0.18080304]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IPT(np.array([0.07818780, 0.06157201, 0.28099326])), np.array([0.35167774, -0.07525627, -0.30921279]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_IPT(self): @@ -57,11 +59,15 @@ def test_n_dimensional_XYZ_to_IPT(self): XYZ = np.tile(XYZ, (6, 1)) IPT = np.tile(IPT, (6, 1)) - np.testing.assert_array_almost_equal(XYZ_to_IPT(XYZ), IPT, decimal=7) + np.testing.assert_allclose( + XYZ_to_IPT(XYZ), IPT, atol=TOLERANCE_ABSOLUTE_TESTS + ) XYZ = np.reshape(XYZ, (2, 3, 3)) IPT = np.reshape(IPT, (2, 3, 3)) - np.testing.assert_array_almost_equal(XYZ_to_IPT(XYZ), IPT, decimal=7) + np.testing.assert_allclose( + XYZ_to_IPT(XYZ), IPT, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_XYZ_to_IPT(self): """ @@ -75,8 +81,10 @@ def test_domain_range_scale_XYZ_to_IPT(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_IPT(XYZ * factor), IPT * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_IPT(XYZ * factor), + IPT * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -97,22 +105,22 @@ class TestIPT_to_XYZ(unittest.TestCase): def test_IPT_to_XYZ(self): """Test :func:`colour.models.ipt.IPT_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_to_XYZ(np.array([0.38426191, 0.38487306, 0.18886838])), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_to_XYZ(np.array([0.49437481, -0.19251742, 0.18080304])), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_to_XYZ(np.array([0.35167774, -0.07525627, -0.30921279])), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_IPT_to_XYZ(self): @@ -126,11 +134,15 @@ def test_n_dimensional_IPT_to_XYZ(self): IPT = np.tile(IPT, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal(IPT_to_XYZ(IPT), XYZ, decimal=7) + np.testing.assert_allclose( + IPT_to_XYZ(IPT), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) IPT = np.reshape(IPT, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal(IPT_to_XYZ(IPT), XYZ, decimal=7) + np.testing.assert_allclose( + IPT_to_XYZ(IPT), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_IPT_to_XYZ(self): """ @@ -144,8 +156,10 @@ def test_domain_range_scale_IPT_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - IPT_to_XYZ(IPT * factor), XYZ * factor, decimal=7 + np.testing.assert_allclose( + IPT_to_XYZ(IPT * factor), + XYZ * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -166,22 +180,22 @@ class TestIPTHueAngle(unittest.TestCase): def test_IPT_hue_angle(self): """Test :func:`colour.models.ipt.IPT_hue_angle` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_hue_angle(np.array([0.20654008, 0.12197225, 0.05136952])), 22.838754548625527, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_hue_angle(np.array([0.14222010, 0.23042768, 0.10495772])), 24.488834912466245, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_hue_angle(np.array([0.07818780, 0.06157201, 0.28099326])), 77.640533743711813, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_IPT_hue_angle(self): @@ -195,14 +209,14 @@ def test_n_dimensional_IPT_hue_angle(self): IPT = np.tile(IPT, (6, 1)) hue = np.tile(hue, 6) - np.testing.assert_array_almost_equal( - IPT_hue_angle(IPT), hue, decimal=7 + np.testing.assert_allclose( + IPT_hue_angle(IPT), hue, atol=TOLERANCE_ABSOLUTE_TESTS ) IPT = np.reshape(IPT, (2, 3, 3)) hue = np.reshape(hue, (2, 3)) - np.testing.assert_array_almost_equal( - IPT_hue_angle(IPT), hue, decimal=7 + np.testing.assert_allclose( + IPT_hue_angle(IPT), hue, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_IPT_hue_angle(self): @@ -217,8 +231,10 @@ def test_domain_range_scale_IPT_hue_angle(self): d_r = (("reference", 1, 1), ("1", 1, 1 / 360), ("100", 100, 1 / 3.6)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - IPT_hue_angle(IPT * factor_a), hue * factor_b, decimal=7 + np.testing.assert_allclose( + IPT_hue_angle(IPT * factor_a), + hue * factor_b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_jzazbz.py b/colour/models/tests/test_jzazbz.py index ee2c2a2dac..b67374c84b 100644 --- a/colour/models/tests/test_jzazbz.py +++ b/colour/models/tests/test_jzazbz.py @@ -1,15 +1,17 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.jzazbz` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - XYZ_to_Izazbz, Izazbz_to_XYZ, - XYZ_to_Jzazbz, Jzazbz_to_XYZ, + XYZ_to_Izazbz, + XYZ_to_Jzazbz, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,31 +39,31 @@ class TestXYZ_to_Izazbz(unittest.TestCase): def test_XYZ_to_Izazbz(self): """Test :func:`colour.models.jzazbz.XYZ_to_Izazbz` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Izazbz(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.01207793, 0.00924302, 0.00526007]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Izazbz(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.01397346, -0.00608426, 0.00534077]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Izazbz(np.array([0.96907232, 1.00000000, 1.12179215])), np.array([0.03927203, 0.00064174, -0.00052906]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Izazbz( np.array([0.20654008, 0.12197225, 0.05136952]), method="Safdar 2021", ), np.array([0.01049146, 0.00924302, 0.00526007]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_array_equal( @@ -85,14 +87,14 @@ def test_n_dimensional_XYZ_to_Izazbz(self): XYZ = np.tile(XYZ, (6, 1)) Izazbz = np.tile(Izazbz, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Izazbz(XYZ), Izazbz, decimal=7 + np.testing.assert_allclose( + XYZ_to_Izazbz(XYZ), Izazbz, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) Izazbz = np.reshape(Izazbz, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_Izazbz(XYZ), Izazbz, decimal=7 + np.testing.assert_allclose( + XYZ_to_Izazbz(XYZ), Izazbz, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_Izazbz(self): @@ -107,8 +109,10 @@ def test_domain_range_scale_XYZ_to_Izazbz(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_Izazbz(XYZ * factor), Izazbz * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_Izazbz(XYZ * factor), + Izazbz * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -135,38 +139,34 @@ def test_Izazbz_to_XYZ(self): np.testing.assert_allclose( Izazbz_to_XYZ(np.array([0.01207793, 0.00924302, 0.00526007])), np.array([0.20654008, 0.12197225, 0.05136952]), - rtol=0.000001, - atol=0.000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( Izazbz_to_XYZ(np.array([0.01397346, -0.00608426, 0.00534077])), np.array([0.14222010, 0.23042768, 0.10495772]), - rtol=0.000001, - atol=0.000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( Izazbz_to_XYZ(np.array([0.03927203, 0.00064174, -0.00052906])), np.array([0.96907232, 1.00000000, 1.12179215]), - rtol=0.000001, - atol=0.000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( Izazbz_to_XYZ(np.array([0.03927203, 0.00064174, -0.00052906])), np.array([0.96907232, 1.00000000, 1.12179215]), - rtol=0.000001, - atol=0.000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( Izazbz_to_XYZ( np.array([0.01049146, 0.00924302, 0.00526007]), method="Safdar 2021", ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_array_equal( @@ -191,13 +191,13 @@ def test_n_dimensional_Izazbz_to_XYZ(self): Izazbz = np.tile(Izazbz, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) np.testing.assert_allclose( - Izazbz_to_XYZ(Izazbz), XYZ, rtol=0.000001, atol=0.000001 + Izazbz_to_XYZ(Izazbz), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Izazbz = np.reshape(Izazbz, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) np.testing.assert_allclose( - Izazbz_to_XYZ(Izazbz), XYZ, rtol=0.000001, atol=0.000001 + Izazbz_to_XYZ(Izazbz), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Izazbz_to_XYZ(self): @@ -215,8 +215,7 @@ def test_domain_range_scale_Izazbz_to_XYZ(self): np.testing.assert_allclose( Izazbz_to_XYZ(Izazbz * factor), XYZ * factor, - rtol=0.000001, - atol=0.000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -240,22 +239,22 @@ class TestXYZ_to_Jzazbz(unittest.TestCase): def test_XYZ_to_Jzazbz(self): """Test :func:`colour.models.jzazbz.XYZ_to_Jzazbz` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Jzazbz(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.00535048, 0.00924302, 0.00526007]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Jzazbz(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.00619681, -0.00608426, 0.00534077]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Jzazbz(np.array([0.96907232, 1.00000000, 1.12179215])), np.array([0.01766826, 0.00064174, -0.00052906]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Jzazbz(self): @@ -269,14 +268,14 @@ def test_n_dimensional_XYZ_to_Jzazbz(self): XYZ = np.tile(XYZ, (6, 1)) Jzazbz = np.tile(Jzazbz, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Jzazbz(XYZ), Jzazbz, decimal=7 + np.testing.assert_allclose( + XYZ_to_Jzazbz(XYZ), Jzazbz, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) Jzazbz = np.reshape(Jzazbz, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_Jzazbz(XYZ), Jzazbz, decimal=7 + np.testing.assert_allclose( + XYZ_to_Jzazbz(XYZ), Jzazbz, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_Jzazbz(self): @@ -291,8 +290,8 @@ def test_domain_range_scale_XYZ_to_Jzazbz(self): d_r = (("reference", 1), ("1", 1), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_Jzazbz(XYZ * factor), Jzazbz * factor, decimal=7 + np.testing.assert_array_equal( + XYZ_to_Jzazbz(XYZ * factor), Jzazbz * factor ) @ignore_numpy_errors @@ -319,22 +318,19 @@ def test_Jzazbz_to_XYZ(self): np.testing.assert_allclose( Jzazbz_to_XYZ(np.array([0.00535048, 0.00924302, 0.00526007])), np.array([0.20654008, 0.12197225, 0.05136952]), - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) np.testing.assert_allclose( Jzazbz_to_XYZ(np.array([0.00619681, -0.00608426, 0.00534077])), np.array([0.14222010, 0.23042768, 0.10495772]), - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) np.testing.assert_allclose( Jzazbz_to_XYZ(np.array([0.01766826, 0.00064174, -0.00052906])), np.array([0.96907232, 1.00000000, 1.12179215]), - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) def test_n_dimensional_Jzazbz_to_XYZ(self): @@ -349,13 +345,13 @@ def test_n_dimensional_Jzazbz_to_XYZ(self): Jzazbz = np.tile(Jzazbz, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) np.testing.assert_allclose( - Jzazbz_to_XYZ(Jzazbz), XYZ, rtol=0.000001, atol=0.000001 + Jzazbz_to_XYZ(Jzazbz), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Jzazbz = np.reshape(Jzazbz, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) np.testing.assert_allclose( - Jzazbz_to_XYZ(Jzazbz), XYZ, rtol=0.000001, atol=0.000001 + Jzazbz_to_XYZ(Jzazbz), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Jzazbz_to_XYZ(self): @@ -373,8 +369,7 @@ def test_domain_range_scale_Jzazbz_to_XYZ(self): np.testing.assert_allclose( Jzazbz_to_XYZ(Jzazbz * factor), XYZ * factor, - rtol=0.000001, - atol=0.000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_oklab.py b/colour/models/tests/test_oklab.py index f04dc89df2..eef65a7d2e 100644 --- a/colour/models/tests/test_oklab.py +++ b/colour/models/tests/test_oklab.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.oklab` module.""" -import numpy as np import unittest from itertools import product -from colour.models import XYZ_to_Oklab, Oklab_to_XYZ +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import Oklab_to_XYZ, XYZ_to_Oklab from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -30,22 +32,22 @@ class TestXYZ_to_Oklab(unittest.TestCase): def test_XYZ_to_Oklab(self): """Test :func:`colour.models.oklab.XYZ_to_Oklab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Oklab(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.51634019, 0.15469500, 0.06289579]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Oklab(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.59910746, -0.11139207, 0.07508465]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Oklab(np.array([0.96907232, 1.00000000, 1.12179215])), np.array([1.00121561, 0.00899591, -0.00535107]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Oklab(self): @@ -59,14 +61,14 @@ def test_n_dimensional_XYZ_to_Oklab(self): XYZ = np.tile(XYZ, (6, 1)) Oklab = np.tile(Oklab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_Oklab(XYZ), Oklab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Oklab(XYZ), Oklab, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) Oklab = np.reshape(Oklab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_Oklab(XYZ), Oklab, decimal=7 + np.testing.assert_allclose( + XYZ_to_Oklab(XYZ), Oklab, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_Oklab(self): @@ -81,8 +83,10 @@ def test_domain_range_scale_XYZ_to_Oklab(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_Oklab(XYZ * factor), Oklab * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_Oklab(XYZ * factor), + Oklab * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -109,22 +113,19 @@ def test_Oklab_to_XYZ(self): np.testing.assert_allclose( Oklab_to_XYZ(np.array([0.51634019, 0.15469500, 0.06289579])), np.array([0.20654008, 0.12197225, 0.05136952]), - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) np.testing.assert_allclose( Oklab_to_XYZ(np.array([0.59910746, -0.11139207, 0.07508465])), np.array([0.14222010, 0.23042768, 0.10495772]), - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) np.testing.assert_allclose( Oklab_to_XYZ(np.array([1.00121561, 0.00899591, -0.00535107])), np.array([0.96907232, 1.00000000, 1.12179215]), - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) def test_n_dimensional_Oklab_to_XYZ(self): @@ -139,13 +140,13 @@ def test_n_dimensional_Oklab_to_XYZ(self): Oklab = np.tile(Oklab, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) np.testing.assert_allclose( - Oklab_to_XYZ(Oklab), XYZ, rtol=0.000001, atol=0.000001 + Oklab_to_XYZ(Oklab), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Oklab = np.reshape(Oklab, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) np.testing.assert_allclose( - Oklab_to_XYZ(Oklab), XYZ, rtol=0.000001, atol=0.000001 + Oklab_to_XYZ(Oklab), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Oklab_to_XYZ(self): @@ -160,11 +161,9 @@ def test_domain_range_scale_Oklab_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_allclose( + np.testing.assert_array_equal( Oklab_to_XYZ(Oklab * factor), XYZ * factor, - rtol=0.000001, - atol=0.000001, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_osa_ucs.py b/colour/models/tests/test_osa_ucs.py index 079331d796..2b58d40391 100644 --- a/colour/models/tests/test_osa_ucs.py +++ b/colour/models/tests/test_osa_ucs.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.osa_ucs` module.""" -import numpy as np import unittest from itertools import product -from colour.models import XYZ_to_OSA_UCS, OSA_UCS_to_XYZ +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import OSA_UCS_to_XYZ, XYZ_to_OSA_UCS from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -30,28 +32,28 @@ class TestXYZ_to_OSA_UCS(unittest.TestCase): def test_XYZ_to_OSA_UCS(self): """Test :func:`colour.models.osa_ucs.XYZ_to_OSA_UCS` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_OSA_UCS( np.array([0.20654008, 0.12197225, 0.05136952]) * 100 ), np.array([-3.00499790, 2.99713697, -9.66784231]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_OSA_UCS( np.array([0.14222010, 0.23042768, 0.10495772]) * 100 ), np.array([-1.64657491, 4.59201565, 5.31738757]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_OSA_UCS( np.array([0.07818780, 0.06157201, 0.28099326]) * 100 ), np.array([-5.08589672, -7.91062749, 0.98107575]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_OSA_UCS(self): @@ -65,14 +67,14 @@ def test_n_dimensional_XYZ_to_OSA_UCS(self): XYZ = np.tile(XYZ, (6, 1)) Ljg = np.tile(Ljg, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_OSA_UCS(XYZ), Ljg, decimal=7 + np.testing.assert_allclose( + XYZ_to_OSA_UCS(XYZ), Ljg, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) Ljg = np.reshape(Ljg, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_OSA_UCS(XYZ), Ljg, decimal=7 + np.testing.assert_allclose( + XYZ_to_OSA_UCS(XYZ), Ljg, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_OSA_UCS(self): @@ -87,8 +89,10 @@ def test_domain_range_scale_XYZ_to_OSA_UCS(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_OSA_UCS(XYZ * factor), Ljg * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_OSA_UCS(XYZ * factor), + Ljg * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -118,8 +122,7 @@ def test_OSA_UCS_to_XYZ(self): {"disp": False}, ), np.array([0.20654008, 0.12197225, 0.05136952]) * 100, - rtol=0.00001, - atol=0.00001, + atol=5e-5, ) np.testing.assert_allclose( @@ -128,8 +131,7 @@ def test_OSA_UCS_to_XYZ(self): {"disp": False}, ), np.array([0.14222010, 0.23042768, 0.10495772]) * 100, - rtol=0.00001, - atol=0.00001, + atol=5e-5, ) np.testing.assert_allclose( @@ -138,8 +140,7 @@ def test_OSA_UCS_to_XYZ(self): {"disp": False}, ), np.array([0.07818780, 0.06157201, 0.28099326]) * 100, - rtol=0.00001, - atol=0.00001, + atol=5e-5, ) def test_n_dimensional_OSA_UCS_to_XYZ(self): @@ -154,13 +155,13 @@ def test_n_dimensional_OSA_UCS_to_XYZ(self): Ljg = np.tile(Ljg, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) np.testing.assert_allclose( - OSA_UCS_to_XYZ(Ljg), XYZ, rtol=0.00001, atol=0.00001 + OSA_UCS_to_XYZ(Ljg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Ljg = np.reshape(Ljg, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) np.testing.assert_allclose( - OSA_UCS_to_XYZ(Ljg), XYZ, rtol=0.00001, atol=0.00001 + OSA_UCS_to_XYZ(Ljg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_OSA_UCS_to_XYZ(self): @@ -175,8 +176,8 @@ def test_domain_range_scale_OSA_UCS_to_XYZ(self): d_r = (("reference", 1), ("1", 0.01), ("100", 1)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - OSA_UCS_to_XYZ(Ljg * factor), XYZ * factor, decimal=7 + np.testing.assert_array_equal( + OSA_UCS_to_XYZ(Ljg * factor), XYZ * factor ) @ignore_numpy_errors diff --git a/colour/models/tests/test_prolab.py b/colour/models/tests/test_prolab.py index 05839b2fae..fc39c93435 100644 --- a/colour/models/tests/test_prolab.py +++ b/colour/models/tests/test_prolab.py @@ -1,12 +1,14 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.prolab` module.""" -import numpy as np import unittest from itertools import product -from colour.models import XYZ_to_ProLab, ProLab_to_XYZ -from colour.utilities import ignore_numpy_errors, domain_range_scale +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import ProLab_to_XYZ, XYZ_to_ProLab +from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -30,22 +32,22 @@ class TestXYZ_to_ProLab(unittest.TestCase): def test_XYZ_to_ProLab(self): """Test :func:`colour.models.ProLab.XYZ_to_ProLab` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ProLab(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([48.7948929, 35.31503175, 13.30044932]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ProLab(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([64.45929636, -21.67007419, 13.25749056]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_ProLab(np.array([0.96907232, 1.00000000, 0.12179215])), np.array([100.0, 5.47367608, 37.26313098]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_ProLab(self): @@ -59,14 +61,14 @@ def test_n_dimensional_XYZ_to_ProLab(self): XYZ = np.tile(XYZ, (6, 1)) ProLab = np.tile(ProLab, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_ProLab(XYZ), ProLab, decimal=7 + np.testing.assert_allclose( + XYZ_to_ProLab(XYZ), ProLab, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) ProLab = np.reshape(ProLab, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_ProLab(XYZ), ProLab, decimal=7 + np.testing.assert_allclose( + XYZ_to_ProLab(XYZ), ProLab, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_ProLab(self): @@ -81,8 +83,10 @@ def test_domain_range_scale_XYZ_to_ProLab(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_ProLab(XYZ * factor), ProLab * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_ProLab(XYZ * factor), + ProLab * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -106,19 +110,22 @@ class TestProLab_to_XYZ(unittest.TestCase): def test_ProLab_to_XYZ(self): """Test :func:`colour.models.ProLab.ProLab_to_XYZ` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ProLab_to_XYZ(np.array([48.7948929, 35.31503175, 13.30044932])), np.array([0.20654008, 0.12197225, 0.05136952]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ProLab_to_XYZ(np.array([64.45929636, -21.67007419, 13.25749056])), np.array([0.14222010, 0.23042768, 0.10495772]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( ProLab_to_XYZ(np.array([100.0, 5.47367608, 37.26313098])), np.array([0.96907232, 1.00000000, 0.12179215]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_ProLab(self): @@ -132,14 +139,14 @@ def test_n_dimensional_XYZ_to_ProLab(self): ProLab = np.tile(ProLab, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - ProLab_to_XYZ(ProLab), XYZ, decimal=7 + np.testing.assert_allclose( + ProLab_to_XYZ(ProLab), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) ProLab = np.reshape(ProLab, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - ProLab_to_XYZ(ProLab), XYZ, decimal=7 + np.testing.assert_allclose( + ProLab_to_XYZ(ProLab), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_ProLab(self): @@ -154,8 +161,10 @@ def test_domain_range_scale_XYZ_to_ProLab(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_ProLab(ProLab * factor), XYZ * factor, decimal=7 + np.testing.assert_allclose( + XYZ_to_ProLab(ProLab * factor), + XYZ * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_ragoo2021.py b/colour/models/tests/test_ragoo2021.py index c5d8aee7f9..e4bfb3be8c 100644 --- a/colour/models/tests/test_ragoo2021.py +++ b/colour/models/tests/test_ragoo2021.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.ragoo2021` module.""" -import numpy as np import unittest from itertools import product -from colour.models import XYZ_to_IPT_Ragoo2021, IPT_Ragoo2021_to_XYZ +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.models import IPT_Ragoo2021_to_XYZ, XYZ_to_IPT_Ragoo2021 from colour.utilities import domain_range_scale, ignore_numpy_errors __author__ = "Colour Developers" @@ -32,28 +34,28 @@ def test_XYZ_to_IPT_Ragoo2021(self): Test :func:`colour.models.ragoo2021.XYZ_to_IPT_Ragoo2021` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IPT_Ragoo2021( np.array([0.20654008, 0.12197225, 0.05136952]) ), np.array([0.42248243, 0.29105140, 0.20410663]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IPT_Ragoo2021( np.array([0.14222010, 0.23042768, 0.10495772]) ), np.array([0.54745257, -0.22795249, 0.10109646]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IPT_Ragoo2021( np.array([0.07818780, 0.06157201, 0.28099326]) ), np.array([0.32151337, 0.06071424, -0.27388774]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_IPT_Ragoo2021(self): @@ -67,14 +69,14 @@ def test_n_dimensional_XYZ_to_IPT_Ragoo2021(self): XYZ = np.tile(XYZ, (6, 1)) IPT = np.tile(IPT, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_IPT_Ragoo2021(XYZ), IPT, decimal=7 + np.testing.assert_allclose( + XYZ_to_IPT_Ragoo2021(XYZ), IPT, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) IPT = np.reshape(IPT, (2, 3, 3)) - np.testing.assert_array_almost_equal( - XYZ_to_IPT_Ragoo2021(XYZ), IPT, decimal=7 + np.testing.assert_allclose( + XYZ_to_IPT_Ragoo2021(XYZ), IPT, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_XYZ_to_IPT_Ragoo2021(self): @@ -89,10 +91,10 @@ def test_domain_range_scale_XYZ_to_IPT_Ragoo2021(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_IPT_Ragoo2021(XYZ * factor), IPT * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -118,28 +120,28 @@ def test_IPT_Ragoo2021_to_XYZ(self): Test :func:`colour.models.ragoo2021.IPT_Ragoo2021_to_XYZ` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_Ragoo2021_to_XYZ( np.array([0.42248243, 0.29105140, 0.20410663]) ), np.array([0.20654008, 0.12197225, 0.05136952]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_Ragoo2021_to_XYZ( np.array([0.54745257, -0.22795249, 0.10109646]) ), np.array([0.14222010, 0.23042768, 0.10495772]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_Ragoo2021_to_XYZ( np.array([0.32151337, 0.06071424, -0.27388774]) ), np.array([0.07818780, 0.06157201, 0.28099326]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_IPT_Ragoo2021_to_XYZ(self): @@ -153,14 +155,14 @@ def test_n_dimensional_IPT_Ragoo2021_to_XYZ(self): IPT = np.tile(IPT, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - IPT_Ragoo2021_to_XYZ(IPT), XYZ, decimal=7 + np.testing.assert_allclose( + IPT_Ragoo2021_to_XYZ(IPT), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) IPT = np.reshape(IPT, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - IPT_Ragoo2021_to_XYZ(IPT), XYZ, decimal=7 + np.testing.assert_allclose( + IPT_Ragoo2021_to_XYZ(IPT), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_IPT_Ragoo2021_to_XYZ(self): @@ -175,10 +177,10 @@ def test_domain_range_scale_IPT_Ragoo2021_to_XYZ(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( IPT_Ragoo2021_to_XYZ(IPT * factor), XYZ * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/models/tests/test_yrg.py b/colour/models/tests/test_yrg.py index eafbe019e2..9666fc80cd 100644 --- a/colour/models/tests/test_yrg.py +++ b/colour/models/tests/test_yrg.py @@ -1,15 +1,17 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.models.yrg` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( - XYZ_to_Yrg, - Yrg_to_XYZ, LMS_to_Yrg, + XYZ_to_Yrg, Yrg_to_LMS, + Yrg_to_XYZ, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -37,22 +39,22 @@ class TestLMS_to_Yrg(unittest.TestCase): def test_LMS_to_Yrg(self): """Test :func:`colour.models.yrg.LMS_to_Yrg` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LMS_to_Yrg(np.array([0.15639195, 0.06741689, 0.03281398])), np.array([0.13137801, 0.49037644, 0.37777391]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LMS_to_Yrg(np.array([0.23145723, 0.22601133, 0.05033211])), np.array([0.23840767, 0.20110504, 0.69668437]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LMS_to_Yrg(np.array([1.07423297, 0.91295620, 0.61375713])), np.array([1.05911888, 0.22010094, 0.53660290]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_LMS_to_Yrg(self): @@ -66,11 +68,15 @@ def test_n_dimensional_LMS_to_Yrg(self): LMS = np.tile(LMS, (6, 1)) Yrg = np.tile(Yrg, (6, 1)) - np.testing.assert_array_almost_equal(LMS_to_Yrg(LMS), Yrg, decimal=7) + np.testing.assert_allclose( + LMS_to_Yrg(LMS), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS + ) LMS = np.reshape(LMS, (2, 3, 3)) Yrg = np.reshape(Yrg, (2, 3, 3)) - np.testing.assert_array_almost_equal(LMS_to_Yrg(LMS), Yrg, decimal=7) + np.testing.assert_allclose( + LMS_to_Yrg(LMS), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_LMS_to_Yrg(self): """ @@ -84,8 +90,10 @@ def test_domain_range_scale_LMS_to_Yrg(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - LMS_to_Yrg(LMS * factor), Yrg * factor, decimal=7 + np.testing.assert_allclose( + LMS_to_Yrg(LMS * factor), + Yrg * factor, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -108,22 +116,19 @@ def test_Yrg_to_LMS(self): np.testing.assert_allclose( Yrg_to_LMS(np.array([0.13137801, 0.49037644, 0.37777391])), np.array([0.15639195, 0.06741689, 0.03281398]), - rtol=0.0001, - atol=0.0001, + atol=1e-4, ) np.testing.assert_allclose( Yrg_to_LMS(np.array([0.23840767, 0.20110504, 0.69668437])), np.array([0.23145723, 0.22601133, 0.05033211]), - rtol=0.0001, - atol=0.0001, + atol=1e-4, ) np.testing.assert_allclose( Yrg_to_LMS(np.array([1.05911888, 0.22010094, 0.53660290])), np.array([1.07423297, 0.91295620, 0.61375713]), - rtol=0.0001, - atol=0.0001, + atol=1e-4, ) def test_n_dimensional_Yrg_to_LMS(self): @@ -138,13 +143,13 @@ def test_n_dimensional_Yrg_to_LMS(self): Yrg = np.tile(Yrg, (6, 1)) LMS = np.tile(LMS, (6, 1)) np.testing.assert_allclose( - Yrg_to_LMS(Yrg), LMS, rtol=0.0001, atol=0.0001 + Yrg_to_LMS(Yrg), LMS, atol=TOLERANCE_ABSOLUTE_TESTS ) Yrg = np.reshape(Yrg, (2, 3, 3)) LMS = np.reshape(LMS, (2, 3, 3)) np.testing.assert_allclose( - Yrg_to_LMS(Yrg), LMS, rtol=0.0001, atol=0.0001 + Yrg_to_LMS(Yrg), LMS, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Yrg_to_LMS(self): @@ -162,8 +167,7 @@ def test_domain_range_scale_Yrg_to_LMS(self): np.testing.assert_allclose( Yrg_to_LMS(Yrg * factor), LMS * factor, - rtol=0.0001, - atol=0.0001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -184,22 +188,22 @@ class TestXYZ_to_Yrg(unittest.TestCase): def test_XYZ_to_Yrg(self): """Test :func:`colour.models.yrg.XYZ_to_Yrg` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Yrg(np.array([0.20654008, 0.12197225, 0.05136952])), np.array([0.13137801, 0.49037645, 0.37777388]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Yrg(np.array([0.14222010, 0.23042768, 0.10495772])), np.array([0.23840767, 0.20110503, 0.69668437]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_Yrg(np.array([0.96907232, 1.00000000, 1.12179215])), np.array([1.05911888, 0.22010094, 0.53660290]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_Yrg(self): @@ -213,11 +217,15 @@ def test_n_dimensional_XYZ_to_Yrg(self): XYZ = np.tile(XYZ, (6, 1)) Yrg = np.tile(Yrg, (6, 1)) - np.testing.assert_array_almost_equal(XYZ_to_Yrg(XYZ), Yrg, decimal=7) + np.testing.assert_allclose( + XYZ_to_Yrg(XYZ), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS + ) XYZ = np.reshape(XYZ, (2, 3, 3)) Yrg = np.reshape(Yrg, (2, 3, 3)) - np.testing.assert_array_almost_equal(XYZ_to_Yrg(XYZ), Yrg, decimal=7) + np.testing.assert_allclose( + XYZ_to_Yrg(XYZ), Yrg, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_XYZ_to_Yrg(self): """ @@ -231,8 +239,8 @@ def test_domain_range_scale_XYZ_to_Yrg(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - XYZ_to_Yrg(XYZ * factor), Yrg * factor, decimal=7 + np.testing.assert_array_equal( + XYZ_to_Yrg(XYZ * factor), Yrg * factor ) @ignore_numpy_errors @@ -255,22 +263,19 @@ def test_Yrg_to_XYZ(self): np.testing.assert_allclose( Yrg_to_XYZ(np.array([0.13137801, 0.49037645, 0.37777388])), np.array([0.20654008, 0.12197225, 0.05136952]), - rtol=0.0001, - atol=0.0001, + atol=1e-4, ) np.testing.assert_allclose( Yrg_to_XYZ(np.array([0.23840767, 0.20110503, 0.69668437])), np.array([0.14222010, 0.23042768, 0.10495772]), - rtol=0.0001, - atol=0.0001, + atol=2e-4, ) np.testing.assert_allclose( Yrg_to_XYZ(np.array([1.05911888, 0.22010094, 0.53660290])), np.array([0.96907232, 1.00000000, 1.12179215]), - rtol=0.0001, - atol=0.0001, + atol=2e-4, ) def test_n_dimensional_Yrg_to_XYZ(self): @@ -285,13 +290,13 @@ def test_n_dimensional_Yrg_to_XYZ(self): Yrg = np.tile(Yrg, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) np.testing.assert_allclose( - Yrg_to_XYZ(Yrg), XYZ, rtol=0.0001, atol=0.0001 + Yrg_to_XYZ(Yrg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) Yrg = np.reshape(Yrg, (2, 3, 3)) XYZ = np.reshape(XYZ, (2, 3, 3)) np.testing.assert_allclose( - Yrg_to_XYZ(Yrg), XYZ, rtol=0.0001, atol=0.0001 + Yrg_to_XYZ(Yrg), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_Yrg_to_XYZ(self): @@ -309,8 +314,7 @@ def test_domain_range_scale_Yrg_to_XYZ(self): np.testing.assert_allclose( Yrg_to_XYZ(Yrg * factor), XYZ * factor, - rtol=0.0001, - atol=0.0001, + atol=1e-4, ) @ignore_numpy_errors diff --git a/colour/notation/munsell.py b/colour/notation/munsell.py index b2bad31997..292172ba02 100644 --- a/colour/notation/munsell.py +++ b/colour/notation/munsell.py @@ -114,9 +114,10 @@ from __future__ import annotations -import numpy as np import re +import numpy as np + from colour.algebra import ( Extrapolator, LinearInterpolator, @@ -129,8 +130,10 @@ ) from colour.colorimetry import CCS_ILLUMINANTS, luminance_ASTMD1535 from colour.constants import ( - INTEGER_THRESHOLD, FLOATING_POINT_NUMBER_PATTERN, + INTEGER_THRESHOLD, + TOLERANCE_ABSOLUTE_DEFAULT, + TOLERANCE_RELATIVE_DEFAULT, ) from colour.hints import ( ArrayLike, @@ -142,7 +145,6 @@ cast, ) from colour.models import Lab_to_LCHab, XYZ_to_Lab, XYZ_to_xy, xyY_to_XYZ -from colour.volume import is_within_macadam_limits from colour.notation import MUNSELL_COLOURS_ALL from colour.utilities import ( CACHE_REGISTRY, @@ -157,16 +159,18 @@ from_range_1, from_range_10, get_domain_range_scale, + is_caching_enabled, + is_integer, + is_numeric, to_domain_1, to_domain_10, to_domain_100, - is_integer, - is_numeric, tsplit, tstack, usage_warning, validate_method, ) +from colour.volume import is_within_macadam_limits __author__ = "Colour Developers, Paul Centore" __copyright__ = "Copyright 2013 Colour Developers" @@ -298,7 +302,7 @@ def _munsell_specifications() -> NDArrayFloat: global _CACHE_MUNSELL_SPECIFICATIONS # noqa: PLW0602 - if "All" in _CACHE_MUNSELL_SPECIFICATIONS: + if is_caching_enabled() and "All" in _CACHE_MUNSELL_SPECIFICATIONS: return _CACHE_MUNSELL_SPECIFICATIONS["All"] munsell_specifications = np.array( @@ -1722,7 +1726,11 @@ def munsell_specification_to_munsell_colour( ) -def xyY_from_renotation(specification: ArrayLike) -> NDArrayFloat: +def xyY_from_renotation( + specification: ArrayLike, + absolute_tolerance: float = TOLERANCE_ABSOLUTE_DEFAULT, + relative_tolerance: float = TOLERANCE_RELATIVE_DEFAULT, +) -> NDArrayFloat: """ Return given existing *Munsell* *Colorlab* specification *CIE xyY* colourspace vector from *Munsell Renotation System* data. @@ -1731,6 +1739,12 @@ def xyY_from_renotation(specification: ArrayLike) -> NDArrayFloat: ---------- specification *Munsell* *Colorlab* specification. + absolute_tolerance + Absolute tolerance to find the existing *Munsell Renotation System* + data. + relative_tolerance + Relative tolerance to find the existing *Munsell Renotation System* + data. Returns ------- @@ -1752,8 +1766,16 @@ def xyY_from_renotation(specification: ArrayLike) -> NDArrayFloat: specification = normalise_munsell_specification(specification) try: - index = np.where( - (_munsell_specifications() == specification).all(axis=-1) + index = np.argwhere( + np.all( + np.isclose( + specification, + _munsell_specifications(), + atol=absolute_tolerance, + rtol=relative_tolerance, + ), + axis=-1, + ) ) return MUNSELL_COLOURS_ALL[as_int_scalar(index[0])][1] diff --git a/colour/notation/tests/test_css_color_3.py b/colour/notation/tests/test_css_color_3.py index 0ae53b7d80..f67e6cd43e 100644 --- a/colour/notation/tests/test_css_color_3.py +++ b/colour/notation/tests/test_css_color_3.py @@ -3,9 +3,11 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.notation import keyword_to_RGB_CSSColor3 __author__ = "Colour Developers" @@ -40,9 +42,10 @@ def test_keyword_to_RGB_CSSColor3(self): keyword_to_RGB_CSSColor3("white"), np.array([1, 1, 1]) ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( keyword_to_RGB_CSSColor3("aliceblue"), np.array([0.94117647, 0.97254902, 1.00000000]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/notation/tests/test_hexadecimal.py b/colour/notation/tests/test_hexadecimal.py index 39df7c2e14..7a1259a657 100644 --- a/colour/notation/tests/test_hexadecimal.py +++ b/colour/notation/tests/test_hexadecimal.py @@ -1,13 +1,15 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.notation.hexadecimal` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.notation.hexadecimal import ( - RGB_to_HEX, HEX_to_RGB, + RGB_to_HEX, ) from colour.utilities import domain_range_scale, ignore_numpy_errors @@ -113,22 +115,22 @@ class TestHEX_to_RGB(unittest.TestCase): def test_HEX_to_RGB(self): """Test :func:`colour.notation.hexadecimal.HEX_to_RGB` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HEX_to_RGB("#74070a"), np.array([0.45620519, 0.03081071, 0.04091952]), - decimal=2, + atol=1e-1, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HEX_to_RGB("#000000"), np.array([0.00000000, 0.00000000, 0.00000000]), - decimal=2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( HEX_to_RGB("#ffffff"), np.array([1.00000000, 1.00000000, 1.00000000]), - decimal=2, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_HEX_to_RGB(self): @@ -142,11 +144,15 @@ def test_n_dimensional_HEX_to_RGB(self): HEX = np.tile(HEX, 6) RGB = np.tile(RGB, (6, 1)) - np.testing.assert_array_almost_equal(HEX_to_RGB(HEX), RGB, decimal=2) + np.testing.assert_allclose( + HEX_to_RGB(HEX), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) HEX = np.reshape(HEX, (2, 3)) RGB = np.reshape(RGB, (2, 3, 3)) - np.testing.assert_array_almost_equal(HEX_to_RGB(HEX), RGB, decimal=2) + np.testing.assert_allclose( + HEX_to_RGB(HEX), RGB, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_domain_range_scale_HEX_to_RGB(self): """ @@ -160,9 +166,7 @@ def test_domain_range_scale_HEX_to_RGB(self): d_r = (("reference", 1), ("1", 1), ("100", 100)) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( - HEX_to_RGB(HEX), RGB * factor, decimal=2 - ) + np.testing.assert_array_equal(HEX_to_RGB(HEX), RGB * factor) if __name__ == "__main__": diff --git a/colour/notation/tests/test_munsell.py b/colour/notation/tests/test_munsell.py index b8c4b52256..827be3aa19 100644 --- a/colour/notation/tests/test_munsell.py +++ b/colour/notation/tests/test_munsell.py @@ -4,54 +4,45 @@ from __future__ import annotations import contextlib -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import NDArrayFloat -from colour.notation.munsell import ( - CCS_ILLUMINANT_MUNSELL, +from colour.notation import ( + munsell_value_ASTMD1535, + munsell_value_Ladd1955, + munsell_value_McCamy1987, + munsell_value_Moon1943, + munsell_value_Munsell1933, + munsell_value_Priest1920, + munsell_value_Saunderson1944, ) from colour.notation.munsell import ( - parse_munsell_colour, + CCS_ILLUMINANT_MUNSELL, + LCHab_to_munsell_specification, + bounding_hues_from_renotation, + hue_angle_to_hue, + hue_to_ASTM_hue, + hue_to_hue_angle, + interpolation_method_from_renotation_ovoid, is_grey_munsell_colour, - normalise_munsell_specification, -) -from colour.notation.munsell import ( + is_specification_in_renotation, + maximum_chroma_from_renotation, munsell_colour_to_munsell_specification, + munsell_colour_to_xyY, munsell_specification_to_munsell_colour, -) -from colour.notation.munsell import ( - xyY_from_renotation, - is_specification_in_renotation, -) -from colour.notation.munsell import bounding_hues_from_renotation -from colour.notation.munsell import hue_to_hue_angle, hue_angle_to_hue -from colour.notation.munsell import hue_to_ASTM_hue -from colour.notation.munsell import ( - interpolation_method_from_renotation_ovoid, + munsell_specification_to_xy, + munsell_specification_to_xyY, + normalise_munsell_specification, + parse_munsell_colour, xy_from_renotation_ovoid, -) -from colour.notation.munsell import LCHab_to_munsell_specification -from colour.notation.munsell import maximum_chroma_from_renotation -from colour.notation.munsell import munsell_specification_to_xy -from colour.notation.munsell import ( - munsell_colour_to_xyY, + xyY_from_renotation, xyY_to_munsell_colour, -) -from colour.notation.munsell import ( - munsell_specification_to_xyY, xyY_to_munsell_specification, ) -from colour.notation import ( - munsell_value_Priest1920, - munsell_value_Munsell1933, - munsell_value_Moon1943, - munsell_value_Saunderson1944, - munsell_value_Ladd1955, - munsell_value_McCamy1987, - munsell_value_ASTMD1535, -) from colour.utilities import ( as_array, as_float_array, @@ -1124,16 +1115,22 @@ def test_munsell_value_Priest1920(self): definition. """ - self.assertAlmostEqual( - munsell_value_Priest1920(12.23634268), 3.498048410185314, places=7 + np.testing.assert_allclose( + munsell_value_Priest1920(12.23634268), + 3.498048410185314, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_Priest1920(22.89399987), 4.7847674833788947, places=7 + np.testing.assert_allclose( + munsell_value_Priest1920(22.89399987), + 4.7847674833788947, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_Priest1920(6.29022535), 2.5080321668591092, places=7 + np.testing.assert_allclose( + munsell_value_Priest1920(6.29022535), + 2.5080321668591092, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_value_Priest1920(self): @@ -1147,20 +1144,20 @@ def test_n_dimensional_munsell_value_Priest1920(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - munsell_value_Priest1920(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Priest1920(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - munsell_value_Priest1920(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Priest1920(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - munsell_value_Priest1920(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Priest1920(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_munsell_value_Priest1920(self): @@ -1175,10 +1172,10 @@ def test_domain_range_scale_munsell_value_Priest1920(self): d_r = (("reference", 1, 1), ("1", 0.01, 0.1), ("100", 1, 10)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_value_Priest1920(Y * factor_a), V * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1205,20 +1202,22 @@ def test_munsell_value_Munsell1933(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( munsell_value_Munsell1933(12.23634268), 4.1627702416858083, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( munsell_value_Munsell1933(22.89399987), 5.5914543020790592, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_Munsell1933(6.29022535), 3.0141971134091761, places=7 + np.testing.assert_allclose( + munsell_value_Munsell1933(6.29022535), + 3.0141971134091761, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_value_Munsell1933(self): @@ -1232,20 +1231,20 @@ def test_n_dimensional_munsell_value_Munsell1933(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - munsell_value_Munsell1933(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Munsell1933(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - munsell_value_Munsell1933(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Munsell1933(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - munsell_value_Munsell1933(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Munsell1933(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_munsell_value_Munsell1933(self): @@ -1260,10 +1259,10 @@ def test_domain_range_scale_munsell_value_Munsell1933(self): d_r = (("reference", 1, 1), ("1", 0.01, 0.1), ("100", 1, 10)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_value_Munsell1933(Y * factor_a), V * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1290,16 +1289,22 @@ def test_munsell_value_Moon1943(self): definition. """ - self.assertAlmostEqual( - munsell_value_Moon1943(12.23634268), 4.0688120634976421, places=7 + np.testing.assert_allclose( + munsell_value_Moon1943(12.23634268), + 4.0688120634976421, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_Moon1943(22.89399987), 5.3133627855494412, places=7 + np.testing.assert_allclose( + munsell_value_Moon1943(22.89399987), + 5.3133627855494412, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_Moon1943(6.29022535), 3.0645015037679695, places=7 + np.testing.assert_allclose( + munsell_value_Moon1943(6.29022535), + 3.0645015037679695, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_value_Moon1943(self): @@ -1313,20 +1318,20 @@ def test_n_dimensional_munsell_value_Moon1943(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - munsell_value_Moon1943(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Moon1943(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - munsell_value_Moon1943(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Moon1943(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - munsell_value_Moon1943(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Moon1943(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_munsell_value_Moon1943(self): @@ -1341,10 +1346,10 @@ def test_domain_range_scale_munsell_value_Moon1943(self): d_r = (("reference", 1, 1), ("1", 0.01, 0.1), ("100", 1, 10)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_value_Moon1943(Y * factor_a), V * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1371,22 +1376,22 @@ def test_munsell_value_Saunderson1944(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( munsell_value_Saunderson1944(12.23634268), 4.0444736723175119, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( munsell_value_Saunderson1944(22.89399987), 5.3783324022305923, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( munsell_value_Saunderson1944(6.29022535), 2.9089633927316823, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_value_Saunderson1944(self): @@ -1400,20 +1405,20 @@ def test_n_dimensional_munsell_value_Saunderson1944(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - munsell_value_Saunderson1944(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Saunderson1944(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - munsell_value_Saunderson1944(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Saunderson1944(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - munsell_value_Saunderson1944(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Saunderson1944(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_munsell_value_Saunderson1944(self): @@ -1428,10 +1433,10 @@ def test_domain_range_scale_munsell_value_Saunderson1944(self): d_r = (("reference", 1, 1), ("1", 0.01, 0.1), ("100", 1, 10)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_value_Saunderson1944(Y * factor_a), V * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1458,16 +1463,22 @@ def test_munsell_value_Ladd1955(self): definition. """ - self.assertAlmostEqual( - munsell_value_Ladd1955(12.23634268), 4.0511633044287088, places=7 + np.testing.assert_allclose( + munsell_value_Ladd1955(12.23634268), + 4.0511633044287088, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_Ladd1955(22.89399987), 5.3718647913936772, places=7 + np.testing.assert_allclose( + munsell_value_Ladd1955(22.89399987), + 5.3718647913936772, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_Ladd1955(6.29022535), 2.9198269939751613, places=7 + np.testing.assert_allclose( + munsell_value_Ladd1955(6.29022535), + 2.9198269939751613, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_value_Ladd1955(self): @@ -1481,20 +1492,20 @@ def test_n_dimensional_munsell_value_Ladd1955(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - munsell_value_Ladd1955(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Ladd1955(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - munsell_value_Ladd1955(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Ladd1955(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - munsell_value_Ladd1955(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_Ladd1955(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_munsell_value_Ladd1955(self): @@ -1509,10 +1520,10 @@ def test_domain_range_scale_munsell_value_Ladd1955(self): d_r = (("reference", 1, 1), ("1", 0.01, 0.1), ("100", 1, 10)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_value_Ladd1955(Y * factor_a), V * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1539,16 +1550,22 @@ def test_munsell_value_McCamy1987(self): definition. """ - self.assertAlmostEqual( - munsell_value_McCamy1987(12.23634268), 4.081434853194113, places=7 + np.testing.assert_allclose( + munsell_value_McCamy1987(12.23634268), + 4.081434853194113, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_McCamy1987(22.89399987), 5.394083970919982, places=7 + np.testing.assert_allclose( + munsell_value_McCamy1987(22.89399987), + 5.394083970919982, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_McCamy1987(6.29022535), 2.9750160800320096, places=7 + np.testing.assert_allclose( + munsell_value_McCamy1987(6.29022535), + 2.9750160800320096, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_value_McCamy1987(self): @@ -1562,20 +1579,20 @@ def test_n_dimensional_munsell_value_McCamy1987(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - munsell_value_McCamy1987(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_McCamy1987(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - munsell_value_McCamy1987(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_McCamy1987(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - munsell_value_McCamy1987(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_McCamy1987(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_munsell_value_McCamy1987(self): @@ -1590,10 +1607,10 @@ def test_domain_range_scale_munsell_value_McCamy1987(self): d_r = (("reference", 1, 1), ("1", 0.01, 0.1), ("100", 1, 10)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_value_McCamy1987(Y * factor_a), V * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1620,16 +1637,22 @@ def test_munsell_value_ASTMD1535(self): definition. """ - self.assertAlmostEqual( - munsell_value_ASTMD1535(12.23634268), 4.0824437076525664, places=7 + np.testing.assert_allclose( + munsell_value_ASTMD1535(12.23634268), + 4.0824437076525664, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_ASTMD1535(22.89399987), 5.3913268228155395, places=7 + np.testing.assert_allclose( + munsell_value_ASTMD1535(22.89399987), + 5.3913268228155395, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - munsell_value_ASTMD1535(6.29022535), 2.9761930839606454, places=7 + np.testing.assert_allclose( + munsell_value_ASTMD1535(6.29022535), + 2.9761930839606454, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_value_ASTMD1535(self): @@ -1643,20 +1666,20 @@ def test_n_dimensional_munsell_value_ASTMD1535(self): V = np.tile(V, 6) Y = np.tile(Y, 6) - np.testing.assert_array_almost_equal( - munsell_value_ASTMD1535(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_ASTMD1535(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3)) Y = np.reshape(Y, (2, 3)) - np.testing.assert_array_almost_equal( - munsell_value_ASTMD1535(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_ASTMD1535(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) V = np.reshape(V, (2, 3, 1)) Y = np.reshape(Y, (2, 3, 1)) - np.testing.assert_array_almost_equal( - munsell_value_ASTMD1535(Y), V, decimal=7 + np.testing.assert_allclose( + munsell_value_ASTMD1535(Y), V, atol=TOLERANCE_ABSOLUTE_TESTS ) def test_domain_range_scale_munsell_value_ASTMD1535(self): @@ -1671,10 +1694,10 @@ def test_domain_range_scale_munsell_value_ASTMD1535(self): d_r = (("reference", 1, 1), ("1", 0.01, 0.1), ("100", 1, 10)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_value_ASTMD1535(Y * factor_a), V * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1705,8 +1728,10 @@ def test_munsell_specification_to_xyY(self): as_float_array(list(MUNSELL_SPECIFICATIONS[..., 0])), as_float_array(list(MUNSELL_SPECIFICATIONS[..., 1])), ) - np.testing.assert_array_almost_equal( - munsell_specification_to_xyY(specification), xyY, decimal=7 + np.testing.assert_allclose( + munsell_specification_to_xyY(specification), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification, xyY = ( @@ -1719,8 +1744,10 @@ def test_munsell_specification_to_xyY(self): [nan_array, specification, nan_array, nan_array] ) - np.testing.assert_array_almost_equal( - munsell_specification_to_xyY(specification), xyY, decimal=7 + np.testing.assert_allclose( + munsell_specification_to_xyY(specification), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_specification_to_xyY(self): @@ -1736,14 +1763,18 @@ def test_n_dimensional_munsell_specification_to_xyY(self): specification = np.tile(specification, (6, 1)) xyY = np.tile(xyY, (6, 1)) - np.testing.assert_array_almost_equal( - munsell_specification_to_xyY(specification), xyY, decimal=7 + np.testing.assert_allclose( + munsell_specification_to_xyY(specification), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = np.reshape(specification, (2, 3, 4)) xyY = np.reshape(xyY, (2, 3, 3)) - np.testing.assert_array_almost_equal( - munsell_specification_to_xyY(specification), xyY, decimal=7 + np.testing.assert_allclose( + munsell_specification_to_xyY(specification), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = np.array([np.nan, 8.9, np.nan, np.nan]) @@ -1751,14 +1782,18 @@ def test_n_dimensional_munsell_specification_to_xyY(self): specification = np.tile(specification, (6, 1)) xyY = np.tile(xyY, (6, 1)) - np.testing.assert_array_almost_equal( - munsell_specification_to_xyY(specification), xyY, decimal=7 + np.testing.assert_allclose( + munsell_specification_to_xyY(specification), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification = np.reshape(specification, (2, 3, 4)) xyY = np.reshape(xyY, (2, 3, 3)) - np.testing.assert_array_almost_equal( - munsell_specification_to_xyY(specification), xyY, decimal=7 + np.testing.assert_allclose( + munsell_specification_to_xyY(specification), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_munsell_specification_to_xyY(self): @@ -1779,10 +1814,10 @@ def test_domain_range_scale_munsell_specification_to_xyY(self): ) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_specification_to_xyY(specification * factor_a), xyY * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -1821,10 +1856,10 @@ def test_domain_range_scale_munsell_colour_to_xyY(self): ) for scale, factor in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_colour_to_xyY(munsell_colour), xyY * factor, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_munsell_colour_to_xyY(self): @@ -1838,14 +1873,18 @@ def test_n_dimensional_munsell_colour_to_xyY(self): munsell_colour = np.tile(munsell_colour, 6) xyY = np.tile(xyY, (6, 1)) - np.testing.assert_array_almost_equal( - munsell_colour_to_xyY(munsell_colour), xyY, decimal=7 + np.testing.assert_allclose( + munsell_colour_to_xyY(munsell_colour), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) munsell_colour = np.reshape(munsell_colour, (2, 3)) xyY = np.reshape(xyY, (2, 3, 3)) - np.testing.assert_array_almost_equal( - munsell_colour_to_xyY(munsell_colour), xyY, decimal=7 + np.testing.assert_allclose( + munsell_colour_to_xyY(munsell_colour), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) munsell_colour = "N8.9" @@ -1853,14 +1892,18 @@ def test_n_dimensional_munsell_colour_to_xyY(self): munsell_colour = np.tile(munsell_colour, 6) xyY = np.tile(xyY, (6, 1)) - np.testing.assert_array_almost_equal( - munsell_colour_to_xyY(munsell_colour), xyY, decimal=7 + np.testing.assert_allclose( + munsell_colour_to_xyY(munsell_colour), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) munsell_colour = np.reshape(munsell_colour, (2, 3)) xyY = np.reshape(xyY, (2, 3, 3)) - np.testing.assert_array_almost_equal( - munsell_colour_to_xyY(munsell_colour), xyY, decimal=7 + np.testing.assert_allclose( + munsell_colour_to_xyY(munsell_colour), + xyY, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1884,8 +1927,7 @@ def test_xyY_to_munsell_specification(self): np.testing.assert_allclose( xyY_to_munsell_specification(xyY), specification, - rtol=0.00001, - atol=0.00001, + atol=5e-5, ) specification, xyY = ( @@ -1901,7 +1943,6 @@ def test_xyY_to_munsell_specification(self): np.testing.assert_allclose( xyY_to_munsell_specification(xyY), specification, - rtol=0.00001, atol=0.00001, ) @@ -1916,14 +1957,18 @@ def test_n_dimensional_xyY_to_munsell_specification(self): xyY = np.tile(xyY, (6, 1)) specification = np.tile(specification, (6, 1)) - np.testing.assert_array_almost_equal( - xyY_to_munsell_specification(xyY), specification, decimal=7 + np.testing.assert_allclose( + xyY_to_munsell_specification(xyY), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) xyY = np.reshape(xyY, (2, 3, 3)) specification = np.reshape(specification, (2, 3, 4)) - np.testing.assert_array_almost_equal( - xyY_to_munsell_specification(xyY), specification, decimal=7 + np.testing.assert_allclose( + xyY_to_munsell_specification(xyY), + specification, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_xyY_to_munsell_specification(self): @@ -1957,8 +2002,7 @@ def test_domain_range_scale_xyY_to_munsell_specification(self): np.testing.assert_allclose( xyY_to_munsell_specification(xyY * factor_a), specification * factor_b, - rtol=0.00001, - atol=0.00001, + atol=2e-5, ) @ignore_numpy_errors @@ -2042,22 +2086,22 @@ def test_parse_munsell_colour(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( parse_munsell_colour("N5.2"), np.array([np.nan, 5.2, np.nan, np.nan]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( parse_munsell_colour("0YR 2.0/4.0"), np.array([0.0, 2.0, 4.0, 6]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( parse_munsell_colour("4.2YR 8.1/5.3"), np.array([4.2, 8.1, 5.3, 6]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_parse_munsell_colour(self): @@ -2104,28 +2148,28 @@ def test_normalise_munsell_specification(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_munsell_specification((0.0, 2.0, 4.0, 6)), np.array([10.0, 2.0, 4.0, 7]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_munsell_specification((0.0, 2.0, 4.0, 8)), np.array([10.0, 2.0, 4.0, 9]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_munsell_specification((0, 2.0, 4.0, 10)), np.array([10.0, 2.0, 4.0, 1]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( normalise_munsell_specification(0.5), np.array([np.nan, 0.5, np.nan, np.nan]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -2141,34 +2185,34 @@ def test_munsell_colour_to_munsell_specification(self): munsell_colour_to_munsell_specification` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_colour_to_munsell_specification("0.0YR 2.0/4.0"), np.array([10.0, 2.0, 4.0, 7]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_colour_to_munsell_specification("0.0RP 2.0/4.0"), np.array([10.0, 2.0, 4.0, 9]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_colour_to_munsell_specification("10.0B 2.0/4.0"), np.array([10.0, 2.0, 4.0, 1]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_colour_to_munsell_specification("N5.2"), np.array([np.nan, 5.2, np.nan, np.nan]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_colour_to_munsell_specification("0.0YR 2.0/0.0"), np.array([np.nan, 2.0, np.nan, np.nan]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -2240,17 +2284,17 @@ def test_xyY_from_renotation(self): """ np.testing.assert_array_equal( - xyY_from_renotation((2.5, 0.2, 2.0, 4)), + xyY_from_renotation([2.5, 0.2, 2.0, 4]), np.array([0.713, 1.414, 0.237]), ) np.testing.assert_array_equal( - xyY_from_renotation((5.0, 0.2, 2.0, 4)), + xyY_from_renotation([5.0, 0.2, 2.0, 4]), np.array([0.449, 1.145, 0.237]), ) np.testing.assert_array_equal( - xyY_from_renotation((7.5, 0.2, 2.0, 4)), + xyY_from_renotation([7.5, 0.2, 2.0, 4]), np.array([0.262, 0.837, 0.237]), ) @@ -2384,10 +2428,10 @@ def test_xy_from_renotation_ovoid(self): for i, (specification, _xyY) in enumerate(MUNSELL_EVEN_SPECIFICATIONS): if is_specification_in_renotation(specification): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( xy_from_renotation_ovoid(specification), MUNSELL_XY_FROM_RENOTATION_OVOID[i], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -2403,44 +2447,44 @@ def test_LCHab_to_munsell_specification(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_munsell_specification( np.array([100.00000000, 21.57210357, 272.22819350]) ), np.array([5.618942638888882, 10.0, 4.314420714000000, 10]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_munsell_specification( np.array([100.00000000, 426.67945353, 72.39590835]) ), np.array([0.109974541666666, 10.0, 85.335890706000001, 5]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_munsell_specification( np.array([100.00000000, 74.05216981, 276.45318193]) ), np.array([6.792550536111119, 10.0, 14.810433961999999, 10]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_munsell_specification( np.array([100.00000000, 21.57210357, 0.00000000]) ), np.array([10.000000000000000, 10.0, 4.314420714000000, 8]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( LCHab_to_munsell_specification( np.array([100.00000000, 21.57210357, 36.00000000]) ), np.array([10.000000000000000, 10.0, 4.314420714000000, 7]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -2480,15 +2524,17 @@ def test_munsell_specification_to_xy(self): """ for specification, xyY in MUNSELL_EVEN_SPECIFICATIONS: - np.testing.assert_array_almost_equal( - munsell_specification_to_xy(specification), xyY[0:2], decimal=7 + np.testing.assert_allclose( + munsell_specification_to_xy(specification), + xyY[0:2], + atol=TOLERANCE_ABSOLUTE_TESTS, ) for specification, xyY in MUNSELL_GREYS_SPECIFICATIONS: - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( munsell_specification_to_xy(specification[0]), xyY[0:2], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/phenomena/rayleigh.py b/colour/phenomena/rayleigh.py index e457bd36e0..082ffe5f3d 100644 --- a/colour/phenomena/rayleigh.py +++ b/colour/phenomena/rayleigh.py @@ -29,7 +29,7 @@ SpectralShape, ) from colour.constants import CONSTANT_AVOGADRO -from colour.hints import Callable, ArrayLike, NDArrayFloat +from colour.hints import ArrayLike, Callable, NDArrayFloat from colour.utilities import as_float, as_float_array, filter_kwargs __author__ = "Colour Developers" diff --git a/colour/phenomena/tests/test_rayleigh.py b/colour/phenomena/tests/test_rayleigh.py index 186f2a4eff..b160d25cd3 100644 --- a/colour/phenomena/tests/test_rayleigh.py +++ b/colour/phenomena/tests/test_rayleigh.py @@ -3,28 +3,30 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.phenomena import ( + rayleigh_optical_depth, + scattering_cross_section, + sd_rayleigh_scattering, +) from colour.phenomena.rayleigh import ( - air_refraction_index_Penndorf1957, - air_refraction_index_Edlen1966, - air_refraction_index_Peck1972, - air_refraction_index_Bodhaine1999, - N2_depolarisation, - O2_depolarisation, - F_air_Penndorf1957, - F_air_Young1981, F_air_Bates1984, F_air_Bodhaine1999, - molecular_density, - mean_molecular_weights, + F_air_Penndorf1957, + F_air_Young1981, + N2_depolarisation, + O2_depolarisation, + air_refraction_index_Bodhaine1999, + air_refraction_index_Edlen1966, + air_refraction_index_Peck1972, + air_refraction_index_Penndorf1957, gravity_List1968, -) -from colour.phenomena import ( - scattering_cross_section, - rayleigh_optical_depth, - sd_rayleigh_scattering, + mean_molecular_weights, + molecular_density, ) from colour.utilities import ignore_numpy_errors @@ -492,22 +494,22 @@ def test_air_refraction_index_Penndorf1957(self): air_refraction_index_Penndorf1957` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Penndorf1957(0.360), 1.000285316795146, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Penndorf1957(0.555), 1.000277729533864, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Penndorf1957(0.830), 1.000274856640486, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_air_refraction_index_Penndorf1957(self): @@ -521,20 +523,26 @@ def test_n_dimensional_air_refraction_index_Penndorf1957(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - air_refraction_index_Penndorf1957(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Penndorf1957(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - air_refraction_index_Penndorf1957(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Penndorf1957(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - air_refraction_index_Penndorf1957(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Penndorf1957(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -561,16 +569,22 @@ def test_air_refraction_index_Edlen1966(self): rayleigh.air_refraction_index_Edlen1966` definition. """ - self.assertAlmostEqual( - air_refraction_index_Edlen1966(0.360), 1.000285308809879, places=10 + np.testing.assert_allclose( + air_refraction_index_Edlen1966(0.360), + 1.000285308809879, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - air_refraction_index_Edlen1966(0.555), 1.000277727690364, places=10 + np.testing.assert_allclose( + air_refraction_index_Edlen1966(0.555), + 1.000277727690364, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - air_refraction_index_Edlen1966(0.830), 1.000274862218835, places=10 + np.testing.assert_allclose( + air_refraction_index_Edlen1966(0.830), + 1.000274862218835, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_air_refraction_index_Edlen1966(self): @@ -584,20 +598,26 @@ def test_n_dimensional_air_refraction_index_Edlen1966(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - air_refraction_index_Edlen1966(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Edlen1966(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - air_refraction_index_Edlen1966(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Edlen1966(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - air_refraction_index_Edlen1966(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Edlen1966(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -624,16 +644,22 @@ def test_air_refraction_index_Peck1972(self): definition. """ - self.assertAlmostEqual( - air_refraction_index_Peck1972(0.360), 1.000285310285056, places=10 + np.testing.assert_allclose( + air_refraction_index_Peck1972(0.360), + 1.000285310285056, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - air_refraction_index_Peck1972(0.555), 1.000277726541484, places=10 + np.testing.assert_allclose( + air_refraction_index_Peck1972(0.555), + 1.000277726541484, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - air_refraction_index_Peck1972(0.830), 1.000274859144804, places=10 + np.testing.assert_allclose( + air_refraction_index_Peck1972(0.830), + 1.000274859144804, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_air_refraction_index_Peck1972(self): @@ -647,20 +673,20 @@ def test_n_dimensional_air_refraction_index_Peck1972(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - air_refraction_index_Peck1972(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Peck1972(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - air_refraction_index_Peck1972(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Peck1972(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - air_refraction_index_Peck1972(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Peck1972(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -687,40 +713,40 @@ def test_air_refraction_index_Bodhaine1999(self): air_refraction_index_Bodhaine1999` definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Bodhaine1999(0.360), 1.000285310285056, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Bodhaine1999(0.555), 1.000277726541484, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Bodhaine1999(0.830), 1.000274859144804, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Bodhaine1999(0.360, 0), 1.000285264064789, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Bodhaine1999(0.555, 360), 1.000277735539824, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( air_refraction_index_Bodhaine1999(0.830, 620), 1.000274906640464, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_air_refraction_index_Bodhaine1999(self): @@ -734,20 +760,26 @@ def test_n_dimensional_air_refraction_index_Bodhaine1999(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - air_refraction_index_Bodhaine1999(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Bodhaine1999(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - air_refraction_index_Bodhaine1999(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Bodhaine1999(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - air_refraction_index_Bodhaine1999(wl), n, decimal=7 + np.testing.assert_allclose( + air_refraction_index_Bodhaine1999(wl), + n, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -770,16 +802,22 @@ class TestN2Depolarisation(unittest.TestCase): def test_N2_depolarisation(self): """Test :func:`colour.phenomena.rayleigh.N2_depolarisation` definition.""" - self.assertAlmostEqual( - N2_depolarisation(0.360), 1.036445987654321, places=7 + np.testing.assert_allclose( + N2_depolarisation(0.360), + 1.036445987654321, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - N2_depolarisation(0.555), 1.035029137245354, places=7 + np.testing.assert_allclose( + N2_depolarisation(0.555), + 1.035029137245354, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - N2_depolarisation(0.830), 1.034460153868486, places=7 + np.testing.assert_allclose( + N2_depolarisation(0.830), + 1.034460153868486, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_N2_depolarisation(self): @@ -793,20 +831,20 @@ def test_n_dimensional_N2_depolarisation(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - N2_depolarisation(wl), n, decimal=7 + np.testing.assert_allclose( + N2_depolarisation(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - N2_depolarisation(wl), n, decimal=7 + np.testing.assert_allclose( + N2_depolarisation(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - N2_depolarisation(wl), n, decimal=7 + np.testing.assert_allclose( + N2_depolarisation(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -828,16 +866,22 @@ class TestO2Depolarisation(unittest.TestCase): def test_O2_depolarisation(self): """Test :func:`colour.phenomena.rayleigh.O2_depolarisation` definition.""" - self.assertAlmostEqual( - O2_depolarisation(0.360), 1.115307746532541, places=7 + np.testing.assert_allclose( + O2_depolarisation(0.360), + 1.115307746532541, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - O2_depolarisation(0.555), 1.102022536201071, places=7 + np.testing.assert_allclose( + O2_depolarisation(0.555), + 1.102022536201071, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - O2_depolarisation(0.830), 1.098315561269013, places=7 + np.testing.assert_allclose( + O2_depolarisation(0.830), + 1.098315561269013, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_O2_depolarisation(self): @@ -851,20 +895,20 @@ def test_n_dimensional_O2_depolarisation(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - O2_depolarisation(wl), n, decimal=7 + np.testing.assert_allclose( + O2_depolarisation(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - O2_depolarisation(wl), n, decimal=7 + np.testing.assert_allclose( + O2_depolarisation(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - O2_depolarisation(wl), n, decimal=7 + np.testing.assert_allclose( + O2_depolarisation(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -902,20 +946,20 @@ def test_n_dimensional_F_air_Penndorf1957(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - F_air_Penndorf1957(wl), n, decimal=7 + np.testing.assert_allclose( + F_air_Penndorf1957(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - F_air_Penndorf1957(wl), n, decimal=7 + np.testing.assert_allclose( + F_air_Penndorf1957(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - F_air_Penndorf1957(wl), n, decimal=7 + np.testing.assert_allclose( + F_air_Penndorf1957(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -950,15 +994,21 @@ def test_n_dimensional_F_air_Young1981(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal(F_air_Young1981(wl), n, decimal=7) + np.testing.assert_allclose( + F_air_Young1981(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS + ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal(F_air_Young1981(wl), n, decimal=7) + np.testing.assert_allclose( + F_air_Young1981(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS + ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal(F_air_Young1981(wl), n, decimal=7) + np.testing.assert_allclose( + F_air_Young1981(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_F_air_Young1981(self): @@ -979,16 +1029,22 @@ class TestF_airBates1984(unittest.TestCase): def test_F_air_Bates1984(self): """Test :func:`colour.phenomena.rayleigh.F_air_Bates1984` definition.""" - self.assertAlmostEqual( - F_air_Bates1984(0.360), 1.051997277711708, places=7 + np.testing.assert_allclose( + F_air_Bates1984(0.360), + 1.051997277711708, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - F_air_Bates1984(0.555), 1.048153579718658, places=7 + np.testing.assert_allclose( + F_air_Bates1984(0.555), + 1.048153579718658, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - F_air_Bates1984(0.830), 1.046947068600589, places=7 + np.testing.assert_allclose( + F_air_Bates1984(0.830), + 1.046947068600589, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_F_air_Bates1984(self): @@ -1002,15 +1058,21 @@ def test_n_dimensional_F_air_Bates1984(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal(F_air_Bates1984(wl), n, decimal=7) + np.testing.assert_allclose( + F_air_Bates1984(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS + ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal(F_air_Bates1984(wl), n, decimal=7) + np.testing.assert_allclose( + F_air_Bates1984(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS + ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal(F_air_Bates1984(wl), n, decimal=7) + np.testing.assert_allclose( + F_air_Bates1984(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_F_air_Bates1984(self): @@ -1034,28 +1096,40 @@ def test_F_air_Bodhaine1999(self): definition. """ - self.assertAlmostEqual( - F_air_Bodhaine1999(0.360), 1.052659005129014, places=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(0.360), + 1.052659005129014, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - F_air_Bodhaine1999(0.555), 1.048769718142427, places=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(0.555), + 1.048769718142427, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - F_air_Bodhaine1999(0.830), 1.047548896943893, places=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(0.830), + 1.047548896943893, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - F_air_Bodhaine1999(0.360, 0), 1.052629792313939, places=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(0.360, 0), + 1.052629792313939, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - F_air_Bodhaine1999(0.555, 360), 1.048775791959338, places=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(0.555, 360), + 1.048775791959338, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - F_air_Bodhaine1999(0.830, 620), 1.047581672775155, places=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(0.830, 620), + 1.047581672775155, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_F_air_Bodhaine1999(self): @@ -1069,20 +1143,20 @@ def test_n_dimensional_F_air_Bodhaine1999(self): wl = np.tile(wl, 6) n = np.tile(n, 6) - np.testing.assert_array_almost_equal( - F_air_Bodhaine1999(wl), n, decimal=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3)) n = np.reshape(n, (2, 3)) - np.testing.assert_array_almost_equal( - F_air_Bodhaine1999(wl), n, decimal=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) wl = np.reshape(wl, (2, 3, 1)) n = np.reshape(n, (2, 3, 1)) - np.testing.assert_array_almost_equal( - F_air_Bodhaine1999(wl), n, decimal=7 + np.testing.assert_allclose( + F_air_Bodhaine1999(wl), n, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -1105,16 +1179,16 @@ class TestMolecularDensity(unittest.TestCase): def test_molecular_density(self): """Test :func:`colour.phenomena.rayleigh.molecular_density` definition.""" - self.assertAlmostEqual( - molecular_density(200), 3.669449208173649e19, delta=10000 + np.testing.assert_allclose( + molecular_density(200), 3.669449208173649e19, atol=10000 ) - self.assertAlmostEqual( - molecular_density(300), 2.4462994721157665e19, delta=10000 + np.testing.assert_allclose( + molecular_density(300), 2.4462994721157665e19, atol=10000 ) - self.assertAlmostEqual( - molecular_density(400), 1.834724604086825e19, delta=10000 + np.testing.assert_allclose( + molecular_density(400), 1.834724604086825e19, atol=10000 ) def test_n_dimensional_molecular_density(self): @@ -1128,20 +1202,20 @@ def test_n_dimensional_molecular_density(self): temperature = np.tile(temperature, 6) N_s = np.tile(N_s, 6) - np.testing.assert_array_almost_equal( - molecular_density(temperature), N_s, decimal=7 + np.testing.assert_allclose( + molecular_density(temperature), N_s, atol=TOLERANCE_ABSOLUTE_TESTS ) temperature = np.reshape(temperature, (2, 3)) N_s = np.reshape(N_s, (2, 3)) - np.testing.assert_array_almost_equal( - molecular_density(temperature), N_s, decimal=7 + np.testing.assert_allclose( + molecular_density(temperature), N_s, atol=TOLERANCE_ABSOLUTE_TESTS ) temperature = np.reshape(temperature, (2, 3, 1)) N_s = np.reshape(N_s, (2, 3, 1)) - np.testing.assert_array_almost_equal( - molecular_density(temperature), N_s, decimal=7 + np.testing.assert_allclose( + molecular_density(temperature), N_s, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -1166,14 +1240,20 @@ def test_mean_molecular_weights(self): definition. """ - self.assertAlmostEqual(mean_molecular_weights(0), 28.9595, places=7) + np.testing.assert_allclose( + mean_molecular_weights(0), 28.9595, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - mean_molecular_weights(360), 28.964920015999997, places=7 + np.testing.assert_allclose( + mean_molecular_weights(360), + 28.964920015999997, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - mean_molecular_weights(620), 28.968834471999998, places=7 + np.testing.assert_allclose( + mean_molecular_weights(620), + 28.968834471999998, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_mean_molecular_weights(self): @@ -1187,20 +1267,20 @@ def test_n_dimensional_mean_molecular_weights(self): CO2_c = np.tile(CO2_c, 6) m_a = np.tile(m_a, 6) - np.testing.assert_array_almost_equal( - mean_molecular_weights(CO2_c), m_a, decimal=7 + np.testing.assert_allclose( + mean_molecular_weights(CO2_c), m_a, atol=TOLERANCE_ABSOLUTE_TESTS ) CO2_c = np.reshape(CO2_c, (2, 3)) m_a = np.reshape(m_a, (2, 3)) - np.testing.assert_array_almost_equal( - mean_molecular_weights(CO2_c), m_a, decimal=7 + np.testing.assert_allclose( + mean_molecular_weights(CO2_c), m_a, atol=TOLERANCE_ABSOLUTE_TESTS ) CO2_c = np.reshape(CO2_c, (2, 3, 1)) m_a = np.reshape(m_a, (2, 3, 1)) - np.testing.assert_array_almost_equal( - mean_molecular_weights(CO2_c), m_a, decimal=7 + np.testing.assert_allclose( + mean_molecular_weights(CO2_c), m_a, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -1224,16 +1304,22 @@ class TestGravityList1968(unittest.TestCase): def test_gravity_List1968(self): """Test :func:`colour.phenomena.rayleigh.gravity_List1968` definition.""" - self.assertAlmostEqual( - gravity_List1968(0.0, 0.0), 978.03560706, places=7 + np.testing.assert_allclose( + gravity_List1968(0.0, 0.0), + 978.03560706, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gravity_List1968(45.0, 1500.0), 980.15334386, places=7 + np.testing.assert_allclose( + gravity_List1968(45.0, 1500.0), + 980.15334386, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - gravity_List1968(48.8567, 35.0), 980.95241784, places=7 + np.testing.assert_allclose( + gravity_List1968(48.8567, 35.0), + 980.95241784, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_gravity_List1968(self): @@ -1243,16 +1329,24 @@ def test_n_dimensional_gravity_List1968(self): """ g = 978.03560706 - np.testing.assert_array_almost_equal(gravity_List1968(), g, decimal=7) + np.testing.assert_allclose( + gravity_List1968(), g, atol=TOLERANCE_ABSOLUTE_TESTS + ) g = np.tile(g, 6) - np.testing.assert_array_almost_equal(gravity_List1968(), g, decimal=7) + np.testing.assert_allclose( + gravity_List1968(), g, atol=TOLERANCE_ABSOLUTE_TESTS + ) g = np.reshape(g, (2, 3)) - np.testing.assert_array_almost_equal(gravity_List1968(), g, decimal=7) + np.testing.assert_allclose( + gravity_List1968(), g, atol=TOLERANCE_ABSOLUTE_TESTS + ) g = np.reshape(g, (2, 3, 1)) - np.testing.assert_array_almost_equal(gravity_List1968(), g, decimal=7) + np.testing.assert_allclose( + gravity_List1968(), g, atol=TOLERANCE_ABSOLUTE_TESTS + ) @ignore_numpy_errors def test_nan_gravity_List1968(self): @@ -1277,58 +1371,58 @@ def test_scattering_cross_section(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(360 * 10e-8), 2.600908533851937e-26, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(555 * 10e-8), 4.346669248087624e-27, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(830 * 10e-8), 8.501515434751428e-28, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(555 * 10e-8, 0), 4.346543336839102e-27, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(555 * 10e-8, 360), 4.346694421271718e-27, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(555 * 10e-8, 620), 4.346803470171720e-27, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(555 * 10e-8, temperature=200), 2.094012829135068e-27, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(555 * 10e-8, temperature=300), 4.711528865553901e-27, - places=32, + atol=1e-30, ) - self.assertAlmostEqual( + np.testing.assert_allclose( scattering_cross_section(555 * 10e-8, temperature=400), 8.376051316540270e-27, - places=32, + atol=1e-30, ) def test_n_dimensional_scattering_cross_section(self): @@ -1341,18 +1435,18 @@ def test_n_dimensional_scattering_cross_section(self): sigma = scattering_cross_section(wl) sigma = np.tile(sigma, 6) - np.testing.assert_array_almost_equal( - scattering_cross_section(wl), sigma, decimal=32 + np.testing.assert_allclose( + scattering_cross_section(wl), sigma, atol=TOLERANCE_ABSOLUTE_TESTS ) sigma = np.reshape(sigma, (2, 3)) - np.testing.assert_array_almost_equal( - scattering_cross_section(wl), sigma, decimal=32 + np.testing.assert_allclose( + scattering_cross_section(wl), sigma, atol=TOLERANCE_ABSOLUTE_TESTS ) sigma = np.reshape(sigma, (2, 3, 1)) - np.testing.assert_array_almost_equal( - scattering_cross_section(wl), sigma, decimal=32 + np.testing.assert_allclose( + scattering_cross_section(wl), sigma, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -1378,86 +1472,94 @@ def test_rayleigh_optical_depth(self): definition. """ - self.assertAlmostEqual( - rayleigh_optical_depth(360 * 10e-8), 0.560246579231107, places=7 + np.testing.assert_allclose( + rayleigh_optical_depth(360 * 10e-8), + 0.560246579231107, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - rayleigh_optical_depth(555 * 10e-8), 0.093629074056042, places=7 + np.testing.assert_allclose( + rayleigh_optical_depth(555 * 10e-8), + 0.093629074056042, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - rayleigh_optical_depth(830 * 10e-8), 0.018312619911882, places=7 + np.testing.assert_allclose( + rayleigh_optical_depth(830 * 10e-8), + 0.018312619911882, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( - rayleigh_optical_depth(555 * 10e-8, 0), 0.093640964348049, places=7 + np.testing.assert_allclose( + rayleigh_optical_depth(555 * 10e-8, 0), + 0.093640964348049, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, 360), 0.093626696247360, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, 620), 0.093616393371777, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, temperature=200), 0.045105912380991, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, temperature=300), 0.101488302857230, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, temperature=400), 0.180423649523964, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, pressure=101325), 0.093629074056042, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, pressure=100325), 0.092705026939772, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, pressure=99325), 0.091780979823502, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, latitude=0, altitude=0), 0.093629074056041, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, latitude=45, altitude=1500), 0.093426777407767, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( rayleigh_optical_depth(555 * 10e-8, latitude=48.8567, altitude=35), 0.093350672894038, - places=10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_rayleigh_optical_depth(self): @@ -1470,18 +1572,18 @@ def test_n_dimensional_rayleigh_optical_depth(self): T_R = rayleigh_optical_depth(wl) T_R = np.tile(T_R, 6) - np.testing.assert_array_almost_equal( - rayleigh_optical_depth(wl), T_R, decimal=7 + np.testing.assert_allclose( + rayleigh_optical_depth(wl), T_R, atol=TOLERANCE_ABSOLUTE_TESTS ) T_R = np.reshape(T_R, (2, 3)) - np.testing.assert_array_almost_equal( - rayleigh_optical_depth(wl), T_R, decimal=7 + np.testing.assert_allclose( + rayleigh_optical_depth(wl), T_R, atol=TOLERANCE_ABSOLUTE_TESTS ) T_R = np.reshape(T_R, (2, 3, 1)) - np.testing.assert_array_almost_equal( - rayleigh_optical_depth(wl), T_R, decimal=7 + np.testing.assert_allclose( + rayleigh_optical_depth(wl), T_R, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -1507,10 +1609,10 @@ def test_sd_rayleigh_scattering(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_rayleigh_scattering().values, DATA_SD_RAYLEIGH_SCATTERING, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/plotting/__init__.py b/colour/plotting/__init__.py index b1d696989a..b85a54df21 100644 --- a/colour/plotting/__init__.py +++ b/colour/plotting/__init__.py @@ -1,14 +1,43 @@ from colour.utilities import is_matplotlib_installed -is_matplotlib_installed(raise_exception=True) +if not is_matplotlib_installed(): + import sys + from unittest.mock import MagicMock + from colour.utilities import usage_warning -from .datasets import * # noqa: E402, F403 -from . import datasets # noqa: E402 -from .common import ( # noqa: E402 + try: + is_matplotlib_installed(raise_exception=True) + except ImportError as error: + usage_warning(str(error)) + + for module in ( + "cycler", + "matplotlib", + "matplotlib.axes", + "matplotlib.cm", + "matplotlib.collections", + "matplotlib.colors", + "matplotlib.figure", + "matplotlib.font_manager", + "matplotlib.patches", + "matplotlib.path", + "matplotlib.pyplot", + "matplotlib.ticker", + "mpl_toolkits", + "mpl_toolkits.mplot3d", + "mpl_toolkits.mplot3d.art3d", + "mpl_toolkits.mplot3d.axes3d", + ): + sys.modules[module] = MagicMock() + +from .datasets import * # noqa: F403 +from . import datasets +from .common import ( CONSTANTS_COLOUR_STYLE, CONSTANTS_ARROW_STYLE, colour_style, override_style, + font_scaling, XYZ_to_plotting_colourspace, ColourSwatch, colour_cycle, @@ -29,8 +58,8 @@ plot_multi_functions, plot_image, ) -from .blindness import plot_cvd_simulation_Machado2009 # noqa: E402 -from .colorimetry import ( # noqa: E402 +from .blindness import plot_cvd_simulation_Machado2009 +from .colorimetry import ( plot_single_sd, plot_multi_sds, plot_single_cmfs, @@ -45,11 +74,14 @@ plot_blackbody_spectral_radiance, plot_blackbody_colours, ) -from .characterisation import ( # noqa: E402 +from .characterisation import ( plot_single_colour_checker, plot_multi_colour_checkers, ) -from .diagrams import ( # noqa: E402 +from .diagrams import ( + METHODS_CHROMATICITY_DIAGRAM, + LABELS_CHROMATICITY_DIAGRAM_DEFAULT, + lines_spectral_locus, plot_chromaticity_diagram_CIE1931, plot_chromaticity_diagram_CIE1960UCS, plot_chromaticity_diagram_CIE1976UCS, @@ -57,12 +89,13 @@ plot_sds_in_chromaticity_diagram_CIE1960UCS, plot_sds_in_chromaticity_diagram_CIE1976UCS, ) -from .corresponding import ( # noqa: E402 +from .corresponding import ( plot_corresponding_chromaticities_prediction, ) # noqa: RUF100 -from .graph import plot_automatic_colour_conversion_graph # noqa: E402 -from .models import ( # noqa: E402 +from .graph import plot_automatic_colour_conversion_graph +from .models import ( colourspace_model_axis_reorder, + lines_pointer_gamut, plot_pointer_gamut, plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931, plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS, @@ -77,31 +110,34 @@ plot_multi_cctfs, plot_constant_hue_loci, ) -from .notation import ( # noqa: E402 +from .notation import ( plot_single_munsell_value_function, plot_multi_munsell_value_functions, ) -from .phenomena import ( # noqa: E402 +from .phenomena import ( plot_single_sd_rayleigh_scattering, plot_the_blue_sky, ) -from .quality import ( # noqa: E402 +from .quality import ( plot_single_sd_colour_rendering_index_bars, plot_multi_sds_colour_rendering_indexes_bars, plot_single_sd_colour_quality_scale_bars, plot_multi_sds_colour_quality_scales_bars, ) -from .section import ( # noqa: E402 +from .section import ( plot_visible_spectrum_section, plot_RGB_colourspace_section, ) -from .temperature import ( # noqa: E402 +from .temperature import ( + lines_daylight_locus, + LABELS_PLANCKIAN_LOCUS_DEFAULT, + lines_planckian_locus, plot_planckian_locus_in_chromaticity_diagram_CIE1931, plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS, plot_planckian_locus_in_chromaticity_diagram_CIE1976UCS, ) -from .tm3018 import plot_single_sd_colour_rendition_report # noqa: E402 -from .volume import ( # noqa: E402 +from .tm3018 import plot_single_sd_colour_rendition_report +from .volume import ( plot_RGB_colourspaces_gamuts, plot_RGB_scatter, ) # noqa: RUF100 @@ -113,6 +149,7 @@ "CONSTANTS_ARROW_STYLE", "colour_style", "override_style", + "font_scaling", "XYZ_to_plotting_colourspace", "ColourSwatch", "colour_cycle", @@ -156,6 +193,9 @@ "plot_multi_colour_checkers", ] __all__ += [ + "METHODS_CHROMATICITY_DIAGRAM", + "LABELS_CHROMATICITY_DIAGRAM_DEFAULT", + "lines_spectral_locus", "plot_chromaticity_diagram_CIE1931", "plot_chromaticity_diagram_CIE1960UCS", "plot_chromaticity_diagram_CIE1976UCS", @@ -171,6 +211,7 @@ ] __all__ += [ "colourspace_model_axis_reorder", + "lines_pointer_gamut", "plot_pointer_gamut", "plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931", "plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS", @@ -204,6 +245,9 @@ "plot_RGB_colourspace_section", ] __all__ += [ + "lines_daylight_locus", + "LABELS_PLANCKIAN_LOCUS_DEFAULT", + "lines_planckian_locus", "plot_planckian_locus_in_chromaticity_diagram_CIE1931", "plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS", "plot_planckian_locus_in_chromaticity_diagram_CIE1976UCS", diff --git a/colour/plotting/blindness.py b/colour/plotting/blindness.py index 91fc9877df..a39adbb3ea 100644 --- a/colour/plotting/blindness.py +++ b/colour/plotting/blindness.py @@ -9,7 +9,8 @@ from __future__ import annotations -import matplotlib.pyplot as plt +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.algebra import vector_dot from colour.blindness import matrix_cvd_Machado2009 @@ -20,7 +21,7 @@ Literal, Tuple, ) -from colour.plotting import CONSTANTS_COLOUR_STYLE, plot_image, override_style +from colour.plotting import CONSTANTS_COLOUR_STYLE, override_style, plot_image from colour.utilities import optional __author__ = "Colour Developers" @@ -43,7 +44,7 @@ def plot_cvd_simulation_Machado2009( severity: float = 0.5, M_a: ArrayLike | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Perform colour vision deficiency simulation on given *RGB* colourspace array using *Machado et al. (2009)* model. diff --git a/colour/plotting/characterisation.py b/colour/plotting/characterisation.py index 98960acce0..1f6f67ce28 100644 --- a/colour/plotting/characterisation.py +++ b/colour/plotting/characterisation.py @@ -11,10 +11,11 @@ from __future__ import annotations import numpy as np -import matplotlib.pyplot as plt +from matplotlib.axes import Axes +from matplotlib.figure import Figure -from colour.hints import Any, Dict, Sequence, Tuple from colour.characterisation import ColourChecker +from colour.hints import Any, Dict, Sequence, Tuple from colour.models import xyY_to_XYZ from colour.plotting import ( CONSTANTS_COLOUR_STYLE, @@ -22,8 +23,8 @@ XYZ_to_plotting_colourspace, artist, filter_colour_checkers, - plot_multi_colour_swatches, override_style, + plot_multi_colour_swatches, render, ) from colour.utilities import attest @@ -54,7 +55,7 @@ def plot_single_colour_checker( colour_checker: ColourChecker | str = "ColorChecker24 - After November 2014", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given colour checker. @@ -103,7 +104,7 @@ def plot_single_colour_checker( def plot_multi_colour_checkers( colour_checkers: ColourChecker | str | Sequence[ColourChecker | str], **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot and compares given colour checkers. diff --git a/colour/plotting/colorimetry.py b/colour/plotting/colorimetry.py index 0f52acceff..801536fb30 100644 --- a/colour/plotting/colorimetry.py +++ b/colour/plotting/colorimetry.py @@ -26,9 +26,12 @@ from __future__ import annotations +from functools import reduce + import matplotlib.pyplot as plt import numpy as np -from functools import reduce +from matplotlib.axes import Axes +from matplotlib.figure import Figure from matplotlib.patches import Polygon from colour.algebra import ( @@ -39,9 +42,9 @@ ) from colour.colorimetry import ( CCS_ILLUMINANTS, - SDS_ILLUMINANTS, LIGHTNESS_METHODS, LUMINANCE_METHODS, + SDS_ILLUMINANTS, MultiSpectralDistributions, SpectralDistribution, SpectralShape, @@ -64,13 +67,13 @@ CONSTANTS_COLOUR_STYLE, XYZ_to_plotting_colourspace, artist, - filter_passthrough, filter_cmfs, filter_illuminants, + filter_passthrough, override_style, - render, - plot_single_colour_swatch, plot_multi_functions, + plot_single_colour_swatch, + render, update_settings_collection, ) from colour.utilities import ( @@ -117,7 +120,7 @@ def plot_single_sd( modulate_colours_with_sd_amplitude: bool = False, equalize_sd_amplitude: bool = False, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given spectral distribution. @@ -272,7 +275,7 @@ def plot_multi_sds( | MultiSpectralDistributions, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given spectral distributions. @@ -420,7 +423,7 @@ def plot_multi_sds( min(x_limit_min), max(x_limit_max), min(y_limit_min), - max(y_limit_max) * 1.05, # pyright: ignore + max(y_limit_max) * 1.05, ) settings: Dict[str, Any] = { "axes": axes, @@ -442,7 +445,7 @@ def plot_single_cmfs( MultiSpectralDistributions | str ] = "CIE 1931 2 Degree Standard Observer", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given colour matching functions. @@ -494,7 +497,7 @@ def plot_multi_cmfs( | str | Sequence[MultiSpectralDistributions | str], **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given colour matching functions. @@ -597,7 +600,7 @@ def plot_single_illuminant_sd( MultiSpectralDistributions | str ] = "CIE 1931 2 Degree Standard Observer", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given single illuminant spectral distribution. @@ -661,7 +664,7 @@ def plot_multi_illuminant_sds( | str | Sequence[SpectralDistribution | str], **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given illuminants spectral distributions. @@ -735,7 +738,7 @@ def plot_visible_spectrum( ] = "CIE 1931 2 Degree Standard Observer", out_of_gamut_clipping: bool = True, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the visible colours spectrum using given standard observer *CIE XYZ* colour matching functions. @@ -812,7 +815,7 @@ def plot_visible_spectrum( @override_style() def plot_single_lightness_function( function: Callable | str, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *Lightness* function. @@ -855,7 +858,7 @@ def plot_single_lightness_function( def plot_multi_lightness_functions( functions: Callable | str | Sequence[Callable | str], **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *Lightness* functions. @@ -908,7 +911,7 @@ def plot_multi_lightness_functions( @override_style() def plot_single_luminance_function( function: Callable | str, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *Luminance* function. @@ -950,7 +953,7 @@ def plot_single_luminance_function( def plot_multi_luminance_functions( functions: Callable | str | Sequence[Callable | str], **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *Luminance* functions. @@ -1010,7 +1013,7 @@ def plot_blackbody_spectral_radiance( ] = "CIE 1931 2 Degree Standard Observer", blackbody: str = "VY Canis Major", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given blackbody spectral radiance. @@ -1111,7 +1114,7 @@ def plot_blackbody_colours( MultiSpectralDistributions | str ] = "CIE 1931 2 Degree Standard Observer", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot blackbody colours. diff --git a/colour/plotting/common.py b/colour/plotting/common.py index dc7fdca919..f5131b18c2 100644 --- a/colour/plotting/common.py +++ b/colour/plotting/common.py @@ -6,6 +6,7 @@ - :func:`colour.plotting.colour_style` - :func:`colour.plotting.override_style` +- :func:`colour.plotting.font_scaling` - :func:`colour.plotting.XYZ_to_plotting_colourspace` - :class:`colour.plotting.ColourSwatch` - :func:`colour.plotting.colour_cycle` @@ -29,22 +30,28 @@ import contextlib import functools import itertools +from contextlib import contextmanager +from dataclasses import dataclass, field +from functools import partial + import matplotlib.cm +import matplotlib.font_manager import matplotlib.pyplot as plt import matplotlib.ticker -from mpl_toolkits.mplot3d.axes3d import Axes3D import numpy as np -from dataclasses import dataclass, field -from functools import partial +from cycler import cycler +from matplotlib.axes import Axes from matplotlib.colors import LinearSegmentedColormap +from matplotlib.figure import Figure, SubFigure from matplotlib.patches import Patch +from mpl_toolkits.mplot3d.axes3d import Axes3D from colour.characterisation import CCS_COLOURCHECKERS, ColourChecker from colour.colorimetry import ( - MultiSpectralDistributions, MSDS_CMFS, SDS_ILLUMINANTS, SDS_LIGHT_SOURCES, + MultiSpectralDistributions, SpectralDistribution, ) from colour.hints import ( @@ -52,8 +59,12 @@ ArrayLike, Callable, Dict, + Generator, List, Literal, + LiteralChromaticAdaptationTransform, + LiteralFontScaling, + LiteralRGBColourspace, Mapping, NDArrayFloat, Sequence, @@ -68,10 +79,10 @@ as_float_array, as_int_scalar, attest, + filter_mapping, first_item, is_sibling, is_string, - filter_mapping, optional, runtime_warning, validate_method, @@ -90,6 +101,7 @@ "CONSTANTS_ARROW_STYLE", "colour_style", "override_style", + "font_scaling", "XYZ_to_plotting_colourspace", "ColourSwatch", "colour_cycle", @@ -157,6 +169,22 @@ "colourspace": RGB_COLOURSPACES["sRGB"], } ), + "font": Structure( + { + "size": 10, + "scaling": Structure( + **{ + "xx_small": 0.579, + "x_small": 0.694, + "small": 0.833, + "medium": 1, + "large": 1 / 0.579, + "x_large": 1 / 0.694, + "xx_large": 1 / 0.833, + } + ), + } + ), "opacity": Structure(**{"high": 0.75, "medium": 0.5, "low": 0.25}), "geometry": Structure(**{"long": 5, "medium": 2.5, "short": 1}), "hatch": Structure( @@ -194,6 +222,15 @@ ) """Various defaults settings used across the plotting sub-package.""" +# NOTE: Adding our font scaling items so that they can be tweaked without +# affecting *Matplotplib* ones. +for _scaling, _value in CONSTANTS_COLOUR_STYLE.font.scaling.items(): + matplotlib.font_manager.font_scalings[ + f'{_scaling.replace("_", "-")}-colour-science' + ] = _value + +del _scaling, _value + CONSTANTS_ARROW_STYLE: Structure = Structure( **{ "color": CONSTANTS_COLOUR_STYLE.colour.dark, @@ -281,7 +318,7 @@ def colour_style(use_style: bool = True) -> dict: "lines.markersize": constants.geometry.short * 3, "lines.markeredgewidth": constants.geometry.short * 0.75, # Cycle - "axes.prop_cycle": matplotlib.cycler(color=constants.colour.cycle), + "axes.prop_cycle": cycler(color=constants.colour.cycle), } if use_style: @@ -338,23 +375,47 @@ def wrapped(*args: Any, **kwargs: Any) -> Any: return wrapper +@contextmanager +def font_scaling(scaling: LiteralFontScaling, value: float) -> Generator: + """ + Define a context manager setting temporarily a *Matplotlib* font scaling. + + Parameters + ---------- + scaling + Font scaling to temporarily set. + value + Value to temporarily set the font scaling with. + + Yields + ------ + Generator. + + Examples + -------- + >>> with font_scaling("medium-colour-science", 2): + ... print( + ... matplotlib.font_manager.font_scalings["medium-colour-science"] + ... ) + ... + 2 + >>> print(matplotlib.font_manager.font_scalings["medium-colour-science"]) + 1 + """ + + current_value = matplotlib.font_manager.font_scalings[scaling] + + matplotlib.font_manager.font_scalings[scaling] = value + + yield + + matplotlib.font_manager.font_scalings[scaling] = current_value + + def XYZ_to_plotting_colourspace( XYZ: ArrayLike, illuminant: ArrayLike = RGB_COLOURSPACES["sRGB"].whitepoint, - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", apply_cctf_encoding: bool = True, @@ -461,11 +522,11 @@ class KwargsArtist(TypedDict): Whether to create the figure with an equal aspect ratio. """ - axes: plt.Axes + axes: Axes uniform: bool -def artist(**kwargs: KwargsArtist | Any) -> Tuple[plt.Figure, plt.Axes]: +def artist(**kwargs: KwargsArtist | Any) -> Tuple[Figure, Axes]: """ Return the current figure and its axes or creates a new one. @@ -491,7 +552,13 @@ def artist(**kwargs: KwargsArtist | Any) -> Tuple[plt.Figure, plt.Axes]: return figure, figure.gca() else: - return cast(plt.Figure, plt.gcf()), cast(plt.Axes, axes) + axes = cast(Axes, axes) + figure = axes.figure + + if isinstance(figure, SubFigure): + figure = figure.get_figure() + + return cast(Figure, figure), axes class KwargsCamera(TypedDict): @@ -513,14 +580,14 @@ class KwargsCamera(TypedDict): Matplotlib axes aspect. Default is *equal*. """ - figure: plt.Figure - axes: plt.Axes + figure: Figure + axes: Axes azimuth: float | None elevation: float | None camera_aspect: Literal["equal"] | str -def camera(**kwargs: KwargsCamera | Any) -> Tuple[plt.Figure, Axes3D]: +def camera(**kwargs: KwargsCamera | Any) -> Tuple[Figure, Axes3D]: """ Set the camera settings. @@ -536,7 +603,7 @@ def camera(**kwargs: KwargsCamera | Any) -> Tuple[plt.Figure, Axes3D]: Current figure and axes. """ - figure = cast(plt.Figure, kwargs.get("figure", plt.gcf())) + figure = cast(Figure, kwargs.get("figure", plt.gcf())) axes = cast(Axes3D, kwargs.get("axes", plt.gca())) settings = Structure( @@ -568,6 +635,8 @@ class KwargsRender(TypedDict): show Whether to show the figure and call :func:`matplotlib.pyplot.show` definition. + block + Whether to block on `show`ing the plot. aspect Matplotlib axes aspect. axes_visible @@ -598,10 +667,11 @@ class KwargsRender(TypedDict): Whether to display the *Y* axis ticker. Default is *True*. """ - figure: plt.Figure - axes: plt.Axes + figure: Figure + axes: Axes filename: str show: bool + block: bool aspect: Literal["auto", "equal"] | float axes_visible: bool bounding_box: ArrayLike @@ -617,7 +687,9 @@ class KwargsRender(TypedDict): y_ticker: bool -def render(**kwargs: KwargsRender | Any) -> Tuple[plt.Figure, plt.Axes]: +def render( + **kwargs: KwargsRender | Any, +) -> Tuple[Figure, Axes] | Tuple[Figure, Axes3D]: """ Render the current figure while adjusting various settings such as the bounding box, the title or background transparency. @@ -634,8 +706,8 @@ def render(**kwargs: KwargsRender | Any) -> Tuple[plt.Figure, plt.Axes]: Current figure and axes. """ - figure = cast(plt.Figure, kwargs.get("figure", plt.gcf())) - axes = cast(plt.Axes, kwargs.get("axes", plt.gca())) + figure = cast(Figure, kwargs.get("figure", plt.gcf())) + axes = cast(Axes, kwargs.get("axes", plt.gca())) kwargs = handle_arguments_deprecation( { @@ -648,6 +720,7 @@ def render(**kwargs: KwargsRender | Any) -> Tuple[plt.Figure, plt.Axes]: **{ "filename": None, "show": True, + "block": True, "aspect": None, "axes_visible": True, "bounding_box": None, @@ -680,9 +753,9 @@ def render(**kwargs: KwargsRender | Any) -> Tuple[plt.Figure, plt.Axes]: if settings.y_label: axes.set_ylabel(settings.y_label) if not settings.x_ticker: - axes.set_xticks([]) # pyright: ignore + axes.set_xticks([]) if not settings.y_ticker: - axes.set_yticks([]) # pyright: ignore + axes.set_yticks([]) if settings.legend: axes.legend(ncol=settings.legend_columns) @@ -696,7 +769,7 @@ def render(**kwargs: KwargsRender | Any) -> Tuple[plt.Figure, plt.Axes]: figure.savefig(settings.filename) if settings.show: - plt.show() + plt.show(block=settings.block) return figure, axes @@ -705,10 +778,10 @@ def label_rectangles( labels: Sequence[str], rectangles: Sequence[Patch], rotation: Literal["horizontal", "vertical"] | str = "vertical", - text_size: float = 10, + text_size: float = CONSTANTS_COLOUR_STYLE.font.scaling.medium, offset: ArrayLike | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Add labels above given rectangles. @@ -751,21 +824,19 @@ def label_rectangles( x_m, y_m = 0, 0 for rectangle in rectangles: - x_m = max(x_m, rectangle.get_width()) - y_m = max(y_m, rectangle.get_height()) + x_m = max(x_m, rectangle.get_width()) # pyright: ignore + y_m = max(y_m, rectangle.get_height()) # pyright: ignore for i, rectangle in enumerate(rectangles): - x = rectangle.get_x() - height = rectangle.get_height() - width = rectangle.get_width() - ha = "center" - va = "bottom" + x = rectangle.get_x() # pyright: ignore + height = rectangle.get_height() # pyright: ignore + width = rectangle.get_width() # pyright: ignore axes.text( x + width / 2 + offset[0] * width, height + offset[1] * y_m, labels[i], - ha=ha, - va=va, + ha="center", + va="bottom", rotation=rotation, fontsize=text_size, clip_on=True, @@ -775,7 +846,7 @@ def label_rectangles( return figure, axes -def uniform_axes3d(**kwargs: Any) -> Tuple[plt.Figure, plt.Axes]: +def uniform_axes3d(**kwargs: Any) -> Tuple[Figure, Axes]: """ Set equal aspect ratio to given 3d axes. @@ -934,7 +1005,10 @@ class instance, then the lower, slugified and canonical keys are also def filter_RGB_colourspaces( - filterers: RGB_Colourspace | str | Sequence[RGB_Colourspace | str], + filterers: RGB_Colourspace + | LiteralRGBColourspace + | str + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str], allow_non_siblings: bool = True, ) -> Dict[str, RGB_Colourspace]: """ @@ -1116,7 +1190,7 @@ def update_settings_collection( ) def plot_single_colour_swatch( colour_swatch: ArrayLike | ColourSwatch, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given colour swatch. @@ -1173,7 +1247,7 @@ def plot_multi_colour_swatches( background_colour: ArrayLike = (1.0, 1.0, 1.0), compare_swatches: Literal["Diagonal", "Stacked"] | str | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given colours swatches. @@ -1344,7 +1418,7 @@ def plot_multi_colour_swatches( x_max = x_max * width + x_max * spacing - spacing y_max = offset_Y - axes.patch.set_facecolor(background_colour) + axes.patch.set_facecolor(background_colour) # pyright: ignore if y == 1: bounding_box = [ @@ -1379,7 +1453,7 @@ def plot_single_function( log_y: int | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given function. @@ -1448,7 +1522,7 @@ def plot_multi_functions( log_y: int | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given functions. @@ -1523,8 +1597,8 @@ def plot_multi_functions( plotting_function = axes.loglog - axes.set_xscale("log", base=log_x) # pyright: ignore - axes.set_yscale("log", base=log_y) # pyright: ignore + axes.set_xscale("log", base=log_x) + axes.set_yscale("log", base=log_y) elif log_x is not None: attest(log_x >= 2, "Log base must be equal or greater than 2.") @@ -1571,7 +1645,7 @@ def plot_image( imshow_kwargs: dict | None = None, text_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given image. diff --git a/colour/plotting/corresponding.py b/colour/plotting/corresponding.py index 1049d790cc..531f68de7f 100644 --- a/colour/plotting/corresponding.py +++ b/colour/plotting/corresponding.py @@ -9,7 +9,8 @@ from __future__ import annotations -import matplotlib.pyplot as plt +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.corresponding import ( CorrespondingColourDataset, @@ -19,8 +20,8 @@ from colour.plotting import ( CONSTANTS_COLOUR_STYLE, artist, - plot_chromaticity_diagram_CIE1976UCS, override_style, + plot_chromaticity_diagram_CIE1976UCS, render, ) from colour.utilities import is_numeric @@ -47,7 +48,7 @@ def plot_corresponding_chromaticities_prediction( | str = "Von Kries", corresponding_chromaticities_prediction_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given chromatic adaptation model corresponding chromaticities prediction. diff --git a/colour/plotting/diagrams.py b/colour/plotting/diagrams.py index 436ee2bea1..7c0ffab3ad 100644 --- a/colour/plotting/diagrams.py +++ b/colour/plotting/diagrams.py @@ -4,6 +4,7 @@ Defines the *CIE* chromaticity diagrams plotting objects: +- :func:`colour.plotting.lines_spectral_locus` - :func:`colour.plotting.plot_chromaticity_diagram_CIE1931` - :func:`colour.plotting.plot_chromaticity_diagram_CIE1960UCS` - :func:`colour.plotting.plot_chromaticity_diagram_CIE1976UCS` @@ -15,27 +16,30 @@ from __future__ import annotations import bisect -import matplotlib.pyplot as plt + import numpy as np +from matplotlib.axes import Axes from matplotlib.collections import LineCollection +from matplotlib.figure import Figure from matplotlib.patches import Polygon from colour.algebra import normalise_maximum, normalise_vector from colour.colorimetry import ( - MultiSpectralDistributions, SDS_ILLUMINANTS, + MultiSpectralDistributions, SpectralDistribution, sd_to_XYZ, sds_and_msds_to_sds, ) +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.hints import ( Any, ArrayLike, - Dict, Callable, + Dict, List, Literal, - NDArrayFloat, + NDArray, Sequence, Tuple, cast, @@ -48,12 +52,14 @@ XYZ_to_Luv, XYZ_to_UCS, XYZ_to_xy, + xy_to_Luv_uv, + xy_to_UCS_uv, xy_to_XYZ, ) from colour.notation import HEX_to_RGB from colour.plotting import ( - CONSTANTS_COLOUR_STYLE, CONSTANTS_ARROW_STYLE, + CONSTANTS_COLOUR_STYLE, XYZ_to_plotting_colourspace, artist, filter_cmfs, @@ -63,14 +69,15 @@ update_settings_collection, ) from colour.utilities import ( + CanonicalMapping, as_float_array, domain_range_scale, first_item, - is_string, optional, tsplit, tstack, validate_method, + zeros, ) __author__ = "Colour Developers" @@ -81,6 +88,9 @@ __status__ = "Production" __all__ = [ + "METHODS_CHROMATICITY_DIAGRAM", + "LABELS_CHROMATICITY_DIAGRAM_DEFAULT", + "lines_spectral_locus", "plot_spectral_locus", "plot_chromaticity_diagram_colours", "plot_chromaticity_diagram", @@ -93,6 +103,269 @@ "plot_sds_in_chromaticity_diagram_CIE1976UCS", ] +METHODS_CHROMATICITY_DIAGRAM: CanonicalMapping = CanonicalMapping( + { + "CIE 1931": { + "XYZ_to_ij": lambda a, *args: XYZ_to_xy(a), # noqa: ARG005 + "ij_to_XYZ": lambda a, *args: xy_to_XYZ(a), # noqa: ARG005 + "xy_to_ij": lambda a, *args: a, # noqa: ARG005 + "uv_to_ij": lambda a, *args: UCS_uv_to_xy(a), # noqa: ARG005 + }, + "CIE 1960 UCS": { + "XYZ_to_ij": lambda a, *args: UCS_to_uv( # noqa: ARG005 + XYZ_to_UCS(a) + ), + "ij_to_XYZ": lambda a, *args: xy_to_XYZ( # noqa: ARG005 + UCS_uv_to_xy(a) + ), + "xy_to_ij": lambda a, *args: xy_to_UCS_uv(a), # noqa: ARG005 + "uv_to_ij": lambda a, *args: a, # noqa: ARG005 + }, + "CIE 1976 UCS": { + "XYZ_to_ij": lambda a, *args: Luv_to_uv( + XYZ_to_Luv(a, *args), *args + ), + "ij_to_XYZ": lambda a, *args: xy_to_XYZ( # noqa: ARG005 + Luv_uv_to_xy(a) + ), + "xy_to_ij": lambda a, *args: xy_to_Luv_uv(a), # noqa: ARG005 + "uv_to_ij": lambda a, *args: xy_to_Luv_uv( # noqa: ARG005 + UCS_uv_to_xy(a) + ), + }, + } +) +"""Chromaticity diagram conversion methods.""" + +LABELS_CHROMATICITY_DIAGRAM_DEFAULT: CanonicalMapping = CanonicalMapping( + { + "CIE 1931": ( + 390, + 460, + 470, + 480, + 490, + 500, + 510, + 520, + 540, + 560, + 580, + 600, + 620, + 700, + ), + "CIE 1960 UCS": ( + 420, + 440, + 450, + 460, + 470, + 480, + 490, + 500, + 510, + 520, + 530, + 540, + 550, + 560, + 570, + 580, + 590, + 600, + 610, + 620, + 630, + 645, + 680, + ), + "CIE 1976 UCS": ( + 420, + 440, + 450, + 460, + 470, + 480, + 490, + 500, + 510, + 520, + 530, + 540, + 550, + 560, + 570, + 580, + 590, + 600, + 610, + 620, + 630, + 645, + 680, + ), + } +) +"""*Chromaticity Diagram* default labels.""" + + +def lines_spectral_locus( + cmfs: MultiSpectralDistributions + | str + | Sequence[ + MultiSpectralDistributions | str + ] = "CIE 1931 2 Degree Standard Observer", + labels: Sequence | None = None, + method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"] + | str = "CIE 1931", +) -> Tuple[NDArray, NDArray]: + """ + Return the *Spectral Locus* line vertices, i.e. positions, normals and + colours, according to given method. + + Parameters + ---------- + cmfs + Standard observer colour matching functions used for computing the + spectral locus boundaries. ``cmfs`` can be of any type or form + supported by the :func:`colour.plotting.common.filter_cmfs` definition. + labels + Array of wavelength labels used to customise which labels will be drawn + around the spectral locus. Passing an empty array will result in no + wavelength labels being drawn. + method + *Chromaticity Diagram* method. + + Returns + ------- + :class:`tuple` + Tuple of *Spectral Locus* vertices and wavelength labels vertices. + + Examples + -------- + >>> lines = lines_spectral_locus() + >>> len(lines) + 2 + >>> lines[0].dtype + dtype([('position', '>> lines[1].dtype + dtype([('position', '= 0 else wavelengths[index] + right = ( + wavelengths[index] if index < len(wavelengths) else wavelengths[-1] + ) + + dx = wl_ij_cmfs[right][0] - wl_ij_cmfs[left][0] + dy = wl_ij_cmfs[right][1] - wl_ij_cmfs[left][1] + + direction = np.array([-dy, dx]) + + normal = ( + np.array([-dy, dx]) + if np.dot( + normalise_vector(ij_l - equal_energy), + normalise_vector(direction), + ) + > 0 + else np.array([dy, -dx]) + ) + normal = normalise_vector(normal) + + ij_n.append([[i, j], [i + normal[0] / 50, j + normal[1] / 50]]) + normal_l.append([normal, normal]) + colour_l.append([ij_l, ij_l]) + + ij_w = as_float_array(ij_n).reshape([-1, 2]) + normal_w = as_float_array(normal_l).reshape([-1, 2]) + colours_w = as_float_array(colour_l).reshape([-1, 2]) + + colour_w = normalise_maximum( + XYZ_to_plotting_colourspace( + np.reshape(ij_to_XYZ(colours_w, illuminant), (-1, 3)) + ), + axis=-1, + ) + + lines_w = zeros( + ij_w.shape[0], + [ + ("position", DTYPE_FLOAT_DEFAULT, 2), + ("normal", DTYPE_FLOAT_DEFAULT, 2), + ("colour", DTYPE_FLOAT_DEFAULT, 3), + ], # pyright: ignore + ) + + lines_w["position"] = ij_w + lines_w["normal"] = normal_w + lines_w["colour"] = colour_w + + return lines_sl, lines_w + @override_style() def plot_spectral_locus( @@ -107,7 +380,7 @@ def plot_spectral_locus( method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"] | str = "CIE 1931", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Spectral Locus* according to given method. @@ -151,14 +424,18 @@ def plot_spectral_locus( :alt: plot_spectral_locus """ - method = validate_method( - method, ("CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS") - ) + method = validate_method(method, tuple(METHODS_CHROMATICITY_DIAGRAM)) spectral_locus_colours = optional( spectral_locus_colours, CONSTANTS_COLOUR_STYLE.colour.dark ) + labels = optional( + spectral_locus_labels, LABELS_CHROMATICITY_DIAGRAM_DEFAULT[method] + ) + + use_RGB_colours = str(spectral_locus_colours).upper() == "RGB" + settings: Dict[str, Any] = {"uniform": True} settings.update(kwargs) @@ -168,198 +445,58 @@ def plot_spectral_locus( MultiSpectralDistributions, first_item(filter_cmfs(cmfs).values()) ) - illuminant = CONSTANTS_COLOUR_STYLE.colour.colourspace.whitepoint - - wavelengths = list(cmfs.wavelengths) - equal_energy = np.array([1 / 3] * 2) - - labels = () - if method == "cie 1931": - ij = XYZ_to_xy(cmfs.values) - labels = optional( - spectral_locus_labels, - ( - 390, - 460, - 470, - 480, - 490, - 500, - 510, - 520, - 540, - 560, - 580, - 600, - 620, - 700, - ), - ) - elif method == "cie 1960 ucs": - ij = UCS_to_uv(XYZ_to_UCS(cmfs.values)) - labels = optional( - spectral_locus_labels, - ( - 420, - 440, - 450, - 460, - 470, - 480, - 490, - 500, - 510, - 520, - 530, - 540, - 550, - 560, - 570, - 580, - 590, - 600, - 610, - 620, - 630, - 645, - 680, - ), - ) - elif method == "cie 1976 ucs": - ij = Luv_to_uv(XYZ_to_Luv(cmfs.values, illuminant), illuminant) - labels = optional( - spectral_locus_labels, - ( - 420, - 440, - 450, - 460, - 470, - 480, - 490, - 500, - 510, - 520, - 530, - 540, - 550, - 560, - 570, - 580, - 590, - 600, - 610, - 620, - 630, - 645, - 680, - ), - ) - - pl_ij = np.reshape( - tstack( - [ - np.linspace(ij[0][0], ij[-1][0], 20), - np.linspace(ij[0][1], ij[-1][1], 20), - ] - ), - (-1, 1, 2), + lines_sl, lines_w = lines_spectral_locus( + cmfs, spectral_locus_labels, method ) - sl_ij = np.copy(ij).reshape(-1, 1, 2) - purple_line_colours: ArrayLike | str | None - if str(spectral_locus_colours).upper() == "RGB": - spectral_locus_colours = normalise_maximum( - XYZ_to_plotting_colourspace(cmfs.values), axis=-1 - ) - - if method == "cie 1931": - XYZ = xy_to_XYZ(pl_ij) - elif method == "cie 1960 ucs": - XYZ = xy_to_XYZ(UCS_uv_to_xy(pl_ij)) - elif method == "cie 1976 ucs": - XYZ = xy_to_XYZ(Luv_uv_to_xy(pl_ij)) - - purple_line_colours = normalise_maximum( - XYZ_to_plotting_colourspace(np.reshape(XYZ, (-1, 3))), axis=-1 - ) - else: - purple_line_colours = spectral_locus_colours - - for slp_ij, slp_colours in ( - (pl_ij, purple_line_colours), - (sl_ij, spectral_locus_colours), - ): - line_collection = LineCollection( - np.concatenate([slp_ij[:-1], slp_ij[1:]], axis=1), - colors=slp_colours, + axes.add_collection( + LineCollection( + np.concatenate( + [lines_sl["position"][:-1], lines_sl["position"][1:]], + axis=1, # pyright: ignore + ).reshape([-1, 2, 2]), + colors=lines_sl["colour"] + if use_RGB_colours + else spectral_locus_colours, alpha=spectral_locus_opacity, - zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_scatter, - ) - axes.add_collection(line_collection) - - wl_ij = dict(zip(wavelengths, ij)) - for label in labels: - ij_l = wl_ij.get(label) - - if ij_l is None: - continue - - ij_l = as_float_array([ij_l]) - i, j = tsplit(ij_l) - - index = bisect.bisect(wavelengths, label) - left = wavelengths[index - 1] if index >= 0 else wavelengths[index] - right = ( - wavelengths[index] if index < len(wavelengths) else wavelengths[-1] - ) - - dx = wl_ij[right][0] - wl_ij[left][0] - dy = wl_ij[right][1] - wl_ij[left][1] - - direction = np.array([-dy, dx]) - - normal = ( - np.array([-dy, dx]) - if np.dot( - normalise_vector(ij_l - equal_energy), - normalise_vector(direction), - ) - > 0 - else np.array([dy, -dx]) - ) - normal = normalise_vector(normal) / 30 - - label_colour = ( - spectral_locus_colours - if is_string(spectral_locus_colours) - else cast(NDArrayFloat, spectral_locus_colours)[index] + zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line, ) - axes.plot( - (i, i + normal[0] * 0.75), - (j, j + normal[1] * 0.75), - color=label_colour, + ) + axes.add_collection( + LineCollection( + lines_w["position"].reshape([-1, 2, 2]), # pyright: ignore + colors=lines_w["colour"][::2] + if use_RGB_colours + else spectral_locus_colours, alpha=spectral_locus_opacity, zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line, ) + ) + + for i, label in enumerate( + [label for label in labels if label in cmfs.wavelengths] + ): + positions = lines_w["position"][::2] + normals = lines_w["normal"][::2] + colours = lines_w["colour"][::2] axes.plot( - i, - j, + positions[i, 0], + positions[i, 1], "o", - color=label_colour, + color=colours[i] if use_RGB_colours else spectral_locus_colours, alpha=spectral_locus_opacity, zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line, ) axes.text( - i + normal[0], - j + normal[1], + positions[i, 0] + normals[i, 0] / 50 * 1.25, + positions[i, 1] + normals[i, 1] / 50 * 1.25, label, clip_on=True, - ha="left" if normal[0] >= 0 else "right", + ha="left" if lines_w["normal"][::2][i, 0] >= 0 else "right", va="center", - fontdict={"size": "small"}, + fontsize="x-small-colour-science", zorder=CONSTANTS_COLOUR_STYLE.zorder.background_label, ) @@ -383,7 +520,7 @@ def plot_chromaticity_diagram_colours( method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"] | str = "CIE 1931", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Chromaticity Diagram* colours according to given method. @@ -448,14 +585,9 @@ def plot_chromaticity_diagram_colours( illuminant = CONSTANTS_COLOUR_STYLE.colour.colourspace.whitepoint - if method == "cie 1931": - spectral_locus = XYZ_to_xy(cmfs.values) - elif method == "cie 1960 ucs": - spectral_locus = UCS_to_uv(XYZ_to_UCS(cmfs.values)) - elif method == "cie 1976 ucs": - spectral_locus = Luv_to_uv( - XYZ_to_Luv(cmfs.values, illuminant), illuminant - ) + XYZ_to_ij = METHODS_CHROMATICITY_DIAGRAM[method]["XYZ_to_ij"] + + spectral_locus = XYZ_to_ij(cmfs.values, illuminant) use_RGB_diagram_colours = str(diagram_colours).upper() == "RGB" if use_RGB_diagram_colours: @@ -464,15 +596,10 @@ def plot_chromaticity_diagram_colours( ) ij = tstack([ii, jj]) - if method == "cie 1931": - XYZ = xy_to_XYZ(ij) - elif method == "cie 1960 ucs": - XYZ = xy_to_XYZ(UCS_uv_to_xy(ij)) - elif method == "cie 1976 ucs": - XYZ = xy_to_XYZ(Luv_uv_to_xy(ij)) + ij_to_XYZ = METHODS_CHROMATICITY_DIAGRAM[method]["ij_to_XYZ"] diagram_colours = normalise_maximum( - XYZ_to_plotting_colourspace(XYZ, illuminant), axis=-1 + XYZ_to_plotting_colourspace(ij_to_XYZ(ij), illuminant), axis=-1 ) polygon = Polygon( @@ -520,7 +647,7 @@ def plot_chromaticity_diagram( method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"] | str = "CIE 1931", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Chromaticity Diagram* according to given method. @@ -592,8 +719,10 @@ def plot_chromaticity_diagram( if method == "cie 1931": x_label, y_label = "CIE x", "CIE y" + elif method == "cie 1960 ucs": x_label, y_label = "CIE u", "CIE v" + elif method == "cie 1976 ucs": x_label, y_label = ( "CIE u'", @@ -627,7 +756,7 @@ def plot_chromaticity_diagram_CIE1931( show_diagram_colours: bool = True, show_spectral_locus: bool = True, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *CIE 1931 Chromaticity Diagram*. @@ -683,7 +812,7 @@ def plot_chromaticity_diagram_CIE1960UCS( show_diagram_colours: bool = True, show_spectral_locus: bool = True, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *CIE 1960 UCS Chromaticity Diagram*. @@ -739,7 +868,7 @@ def plot_chromaticity_diagram_CIE1976UCS( show_diagram_colours: bool = True, show_spectral_locus: bool = True, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *CIE 1976 UCS Chromaticity Diagram*. @@ -801,7 +930,7 @@ def plot_sds_in_chromaticity_diagram( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given spectral distribution chromaticity coordinates into the *Chromaticity Diagram* using given method. @@ -921,39 +1050,15 @@ def plot_sds_in_chromaticity_diagram( chromaticity_diagram_callable(**settings) - if method == "cie 1931": - - def XYZ_to_ij(XYZ: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE XYZ* tristimulus values to *ij* chromaticity - coordinates. - """ - - return XYZ_to_xy(XYZ) + XYZ_to_ij = METHODS_CHROMATICITY_DIAGRAM[method]["XYZ_to_ij"] + if method == "cie 1931": bounding_box = (-0.1, 0.9, -0.1, 0.9) - elif method == "cie 1960 ucs": - - def XYZ_to_ij(XYZ: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE XYZ* tristimulus values to *ij* chromaticity - coordinates. - """ - - return UCS_to_uv(XYZ_to_UCS(XYZ)) + elif method == "cie 1960 ucs": bounding_box = (-0.1, 0.7, -0.2, 0.6) elif method == "cie 1976 ucs": - - def XYZ_to_ij(XYZ: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE XYZ* tristimulus values to *ij* chromaticity - coordinates. - """ - - return Luv_to_uv(XYZ_to_Luv(XYZ)) - bounding_box = (-0.1, 0.7, -0.1, 0.7) annotate_settings_collection = [ @@ -1024,7 +1129,7 @@ def XYZ_to_ij(XYZ: NDArrayFloat) -> NDArrayFloat: XYZ_to_plotting_colourspace(XYZ), 0, 1 ) - ij = XYZ_to_ij(XYZ) + ij = cast(tuple[float, float], XYZ_to_ij(XYZ)) axes.plot(ij[0], ij[1], **plot_settings) @@ -1055,7 +1160,7 @@ def plot_sds_in_chromaticity_diagram_CIE1931( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given spectral distribution chromaticity coordinates into the *CIE 1931 Chromaticity Diagram*. @@ -1165,7 +1270,7 @@ def plot_sds_in_chromaticity_diagram_CIE1960UCS( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given spectral distribution chromaticity coordinates into the *CIE 1960 UCS Chromaticity Diagram*. @@ -1276,7 +1381,7 @@ def plot_sds_in_chromaticity_diagram_CIE1976UCS( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given spectral distribution chromaticity coordinates into the *CIE 1976 UCS Chromaticity Diagram*. diff --git a/colour/plotting/graph.py b/colour/plotting/graph.py index 5a7e57dab2..b4b24f3f7f 100644 --- a/colour/plotting/graph.py +++ b/colour/plotting/graph.py @@ -14,7 +14,7 @@ CONVERSION_GRAPH_NODE_LABELS, describe_conversion_path, ) -from colour.hints import Literal +from colour.hints import Literal, cast from colour.utilities import required, validate_method __author__ = "Colour Developers" @@ -39,7 +39,7 @@ def plot_automatic_colour_conversion_graph( ) -> AGraph: # pyright: ignore # noqa: F821 """ Plot *Colour* automatic colour conversion graph using - `Graphviz `__ and + `Graphviz `__ and `pyraphviz `__. Parameters @@ -88,7 +88,9 @@ def plot_automatic_colour_conversion_graph( # TODO: Investigate API to trigger the conversion graph build. describe_conversion_path("RGB", "RGB", print_callable=lambda x: x) - agraph = nx.nx_agraph.to_agraph(colour.graph.CONVERSION_GRAPH) + agraph = nx.nx_agraph.to_agraph( + cast(nx.DiGraph, colour.graph.CONVERSION_GRAPH) + ) for node in agraph.nodes(): node.attr.update(label=CONVERSION_GRAPH_NODE_LABELS[node.name]) diff --git a/colour/plotting/models.py b/colour/plotting/models.py index 4cfea6b3f9..fa56ead1bc 100644 --- a/colour/plotting/models.py +++ b/colour/plotting/models.py @@ -4,6 +4,7 @@ Defines the colour models plotting objects: +- :func:`colour.plotting.lines_pointer_gamut` - :func:`colour.plotting.\ plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931` - :func:`colour.plotting.\ @@ -42,18 +43,22 @@ from __future__ import annotations -import matplotlib.pyplot as plt import numpy as np import scipy.optimize +from matplotlib.axes import Axes +from matplotlib.collections import LineCollection +from matplotlib.figure import Figure from matplotlib.patches import Ellipse from matplotlib.path import Path +from colour.adaptation import chromatic_adaptation_VonKries +from colour.algebra import normalise_maximum from colour.colorimetry import MultiSpectralDistributions -from colour.constants import EPSILON +from colour.constants import DTYPE_FLOAT_DEFAULT, EPSILON from colour.geometry import ( - point_at_angle_on_ellipse, ellipse_coefficients_canonical_form, ellipse_fitting, + point_at_angle_on_ellipse, ) from colour.graph import convert from colour.hints import ( @@ -63,47 +68,46 @@ Dict, List, Literal, + LiteralColourspaceModel, + LiteralRGBColourspace, NDArrayFloat, Sequence, Tuple, cast, ) from colour.models import ( + CCS_ILLUMINANT_POINTER_GAMUT, + CCS_POINTER_GAMUT_BOUNDARY, + CCTF_DECODINGS, + CCTF_ENCODINGS, COLOURSPACE_MODELS_AXIS_LABELS, COLOURSPACE_MODELS_DOMAIN_RANGE_SCALE_1_TO_REFERENCE, - CCTF_ENCODINGS, - CCTF_DECODINGS, - LCHab_to_Lab, - Lab_to_XYZ, - Luv_to_uv, DATA_MACADAM_1942_ELLIPSES, - CCS_POINTER_GAMUT_BOUNDARY, DATA_POINTER_GAMUT_VOLUME, - CCS_ILLUMINANT_POINTER_GAMUT, + Lab_to_XYZ, + LCHab_to_Lab, RGB_Colourspace, RGB_to_RGB, RGB_to_XYZ, - UCS_to_uv, - XYZ_to_Luv, XYZ_to_RGB, - XYZ_to_UCS, XYZ_to_xy, - xy_to_Luv_uv, - xy_to_UCS_uv, + xy_to_XYZ, ) from colour.plotting import ( CONSTANTS_COLOUR_STYLE, - plot_chromaticity_diagram_CIE1931, + METHODS_CHROMATICITY_DIAGRAM, + XYZ_to_plotting_colourspace, artist, - plot_chromaticity_diagram_CIE1960UCS, - plot_chromaticity_diagram_CIE1976UCS, colour_cycle, colour_style, + filter_cmfs, filter_passthrough, filter_RGB_colourspaces, - filter_cmfs, - plot_multi_functions, override_style, + plot_chromaticity_diagram_CIE1931, + plot_chromaticity_diagram_CIE1960UCS, + plot_chromaticity_diagram_CIE1976UCS, + plot_multi_functions, render, update_settings_collection, ) @@ -118,6 +122,7 @@ optional, tsplit, validate_method, + zeros, ) __author__ = "Colour Developers" @@ -130,6 +135,7 @@ __all__ = [ "COLOURSPACE_MODELS_AXIS_ORDER", "colourspace_model_axis_reorder", + "lines_pointer_gamut", "plot_pointer_gamut", "plot_RGB_colourspaces_in_chromaticity_diagram", "plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931", @@ -157,28 +163,35 @@ "CAM16LCD": (1, 2, 0), "CAM16SCD": (1, 2, 0), "CAM16UCS": (1, 2, 0), - "CIE XYZ": (0, 1, 2), - "CIE xyY": (0, 1, 2), - "CIE Lab": (1, 2, 0), "CIE LCHab": (1, 2, 0), - "CIE Luv": (1, 2, 0), "CIE LCHuv": (1, 2, 0), + "CIE Lab": (1, 2, 0), + "CIE Luv": (1, 2, 0), "CIE UCS": (0, 1, 2), "CIE UVW": (1, 2, 0), + "CIE XYZ": (0, 1, 2), + "CIE xyY": (0, 1, 2), "DIN99": (1, 2, 0), + "HCL": (0, 1, 2), + "HSL": (0, 1, 2), + "HSV": (0, 1, 2), "Hunter Lab": (1, 2, 0), "Hunter Rdab": (1, 2, 0), "ICaCb": (1, 2, 0), "ICtCp": (1, 2, 0), - "IPT": (1, 2, 0), + "IHLS": (0, 2, 1), "IPT Ragoo 2021": (1, 2, 0), + "IPT": (1, 2, 0), "IgPgTg": (1, 2, 0), "Jzazbz": (1, 2, 0), "OSA UCS": (1, 2, 0), "Oklab": (1, 2, 0), + "RGB": (0, 1, 2), + "YCbCr": (1, 2, 0), + "YCoCg": (1, 2, 0), + "Yrg": (1, 2, 0), "hdr-CIELAB": (1, 2, 0), "hdr-IPT": (1, 2, 0), - "Yrg": (1, 2, 0), } ) """Colourspace models axis order.""" @@ -186,37 +199,7 @@ def colourspace_model_axis_reorder( a: ArrayLike, - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE LCHab", - "CIE Luv", - "CIE LCHuv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IPT Ragoo 2021", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - "Yrg", - ] - | str, + model: LiteralColourspaceModel | str, direction: Literal["Forward", "Inverse"] | str = "Forward", ) -> NDArrayFloat: """ @@ -276,6 +259,97 @@ def colourspace_model_axis_reorder( return a[..., indexes] +def lines_pointer_gamut( + method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"] + | str = "CIE 1931" +): + """ + Return the *Pointer's Gamut* line vertices, i.e. positions, normals and + colours, according to given method. + + Parameters + ---------- + method + *Chromaticity Diagram* method. + + Returns + ------- + :class:`tuple` + Tuple of *Pointer's Gamut* boundary and volume vertices. + + Examples + -------- + >>> lines = lines_pointer_gamut() + >>> len(lines) + 2 + >>> lines[0].dtype + dtype([('position', '>> lines[1].dtype + dtype([('position', ' Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot *Pointer's Gamut* according to given method. @@ -309,7 +383,7 @@ def plot_pointer_gamut( Examples -------- - >>> plot_pointer_gamut() # doctest: +ELLIPSIS + >>> plot_pointer_gamut(pointer_gamut_colours="RGB") # doctest: +ELLIPSIS (
, <...Axes...>) .. image:: ../_static/Plotting_Plot_Pointer_Gamut.png @@ -324,6 +398,9 @@ def plot_pointer_gamut( pointer_gamut_colours = optional( pointer_gamut_colours, CONSTANTS_COLOUR_STYLE.colour.dark ) + + use_RGB_colours = str(pointer_gamut_colours).upper() == "RGB" + pointer_gamut_opacity = optional( pointer_gamut_opacity, CONSTANTS_COLOUR_STYLE.opacity.high ) @@ -333,93 +410,33 @@ def plot_pointer_gamut( _figure, axes = artist(**settings) - if method == "cie 1931": - - def XYZ_to_ij( - XYZ: NDArrayFloat, *args: Any # noqa: ARG001 - ) -> NDArrayFloat: - """ - Convert given *CIE XYZ* tristimulus values to *ij* chromaticity - coordinates. - """ - - return XYZ_to_xy(XYZ) - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy - - elif method == "cie 1960 ucs": - - def XYZ_to_ij( - XYZ: NDArrayFloat, *args: Any # noqa: ARG001 - ) -> NDArrayFloat: - """ - Convert given *CIE XYZ* tristimulus values to *ij* chromaticity - coordinates. - """ - - return UCS_to_uv(XYZ_to_UCS(XYZ)) - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy_to_UCS_uv(xy) - - elif method == "cie 1976 ucs": - - def XYZ_to_ij(XYZ: NDArrayFloat, *args: Any) -> NDArrayFloat: - """ - Convert given *CIE XYZ* tristimulus values to *ij* chromaticity - coordinates. - """ - - return Luv_to_uv(XYZ_to_Luv(XYZ, *args), *args) - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy_to_Luv_uv(xy) - - ij = xy_to_ij(CCS_POINTER_GAMUT_BOUNDARY) - axes.plot( - ij[..., 0], - ij[..., 1], - label="Pointer's Gamut", - color=pointer_gamut_colours, - alpha=pointer_gamut_opacity, - zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, - ) - axes.plot( - (ij[-1][0], ij[0][0]), - (ij[-1][1], ij[0][1]), - color=pointer_gamut_colours, - alpha=pointer_gamut_opacity, - zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, - ) - - XYZ = Lab_to_XYZ( - LCHab_to_Lab(DATA_POINTER_GAMUT_VOLUME), CCS_ILLUMINANT_POINTER_GAMUT + lines_b, lines_v = lines_pointer_gamut(method) + + axes.add_collection( + LineCollection( + np.concatenate( + [lines_b["position"][:-1], lines_b["position"][1:]], + axis=1, # pyright: ignore + ).reshape([-1, 2, 2]), + colors=lines_b["colour"] + if use_RGB_colours + else pointer_gamut_colours, + alpha=pointer_gamut_opacity, + zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, + ) ) - ij = XYZ_to_ij(XYZ, CCS_ILLUMINANT_POINTER_GAMUT) scatter_settings = { "alpha": pointer_gamut_opacity / 2, - "color": pointer_gamut_colours, + "c": lines_v["colour"] if use_RGB_colours else pointer_gamut_colours, "marker": "+", "zorder": CONSTANTS_COLOUR_STYLE.zorder.foreground_scatter, } - axes.scatter(ij[..., 0], ij[..., 1], **scatter_settings) + axes.scatter( + lines_v["position"][..., 0], + lines_v["position"][..., 1], + **scatter_settings, + ) settings.update({"axes": axes}) settings.update(kwargs) @@ -429,7 +446,10 @@ def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: @override_style() def plot_RGB_colourspaces_in_chromaticity_diagram( - colourspaces: RGB_Colourspace | str | Sequence[RGB_Colourspace | str], + colourspaces: RGB_Colourspace + | LiteralRGBColourspace + | str + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str], cmfs: MultiSpectralDistributions | str | Sequence[ @@ -443,7 +463,7 @@ def plot_RGB_colourspaces_in_chromaticity_diagram( chromatically_adapt: bool = False, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspaces in the *Chromaticity Diagram* according to given method. @@ -546,42 +566,17 @@ def plot_RGB_colourspaces_in_chromaticity_diagram( plot_pointer_gamut(**settings) - if method == "cie 1931": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy + xy_to_ij = METHODS_CHROMATICITY_DIAGRAM[method]["xy_to_ij"] + if method == "cie 1931": x_limit_min, x_limit_max = [-0.1], [0.9] y_limit_min, y_limit_max = [-0.1], [0.9] elif method == "cie 1960 ucs": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy_to_UCS_uv(xy) - x_limit_min, x_limit_max = [-0.1], [0.7] y_limit_min, y_limit_max = [-0.2], [0.6] elif method == "cie 1976 ucs": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy_to_Luv_uv(xy) - x_limit_min, x_limit_max = [-0.1], [0.7] y_limit_min, y_limit_max = [-0.1], [0.7] @@ -665,7 +660,10 @@ def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: @override_style() def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931( - colourspaces: RGB_Colourspace | str | Sequence[RGB_Colourspace | str], + colourspaces: RGB_Colourspace + | LiteralRGBColourspace + | str + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str], cmfs: MultiSpectralDistributions | str | Sequence[ @@ -679,7 +677,7 @@ def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931( chromatically_adapt: bool = False, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspaces in the *CIE 1931 Chromaticity Diagram*. @@ -757,7 +755,10 @@ def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931( @override_style() def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS( - colourspaces: RGB_Colourspace | str | Sequence[RGB_Colourspace | str], + colourspaces: RGB_Colourspace + | LiteralRGBColourspace + | str + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str], cmfs: MultiSpectralDistributions | str | Sequence[ @@ -771,7 +772,7 @@ def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS( chromatically_adapt: bool = False, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspaces in the *CIE 1960 UCS Chromaticity Diagram*. @@ -850,7 +851,10 @@ def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS( @override_style() def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS( - colourspaces: RGB_Colourspace | str | Sequence[RGB_Colourspace | str], + colourspaces: RGB_Colourspace + | LiteralRGBColourspace + | str + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str], cmfs: MultiSpectralDistributions | str | Sequence[ @@ -864,7 +868,7 @@ def plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS( chromatically_adapt: bool = False, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspaces in the *CIE 1976 UCS Chromaticity Diagram*. @@ -946,7 +950,7 @@ def plot_RGB_chromaticities_in_chromaticity_diagram( RGB: ArrayLike, colourspace: RGB_Colourspace | str - | Sequence[RGB_Colourspace | str] = "sRGB", + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str] = "sRGB", chromaticity_diagram_callable: Callable = ( plot_RGB_colourspaces_in_chromaticity_diagram ), @@ -954,7 +958,7 @@ def plot_RGB_chromaticities_in_chromaticity_diagram( | str = "CIE 1931", scatter_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspace array in the *Chromaticity Diagram* according to given method. @@ -1063,16 +1067,9 @@ def plot_RGB_chromaticities_in_chromaticity_diagram( XYZ = RGB_to_XYZ(RGB, colourspace) - if method == "cie 1931": - ij = XYZ_to_xy(XYZ) + XYZ_to_ij = METHODS_CHROMATICITY_DIAGRAM[method]["XYZ_to_ij"] - elif method == "cie 1960 ucs": - ij = UCS_to_uv(XYZ_to_UCS(XYZ)) - - elif method == "cie 1976 ucs": - ij = Luv_to_uv( - XYZ_to_Luv(XYZ, colourspace.whitepoint), colourspace.whitepoint - ) + ij = XYZ_to_ij(XYZ, colourspace.whitepoint) axes.scatter(ij[..., 0], ij[..., 1], **scatter_settings) @@ -1087,13 +1084,13 @@ def plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931( RGB: ArrayLike, colourspace: RGB_Colourspace | str - | Sequence[RGB_Colourspace | str] = "sRGB", + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str] = "sRGB", chromaticity_diagram_callable_CIE1931: Callable = ( plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931 ), scatter_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspace array in the *CIE 1931 Chromaticity Diagram*. @@ -1165,13 +1162,13 @@ def plot_RGB_chromaticities_in_chromaticity_diagram_CIE1960UCS( RGB: ArrayLike, colourspace: RGB_Colourspace | str - | Sequence[RGB_Colourspace | str] = "sRGB", + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str] = "sRGB", chromaticity_diagram_callable_CIE1960UCS: Callable = ( plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS ), scatter_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspace array in the *CIE 1960 UCS Chromaticity Diagram*. @@ -1245,13 +1242,13 @@ def plot_RGB_chromaticities_in_chromaticity_diagram_CIE1976UCS( RGB: ArrayLike, colourspace: RGB_Colourspace | str - | Sequence[RGB_Colourspace | str] = "sRGB", + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str] = "sRGB", chromaticity_diagram_callable_CIE1976UCS: Callable = ( plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS ), scatter_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspace array in the *CIE 1976 UCS Chromaticity Diagram*. @@ -1349,35 +1346,7 @@ def ellipses_MacAdam1942( method, ("CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS") ) - if method == "cie 1931": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy - - elif method == "cie 1960 ucs": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy_to_UCS_uv(xy) - - elif method == "cie 1976 ucs": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy_to_Luv_uv(xy) + xy_to_ij = METHODS_CHROMATICITY_DIAGRAM[method]["xy_to_ij"] x, y, _a, _b, _theta, a, b, theta = tsplit(DATA_MACADAM_1942_ELLIPSES) @@ -1403,7 +1372,7 @@ def plot_ellipses_MacAdam1942_in_chromaticity_diagram( chromaticity_diagram_clipping: bool = False, ellipse_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot *MacAdam (1942) Ellipses (Observer PGN)* in the *Chromaticity Diagram* according to given method. @@ -1526,7 +1495,7 @@ def plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1931( chromaticity_diagram_clipping: bool = False, ellipse_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot *MacAdam (1942) Ellipses (Observer PGN)* in the *CIE 1931 Chromaticity Diagram*. @@ -1590,7 +1559,7 @@ def plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1960UCS( chromaticity_diagram_clipping: bool = False, ellipse_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot *MacAdam (1942) Ellipses (Observer PGN)* in the *CIE 1960 UCS Chromaticity Diagram*. @@ -1655,7 +1624,7 @@ def plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1976UCS( chromaticity_diagram_clipping: bool = False, ellipse_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot *MacAdam (1942) Ellipses (Observer PGN)* in the *CIE 1976 UCS Chromaticity Diagram*. @@ -1715,7 +1684,7 @@ def plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1976UCS( @override_style() def plot_single_cctf( cctf: Callable | str, cctf_decoding: bool = False, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given colourspace colour component transfer function. @@ -1764,7 +1733,7 @@ def plot_multi_cctfs( cctfs: Callable | str | Sequence[Callable | str], cctf_decoding: bool = False, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given colour component transfer functions. @@ -1823,38 +1792,11 @@ def plot_multi_cctfs( @override_style() def plot_constant_hue_loci( data: ArrayLike, - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE Luv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IPT Ragoo 2021", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - ] - | str = "CIE Lab", + model: LiteralColourspaceModel | str = "CIE Lab", scatter_kwargs: dict | None = None, convert_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given constant hue loci colour matches data such as that from :cite:`Hung1995` or :cite:`Ebner1998` that are easily loaded with diff --git a/colour/plotting/notation.py b/colour/plotting/notation.py index bb2d71b880..cd6a8df8ea 100644 --- a/colour/plotting/notation.py +++ b/colour/plotting/notation.py @@ -10,15 +10,16 @@ from __future__ import annotations -import matplotlib.pyplot as plt import numpy as np +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.hints import Any, Callable, Dict, Sequence, Tuple from colour.notation import MUNSELL_VALUE_METHODS from colour.plotting import ( filter_passthrough, - plot_multi_functions, override_style, + plot_multi_functions, ) __author__ = "Colour Developers" @@ -37,7 +38,7 @@ @override_style() def plot_single_munsell_value_function( function: Callable | str, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *Lightness* function. @@ -83,7 +84,7 @@ def plot_single_munsell_value_function( def plot_multi_munsell_value_functions( functions: Callable | str | Sequence[Callable | str], **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *Munsell* value functions. diff --git a/colour/plotting/phenomena.py b/colour/plotting/phenomena.py index 322a03af1c..790cb4839d 100644 --- a/colour/plotting/phenomena.py +++ b/colour/plotting/phenomena.py @@ -11,6 +11,8 @@ from __future__ import annotations import matplotlib.pyplot as plt +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.algebra import normalise_maximum from colour.colorimetry import ( @@ -27,15 +29,15 @@ CONSTANT_STANDARD_CO2_CONCENTRATION, ) from colour.plotting import ( - SD_ASTMG173_ETR, CONSTANTS_COLOUR_STYLE, + SD_ASTMG173_ETR, ColourSwatch, XYZ_to_plotting_colourspace, filter_cmfs, override_style, - render, plot_single_colour_swatch, plot_single_sd, + render, ) from colour.utilities import first_item @@ -65,7 +67,7 @@ def plot_single_sd_rayleigh_scattering( MultiSpectralDistributions | str ] = "CIE 1931 2 Degree Standard Observer", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot a single *Rayleigh* scattering spectral distribution. @@ -138,7 +140,7 @@ def plot_the_blue_sky( MultiSpectralDistributions | str ] = "CIE 1931 2 Degree Standard Observer", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the blue sky. diff --git a/colour/plotting/quality.py b/colour/plotting/quality.py index d5b08fdc8a..7f61dd7402 100644 --- a/colour/plotting/quality.py +++ b/colour/plotting/quality.py @@ -12,16 +12,18 @@ from __future__ import annotations -import matplotlib.pyplot as plt -import numpy as np from itertools import cycle -from colour.constants import DEFAULT_FLOAT_DTYPE +import numpy as np +from matplotlib.axes import Axes +from matplotlib.figure import Figure + from colour.colorimetry import ( MultiSpectralDistributions, SpectralDistribution, sds_and_msds_to_sds, ) +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.hints import ( Any, Dict, @@ -73,7 +75,7 @@ def plot_colour_quality_bars( hatching: bool | None = None, hatching_repeat: int = 2, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the colour quality data of given illuminants or light sources colour quality specifications. @@ -150,7 +152,7 @@ def plot_colour_quality_bars( 0, (count_Q_as + 1) * (count_s + 1), (count_s + 1), - dtype=DEFAULT_FLOAT_DTYPE, + dtype=DTYPE_FLOAT_DEFAULT, ) ) * bar_width @@ -205,19 +207,17 @@ def plot_colour_quality_bars( 0, (count_Q_as + 1) * (count_s + 1), (count_s + 1), - dtype=DEFAULT_FLOAT_DTYPE, + dtype=DTYPE_FLOAT_DEFAULT, ) - bar_width ) * bar_width + (count_s * bar_width / 2) - ) # pyright: ignore + ) axes.set_xticklabels( ["Qa"] + [f"Q{index + 1}" for index in range(0, count_Q_as, 1)] - ) # pyright: ignore - axes.set_yticks( - range(0, 100 + y_ticks_interval, y_ticks_interval) - ) # pyright: ignore + ) + axes.set_yticks(range(0, 100 + y_ticks_interval, y_ticks_interval)) aspect = 1 / (120 / (bar_width + len(Q_as) + bar_width * 2)) bounding_box = ( @@ -242,7 +242,7 @@ def plot_colour_quality_bars( @override_style() def plot_single_sd_colour_rendering_index_bars( sd: SpectralDistribution, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Colour Rendering Index* (CRI) of given illuminant or light source spectral distribution. @@ -289,7 +289,7 @@ def plot_multi_sds_colour_rendering_indexes_bars( | SpectralDistribution | MultiSpectralDistributions, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Colour Rendering Index* (CRI) of given illuminants or light sources spectral distributions. @@ -373,7 +373,7 @@ def plot_single_sd_colour_quality_scale_bars( sd: SpectralDistribution, method: Literal["NIST CQS 7.4", "NIST CQS 9.0"] | str = "NIST CQS 9.0", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Colour Quality Scale* (CQS) of given illuminant or light source spectral distribution. @@ -425,7 +425,7 @@ def plot_multi_sds_colour_quality_scales_bars( | MultiSpectralDistributions, method: Literal["NIST CQS 7.4", "NIST CQS 9.0"] | str = "NIST CQS 9.0", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Colour Quality Scale* (CQS) of given illuminants or light sources spectral distributions. diff --git a/colour/plotting/section.py b/colour/plotting/section.py index 42a40acd9f..b93a3568dd 100644 --- a/colour/plotting/section.py +++ b/colour/plotting/section.py @@ -12,9 +12,10 @@ from __future__ import annotations -import matplotlib.pyplot as plt import numpy as np +from matplotlib.axes import Axes from matplotlib.collections import LineCollection +from matplotlib.figure import Figure from matplotlib.patches import Polygon from colour.colorimetry import ( @@ -30,6 +31,8 @@ ArrayLike, Dict, Literal, + LiteralColourspaceModel, + LiteralRGBColourspace, Real, Sequence, Tuple, @@ -48,12 +51,11 @@ artist, colourspace_model_axis_reorder, filter_cmfs, - filter_RGB_colourspaces, filter_illuminants, + filter_RGB_colourspaces, override_style, render, ) -from colour.volume import solid_RoschMacAdam from colour.utilities import ( CanonicalMapping, as_int_array, @@ -65,6 +67,7 @@ tstack, validate_method, ) +from colour.volume import solid_RoschMacAdam __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -91,33 +94,7 @@ @override_style() def plot_hull_section_colours( hull: trimesh.Trimesh, # pyright: ignore # noqa: F821 - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE Luv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - ] - | str = "CIE xyY", + model: LiteralColourspaceModel | str = "CIE xyY", axis: Literal["+z", "+x", "+y"] | str = "+z", origin: float = 0.5, normalise: bool = True, @@ -126,7 +103,7 @@ def plot_hull_section_colours( convert_kwargs: dict | None = None, samples: int = 256, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the section colours of given *trimesh* hull along given axis and origin. @@ -297,33 +274,7 @@ def plot_hull_section_colours( @override_style() def plot_hull_section_contour( hull: trimesh.Trimesh, # pyright: ignore # noqa: F821 - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE Luv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - ] - | str = "CIE xyY", + model: LiteralColourspaceModel | str = "CIE xyY", axis: Literal["+z", "+x", "+y"] | str = "+z", origin: float = 0.5, normalise: bool = True, @@ -331,7 +282,7 @@ def plot_hull_section_contour( contour_opacity: float = 1, convert_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the section contour of given *trimesh* hull along given axis and origin. @@ -446,7 +397,7 @@ def plot_hull_section_contour( section = np.reshape(section[..., plane], (-1, 1, 2)) line_collection = LineCollection( - np.concatenate([section[:-1], section[1:]], axis=1), + np.concatenate([section[:-1], section[1:]], axis=1), # pyright: ignore colors=contour_colours, alpha=contour_opacity, zorder=CONSTANTS_COLOUR_STYLE.zorder.background_line, @@ -471,40 +422,14 @@ def plot_visible_spectrum_section( MultiSpectralDistributions | str ] = "CIE 1931 2 Degree Standard Observer", illuminant: SpectralDistribution | str = "D65", - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE Luv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - ] - | str = "CIE xyY", + model: LiteralColourspaceModel | str = "CIE xyY", axis: Literal["+z", "+x", "+y"] | str = "+z", origin: float = 0.5, normalise: bool = True, show_section_colours: bool = True, show_section_contour: bool = True, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the visible spectrum volume, i.e. *Rösch-MacAdam* colour solid, section colours along given axis and origin. @@ -643,41 +568,18 @@ def plot_visible_spectrum_section( @required("trimesh") @override_style() def plot_RGB_colourspace_section( - colourspace: RGB_Colourspace | str | Sequence[RGB_Colourspace | str], - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE Luv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - ] - | str = "CIE xyY", + colourspace: RGB_Colourspace + | LiteralRGBColourspace + | str + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str], + model: LiteralColourspaceModel | str = "CIE xyY", axis: Literal["+z", "+x", "+y"] | str = "+z", origin: float = 0.5, normalise: bool = True, show_section_colours: bool = True, show_section_contour: bool = True, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot given *RGB* colourspace section colours along given axis and origin. diff --git a/colour/plotting/temperature.py b/colour/plotting/temperature.py index 58e959de2d..f44fb15073 100644 --- a/colour/plotting/temperature.py +++ b/colour/plotting/temperature.py @@ -5,6 +5,8 @@ Defines the colour temperature and correlated colour temperature plotting objects: +- :func:`colour.plotting.lines_daylight_locus` +- :func:`colour.plotting.lines_planckian_locus` - :func:`colour.plotting.\ plot_planckian_locus_in_chromaticity_diagram_CIE1931` - :func:`colour.plotting.\ @@ -15,12 +17,14 @@ from __future__ import annotations -import matplotlib.pyplot as plt import numpy as np +from matplotlib.axes import Axes from matplotlib.collections import LineCollection +from matplotlib.figure import Figure -from colour.algebra import normalise_maximum -from colour.colorimetry import MSDS_CMFS, CCS_ILLUMINANTS +from colour.algebra import normalise_maximum, normalise_vector +from colour.colorimetry import CCS_ILLUMINANTS, MSDS_CMFS +from colour.constants import DTYPE_FLOAT_DEFAULT from colour.hints import ( Any, ArrayLike, @@ -28,37 +32,36 @@ Dict, List, Literal, - NDArrayFloat, + NDArray, Sequence, Tuple, cast, ) from colour.models import ( - UCS_to_uv, UCS_uv_to_xy, - XYZ_to_UCS, - xy_to_Luv_uv, - xy_to_UCS_uv, xy_to_XYZ, ) -from colour.temperature import mired_to_CCT, CCT_to_uv, CCT_to_xy_CIE_D from colour.plotting import ( - CONSTANTS_COLOUR_STYLE, CONSTANTS_ARROW_STYLE, + CONSTANTS_COLOUR_STYLE, + METHODS_CHROMATICITY_DIAGRAM, XYZ_to_plotting_colourspace, artist, + filter_passthrough, + override_style, plot_chromaticity_diagram_CIE1931, plot_chromaticity_diagram_CIE1960UCS, plot_chromaticity_diagram_CIE1976UCS, - filter_passthrough, - override_style, render, update_settings_collection, ) from colour.plotting.diagrams import plot_chromaticity_diagram +from colour.temperature import CCT_to_uv, CCT_to_xy_CIE_D, mired_to_CCT from colour.utilities import ( - as_int_scalar, + CanonicalMapping, + as_float_array, as_float_scalar, + as_int_scalar, full, optional, tstack, @@ -74,7 +77,10 @@ __status__ = "Production" __all__ = [ + "lines_daylight_locus", "plot_daylight_locus", + "LABELS_PLANCKIAN_LOCUS_DEFAULT", + "lines_planckian_locus", "plot_planckian_locus", "plot_planckian_locus_in_chromaticity_diagram", "plot_planckian_locus_in_chromaticity_diagram_CIE1931", @@ -83,15 +89,86 @@ ] +def lines_daylight_locus( + mireds: bool = False, + method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"] + | str = "CIE 1931", +) -> Tuple[NDArray]: + """ + Return the *Daylight Locus* line vertices, i.e. positions, normals and + colours, according to given method. + + Parameters + ---------- + mireds + Whether to use micro reciprocal degrees for the iso-temperature lines. + method + *Daylight Locus* method. + + Returns + ------- + :class:`tuple` + Tuple of *Spectral Locus* vertices. + + Examples + -------- + >>> lines = lines_daylight_locus() + >>> len(lines) + 1 + >>> lines[0].dtype + dtype([('position', ' Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Daylight Locus* according to given method. @@ -103,7 +180,7 @@ def plot_daylight_locus( chromaticity coordinates. daylight_locus_opacity Opacity of the *Daylight Locus*. - daylight_locus_use_mireds + daylight_locus_mireds Whether to use micro reciprocal degrees for the iso-temperature lines. method *Chromaticity Diagram* method. @@ -134,6 +211,10 @@ def plot_daylight_locus( method, ("CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS") ) + use_RGB_daylight_locus_colours = ( + str(daylight_locus_colours).upper() == "RGB" + ) + daylight_locus_colours = optional( daylight_locus_colours, CONSTANTS_COLOUR_STYLE.colour.dark ) @@ -143,75 +224,168 @@ def plot_daylight_locus( _figure, axes = artist(**settings) - if method == "cie 1931": + lines_sl, *_ = lines_daylight_locus(daylight_locus_mireds, method) - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ + line_collection = LineCollection( + np.concatenate( + [lines_sl["position"][:-1], lines_sl["position"][1:]], axis=1 + ).reshape( + [-1, 2, 2] + ), # pyright: ignore + colors=lines_sl["colour"] + if use_RGB_daylight_locus_colours + else daylight_locus_colours, + alpha=daylight_locus_opacity, + zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, + ) + axes.add_collection(line_collection) - return xy + settings = {"axes": axes} + settings.update(kwargs) - elif method == "cie 1960 ucs": + return render(**settings) - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - return xy_to_UCS_uv(xy) +LABELS_PLANCKIAN_LOCUS_DEFAULT: CanonicalMapping = CanonicalMapping( + { + "Default": (1e6 / 600, 2000, 2500, 3000, 4000, 6000, 1e6 / 100), + "Mireds": (0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000), + } +) +"""*Planckian Locus* default labels.""" - elif method == "cie 1976 ucs": - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ +def lines_planckian_locus( + labels: Sequence | None = None, + mireds: bool = False, + iso_temperature_lines_D_uv: float = 0.05, + method: Literal["CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS"] + | str = "CIE 1931", +) -> Tuple[NDArray, NDArray]: + """ + Return the *Planckian Locus* line vertices, i.e. positions, normals and + colours, according to given method. - return xy_to_Luv_uv(xy) + Parameters + ---------- + labels + Array of labels used to customise which iso-temperature lines will be + drawn along the *Planckian Locus*. Passing an empty array will result + in no iso-temperature lines being drawn. + mireds + Whether to use micro reciprocal degrees for the iso-temperature lines. + iso_temperature_lines_D_uv + Iso-temperature lines :math:`\\Delta_{uv}` length on each side of the + *Planckian Locus*. + method + *Planckian Locus* method. - def CCT_to_plotting_colourspace(CCT): + Returns + ------- + :class:`tuple` + Tuple of *Planckian Locus* vertices and wavelength labels vertices. + + Examples + -------- + >>> lines = lines_planckian_locus() + >>> len(lines) + 2 + >>> lines[0].dtype + dtype([('position', '>> lines[1].dtype + dtype([('position', ' Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Planckian Locus* according to given method. @@ -240,12 +414,11 @@ def plot_planckian_locus( Array of labels used to customise which iso-temperature lines will be drawn along the *Planckian Locus*. Passing an empty array will result in no iso-temperature lines being drawn. - planckian_locus_use_mireds + planckian_locus_mireds Whether to use micro reciprocal degrees for the iso-temperature lines. planckian_locus_iso_temperature_lines_D_uv Iso-temperature lines :math:`\\Delta_{uv}` length on each side of the *Planckian Locus*. - method *Chromaticity Diagram* method. @@ -271,134 +444,76 @@ def plot_planckian_locus( :alt: plot_planckian_locus """ - method = validate_method( - method, ("CIE 1931", "CIE 1960 UCS", "CIE 1976 UCS") - ) - planckian_locus_colours = optional( planckian_locus_colours, CONSTANTS_COLOUR_STYLE.colour.dark ) + use_RGB_planckian_locus_colours = ( + str(planckian_locus_colours).upper() == "RGB" + ) + labels = cast( tuple, optional( planckian_locus_labels, - (0, 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000) - if planckian_locus_use_mireds - else (1e6 / 600, 2000, 2500, 3000, 4000, 6000, 1e6 / 100), + LABELS_PLANCKIAN_LOCUS_DEFAULT[ + "Mireds" if planckian_locus_mireds else "Default" + ], ), ) - D_uv = planckian_locus_iso_temperature_lines_D_uv settings: Dict[str, Any] = {"uniform": True} settings.update(kwargs) _figure, axes = artist(**settings) - if method == "cie 1931": - - def uv_to_ij(uv: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *uv* chromaticity coordinates to *ij* chromaticity - coordinates. - """ - - return UCS_uv_to_xy(uv) - - elif method == "cie 1960 ucs": - - def uv_to_ij(uv: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *uv* chromaticity coordinates to *ij* chromaticity - coordinates. - """ - - return uv - - elif method == "cie 1976 ucs": - - def uv_to_ij(uv: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *uv* chromaticity coordinates to *ij* chromaticity - coordinates. - """ - - return xy_to_Luv_uv(UCS_uv_to_xy(uv)) - - def CCT_D_uv_to_plotting_colourspace(CCT_D_uv): - """ - Convert given correlated colour temperature :math:`T_{cp}` and - :math:`\\Delta_{uv}` to the default plotting colourspace. - """ - - return normalise_maximum( - XYZ_to_plotting_colourspace( - xy_to_XYZ(UCS_uv_to_xy(CCT_to_uv(CCT_D_uv, "Robertson 1968"))) - ), - axis=-1, - ) - - start, end = ( - (0, 1000) if planckian_locus_use_mireds else (1e6 / 600, 1e6 / 10) + lines_pl, lines_l = lines_planckian_locus( + labels, + planckian_locus_mireds, + planckian_locus_iso_temperature_lines_D_uv, + method, ) - CCT = np.arange(start, end + 100, 10) - CCT = mired_to_CCT(CCT) if planckian_locus_use_mireds else CCT - CCT_D_uv = np.reshape(tstack([CCT, zeros(CCT.shape)]), (-1, 1, 2)) - ij = uv_to_ij(CCT_to_uv(CCT_D_uv, "Robertson 1968")) - - use_RGB_planckian_locus_colours = ( - str(planckian_locus_colours).upper() == "RGB" - ) - if use_RGB_planckian_locus_colours: - pl_colours = CCT_D_uv_to_plotting_colourspace(CCT_D_uv) - else: - pl_colours = planckian_locus_colours - - line_collection = LineCollection( - np.concatenate([ij[:-1], ij[1:]], axis=1), - colors=pl_colours, - alpha=planckian_locus_opacity, - zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, + axes.add_collection( + LineCollection( + np.concatenate( + [lines_pl["position"][:-1], lines_pl["position"][1:]], axis=1 + ).reshape( + [-1, 2, 2] + ), # pyright: ignore + colors=lines_pl["colour"] + if use_RGB_planckian_locus_colours + else planckian_locus_colours, + alpha=planckian_locus_opacity, + zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, + ) ) - axes.add_collection(line_collection) - for label in labels: - CCT_D_uv = np.reshape( - tstack( - [ - full( - 10, - as_float_scalar(mired_to_CCT(label)) - if planckian_locus_use_mireds - else label, - ), - np.linspace(-D_uv, D_uv, 10), - ] - ), - (-1, 1, 2), + lines_itl = lines_l["position"].reshape([len(labels), 20, 2]) + colours_itl = lines_l["colour"].reshape([len(labels), 20, 3]) + for i, label in enumerate(labels): + axes.add_collection( + LineCollection( + np.concatenate( + [lines_itl[i][:-1], lines_itl[i][1:]], # pyright: ignore + axis=1, + ).reshape([-1, 2, 2]), + colors=colours_itl[i] + if use_RGB_planckian_locus_colours + else planckian_locus_colours, + alpha=planckian_locus_opacity, + zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, + ) ) - if use_RGB_planckian_locus_colours: - itl_colours = CCT_D_uv_to_plotting_colourspace(CCT_D_uv) - else: - itl_colours = planckian_locus_colours - - ij = uv_to_ij(CCT_to_uv(CCT_D_uv, "Robertson 1968")) - - line_collection = LineCollection( - np.concatenate([ij[:-1], ij[1:]], axis=1), - colors=itl_colours, - alpha=planckian_locus_opacity, - zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_line, - ) - axes.add_collection(line_collection) - axes.annotate( - f'{as_int_scalar(label)}{"M" if planckian_locus_use_mireds else "K"}', - xy=(ij[-1, :, 0], ij[-1, :, 1]), - xytext=(0, CONSTANTS_COLOUR_STYLE.geometry.long / 2), - textcoords="offset points", - size="x-small", + axes.text( + lines_itl[i][-1, 0], + lines_itl[i][-1, 1], + f'{as_int_scalar(label)}{"M" if planckian_locus_mireds else "K"}', + clip_on=True, + ha="left", + va="bottom", + fontsize="x-small-colour-science", zorder=CONSTANTS_COLOUR_STYLE.zorder.foreground_label, ) @@ -417,7 +532,7 @@ def plot_planckian_locus_in_chromaticity_diagram( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Planckian Locus* and given illuminants in the *Chromaticity Diagram* according to given method. @@ -515,39 +630,15 @@ def plot_planckian_locus_in_chromaticity_diagram( plot_planckian_locus(**settings) - if method == "CIE 1931": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy + xy_to_ij = METHODS_CHROMATICITY_DIAGRAM[method]["xy_to_ij"] + if method == "CIE 1931": bounding_box = (-0.1, 0.9, -0.1, 0.9) - elif method == "CIE 1960 UCS": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return UCS_to_uv(XYZ_to_UCS(xy_to_XYZ(xy))) + elif method == "CIE 1960 UCS": bounding_box = (-0.1, 0.7, -0.2, 0.6) elif method == "CIE 1976 UCS": - - def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: - """ - Convert given *CIE xy* chromaticity coordinates to *ij* - chromaticity coordinates. - """ - - return xy_to_Luv_uv(xy) - bounding_box = (-0.1, 0.7, -0.1, 0.7) annotate_settings_collection = [ @@ -592,7 +683,7 @@ def xy_to_ij(xy: NDArrayFloat) -> NDArrayFloat: for i, (illuminant, xy) in enumerate(illuminants_filtered.items()): plot_settings = plot_settings_collection[i] - ij = xy_to_ij(xy) + ij = cast(tuple[float, float], xy_to_ij(xy)) axes.plot(ij[0], ij[1], **plot_settings) @@ -637,7 +728,7 @@ def plot_planckian_locus_in_chromaticity_diagram_CIE1931( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Planckian Locus* and given illuminants in *CIE 1931 Chromaticity Diagram*. @@ -716,7 +807,7 @@ def plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Planckian Locus* and given illuminants in *CIE 1960 UCS Chromaticity Diagram*. @@ -797,7 +888,7 @@ def plot_planckian_locus_in_chromaticity_diagram_CIE1976UCS( annotate_kwargs: dict | List[dict] | None = None, plot_kwargs: dict | List[dict] | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the *Planckian Locus* and given illuminants in *CIE 1976 UCS Chromaticity Diagram*. diff --git a/colour/plotting/tests/test_blindness.py b/colour/plotting/tests/test_blindness.py index c39f482960..31d591c4e2 100644 --- a/colour/plotting/tests/test_blindness.py +++ b/colour/plotting/tests/test_blindness.py @@ -1,9 +1,11 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.plotting.blindness` module.""" -import numpy as np import unittest -from matplotlib.pyplot import Axes, Figure + +import numpy as np +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.plotting import plot_cvd_simulation_Machado2009 diff --git a/colour/plotting/tests/test_characterisation.py b/colour/plotting/tests/test_characterisation.py index 3bfd7b0877..87d606449b 100644 --- a/colour/plotting/tests/test_characterisation.py +++ b/colour/plotting/tests/test_characterisation.py @@ -2,11 +2,13 @@ """Define the unit tests for the :mod:`colour.plotting.characterisation` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.plotting import ( - plot_single_colour_checker, plot_multi_colour_checkers, + plot_single_colour_checker, ) __author__ = "Colour Developers" diff --git a/colour/plotting/tests/test_colorimetry.py b/colour/plotting/tests/test_colorimetry.py index 9c3bbf6dd8..e8eeefbbdc 100644 --- a/colour/plotting/tests/test_colorimetry.py +++ b/colour/plotting/tests/test_colorimetry.py @@ -2,23 +2,25 @@ """Define the unit tests for the :mod:`colour.plotting.colorimetry` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.colorimetry import SpectralDistribution from colour.plotting import ( - plot_single_sd, + plot_blackbody_colours, + plot_blackbody_spectral_radiance, + plot_multi_cmfs, + plot_multi_illuminant_sds, + plot_multi_lightness_functions, + plot_multi_luminance_functions, plot_multi_sds, plot_single_cmfs, - plot_multi_cmfs, plot_single_illuminant_sd, - plot_multi_illuminant_sds, - plot_visible_spectrum, plot_single_lightness_function, - plot_multi_lightness_functions, plot_single_luminance_function, - plot_multi_luminance_functions, - plot_blackbody_spectral_radiance, - plot_blackbody_colours, + plot_single_sd, + plot_visible_spectrum, ) __author__ = "Colour Developers" diff --git a/colour/plotting/tests/test_common.py b/colour/plotting/tests/test_common.py index f63b33cf5d..dc1b3ab0ef 100644 --- a/colour/plotting/tests/test_common.py +++ b/colour/plotting/tests/test_common.py @@ -1,41 +1,46 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.plotting.common` module.""" -import matplotlib.pyplot as plt -import numpy as np import os import shutil import tempfile import unittest from functools import partial -from matplotlib.pyplot import Axes, Figure + +import matplotlib.font_manager +import matplotlib.pyplot as plt +import numpy as np +from matplotlib.axes import Axes +from matplotlib.figure import Figure import colour from colour.colorimetry import SDS_ILLUMINANTS +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.io import read_image from colour.models import RGB_COLOURSPACES, XYZ_to_sRGB, gamma_function -from colour.plotting import ColourSwatch from colour.plotting import ( - colour_style, - override_style, + ColourSwatch, XYZ_to_plotting_colourspace, - colour_cycle, artist, camera, - render, - label_rectangles, - uniform_axes3d, - filter_passthrough, - filter_RGB_colourspaces, + colour_cycle, + colour_style, filter_cmfs, - filter_illuminants, filter_colour_checkers, - update_settings_collection, - plot_single_colour_swatch, + filter_illuminants, + filter_passthrough, + filter_RGB_colourspaces, + font_scaling, + label_rectangles, + override_style, + plot_image, plot_multi_colour_swatches, - plot_single_function, plot_multi_functions, - plot_image, + plot_single_colour_swatch, + plot_single_function, + render, + uniform_axes3d, + update_settings_collection, ) from colour.utilities import attest @@ -49,7 +54,8 @@ __all__ = [ "TestColourStyle", "TestOverrideStyle", - "TestXyzToPlottingColourspace", + "TestFontScaling", + "TestXYZToPlottingColourspace", "TestColourCycle", "TestArtist", "TestCamera", @@ -105,7 +111,27 @@ def test_text_color_override(): plt.rcParams["text.color"] = text_color -class TestXyzToPlottingColourspace(unittest.TestCase): +class TestFontScaling(unittest.TestCase): + """ + Define :func:`colour.plotting.common.font_scaling` definition unit tests + methods. + """ + + def test_font_scaling(self): + """Test :func:`colour.plotting.common.font_scaling` definition.""" + + with font_scaling("medium-colour-science", 2): + self.assertEqual( + matplotlib.font_manager.font_scalings["medium-colour-science"], + 2, + ) + + self.assertEqual( + matplotlib.font_manager.font_scalings["medium-colour-science"], 1 + ) + + +class TestXYZToPlottingColourspace(unittest.TestCase): """ Define :func:`colour.plotting.common.XYZ_to_plotting_colourspace` definition unit tests methods. @@ -118,8 +144,10 @@ def test_XYZ_to_plotting_colourspace(self): """ XYZ = np.random.random(3) - np.testing.assert_array_almost_equal( - XYZ_to_sRGB(XYZ), XYZ_to_plotting_colourspace(XYZ), decimal=7 + np.testing.assert_allclose( + XYZ_to_sRGB(XYZ), + XYZ_to_plotting_colourspace(XYZ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -134,30 +162,30 @@ def test_colour_cycle(self): cycler = colour_cycle() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( next(cycler), np.array([0.95686275, 0.26274510, 0.21176471, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( next(cycler), np.array([0.61582468, 0.15423299, 0.68456747, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( next(cycler), np.array([0.25564014, 0.31377163, 0.70934256, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) cycler = colour_cycle(colour_cycle_map="viridis") - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( next(cycler), np.array([0.26700400, 0.00487400, 0.32941500, 1.00000000]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -167,6 +195,24 @@ class TestArtist(unittest.TestCase): methods. """ + def test_axes_args(self): + """ + Test `colour.plotting.common.artist` figure / axis association + """ + fig1 = plt.figure() + fig_sub1 = fig1.subfigures() + fig_sub2 = fig_sub1.subfigures() + ax1 = fig_sub2.gca() + + fig_result1, _ = artist(axes=ax1) + + self.assertIs(fig1, fig_result1) + + _ = plt.figure() + + fig_result2, _ = artist(axes=ax1) + self.assertIs(fig1, fig_result2) + def test_artist(self): """Test :func:`colour.plotting.common.artist` definition.""" diff --git a/colour/plotting/tests/test_corresponding.py b/colour/plotting/tests/test_corresponding.py index b7196dd257..5e44b0249c 100644 --- a/colour/plotting/tests/test_corresponding.py +++ b/colour/plotting/tests/test_corresponding.py @@ -2,7 +2,9 @@ """Define the unit tests for the :mod:`colour.plotting.corresponding` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.plotting import plot_corresponding_chromaticities_prediction diff --git a/colour/plotting/tests/test_diagrams.py b/colour/plotting/tests/test_diagrams.py index 8805082796..ed98597000 100644 --- a/colour/plotting/tests/test_diagrams.py +++ b/colour/plotting/tests/test_diagrams.py @@ -2,7 +2,9 @@ """Define the unit tests for the :mod:`colour.plotting.diagrams` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.colorimetry import ( MSDS_CMFS, @@ -11,6 +13,7 @@ reshape_msds, ) from colour.plotting import ( + lines_spectral_locus, plot_chromaticity_diagram_CIE1931, plot_chromaticity_diagram_CIE1960UCS, plot_chromaticity_diagram_CIE1976UCS, @@ -19,10 +22,10 @@ plot_sds_in_chromaticity_diagram_CIE1976UCS, ) from colour.plotting.diagrams import ( - plot_spectral_locus, - plot_chromaticity_diagram_colours, plot_chromaticity_diagram, + plot_chromaticity_diagram_colours, plot_sds_in_chromaticity_diagram, + plot_spectral_locus, ) __author__ = "Colour Developers" @@ -33,6 +36,7 @@ __status__ = "Production" __all__ = [ + "TestLinesSpectralLocus", "TestPlotSpectralLocus", "TestPlotChromaticityDiagramColours", "TestPlotChromaticityDiagram", @@ -46,6 +50,21 @@ ] +class TestLinesSpectralLocus(unittest.TestCase): + """ + Define :func:`colour.plotting.diagrams.lines_spectral_locus` definition + unit tests methods. + """ + + def test_lines_spectral_locus(self): + """ + Test :func:`colour.plotting.diagrams.lines_spectral_locus` + definition. + """ + + self.assertEqual(len(lines_spectral_locus()), 2) + + class TestPlotSpectralLocus(unittest.TestCase): """ Define :func:`colour.plotting.diagrams.plot_spectral_locus` definition @@ -53,7 +72,9 @@ class TestPlotSpectralLocus(unittest.TestCase): """ def test_plot_spectral_locus(self): - """Test :func:`colour.plotting.diagrams.plot_spectral_locus` definition.""" + """ + Test :func:`colour.plotting.diagrams.plot_spectral_locus` definition. + """ figure, axes = plot_spectral_locus() diff --git a/colour/plotting/tests/test_models.py b/colour/plotting/tests/test_models.py index 6f1f5d122f..fd6e6365df 100644 --- a/colour/plotting/tests/test_models.py +++ b/colour/plotting/tests/test_models.py @@ -1,31 +1,35 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.plotting.models` module.""" -import numpy as np import unittest -from matplotlib.pyplot import Axes, Figure +import numpy as np +from matplotlib.axes import Axes +from matplotlib.figure import Figure + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.plotting import ( colourspace_model_axis_reorder, + lines_pointer_gamut, + plot_constant_hue_loci, + plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1931, + plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1960UCS, + plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1976UCS, + plot_multi_cctfs, plot_pointer_gamut, - plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931, - plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS, - plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS, plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931, plot_RGB_chromaticities_in_chromaticity_diagram_CIE1960UCS, plot_RGB_chromaticities_in_chromaticity_diagram_CIE1976UCS, - plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1931, - plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1960UCS, - plot_ellipses_MacAdam1942_in_chromaticity_diagram_CIE1976UCS, + plot_RGB_colourspaces_in_chromaticity_diagram_CIE1931, + plot_RGB_colourspaces_in_chromaticity_diagram_CIE1960UCS, + plot_RGB_colourspaces_in_chromaticity_diagram_CIE1976UCS, plot_single_cctf, - plot_multi_cctfs, - plot_constant_hue_loci, ) from colour.plotting.models import ( - plot_RGB_colourspaces_in_chromaticity_diagram, - plot_RGB_chromaticities_in_chromaticity_diagram, ellipses_MacAdam1942, plot_ellipses_MacAdam1942_in_chromaticity_diagram, + plot_RGB_chromaticities_in_chromaticity_diagram, + plot_RGB_colourspaces_in_chromaticity_diagram, ) __author__ = "Colour Developers" @@ -37,6 +41,7 @@ __all__ = [ "TestCommonColourspaceModelAxisReorder", + "TestLinesPointerGamut", "TestPlotPointerGamut", "TestPlotRGBColourspacesInChromaticityDiagram", "TestPlotRGBColourspacesInChromaticityDiagramCIE1931", @@ -70,35 +75,49 @@ def test_colourspace_model_axis_reorder(self): a = np.array([0, 1, 2]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace_model_axis_reorder(a, "CIE Lab"), np.array([1, 2, 0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace_model_axis_reorder(a, "IPT"), np.array([1, 2, 0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace_model_axis_reorder(a, "OSA UCS"), np.array([1, 2, 0]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( colourspace_model_axis_reorder( colourspace_model_axis_reorder(a, "OSA UCS"), "OSA UCS", "Inverse", ), np.array([0, 1, 2]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) +class TestLinesPointerGamut(unittest.TestCase): + """ + Define :func:`colour.plotting.models.lines_pointer_gamut` definition unit + tests methods. + """ + + def test_lines_pointer_gamut(self): + """ + Test :func:`colour.plotting.models.lines_pointer_gamut` definition. + """ + + self.assertEqual(len(lines_pointer_gamut()), 2) + + class TestPlotPointerGamut(unittest.TestCase): """ Define :func:`colour.plotting.models.plot_pointer_gamut` definition unit diff --git a/colour/plotting/tests/test_notation.py b/colour/plotting/tests/test_notation.py index 12d95961bb..aa51a04dc7 100644 --- a/colour/plotting/tests/test_notation.py +++ b/colour/plotting/tests/test_notation.py @@ -2,11 +2,13 @@ """Define the unit tests for the :mod:`colour.plotting.notation` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.plotting import ( - plot_single_munsell_value_function, plot_multi_munsell_value_functions, + plot_single_munsell_value_function, ) __author__ = "Colour Developers" diff --git a/colour/plotting/tests/test_phenomena.py b/colour/plotting/tests/test_phenomena.py index d56a487bac..06d9777803 100644 --- a/colour/plotting/tests/test_phenomena.py +++ b/colour/plotting/tests/test_phenomena.py @@ -2,7 +2,9 @@ """Define the unit tests for the :mod:`colour.plotting.phenomena` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.plotting import ( plot_single_sd_rayleigh_scattering, diff --git a/colour/plotting/tests/test_quality.py b/colour/plotting/tests/test_quality.py index fb266eab79..75076493b9 100644 --- a/colour/plotting/tests/test_quality.py +++ b/colour/plotting/tests/test_quality.py @@ -2,7 +2,9 @@ """Define the unit tests for the :mod:`colour.plotting.quality` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.colorimetry import ( SDS_ILLUMINANTS, @@ -11,10 +13,10 @@ reshape_sd, ) from colour.plotting import ( - plot_single_sd_colour_rendering_index_bars, + plot_multi_sds_colour_quality_scales_bars, plot_multi_sds_colour_rendering_indexes_bars, plot_single_sd_colour_quality_scale_bars, - plot_multi_sds_colour_quality_scales_bars, + plot_single_sd_colour_rendering_index_bars, ) from colour.plotting.quality import plot_colour_quality_bars from colour.quality import colour_quality_scale diff --git a/colour/plotting/tests/test_section.py b/colour/plotting/tests/test_section.py index fb66e88d9e..f7ac9c2093 100644 --- a/colour/plotting/tests/test_section.py +++ b/colour/plotting/tests/test_section.py @@ -2,13 +2,15 @@ """Define the unit tests for the :mod:`colour.plotting.section` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.geometry import primitive_cube from colour.models import RGB_COLOURSPACE_sRGB, RGB_to_XYZ from colour.plotting import ( - plot_visible_spectrum_section, plot_RGB_colourspace_section, + plot_visible_spectrum_section, ) from colour.plotting.section import ( plot_hull_section_colours, diff --git a/colour/plotting/tests/test_temperature.py b/colour/plotting/tests/test_temperature.py index c85dd213a3..a2e29ddb08 100644 --- a/colour/plotting/tests/test_temperature.py +++ b/colour/plotting/tests/test_temperature.py @@ -2,13 +2,17 @@ """Define the unit tests for the :mod:`colour.plotting.temperature` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.plotting import ( plot_planckian_locus_in_chromaticity_diagram_CIE1931, plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS, ) from colour.plotting.temperature import ( + lines_daylight_locus, + lines_planckian_locus, plot_daylight_locus, plot_planckian_locus, plot_planckian_locus_in_chromaticity_diagram, @@ -22,7 +26,9 @@ __status__ = "Production" __all__ = [ + "TestLinesPlanckianLocus", "TestPlotDaylightLocus", + "TestLinesPlanckianLocus", "TestPlotPlanckianLocus", "TestPlotPlanckianLocusInChromaticityDiagram", "TestPlotPlanckianLocusInChromaticityDiagramCIE1931", @@ -30,6 +36,20 @@ ] +class TestLinesDaylightLocus(unittest.TestCase): + """ + Define :func:`colour.plotting.diagrams.lines_daylight_locus` definition + unit tests methods. + """ + + def test_lines_daylight_locus(self): + """ + Test :func:`colour.plotting.diagrams.lines_daylight_locus` definition. + """ + + self.assertEqual(len(lines_daylight_locus()), 1) + + class TestPlotDaylightLocus(unittest.TestCase): """ Define :func:`colour.plotting.temperature.plot_daylight_locus` definition @@ -62,6 +82,20 @@ def test_plot_daylight_locus(self): self.assertIsInstance(axes, Axes) +class TestLinesPlanckianLocus(unittest.TestCase): + """ + Define :func:`colour.plotting.diagrams.lines_planckian_locus` definition + unit tests methods. + """ + + def test_lines_planckian_locus(self): + """ + Test :func:`colour.plotting.diagrams.lines_planckian_locus` definition. + """ + + self.assertEqual(len(lines_planckian_locus()), 2) + + class TestPlotPlanckianLocus(unittest.TestCase): """ Define :func:`colour.plotting.temperature.plot_planckian_locus` definition diff --git a/colour/plotting/tests/test_volume.py b/colour/plotting/tests/test_volume.py index 4f2f8abc87..0c914a01e5 100644 --- a/colour/plotting/tests/test_volume.py +++ b/colour/plotting/tests/test_volume.py @@ -1,12 +1,15 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.plotting.volume` module.""" -import numpy as np import unittest -from matplotlib.pyplot import Axes, Figure +import numpy as np +from matplotlib.axes import Axes +from matplotlib.figure import Figure + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.plotting import plot_RGB_colourspaces_gamuts, plot_RGB_scatter -from colour.plotting.volume import nadir_grid, RGB_identity_cube +from colour.plotting.volume import RGB_identity_cube, nadir_grid __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -34,7 +37,7 @@ def test_nadir_grid(self): quads, faces_colours, edges_colours = nadir_grid(segments=1) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( quads, np.array( [ @@ -82,10 +85,10 @@ def test_nadir_grid(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( faces_colours, np.array( [ @@ -98,10 +101,10 @@ def test_nadir_grid(self): [0.00000000, 0.00000000, 0.00000000, 1.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( edges_colours, np.array( [ @@ -114,7 +117,7 @@ def test_nadir_grid(self): [0.00000000, 0.00000000, 0.00000000, 1.00000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -129,7 +132,7 @@ def test_RGB_identity_cube(self): vertices, RGB = RGB_identity_cube(1, 1, 1) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( vertices, np.array( [ @@ -171,10 +174,10 @@ def test_RGB_identity_cube(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB, np.array( [ @@ -186,7 +189,7 @@ def test_RGB_identity_cube(self): [1.00000000, 0.50000000, 0.50000000], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/plotting/tm3018/components.py b/colour/plotting/tm3018/components.py index 3fd987fdd9..6d0d388c3b 100644 --- a/colour/plotting/tm3018/components.py +++ b/colour/plotting/tm3018/components.py @@ -17,8 +17,11 @@ from __future__ import annotations import os + import numpy as np -import matplotlib.pyplot as plt +from matplotlib.axes import Axes +from matplotlib.figure import Figure +from matplotlib.patches import Circle from colour.algebra import sdiv, sdiv_mode from colour.colorimetry import sd_to_XYZ @@ -201,7 +204,7 @@ @override_style() def plot_spectra_ANSIIESTM3018( specification: ColourQuality_Specification_ANSIIESTM3018, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot a comparison of the spectral distributions of a test emission source and a reference illuminant for *ANSI/IES TM-30-18 Colour Rendition Report*. @@ -259,7 +262,7 @@ def plot_spectra_ANSIIESTM3018( zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_line, ) axes.tick_params(axis="y", which="both", length=0) - axes.set_yticklabels([]) # pyright: ignore + axes.set_yticklabels([]) settings = { "axes": axes, @@ -275,7 +278,7 @@ def plot_spectra_ANSIIESTM3018( def plot_colour_vector_graphic( specification: ColourQuality_Specification_ANSIIESTM3018, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot *Color Vector Graphic* according to *ANSI/IES TM-30-18 Colour Rendition Report*. @@ -348,7 +351,7 @@ def plot_colour_vector_graphic( ) # Circles. - circle = plt.Circle( + circle = Circle( (0, 0), 1, color="black", @@ -358,9 +361,9 @@ def plot_colour_vector_graphic( ) axes.add_artist(circle) for radius in [0.8, 0.9, 1.1, 1.2]: - circle = plt.Circle( + circle = Circle( (0, 0), - radius, # pyright: ignore + radius, color="white", lw=0.75, fill=False, @@ -482,7 +485,7 @@ def plot_16_bin_bars( x_ticker: bool = False, label_orientation: Literal["Horizontal", "Vertical"] | str = "Vertical", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the 16 bin bars for given values according to *ANSI/IES TM-30-18 Colour Rendition Report*. @@ -536,10 +539,10 @@ def plot_16_bin_bars( ) axes.set_xlim(0.5, bar_count + 0.5) if x_ticker: - axes.set_xticks(np.arange(1, bar_count + 1)) # pyright: ignore + axes.set_xticks(np.arange(1, bar_count + 1)) axes.set_xlabel("Hue-Angle Bin (j)") else: - axes.set_xticks([]) # pyright: ignore + axes.set_xticks([]) label_orientation = label_orientation.lower() value_max = np.max(values) @@ -554,7 +557,7 @@ def plot_16_bin_bars( label_template.format(value), xy=(i + 1, value + vo), rotation=90, - fontsize="xx-small", + fontsize="xx-small-colour-science", ha="center", va=va, zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_label, @@ -568,7 +571,7 @@ def plot_16_bin_bars( axes.annotate( label_template.format(value), xy=(i + 1, value + vo), - fontsize="xx-small", + fontsize="xx-small-colour-science", ha="center", va=va, zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_label, @@ -581,7 +584,7 @@ def plot_local_chroma_shifts( specification: ColourQuality_Specification_ANSIIESTM3018, x_ticker: bool = False, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the local chroma shifts according to *ANSI/IES TM-30-18 Colour Rendition Report*. @@ -626,8 +629,8 @@ def plot_local_chroma_shifts( axes.set_ylabel("Local Chroma Shift ($R_{cs,hj}$)") ticks = np.arange(-40, 41, 10) - axes.set_yticks(ticks) # pyright: ignore - axes.set_yticklabels([f"{value}%" for value in ticks]) # pyright: ignore + axes.set_yticks(ticks) + axes.set_yticklabels([f"{value}%" for value in ticks]) settings = {"show": True} settings.update(kwargs) @@ -639,7 +642,7 @@ def plot_local_hue_shifts( specification: ColourQuality_Specification_ANSIIESTM3018, x_ticker: bool = False, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the local hue shifts according to *ANSI/IES TM-30-18 Colour Rendition Report*. @@ -680,7 +683,7 @@ def plot_local_hue_shifts( specification.R_hs, "{0:.2f}", x_ticker, **settings ) axes.set_ylim(-0.5, 0.5) - axes.set_yticks(np.arange(-0.5, 0.51, 0.1)) # pyright: ignore + axes.set_yticks(np.arange(-0.5, 0.51, 0.1)) axes.set_ylabel("Local Hue Shift ($R_{hs,hj}$)") settings = {"show": True} @@ -693,7 +696,7 @@ def plot_local_colour_fidelities( specification: ColourQuality_Specification_ANSIIESTM3018, x_ticker: bool = False, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the local colour fidelities according to *ANSI/IES TM-30-18 Colour Rendition Report*. @@ -734,7 +737,7 @@ def plot_local_colour_fidelities( specification.R_fs, "{0:.0f}", x_ticker, "Horizontal", **settings ) axes.set_ylim(0, 100) - axes.set_yticks(np.arange(0, 101, 10)) # pyright: ignore + axes.set_yticks(np.arange(0, 101, 10)) axes.set_ylabel("Local Color Fidelity ($R_{f,hj}$)") settings = {"show": True} @@ -745,7 +748,7 @@ def plot_local_colour_fidelities( def plot_colour_fidelity_indexes( specification: ColourQuality_Specification_ANSIIESTM3018, **kwargs: Any -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Plot the local chroma shifts according to *ANSI/IES TM-30-18 Colour Rendition Report*. @@ -791,15 +794,15 @@ def plot_colour_fidelity_indexes( ) axes.set_xlim(0.5, bar_count + 0.5) axes.set_ylim(0, 100) - axes.set_yticks(np.arange(0, 110, 10)) # pyright: ignore + axes.set_yticks(np.arange(0, 110, 10)) axes.set_ylabel("Color Sample Fidelity ($R_{f,CESi}$)") ticks = list(range(1, bar_count + 1, 1)) - axes.set_xticks(ticks) # pyright: ignore + axes.set_xticks(ticks) labels = [ f"CES{i:02d}" if i % 3 == 1 else "" for i in range(1, bar_count + 1) ] - axes.set_xticklabels(labels, rotation=90) # pyright: ignore + axes.set_xticklabels(labels, rotation=90) return render(**kwargs) diff --git a/colour/plotting/tm3018/report.py b/colour/plotting/tm3018/report.py index 5dbae959b6..2d4fdb0b08 100644 --- a/colour/plotting/tm3018/report.py +++ b/colour/plotting/tm3018/report.py @@ -15,18 +15,21 @@ from __future__ import annotations import matplotlib.pyplot as plt +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.colorimetry import SpectralDistribution, sd_to_XYZ from colour.hints import Any, Dict, Literal, Tuple, cast from colour.io import SpectralDistribution_IESTM2714 -from colour.models import XYZ_to_xy, XYZ_to_Luv, Luv_to_uv +from colour.models import Luv_to_uv, XYZ_to_Luv, XYZ_to_xy +from colour.plotting import CONSTANTS_COLOUR_STYLE, override_style, render from colour.plotting.tm3018.components import ( - plot_spectra_ANSIIESTM3018, + plot_colour_fidelity_indexes, plot_colour_vector_graphic, plot_local_chroma_shifts, - plot_local_hue_shifts, plot_local_colour_fidelities, - plot_colour_fidelity_indexes, + plot_local_hue_shifts, + plot_spectra_ANSIIESTM3018, ) from colour.quality import ( ColourQuality_Specification_ANSIIESTM3018, @@ -34,7 +37,6 @@ colour_fidelity_index_ANSIIESTM3018, colour_rendering_index, ) -from colour.plotting import CONSTANTS_COLOUR_STYLE, override_style, render from colour.utilities import ( as_float_scalar, describe_environment, @@ -153,7 +155,7 @@ _VALUE_NOT_APPLICABLE: str = "N/A" -def _plot_report_header(axes: plt.Axes) -> plt.Axes: +def _plot_report_header(axes: Axes) -> Axes: """ Plot the report header, i.e. the title, on given axes. @@ -183,7 +185,7 @@ def _plot_report_header(axes: plt.Axes) -> plt.Axes: return axes -def _plot_report_footer(axes: plt.Axes) -> plt.Axes: +def _plot_report_footer(axes: Axes) -> Axes: """ Plot the report footer on given axes. @@ -228,11 +230,11 @@ def plot_single_sd_colour_rendition_report_full( manufacturer: str | None = None, model: str | None = None, notes: str | None = None, - report_size: tuple = CONSTANT_REPORT_SIZE_FULL, + report_size: tuple[float, float] = CONSTANT_REPORT_SIZE_FULL, report_row_height_ratios: tuple = CONSTANT_REPORT_ROW_HEIGHT_RATIOS_FULL, report_box_padding: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Generate the full *ANSI/IES TM-30-18 Colour Rendition Report* for given spectral distribution. @@ -540,7 +542,7 @@ def plot_single_sd_colour_rendition_report_full( axes_footer = figure.add_subplot(gridspec_footer[0]) _plot_report_footer(axes_footer) - figure.get_layout_engine().set(**report_box_padding) + figure.get_layout_engine().set(**report_box_padding) # pyright: ignore settings = dict(kwargs) settings["tight_layout"] = False @@ -551,13 +553,13 @@ def plot_single_sd_colour_rendition_report_full( @override_style(**CONSTANTS_REPORT_STYLE) def plot_single_sd_colour_rendition_report_intermediate( sd: SpectralDistribution, - report_size: tuple = CONSTANT_REPORT_SIZE_INTERMEDIATE, + report_size: tuple[float, float] = CONSTANT_REPORT_SIZE_INTERMEDIATE, report_row_height_ratios: tuple = ( CONSTANT_REPORT_ROW_HEIGHT_RATIOS_INTERMEDIATE ), report_box_padding: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Generate the intermediate *ANSI/IES TM-30-18 Colour Rendition Report* for given spectral distribution. @@ -646,7 +648,7 @@ def plot_single_sd_colour_rendition_report_intermediate( axes_footer = figure.add_subplot(gridspec_footer[0]) _plot_report_footer(axes_footer) - figure.get_layout_engine().set(**report_box_padding) + figure.get_layout_engine().set(**report_box_padding) # pyright: ignore settings = dict(kwargs) settings["tight_layout"] = False @@ -656,11 +658,11 @@ def plot_single_sd_colour_rendition_report_intermediate( def plot_single_sd_colour_rendition_report_simple( sd: SpectralDistribution, - report_size: tuple = CONSTANT_REPORT_SIZE_SIMPLE, + report_size: tuple[float, float] = CONSTANT_REPORT_SIZE_SIMPLE, report_row_height_ratios: tuple = CONSTANT_REPORT_ROW_HEIGHT_RATIOS_SIMPLE, report_box_padding: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Generate the simple *ANSI/IES TM-30-18 Colour Rendition Report* for given spectral distribution. @@ -739,7 +741,7 @@ def plot_single_sd_colour_rendition_report_simple( axes_footer = figure.add_subplot(gridspec_footer[0]) _plot_report_footer(axes_footer) - figure.get_layout_engine().set(**report_box_padding) + figure.get_layout_engine().set(**report_box_padding) # pyright: ignore settings = dict(kwargs) settings["tight_layout"] = False @@ -751,7 +753,7 @@ def plot_single_sd_colour_rendition_report( sd: SpectralDistribution, method: Literal["Full", "Intermediate", "Simple"] | str = "Full", **kwargs: Any, -) -> Tuple[plt.Figure, plt.Axes]: +) -> Tuple[Figure, Axes]: """ Generate the *ANSI/IES TM-30-18 Colour Rendition Report* for given spectral distribution according to given method. diff --git a/colour/plotting/tm3018/tests/test_components.py b/colour/plotting/tm3018/tests/test_components.py index 913af30cda..9f53ca2955 100644 --- a/colour/plotting/tm3018/tests/test_components.py +++ b/colour/plotting/tm3018/tests/test_components.py @@ -4,22 +4,24 @@ from __future__ import annotations import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.colorimetry import SDS_ILLUMINANTS from colour.hints import cast -from colour.quality import ( - ColourQuality_Specification_ANSIIESTM3018, - colour_fidelity_index_ANSIIESTM3018, -) from colour.plotting.tm3018.components import ( - plot_spectra_ANSIIESTM3018, - plot_colour_vector_graphic, plot_16_bin_bars, + plot_colour_fidelity_indexes, + plot_colour_vector_graphic, plot_local_chroma_shifts, - plot_local_hue_shifts, plot_local_colour_fidelities, - plot_colour_fidelity_indexes, + plot_local_hue_shifts, + plot_spectra_ANSIIESTM3018, +) +from colour.quality import ( + ColourQuality_Specification_ANSIIESTM3018, + colour_fidelity_index_ANSIIESTM3018, ) __author__ = "Colour Developers" diff --git a/colour/plotting/tm3018/tests/test_report.py b/colour/plotting/tm3018/tests/test_report.py index c4ea8ae96c..944490bdea 100644 --- a/colour/plotting/tm3018/tests/test_report.py +++ b/colour/plotting/tm3018/tests/test_report.py @@ -2,14 +2,16 @@ """Define the unit tests for the :mod:`colour.plotting.tm3018.report` module.""" import unittest -from matplotlib.pyplot import Axes, Figure + +from matplotlib.axes import Axes +from matplotlib.figure import Figure from colour.colorimetry import SDS_ILLUMINANTS from colour.plotting.tm3018.report import ( + plot_single_sd_colour_rendition_report, plot_single_sd_colour_rendition_report_full, plot_single_sd_colour_rendition_report_intermediate, plot_single_sd_colour_rendition_report_simple, - plot_single_sd_colour_rendition_report, ) __author__ = "Colour Developers" diff --git a/colour/plotting/volume.py b/colour/plotting/volume.py index a927375138..a74e8c3e80 100644 --- a/colour/plotting/volume.py +++ b/colour/plotting/volume.py @@ -12,11 +12,12 @@ import matplotlib.pyplot as plt import numpy as np -from mpl_toolkits.mplot3d.axes3d import Axes3D +from matplotlib.figure import Figure from mpl_toolkits.mplot3d.art3d import Poly3DCollection +from mpl_toolkits.mplot3d.axes3d import Axes3D -from colour.constants import EPSILON from colour.colorimetry import MultiSpectralDistributions +from colour.constants import EPSILON from colour.geometry import ( primitive_vertices_cube_mpl, primitive_vertices_grid_mpl, @@ -27,6 +28,8 @@ ArrayLike, List, Literal, + LiteralColourspaceModel, + LiteralRGBColourspace, NDArrayFloat, Sequence, Tuple, @@ -37,16 +40,16 @@ from colour.plotting import ( CONSTANTS_COLOUR_STYLE, colourspace_model_axis_reorder, - filter_RGB_colourspaces, filter_cmfs, + filter_RGB_colourspaces, override_style, render, ) from colour.utilities import ( Structure, as_float_array, - as_int_scalar, as_int_array, + as_int_scalar, first_item, full, is_integer, @@ -418,34 +421,11 @@ def RGB_identity_cube( @override_style() def plot_RGB_colourspaces_gamuts( - colourspaces: RGB_Colourspace | str | Sequence[RGB_Colourspace | str], - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE Luv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - ] - | str = "CIE xyY", + colourspaces: RGB_Colourspace + | LiteralRGBColourspace + | str + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str], + model: LiteralColourspaceModel | str = "CIE xyY", segments: int = 8, show_grid: bool = True, grid_segments: int = 10, @@ -459,14 +439,14 @@ def plot_RGB_colourspaces_gamuts( chromatically_adapt: bool = False, convert_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, Axes3D]: +) -> Tuple[Figure, Axes3D]: """ Plot given *RGB* colourspaces gamuts in given reference colourspace. Parameters ---------- colourspaces - *RGB* colourspaces to plot the gamuts. ``colourspaces`` elements + *RGB* colourspaces to plot the gamuts of. ``colourspaces`` elements can be of any type or form supported by the :func:`colour.plotting.common.filter_RGB_colourspaces` definition. model @@ -561,7 +541,7 @@ def plot_RGB_colourspaces_gamuts( settings.update(kwargs) figure = plt.figure() - axes = figure.add_subplot(111, projection="3d") + axes = cast(Axes3D, figure.add_subplot(111, projection="3d")) points = zeros((4, 3)) if show_spectral_locus: @@ -676,8 +656,8 @@ def plot_RGB_colourspaces_gamuts( RGB_e = np.vstack([RGB_ge, RGB_e]) collection = Poly3DCollection(quads) - collection.set_facecolors(RGB_f) - collection.set_edgecolors(RGB_e) + collection.set_facecolors(RGB_f) # pyright: ignore + collection.set_edgecolors(RGB_e) # pyright: ignore axes.add_collection3d(collection) @@ -686,7 +666,7 @@ def plot_RGB_colourspaces_gamuts( ) settings.update(kwargs) - return render(**settings) + return cast(Tuple[Figure, Axes3D], render(**settings)) @override_style() @@ -694,37 +674,11 @@ def plot_RGB_scatter( RGB: ArrayLike, colourspace: RGB_Colourspace | str - | Sequence[RGB_Colourspace | str] = "sRGB", - model: Literal[ - "CAM02LCD", - "CAM02SCD", - "CAM02UCS", - "CAM16LCD", - "CAM16SCD", - "CAM16UCS", - "CIE XYZ", - "CIE xyY", - "CIE Lab", - "CIE Luv", - "CIE UCS", - "CIE UVW", - "DIN99", - "Hunter Lab", - "Hunter Rdab", - "ICaCb", - "ICtCp", - "IPT", - "IgPgTg", - "Jzazbz", - "OSA UCS", - "Oklab", - "hdr-CIELAB", - "hdr-IPT", - ] - | str = "CIE xyY", + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str] = "sRGB", + model: LiteralColourspaceModel | str = "CIE xyY", colourspaces: RGB_Colourspace | str - | Sequence[RGB_Colourspace | str] + | Sequence[RGB_Colourspace | LiteralRGBColourspace | str] | None = None, segments: int = 8, show_grid: bool = True, @@ -740,7 +694,7 @@ def plot_RGB_scatter( chromatically_adapt: bool = False, convert_kwargs: dict | None = None, **kwargs: Any, -) -> Tuple[plt.Figure, Axes3D]: +) -> Tuple[Figure, Axes3D]: """ Plot given *RGB* colourspace array in a scatter plot. @@ -756,7 +710,7 @@ def plot_RGB_scatter( Colourspace model, see :attr:`colour.COLOURSPACE_MODELS` attribute for the list of supported colourspace models. colourspaces - *RGB* colourspaces to plot the gamuts. ``colourspaces`` elements + *RGB* colourspaces to plot the gamuts of. ``colourspaces`` elements can be of any type or form supported by the :func:`colour.plotting.common.filter_RGB_colourspaces` definition. segments @@ -852,12 +806,12 @@ def plot_RGB_scatter( points[..., 0], points[..., 1], points[..., 2], - color=np.reshape(RGB, (-1, 3)), - s=points_size, + c=np.reshape(RGB, (-1, 3)), + s=points_size, # pyright: ignore zorder=CONSTANTS_COLOUR_STYLE.zorder.midground_scatter, ) settings.update({"axes": axes, "show": True}) settings.update(kwargs) - return render(**settings) + return cast(Tuple[Figure, Axes3D], render(**settings)) diff --git a/colour/quality/cfi2017.py b/colour/quality/cfi2017.py index bb0da1f032..60c47dbcdc 100644 --- a/colour/quality/cfi2017.py +++ b/colour/quality/cfi2017.py @@ -15,30 +15,31 @@ from __future__ import annotations -import numpy as np import os from dataclasses import dataclass +import numpy as np + from colour.algebra import Extrapolator, euclidean_distance, linstep_function from colour.appearance import ( + VIEWING_CONDITIONS_CIECAM02, CAM_Specification_CIECAM02, XYZ_to_CIECAM02, - VIEWING_CONDITIONS_CIECAM02, ) from colour.colorimetry import ( MSDS_CMFS, MultiSpectralDistributions, - SpectralShape, SpectralDistribution, + SpectralShape, msds_to_XYZ, - sd_to_XYZ, - sd_blackbody, reshape_msds, + sd_blackbody, sd_CIE_illuminant_D_series, + sd_to_XYZ, ) from colour.hints import ArrayLike, List, NDArrayFloat, Tuple, cast -from colour.models import XYZ_to_UCS, UCS_to_uv, JMh_CIECAM02_to_CAM02UCS -from colour.temperature import uv_to_CCT_Ohno2013, CCT_to_xy_CIE_D +from colour.models import JMh_CIECAM02_to_CAM02UCS, UCS_to_uv, XYZ_to_UCS +from colour.temperature import CCT_to_xy_CIE_D, uv_to_CCT_Ohno2013 from colour.utilities import ( CACHE_REGISTRY, as_float, @@ -46,6 +47,7 @@ as_float_scalar, as_int_scalar, attest, + is_caching_enabled, tsplit, tstack, usage_warning, @@ -277,7 +279,7 @@ def load_TCS_CIE2017(shape: SpectralShape) -> MultiSpectralDistributions: filename = f"tcs_cfi2017_{as_int_scalar(interval)}_nm.csv.gz" - if filename in _CACHE_TCS_CIE2017: + if is_caching_enabled() and filename in _CACHE_TCS_CIE2017: return _CACHE_TCS_CIE2017[filename] data = np.genfromtxt( diff --git a/colour/quality/cqs.py b/colour/quality/cqs.py index 067320e676..dd6b5710d1 100644 --- a/colour/quality/cqs.py +++ b/colour/quality/cqs.py @@ -23,20 +23,22 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass +import numpy as np + +from colour.adaptation import chromatic_adaptation_VonKries from colour.algebra import euclidean_distance, sdiv, sdiv_mode from colour.colorimetry import ( CCS_ILLUMINANTS, MSDS_CMFS, - MultiSpectralDistributions, SPECTRAL_SHAPE_DEFAULT, + MultiSpectralDistributions, SpectralDistribution, reshape_msds, reshape_sd, - sd_CIE_illuminant_D_series, sd_blackbody, + sd_CIE_illuminant_D_series, sd_to_XYZ, ) from colour.hints import ( @@ -57,7 +59,6 @@ ) from colour.quality.datasets.vs import INDEXES_TO_NAMES_VS, SDS_VS from colour.temperature import CCT_to_xy_CIE_D, uv_to_CCT_Ohno2013 -from colour.adaptation import chromatic_adaptation_VonKries from colour.utilities import ( as_float_array, domain_range_scale, diff --git a/colour/quality/cri.py b/colour/quality/cri.py index acc0a0434d..b12f1904b2 100644 --- a/colour/quality/cri.py +++ b/colour/quality/cri.py @@ -17,19 +17,20 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass +import numpy as np + from colour.algebra import euclidean_distance, sdiv, sdiv_mode, spow from colour.colorimetry import ( MSDS_CMFS, - MultiSpectralDistributions, SPECTRAL_SHAPE_DEFAULT, + MultiSpectralDistributions, SpectralDistribution, reshape_msds, reshape_sd, - sd_CIE_illuminant_D_series, sd_blackbody, + sd_CIE_illuminant_D_series, sd_to_XYZ, ) from colour.hints import Dict, NDArrayFloat, Tuple, cast diff --git a/colour/quality/tests/test_cfi2017.py b/colour/quality/tests/test_cfi2017.py index f9a5cf29cb..8f3fa9e9f2 100644 --- a/colour/quality/tests/test_cfi2017.py +++ b/colour/quality/tests/test_cfi2017.py @@ -9,20 +9,21 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( SDS_ILLUMINANTS, - SpectralShape, SpectralDistribution, + SpectralShape, reshape_sd, sd_blackbody, ) from colour.quality.cfi2017 import ( CCT_reference_illuminant, - sd_reference_illuminant, colour_fidelity_index_CIE2017, + sd_reference_illuminant, ) from colour.utilities import ColourUsageWarning @@ -552,8 +553,8 @@ def test_colour_fidelity_index_CIE2017(self): specification = colour_fidelity_index_CIE2017( sd, additional_data=True ) - np.testing.assert_array_almost_equal(specification.R_f, 81.6, 1) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose(specification.R_f, 81.6, atol=0.1) + np.testing.assert_allclose( specification.R_s, [ 89.5, @@ -656,14 +657,14 @@ def test_colour_fidelity_index_CIE2017(self): 84.2, 77.4, ], - 1, + atol=0.1, ) specification = colour_fidelity_index_CIE2017( SDS_ILLUMINANTS["FL1"], additional_data=True ) - np.testing.assert_array_almost_equal(specification.R_f, 80.6, 1) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose(specification.R_f, 80.6, atol=0.1) + np.testing.assert_allclose( specification.R_s, [ 85.1, @@ -766,14 +767,14 @@ def test_colour_fidelity_index_CIE2017(self): 75.2, 55.5, ], - 1, + atol=0.1, ) specification = colour_fidelity_index_CIE2017( SDS_ILLUMINANTS["FL2"], additional_data=True ) - np.testing.assert_array_almost_equal(specification.R_f, 70.1, 1) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose(specification.R_f, 70.1, atol=0.1) + np.testing.assert_allclose( specification.R_s, [ 78.9, @@ -876,7 +877,7 @@ def test_colour_fidelity_index_CIE2017(self): 67.0, 45.0, ], - 1, + atol=0.1, ) def test_raise_exception_colour_fidelity_index_CFI2017(self): @@ -906,7 +907,7 @@ def test_CCT_reference_illuminant(self): for sd in [SD_SAMPLE_5NM, SD_SAMPLE_1NM]: CCT, D_uv = CCT_reference_illuminant(sd) - np.testing.assert_allclose(CCT, 3287.5, rtol=0.25) + np.testing.assert_allclose(CCT, 3287.5, atol=0.5) np.testing.assert_allclose(D_uv, -0.000300000000000, atol=0.0005) @@ -932,7 +933,7 @@ def test_sd_reference_illuminant(self): np.testing.assert_allclose( sd_reference.values, sd_blackbody(3288, shape).values, - rtol=0.005, + atol=1.75, ) diff --git a/colour/quality/tests/test_cqs.py b/colour/quality/tests/test_cqs.py index 30e78a8232..8476d6ffd7 100644 --- a/colour/quality/tests/test_cqs.py +++ b/colour/quality/tests/test_cqs.py @@ -1,14 +1,16 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.quality.cqs` module.""" -import numpy as np import unittest +import numpy as np + +from colour.colorimetry import SDS_ILLUMINANTS, SDS_LIGHT_SOURCES +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.quality import ( ColourRendering_Specification_CQS, colour_quality_scale, ) -from colour.colorimetry import SDS_ILLUMINANTS, SDS_LIGHT_SOURCES from colour.quality.cqs import DataColorimetry_VS, DataColourQualityScale_VS __author__ = "Colour Developers" @@ -32,64 +34,64 @@ class TestColourQualityScale(unittest.TestCase): def test_colour_quality_scale(self): """Test :func:`colour.quality.cqs.colour_quality_scale` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale(SDS_ILLUMINANTS["FL1"]), 74.982585798279914, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale( SDS_ILLUMINANTS["FL1"], method="NIST CQS 7.4" ), 75.377089740493361, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale(SDS_ILLUMINANTS["FL2"]), 64.111822015662852, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale( SDS_ILLUMINANTS["FL2"], method="NIST CQS 7.4" ), 64.774586908581369, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale(SDS_LIGHT_SOURCES["Neodimium Incandescent"]), 89.737456186836681, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale( SDS_LIGHT_SOURCES["Neodimium Incandescent"], method="NIST CQS 7.4", ), 87.700300087538821, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale( SDS_LIGHT_SOURCES["F32T8/TL841 (Triphosphor)"] ), 84.934928463428903, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_quality_scale( SDS_LIGHT_SOURCES["F32T8/TL841 (Triphosphor)"], method="NIST CQS 7.4", ), 83.255457439460713, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification_r = ColourRendering_Specification_CQS( @@ -404,7 +406,7 @@ def test_colour_quality_scale(self): SDS_ILLUMINANTS["FL1"], additional_data=True, method="NIST CQS 7.4" ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( [ data.Q_a for _index, data in sorted(specification_r.Q_as.items()) @@ -413,7 +415,7 @@ def test_colour_quality_scale(self): data.Q_a for _index, data in sorted(specification_t.Q_as.items()) ], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification_r = ColourRendering_Specification_CQS( @@ -728,7 +730,7 @@ def test_colour_quality_scale(self): SDS_ILLUMINANTS["FL1"], additional_data=True, method="NIST CQS 9.0" ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( [ data.Q_a for _index, data in sorted(specification_r.Q_as.items()) @@ -737,7 +739,7 @@ def test_colour_quality_scale(self): data.Q_a for _index, data in sorted(specification_t.Q_as.items()) ], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/quality/tests/test_cri.py b/colour/quality/tests/test_cri.py index e5db1ed11f..66526a4f56 100644 --- a/colour/quality/tests/test_cri.py +++ b/colour/quality/tests/test_cri.py @@ -3,10 +3,12 @@ from __future__ import annotations -import numpy as np import unittest +import numpy as np + from colour.colorimetry import SDS_ILLUMINANTS, SpectralDistribution +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.quality import ( ColourRendering_Specification_CRI, colour_rendering_index, @@ -118,28 +120,28 @@ class TestColourRenderingIndex(unittest.TestCase): def test_colour_rendering_index(self): """Test :func:`colour.quality.cri.colour_rendering_index` definition.""" - self.assertAlmostEqual( + np.testing.assert_allclose( colour_rendering_index(SDS_ILLUMINANTS["FL1"]), 75.852827992149358, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_rendering_index(SDS_ILLUMINANTS["FL2"]), 64.233724121664778, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_rendering_index(SDS_ILLUMINANTS["A"]), 99.996230290506887, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( colour_rendering_index(SpectralDistribution(DATA_SAMPLE)), 70.815265381660197, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) specification_r = ColourRendering_Specification_CRI( @@ -377,7 +379,7 @@ def test_colour_rendering_index(self): SDS_ILLUMINANTS["FL1"], additional_data=True ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( [ data.Q_a for _index, data in sorted(specification_r.Q_as.items()) @@ -386,7 +388,7 @@ def test_colour_rendering_index(self): data.Q_a for _index, data in sorted(specification_t.Q_as.items()) ], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/quality/tests/test_ssi.py b/colour/quality/tests/test_ssi.py index 4ea7dd55f8..b266fdcb81 100644 --- a/colour/quality/tests/test_ssi.py +++ b/colour/quality/tests/test_ssi.py @@ -5,6 +5,8 @@ import unittest +import numpy as np + from colour.colorimetry import SDS_ILLUMINANTS, SpectralDistribution from colour.quality import spectral_similarity_index @@ -583,23 +585,23 @@ def test_spectral_similarity_rounding(self): """ # Test values were computed at ed2e90 - self.assertAlmostEqual( + np.testing.assert_allclose( spectral_similarity_index( SDS_ILLUMINANTS["C"], SDS_ILLUMINANTS["D65"], round_result=False, ), 94.182, - places=2, + atol=0.01, ) - self.assertAlmostEqual( + np.testing.assert_allclose( spectral_similarity_index( SpectralDistribution(DATA_HMI), SDS_ILLUMINANTS["D50"], round_result=False, ), 71.775, - places=2, + atol=0.01, ) diff --git a/colour/quality/tests/test_tm3018.py b/colour/quality/tests/test_tm3018.py index 0ccb439890..11b3510654 100644 --- a/colour/quality/tests/test_tm3018.py +++ b/colour/quality/tests/test_tm3018.py @@ -8,9 +8,10 @@ http://media.ies.org/docs/errata/TM-30-18_tools_etc.zip. """ -import numpy as np import unittest +import numpy as np + from colour.colorimetry import SDS_ILLUMINANTS from colour.quality.tm3018 import ( averages_area, @@ -47,12 +48,12 @@ def test_colour_fidelity_index_ANSIIESTM3018(self): SDS_ILLUMINANTS["FL2"], additional_data=True ) - np.testing.assert_array_almost_equal(specification.R_f, 70, 0) - np.testing.assert_array_almost_equal(specification.R_g, 86, 0) - np.testing.assert_array_almost_equal(specification.CCT, 4225, 0) - np.testing.assert_array_almost_equal(specification.D_uv, 0.0019, 4) + np.testing.assert_allclose(specification.R_f, 70, atol=2e-1) + np.testing.assert_allclose(specification.R_g, 86, atol=5e-1) + np.testing.assert_allclose(specification.CCT, 4225, atol=1) + np.testing.assert_allclose(specification.D_uv, 0.0019, atol=1e-3) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( specification.R_s, [ 79, @@ -155,20 +156,20 @@ def test_colour_fidelity_index_ANSIIESTM3018(self): 67, 45, ], - 0, + atol=0.75, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( specification.R_fs, [60, 61, 53, 68, 80, 88, 77, 73, 76, 62, 70, 77, 81, 71, 64, 65], - 0, + atol=0.75, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( specification.R_cs, [-25, -18, -9, 5, 11, 4, -8, -15, -17, -15, -4, 5, 11, 7, -6, -16], - 0, + atol=0.75, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( specification.R_hs, [ -0.02, @@ -188,7 +189,7 @@ def test_colour_fidelity_index_ANSIIESTM3018(self): -0.26, -0.17, ], - 2, + atol=0.75, ) diff --git a/colour/quality/tm3018.py b/colour/quality/tm3018.py index e24de166ae..b61f4fa098 100644 --- a/colour/quality/tm3018.py +++ b/colour/quality/tm3018.py @@ -19,9 +19,10 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass +import numpy as np + from colour.colorimetry import SpectralDistribution from colour.hints import ArrayLike, NDArrayFloat, NDArrayInt, Tuple, cast from colour.quality import colour_fidelity_index_CIE2017 @@ -146,7 +147,7 @@ def colour_fidelity_index_ANSIIESTM3018( np.floor(specification.colorimetry_data[1].JMh[:, 2] / 22.5) ) - bin_mask = bins == np.arange(16).reshape(-1, 1) + bin_mask = bins == np.arange(16).reshape([-1, 1]) # "bin_mask" is used later with Numpy broadcasting and "np.nanmean" # to skip a list comprehension and keep all the mean calculation vectorised @@ -185,7 +186,7 @@ def colour_fidelity_index_ANSIIESTM3018( # Local colour fidelity indexes, i.e. 16 CFIs for each bin. bin_delta_E_s = np.nanmean( - specification.delta_E_s.reshape(1, -1) * bin_mask, axis=1 + specification.delta_E_s.reshape([1, -1]) * bin_mask, axis=1 ) R_fs = as_float_array(delta_E_to_R_f(bin_delta_E_s)) diff --git a/colour/recovery/jakob2019.py b/colour/recovery/jakob2019.py index f0f583aaf5..921133ea7a 100644 --- a/colour/recovery/jakob2019.py +++ b/colour/recovery/jakob2019.py @@ -19,13 +19,13 @@ from __future__ import annotations -import numpy as np import struct -from scipy.optimize import minimize + +import numpy as np from scipy.interpolate import RegularGridInterpolator +from scipy.optimize import minimize from colour.algebra import smoothstep_function, spow -from colour.constants import DEFAULT_INT_DTYPE from colour.colorimetry import ( MultiSpectralDistributions, SpectralDistribution, @@ -34,6 +34,7 @@ intermediate_lightness_function_CIE1976, sd_to_XYZ_integration, ) +from colour.constants import DTYPE_INT_DEFAULT from colour.difference import JND_CIE1976 from colour.hints import ( ArrayLike, @@ -41,7 +42,7 @@ NDArrayFloat, Tuple, ) -from colour.models import RGB_Colourspace, XYZ_to_xy, XYZ_to_Lab, RGB_to_XYZ +from colour.models import RGB_Colourspace, RGB_to_XYZ, XYZ_to_Lab, XYZ_to_xy from colour.utilities import ( as_float_array, as_float_scalar, @@ -921,7 +922,7 @@ def optimize( appropriate cell. """ - i, j, k, L = tsplit(ijkL, dtype=DEFAULT_INT_DTYPE) + i, j, k, L = tsplit(ijkL, dtype=DTYPE_INT_DEFAULT) RGB = self._lightness_scale[L] * chroma @@ -951,7 +952,7 @@ def optimize( # Down the lightness scale. coefficients_0 = coefficients_middle - for L in reversed(range(0, L_middle)): + for L in reversed(range(L_middle)): coefficients_0 = optimize( np.hstack([ijk, L]), coefficients_0, chroma ) diff --git a/colour/recovery/jiang2013.py b/colour/recovery/jiang2013.py index 3368e03fca..28339c841e 100644 --- a/colour/recovery/jiang2013.py +++ b/colour/recovery/jiang2013.py @@ -38,8 +38,7 @@ cast, ) from colour.recovery import BASIS_FUNCTIONS_DYER2017 -from colour.utilities import as_float_array, optional, tsplit, runtime_warning - +from colour.utilities import as_float_array, optional, runtime_warning, tsplit __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/recovery/mallett2019.py b/colour/recovery/mallett2019.py index a433e5ea33..34a3a849ef 100644 --- a/colour/recovery/mallett2019.py +++ b/colour/recovery/mallett2019.py @@ -26,8 +26,8 @@ SpectralDistribution, handle_spectral_arguments, ) -from colour.models import RGB_Colourspace from colour.hints import ArrayLike, Callable +from colour.models import RGB_Colourspace from colour.recovery import MSDS_BASIS_FUNCTIONS_sRGB_MALLETT2019 from colour.utilities import to_domain_1 diff --git a/colour/recovery/meng2015.py b/colour/recovery/meng2015.py index 6c5e51263d..218242afd2 100644 --- a/colour/recovery/meng2015.py +++ b/colour/recovery/meng2015.py @@ -28,7 +28,7 @@ sd_to_XYZ_integration, ) from colour.hints import ArrayLike, NDArrayFloat, cast -from colour.utilities import to_domain_1, from_range_100 +from colour.utilities import from_range_100, to_domain_1 __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/recovery/otsu2018.py b/colour/recovery/otsu2018.py index 5017916958..f3acaa0992 100644 --- a/colour/recovery/otsu2018.py +++ b/colour/recovery/otsu2018.py @@ -18,9 +18,10 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass +import numpy as np + from colour.algebra import eigen_decomposition from colour.colorimetry import ( MultiSpectralDistributions, @@ -36,18 +37,18 @@ ArrayLike, Callable, Dict, - List, NDArrayFloat, Self, + Sequence, Tuple, cast, ) from colour.models import XYZ_to_xy from colour.recovery import ( - SPECTRAL_SHAPE_OTSU2018, BASIS_FUNCTIONS_OTSU2018, CLUSTER_MEANS_OTSU2018, SELECTOR_ARRAY_OTSU2018, + SPECTRAL_SHAPE_OTSU2018, ) from colour.utilities import ( Node, @@ -814,7 +815,9 @@ def origin(self, i: int, direction: int) -> float: else: raise ValueError('The "chromaticity coordinates" are undefined!') - def partition(self, axis: PartitionAxis) -> Tuple[Self, Self]: + def partition( + self, axis: PartitionAxis + ) -> Tuple[Data_Otsu2018, Data_Otsu2018]: """ Partition the data using given partition axis. @@ -1016,7 +1019,7 @@ def __init__( self._partition_axis: PartitionAxis | None = None self._best_partition: Tuple[ - List[Node_Otsu2018], PartitionAxis, float + Sequence[Node_Otsu2018], PartitionAxis, float ] | None = None @property @@ -1058,7 +1061,7 @@ def row(self) -> Tuple[float, float, Self, Self]: else: raise ValueError('The "partition axis" is undefined!') - def split(self, children: List[Self], axis: PartitionAxis): + def split(self, children: Sequence[Self], axis: PartitionAxis): """ Convert the leaf node into an inner node using given children and partition axis. @@ -1080,7 +1083,7 @@ def split(self, children: List[Self], axis: PartitionAxis): def minimise( self, minimum_cluster_size: int - ) -> Tuple[List[Self], PartitionAxis, float]: + ) -> Tuple[Sequence[Node_Otsu2018], PartitionAxis, float]: """ Find the best partition for the node that minimises the leaf reconstruction error. @@ -1089,7 +1092,7 @@ def minimise( ---------- minimum_cluster_size Smallest acceptable cluster size. It must be at least 3 or the - *Principal Component Analysis* (PCA) is not be possible. + *Principal Component Analysis* (PCA) is not possible. Returns ------- diff --git a/colour/recovery/smits1999.py b/colour/recovery/smits1999.py index 2a36c68ed2..09f605ebea 100644 --- a/colour/recovery/smits1999.py +++ b/colour/recovery/smits1999.py @@ -16,9 +16,9 @@ from colour.colorimetry import CCS_ILLUMINANTS, SpectralDistribution from colour.hints import ArrayLike, NDArrayFloat from colour.models import ( - XYZ_to_RGB, RGB_Colourspace, RGB_COLOURSPACE_sRGB, + XYZ_to_RGB, ) from colour.recovery import SDS_SMITS1999 from colour.utilities import to_domain_1 diff --git a/colour/recovery/tests/test__init__.py b/colour/recovery/tests/test__init__.py index 28a55ce5ec..c91d94cc93 100644 --- a/colour/recovery/tests/test__init__.py +++ b/colour/recovery/tests/test__init__.py @@ -1,9 +1,10 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.recovery` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( MSDS_CMFS, SDS_ILLUMINANTS, @@ -12,6 +13,7 @@ reshape_sd, sd_to_XYZ_integration, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.recovery import XYZ_to_sd from colour.utilities import domain_range_scale @@ -72,7 +74,7 @@ def test_domain_range_scale_XYZ_to_sd(self): for method, value in zip(m, v): for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( XYZ_to_sd( XYZ * factor_a, @@ -84,7 +86,7 @@ def test_domain_range_scale_XYZ_to_sd(self): self._sd_D65, ), value * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/recovery/tests/test_jakob2019.py b/colour/recovery/tests/test_jakob2019.py index e5a45db23d..ed59239628 100644 --- a/colour/recovery/tests/test_jakob2019.py +++ b/colour/recovery/tests/test_jakob2019.py @@ -1,14 +1,16 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.recovery.jakob2019` module.""" -import numpy as np import os import shutil import tempfile import unittest +import numpy as np + from colour.characterisation import SDS_COLOURCHECKERS from colour.colorimetry import handle_spectral_arguments, sd_to_XYZ +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.difference import JND_CIE1976, delta_E_CIE1976 from colour.models import ( RGB_COLOURSPACE_sRGB, @@ -17,12 +19,12 @@ XYZ_to_xy, ) from colour.recovery.jakob2019 import ( - XYZ_to_sd_Jakob2019, - sd_Jakob2019, - error_function, - dimensionalise_coefficients, SPECTRAL_SHAPE_JAKOB2019, LUT3D_Jakob2019, + XYZ_to_sd_Jakob2019, + dimensionalise_coefficients, + error_function, + sd_Jakob2019, ) from colour.utilities import domain_range_scale, full, ones, zeros @@ -99,8 +101,12 @@ def test_intermediates(self): sd_Lab = XYZ_to_Lab(XYZ, self._xy_D65) error_reference = delta_E_CIE1976(self._Lab_e, Lab) - np.testing.assert_allclose(sd.values, R, atol=1e-14) - np.testing.assert_allclose(XYZ, sd_XYZ, atol=1e-14) + np.testing.assert_allclose( + sd.values, R, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + XYZ, sd_XYZ, atol=TOLERANCE_ABSOLUTE_TESTS + ) self.assertLess(abs(error_reference - error), JND_CIE1976 / 100) self.assertLess(delta_E_CIE1976(Lab, sd_Lab), JND_CIE1976 / 100) @@ -136,7 +142,7 @@ def test_derivatives(self): # The approximated derivatives aren't too accurate, so tolerances # have to be rather loose. np.testing.assert_allclose( - staggered_derrors, approximate_derrors, atol=1e-3, rtol=1e-2 + staggered_derrors, approximate_derrors, atol=5e-3 ) @@ -184,7 +190,7 @@ def test_domain_range_scale_XYZ_to_sd_Jakob2019(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ( XYZ_to_sd_Jakob2019( XYZ_i * factor_a, self._cmfs, self._sd_D65 @@ -193,7 +199,7 @@ def test_domain_range_scale_XYZ_to_sd_Jakob2019(self): self._sd_D65, ), XYZ_o * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -269,12 +275,12 @@ def test_lightness_scale(self): property. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( TestLUT3D_Jakob2019.generate_LUT().lightness_scale, np.array( [0.00000000, 0.06561279, 0.50000000, 0.93438721, 1.00000000] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_coefficients(self): @@ -303,14 +309,15 @@ def test_LUT3D_Jakob2019(self): LUT.write(path) LUT_t = LUT3D_Jakob2019().read(path) - np.testing.assert_array_almost_equal( - LUT.lightness_scale, LUT_t.lightness_scale, decimal=7 + np.testing.assert_allclose( + LUT.lightness_scale, + LUT_t.lightness_scale, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( LUT.coefficients, LUT_t.coefficients, - atol=0.000001, - rtol=0.000001, + atol=1e-6, ) finally: shutil.rmtree(temporary_directory) diff --git a/colour/recovery/tests/test_jiang2013.py b/colour/recovery/tests/test_jiang2013.py index 03a6f382cc..3589a62e93 100644 --- a/colour/recovery/tests/test_jiang2013.py +++ b/colour/recovery/tests/test_jiang2013.py @@ -1,9 +1,14 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.recovery.jiang2013` module.""" -import numpy as np import unittest +import numpy as np + +from colour.characterisation import ( + MSDS_CAMERA_SENSITIVITIES, + SDS_COLOURCHECKERS, +) from colour.colorimetry import ( SDS_ILLUMINANTS, SpectralDistribution, @@ -13,17 +18,14 @@ reshape_sd, sds_and_msds_to_msds, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.hints import cast -from colour.characterisation import ( - MSDS_CAMERA_SENSITIVITIES, - SDS_COLOURCHECKERS, -) from colour.recovery import ( BASIS_FUNCTIONS_DYER2017, + SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, PCA_Jiang2013, - RGB_to_sd_camera_sensitivity_Jiang2013, RGB_to_msds_camera_sensitivities_Jiang2013, - SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, + RGB_to_sd_camera_sensitivity_Jiang2013, ) from colour.utilities import tsplit @@ -60,7 +62,7 @@ def test_PCA_Jiang2013(self): # TODO: Last eigen value seems to be very sensitive and produce # differences on ARM. - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(w)[..., 0:2], np.array( [ @@ -165,9 +167,9 @@ def test_PCA_Jiang2013(self): ], ] )[..., 0:2], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(v)[..., 0:2], np.array( [ @@ -176,7 +178,7 @@ def test_PCA_Jiang2013(self): [1.90414282e01, 2.60426480e00, 5.11235833e-15], ] )[..., 0:2], - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -229,7 +231,7 @@ def test_RGB_to_sd_camera_sensitivity_Jiang2013(self): R_w, _G_w, _B_w = tsplit(np.moveaxis(BASIS_FUNCTIONS_DYER2017, 0, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_sd_camera_sensitivity_Jiang2013( self._RGB[..., 0], self._sd_D65, @@ -272,7 +274,7 @@ def test_RGB_to_sd_camera_sensitivity_Jiang2013(self): -0.00061428, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -295,7 +297,7 @@ def test_RGB_to_msds_camera_sensitivities_Jiang2013(self): RGB_to_msds_camera_sensitivities_Jiang2013` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_msds_camera_sensitivities_Jiang2013( self._RGB, self._sd_D65, @@ -338,7 +340,7 @@ def test_RGB_to_msds_camera_sensitivities_Jiang2013(self): [-6.00395414e-03, 1.54678227e-03, 5.40394352e-04], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/recovery/tests/test_mallett2019.py b/colour/recovery/tests/test_mallett2019.py index 6f347f0d2a..79bcbe44cc 100644 --- a/colour/recovery/tests/test_mallett2019.py +++ b/colour/recovery/tests/test_mallett2019.py @@ -2,12 +2,13 @@ """Define the unit tests for the :mod:`colour.recovery.mallett2019` module.""" import unittest + import numpy as np from colour.characterisation import SDS_COLOURCHECKERS from colour.colorimetry import ( - MSDS_CMFS, CCS_ILLUMINANTS, + MSDS_CMFS, SDS_ILLUMINANTS, SpectralShape, reshape_msds, @@ -18,13 +19,13 @@ from colour.models import ( RGB_COLOURSPACE_PAL_SECAM, RGB_COLOURSPACE_sRGB, - XYZ_to_RGB, XYZ_to_Lab, + XYZ_to_RGB, ) from colour.recovery import ( MSDS_BASIS_FUNCTIONS_sRGB_MALLETT2019, - spectral_primary_decomposition_Mallett2019, RGB_to_sd_Mallett2019, + spectral_primary_decomposition_Mallett2019, ) __author__ = "Colour Developers" diff --git a/colour/recovery/tests/test_meng2015.py b/colour/recovery/tests/test_meng2015.py index 5c31788560..352adfbc22 100644 --- a/colour/recovery/tests/test_meng2015.py +++ b/colour/recovery/tests/test_meng2015.py @@ -1,9 +1,10 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.recovery.meng2015` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry import ( MSDS_CMFS, SDS_ILLUMINANTS, @@ -12,6 +13,7 @@ reshape_sd, sd_to_XYZ_integration, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.recovery import XYZ_to_sd_Meng2015 from colour.utilities import domain_range_scale @@ -47,7 +49,7 @@ def test_XYZ_to_sd_Meng2015(self): """Test :func:`colour.recovery.meng2015.XYZ_to_sd_Meng2015` definition.""" XYZ = np.array([0.20654008, 0.12197225, 0.05136952]) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( XYZ_to_sd_Meng2015(XYZ, self._cmfs, self._sd_D65), self._cmfs, @@ -55,10 +57,10 @@ def test_XYZ_to_sd_Meng2015(self): ) / 100, XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( XYZ_to_sd_Meng2015(XYZ, self._cmfs, self._sd_E), self._cmfs, @@ -66,10 +68,10 @@ def test_XYZ_to_sd_Meng2015(self): ) / 100, XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( XYZ_to_sd_Meng2015( XYZ, @@ -86,18 +88,18 @@ def test_XYZ_to_sd_Meng2015(self): ) / 100, XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) shape = SpectralShape(400, 700, 5) cmfs = reshape_msds(self._cmfs, shape) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( XYZ_to_sd_Meng2015(XYZ, cmfs, self._sd_D65), cmfs, self._sd_D65 ) / 100, XYZ, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_XYZ_to_sd_Meng2015(self): @@ -131,7 +133,7 @@ def test_domain_range_scale_XYZ_to_sd_Meng2015(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( XYZ_to_sd_Meng2015( XYZ_i * factor_a, self._cmfs, self._sd_D65 @@ -140,7 +142,7 @@ def test_domain_range_scale_XYZ_to_sd_Meng2015(self): self._sd_D65, ), XYZ_o * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/recovery/tests/test_otsu2018.py b/colour/recovery/tests/test_otsu2018.py index b84594588f..b6f6e503b9 100644 --- a/colour/recovery/tests/test_otsu2018.py +++ b/colour/recovery/tests/test_otsu2018.py @@ -1,12 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.recovery.jakob2019` module.""" -import numpy as np import os import shutil import tempfile import unittest +import numpy as np + from colour.characterisation import SDS_COLOURCHECKERS from colour.colorimetry import ( handle_spectral_arguments, @@ -15,13 +16,14 @@ sd_to_XYZ, sds_and_msds_to_msds, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.difference import delta_E_CIE1976 from colour.models import XYZ_to_Lab, XYZ_to_xy from colour.recovery import ( - XYZ_to_sd_Otsu2018, SPECTRAL_SHAPE_OTSU2018, Dataset_Otsu2018, Tree_Otsu2018, + XYZ_to_sd_Otsu2018, ) from colour.recovery.otsu2018 import ( DATASET_REFERENCE_OTSU2018, @@ -274,7 +276,7 @@ def test_domain_range_scale_XYZ_to_sd_Otsu2018(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ( XYZ_to_sd_Otsu2018( XYZ_i * factor_a, self._cmfs, self._sd_D65 @@ -283,7 +285,7 @@ def test_domain_range_scale_XYZ_to_sd_Otsu2018(self): self._sd_D65, ), XYZ_o * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -404,8 +406,10 @@ def test__len__(self): def test_origin(self): """Test :meth:`colour.recovery.otsu2018.Data_Otsu2018.origin` method.""" - self.assertAlmostEqual( - self._data.origin(4, 1), 0.255284008578559, places=7 + np.testing.assert_allclose( + self._data.origin(4, 1), + 0.255284008578559, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_origin(self): @@ -447,7 +451,7 @@ def test_PCA(self): data.PCA() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( data.basis_functions, np.array( [ @@ -567,10 +571,10 @@ def test_PCA(self): ], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( data.mean, np.array( [ @@ -612,7 +616,7 @@ def test_PCA(self): 0.41287500, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_reconstruct(self): @@ -625,7 +629,7 @@ def test_reconstruct(self): data.PCA() - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( data.reconstruct( np.array( [ @@ -675,7 +679,7 @@ def test_reconstruct(self): 0.63971254, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_reconstruct(self): @@ -698,8 +702,10 @@ def test_reconstruction_error(self): data = Data_Otsu2018(self._reflectances, self._cmfs, self._sd_D65) - self.assertAlmostEqual( - data.reconstruction_error(), 2.753352549148681, places=7 + np.testing.assert_allclose( + data.reconstruction_error(), + 2.753352549148681, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_raise_exception_reconstruction_error(self): @@ -819,8 +825,12 @@ def test_minimise(self): self.assertTupleEqual( (len(partition[0].data), len(partition[1].data)), (10, 14) ) - self.assertAlmostEqual(axis.origin, 0.324111380117147, places=7) - self.assertAlmostEqual(partition_error, 2.0402980027, places=7) + np.testing.assert_allclose( + axis.origin, 0.324111380117147, atol=TOLERANCE_ABSOLUTE_TESTS + ) + np.testing.assert_allclose( + partition_error, 2.0402980027, atol=TOLERANCE_ABSOLUTE_TESTS + ) def test_leaf_reconstruction_error(self): """ @@ -828,10 +838,10 @@ def test_leaf_reconstruction_error(self): leaf_reconstruction_error` method. """ - self.assertAlmostEqual( + np.testing.assert_allclose( self._node_b.leaf_reconstruction_error(), 1.145340908277367e-29, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_branch_reconstruction_error(self): @@ -840,10 +850,10 @@ def test_branch_reconstruction_error(self): branch_reconstruction_error` method. """ - self.assertAlmostEqual( + np.testing.assert_allclose( self._node_a.branch_reconstruction_error(), 3.900015991807948e-25, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -906,14 +916,14 @@ def test_reflectances(self): property. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( self._tree.reflectances, np.transpose( reshape_msds( sds_and_msds_to_msds(self._reflectances), self._shape ).values ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_cmfs(self): diff --git a/colour/recovery/tests/test_smits1999.py b/colour/recovery/tests/test_smits1999.py index d411c70d74..a96677d8b8 100644 --- a/colour/recovery/tests/test_smits1999.py +++ b/colour/recovery/tests/test_smits1999.py @@ -1,10 +1,12 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.recovery.smits1999` module.""" -import numpy as np import unittest +import numpy as np + from colour.colorimetry import sd_to_XYZ_integration +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.recovery import RGB_to_sd_Smits1999 from colour.recovery.smits1999 import XYZ_to_RGB_Smits1999 from colour.utilities import domain_range_scale @@ -33,7 +35,7 @@ def test_RGB_to_sd_Smits1999(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_sd_Smits1999( XYZ_to_RGB_Smits1999( np.array([0.21781186, 0.12541048, 0.04697113]) @@ -53,10 +55,10 @@ def test_RGB_to_sd_Smits1999(self): 0.41180754, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_sd_Smits1999( XYZ_to_RGB_Smits1999( np.array([0.15434689, 0.22960951, 0.09620221]) @@ -76,10 +78,10 @@ def test_RGB_to_sd_Smits1999(self): 0.08272671, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_sd_Smits1999( XYZ_to_RGB_Smits1999( np.array([0.07683480, 0.06006092, 0.25833845]) @@ -99,10 +101,10 @@ def test_RGB_to_sd_Smits1999(self): 0.03504156, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_sd_Smits1999( XYZ_to_RGB_Smits1999(np.array([0.0, 1.0, 0.0])) ).values, @@ -120,10 +122,10 @@ def test_RGB_to_sd_Smits1999(self): -1.2703551, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_sd_Smits1999( XYZ_to_RGB_Smits1999(np.array([1.0, 1.0, 0.0])) ).values, @@ -141,10 +143,10 @@ def test_RGB_to_sd_Smits1999(self): 1.4027005, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_to_sd_Smits1999( XYZ_to_RGB_Smits1999(np.array([0.5, 0.0, 1.0])) ).values, @@ -162,7 +164,7 @@ def test_RGB_to_sd_Smits1999(self): 0.9383386, ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_domain_range_scale_RGB_to_sd_Smits1999(self): @@ -178,12 +180,12 @@ def test_domain_range_scale_RGB_to_sd_Smits1999(self): d_r = (("reference", 1, 1), ("1", 1, 0.01), ("100", 100, 1)) for scale, factor_a, factor_b in d_r: with domain_range_scale(scale): - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( sd_to_XYZ_integration( RGB_to_sd_Smits1999(RGB_i * factor_a) ), XYZ_o * factor_b, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/temperature/cie_d.py b/colour/temperature/cie_d.py index c742148a5e..9a4d1b6f30 100644 --- a/colour/temperature/cie_d.py +++ b/colour/temperature/cie_d.py @@ -27,7 +27,7 @@ from colour.colorimetry import daylight_locus_function from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float, tstack, usage_warning +from colour.utilities import as_float, as_float_array, tstack, usage_warning __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/temperature/hernandez1999.py b/colour/temperature/hernandez1999.py index b01d18a24e..9b267b1c2d 100644 --- a/colour/temperature/hernandez1999.py +++ b/colour/temperature/hernandez1999.py @@ -28,7 +28,7 @@ from colour.algebra import sdiv, sdiv_mode from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float, tsplit, usage_warning +from colour.utilities import as_float, as_float_array, tsplit, usage_warning __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/temperature/kang2002.py b/colour/temperature/kang2002.py index efd1311b27..1cc9933a49 100644 --- a/colour/temperature/kang2002.py +++ b/colour/temperature/kang2002.py @@ -25,7 +25,7 @@ from scipy.optimize import minimize from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float, tstack, usage_warning +from colour.utilities import as_float, as_float_array, tstack, usage_warning __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/temperature/krystek1985.py b/colour/temperature/krystek1985.py index 11a7553c79..b2fb947af0 100644 --- a/colour/temperature/krystek1985.py +++ b/colour/temperature/krystek1985.py @@ -25,7 +25,7 @@ from scipy.optimize import minimize from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float, tstack +from colour.utilities import as_float, as_float_array, tstack __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/temperature/mccamy1992.py b/colour/temperature/mccamy1992.py index c91d8b2f67..e24a19ced7 100644 --- a/colour/temperature/mccamy1992.py +++ b/colour/temperature/mccamy1992.py @@ -26,7 +26,7 @@ from colour.algebra import sdiv, sdiv_mode from colour.colorimetry import CCS_ILLUMINANTS from colour.hints import ArrayLike, NDArrayFloat -from colour.utilities import as_float_array, as_float, tsplit, usage_warning +from colour.utilities import as_float, as_float_array, tsplit, usage_warning __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/temperature/ohno2013.py b/colour/temperature/ohno2013.py index 8ad29f1293..87ca3b4f7c 100644 --- a/colour/temperature/ohno2013.py +++ b/colour/temperature/ohno2013.py @@ -29,12 +29,13 @@ handle_spectral_arguments, ) from colour.hints import ArrayLike, NDArrayFloat -from colour.models import UCS_to_XYZ, UCS_to_uv, XYZ_to_UCS, uv_to_UCS +from colour.models import UCS_to_uv, UCS_to_XYZ, XYZ_to_UCS, uv_to_UCS from colour.temperature import CCT_to_uv_Planck1900 from colour.utilities import ( CACHE_REGISTRY, as_float_array, attest, + is_caching_enabled, optional, runtime_warning, tsplit, @@ -114,9 +115,9 @@ def planckian_table( [ 1.01000000e+03, 4.4563...e-01, 3.5483...e-01]]) """ - cache_key = hash((cmfs, start, end, spacing)) - if cache_key in _CACHE_PLANCKIAN_TABLE: - table = _CACHE_PLANCKIAN_TABLE[cache_key].copy() + hash_key = hash((cmfs, start, end, spacing)) + if is_caching_enabled() and hash_key in _CACHE_PLANCKIAN_TABLE: + table = _CACHE_PLANCKIAN_TABLE[hash_key].copy() else: attest(spacing > 1, "Spacing value must be greater than 1!") @@ -137,7 +138,7 @@ def planckian_table( table = np.concatenate( [Ti.reshape((-1, 1)), CCT_to_uv_Planck1900(Ti, cmfs)], axis=1 ) - _CACHE_PLANCKIAN_TABLE[cache_key] = table.copy() + _CACHE_PLANCKIAN_TABLE[hash_key] = table.copy() return table diff --git a/colour/temperature/robertson1968.py b/colour/temperature/robertson1968.py index f0341b4cca..929b1da707 100644 --- a/colour/temperature/robertson1968.py +++ b/colour/temperature/robertson1968.py @@ -39,9 +39,10 @@ from __future__ import annotations -import numpy as np from dataclasses import dataclass +import numpy as np + from colour.algebra import sdiv, sdiv_mode from colour.hints import ArrayLike, NDArrayFloat from colour.utilities import as_float_array, tsplit diff --git a/colour/temperature/tests/test_cie_d.py b/colour/temperature/tests/test_cie_d.py index 0d2e9743bb..21684cafff 100644 --- a/colour/temperature/tests/test_cie_d.py +++ b/colour/temperature/tests/test_cie_d.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.temperature.cie_d` module.""" -import numpy as np import unittest from itertools import product -from colour.temperature import xy_to_CCT_CIE_D, CCT_to_xy_CIE_D +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.temperature import CCT_to_xy_CIE_D, xy_to_CCT_CIE_D from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -36,8 +38,7 @@ def test_xy_to_CCT_CIE_D(self): {"method": "Nelder-Mead"}, ), 4000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -46,8 +47,7 @@ def test_xy_to_CCT_CIE_D(self): {"method": "Nelder-Mead"}, ), 7000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -56,8 +56,7 @@ def test_xy_to_CCT_CIE_D(self): {"method": "Nelder-Mead"}, ), 25000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_CCT_CIE_D(self): @@ -71,14 +70,14 @@ def test_n_dimensional_xy_to_CCT_CIE_D(self): xy = np.tile(xy, (6, 1)) CCT = np.tile(CCT, 6) - np.testing.assert_array_almost_equal( - xy_to_CCT_CIE_D(xy), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_CIE_D(xy), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) xy = np.reshape(xy, (2, 3, 2)) CCT = np.reshape(CCT, (2, 3)) - np.testing.assert_array_almost_equal( - xy_to_CCT_CIE_D(xy), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_CIE_D(xy), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -102,22 +101,22 @@ class TestCCT_to_xy_CIE_D(unittest.TestCase): def test_CCT_to_xy_CIE_D(self): """Test :func:`colour.temperature.cie_d.CCT_to_xy_CIE_D` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_CIE_D(4000), np.array([0.382343625000000, 0.383766261015578]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_CIE_D(7000), np.array([0.305357431486880, 0.321646345474552]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_CIE_D(25000), np.array([0.24985367, 0.254799464210944]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_xy_CIE_D(self): @@ -131,14 +130,14 @@ def test_n_dimensional_CCT_to_xy_CIE_D(self): CCT = np.tile(CCT, 6) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_xy_CIE_D(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_CIE_D(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT = np.reshape(CCT, (2, 3)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_xy_CIE_D(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_CIE_D(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/temperature/tests/test_hernandez1999.py b/colour/temperature/tests/test_hernandez1999.py index 48f5be41e1..c0be3c985d 100644 --- a/colour/temperature/tests/test_hernandez1999.py +++ b/colour/temperature/tests/test_hernandez1999.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.temperature.hernandez1999` module.""" -import numpy as np import unittest from itertools import product -from colour.temperature import xy_to_CCT_Hernandez1999, CCT_to_xy_Hernandez1999 +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.temperature import CCT_to_xy_Hernandez1999, xy_to_CCT_Hernandez1999 from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -33,24 +35,24 @@ def test_xy_to_CCT_Hernandez1999(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( xy_to_CCT_Hernandez1999(np.array([0.31270, 0.32900])), 6500.74204318, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( xy_to_CCT_Hernandez1999(np.array([0.44757, 0.40745])), 2790.64222533, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( xy_to_CCT_Hernandez1999( np.array([0.244162248213914, 0.240333674758318]) ), 64448.11092565, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_CCT_Hernandez1999(self): @@ -64,14 +66,14 @@ def test_n_dimensional_xy_to_CCT_Hernandez1999(self): xy = np.tile(xy, (6, 1)) CCT = np.tile(CCT, 6) - np.testing.assert_array_almost_equal( - xy_to_CCT_Hernandez1999(xy), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_Hernandez1999(xy), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) xy = np.reshape(xy, (2, 3, 2)) CCT = np.reshape(CCT, (2, 3)) - np.testing.assert_array_almost_equal( - xy_to_CCT_Hernandez1999(xy), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_Hernandez1999(xy), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -98,22 +100,22 @@ def test_CCT_to_xy_Hernandez1999(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_Hernandez1999(6500.74204318, {"method": "Nelder-Mead"}), np.array([0.31269943, 0.32900373]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_Hernandez1999(2790.64222533, {"method": "Nelder-Mead"}), np.array([0.42864308, 0.36754776]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_Hernandez1999(64448.11092565, {"method": "Nelder-Mead"}), np.array([0.08269106, 0.36612620]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_xy_Hernandez1999(self): @@ -127,14 +129,14 @@ def test_n_dimensional_CCT_to_xy_Hernandez1999(self): CCT = np.tile(CCT, 6) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_xy_Hernandez1999(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_Hernandez1999(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT = np.reshape(CCT, (2, 3)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_xy_Hernandez1999(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_Hernandez1999(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/temperature/tests/test_kang2002.py b/colour/temperature/tests/test_kang2002.py index c76f4b93a5..a32eee8fd2 100644 --- a/colour/temperature/tests/test_kang2002.py +++ b/colour/temperature/tests/test_kang2002.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.temperature.kang2002` module.""" -import numpy as np import unittest from itertools import product -from colour.temperature import xy_to_CCT_Kang2002, CCT_to_xy_Kang2002 +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.temperature import CCT_to_xy_Kang2002, xy_to_CCT_Kang2002 from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -39,8 +41,7 @@ def test_xy_to_CCT_Kang2002(self): {"method": "Nelder-Mead"}, ), 4000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -49,8 +50,7 @@ def test_xy_to_CCT_Kang2002(self): {"method": "Nelder-Mead"}, ), 7000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -59,8 +59,7 @@ def test_xy_to_CCT_Kang2002(self): {"method": "Nelder-Mead"}, ), 25000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_CCT_Kang2002(self): @@ -74,14 +73,14 @@ def test_n_dimensional_xy_to_CCT_Kang2002(self): uv = np.tile(uv, (6, 1)) CCT = np.tile(CCT, 6) - np.testing.assert_array_almost_equal( - xy_to_CCT_Kang2002(uv), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_Kang2002(uv), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) uv = np.reshape(uv, (2, 3, 2)) CCT = np.reshape(CCT, (2, 3)) - np.testing.assert_array_almost_equal( - xy_to_CCT_Kang2002(uv), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_Kang2002(uv), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -108,22 +107,22 @@ def test_CCT_to_xy_Kang2002(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_Kang2002(4000), np.array([0.380528282812500, 0.376733530961114]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_Kang2002(7000), np.array([0.306374019533528, 0.316552869726577]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_Kang2002(25000), np.array([0.252472994438400, 0.252254791243654]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_xy_Kang2002(self): @@ -137,14 +136,14 @@ def test_n_dimensional_CCT_to_xy_Kang2002(self): CCT = np.tile(CCT, 6) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_xy_Kang2002(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_Kang2002(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT = np.reshape(CCT, (2, 3)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_xy_Kang2002(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_Kang2002(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/temperature/tests/test_krystek1985.py b/colour/temperature/tests/test_krystek1985.py index c452a72e66..897197f428 100644 --- a/colour/temperature/tests/test_krystek1985.py +++ b/colour/temperature/tests/test_krystek1985.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.temperature.krystek1985` module.""" -import numpy as np import unittest from itertools import product -from colour.temperature import uv_to_CCT_Krystek1985, CCT_to_uv_Krystek1985 +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.temperature import CCT_to_uv_Krystek1985, uv_to_CCT_Krystek1985 from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -38,8 +40,7 @@ def test_uv_to_CCT_Krystek1985(self): {"method": "Nelder-Mead"}, ), 1000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -48,8 +49,7 @@ def test_uv_to_CCT_Krystek1985(self): {"method": "Nelder-Mead"}, ), 7000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -58,8 +58,7 @@ def test_uv_to_CCT_Krystek1985(self): {"method": "Nelder-Mead"}, ), 15000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_uv_to_CCT_Krystek1985(self): @@ -73,14 +72,14 @@ def test_n_dimensional_uv_to_CCT_Krystek1985(self): uv = np.tile(uv, (6, 1)) CCT = np.tile(CCT, 6) - np.testing.assert_array_almost_equal( - uv_to_CCT_Krystek1985(uv), CCT, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Krystek1985(uv), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) uv = np.reshape(uv, (2, 3, 2)) CCT = np.reshape(CCT, (2, 3)) - np.testing.assert_array_almost_equal( - uv_to_CCT_Krystek1985(uv), CCT, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Krystek1985(uv), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -107,22 +106,22 @@ def test_CCT_to_uv_Krystek1985(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Krystek1985(1000), np.array([0.448087794140145, 0.354731965027727]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Krystek1985(7000), np.array([0.198152565091092, 0.307023596915037]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Krystek1985(15000), np.array([0.185675876767054, 0.282233658593898]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_uv_Krystek1985(self): @@ -136,14 +135,14 @@ def test_n_dimensional_CCT_to_uv_Krystek1985(self): CCT = np.tile(CCT, 6) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Krystek1985(CCT), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Krystek1985(CCT), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT = np.reshape(CCT, (2, 3)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Krystek1985(CCT), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Krystek1985(CCT), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/temperature/tests/test_mccamy1992.py b/colour/temperature/tests/test_mccamy1992.py index b5c1a82b94..af8c4f0b60 100644 --- a/colour/temperature/tests/test_mccamy1992.py +++ b/colour/temperature/tests/test_mccamy1992.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.temperature.mccamy1992` module.""" -import numpy as np import unittest from itertools import product -from colour.temperature import xy_to_CCT_McCamy1992, CCT_to_xy_McCamy1992 +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.temperature import CCT_to_xy_McCamy1992, xy_to_CCT_McCamy1992 from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -33,24 +35,24 @@ def test_xy_to_CCT_McCamy1992(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( xy_to_CCT_McCamy1992(np.array([0.31270, 0.32900])), 6505.08059131, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( xy_to_CCT_McCamy1992(np.array([0.44757, 0.40745])), 2857.28961266, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - self.assertAlmostEqual( + np.testing.assert_allclose( xy_to_CCT_McCamy1992( np.array([0.252520939374083, 0.252220883926284]) ), 19501.61953130, - places=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_xy_to_CCT_McCamy1992(self): @@ -64,14 +66,14 @@ def test_n_dimensional_xy_to_CCT_McCamy1992(self): xy = np.tile(xy, (6, 1)) CCT = np.tile(CCT, 6) - np.testing.assert_array_almost_equal( - xy_to_CCT_McCamy1992(xy), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_McCamy1992(xy), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) xy = np.reshape(xy, (2, 3, 2)) CCT = np.reshape(CCT, (2, 3)) - np.testing.assert_array_almost_equal( - xy_to_CCT_McCamy1992(xy), CCT, decimal=7 + np.testing.assert_allclose( + xy_to_CCT_McCamy1992(xy), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -98,22 +100,22 @@ def test_CCT_to_xy_McCamy1992(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_McCamy1992(6505.08059131, {"method": "Nelder-Mead"}), np.array([0.31269945, 0.32900411]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_McCamy1992(2857.28961266, {"method": "Nelder-Mead"}), np.array([0.42350314, 0.36129253]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_xy_McCamy1992(19501.61953130, {"method": "Nelder-Mead"}), np.array([0.11173782, 0.36987375]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_xy_McCamy1992(self): @@ -127,14 +129,14 @@ def test_n_dimensional_CCT_to_xy_McCamy1992(self): CCT = np.tile(CCT, 6) xy = np.tile(xy, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_xy_McCamy1992(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_McCamy1992(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT = np.reshape(CCT, (2, 3)) xy = np.reshape(xy, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_xy_McCamy1992(CCT), xy, decimal=7 + np.testing.assert_allclose( + CCT_to_xy_McCamy1992(CCT), xy, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/temperature/tests/test_ohno2013.py b/colour/temperature/tests/test_ohno2013.py index f5b050b953..bc951166a0 100644 --- a/colour/temperature/tests/test_ohno2013.py +++ b/colour/temperature/tests/test_ohno2013.py @@ -1,16 +1,18 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.temperature.ohno2013` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.colorimetry import MSDS_CMFS +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.temperature import ( CCT_to_uv_Ohno2013, - uv_to_CCT_Ohno2013, CCT_to_XYZ_Ohno2013, XYZ_to_CCT_Ohno2013, + uv_to_CCT_Ohno2013, ) from colour.temperature.ohno2013 import ( planckian_table, @@ -76,8 +78,7 @@ def test_planckian_table(self): [6.00000000e03, 2.03307932e-01, 3.14117832e-01], ] ), - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) @@ -102,22 +103,22 @@ def test_uv_to_CCT_Ohno2013(self): np.testing.assert_allclose(table_t[1, :], table_r[1, :], atol=1) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_CCT_Ohno2013(np.array([0.1978, 0.3122])), np.array([6507.474788799616363, 0.003223346337596]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_CCT_Ohno2013(np.array([0.4328, 0.2883])), np.array([1041.678320000468375, -0.067378053475797]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( uv_to_CCT_Ohno2013(np.array([0.2927, 0.2722])), np.array([2444.971818951082696, -0.084370641205118]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_uv_to_CCT_Ohno2013(self): @@ -131,14 +132,14 @@ def test_n_dimensional_uv_to_CCT_Ohno2013(self): uv = np.tile(uv, (6, 1)) CCT_D_uv = np.tile(CCT_D_uv, (6, 1)) - np.testing.assert_array_almost_equal( - uv_to_CCT_Ohno2013(uv), CCT_D_uv, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Ohno2013(uv), CCT_D_uv, atol=TOLERANCE_ABSOLUTE_TESTS ) uv = np.reshape(uv, (2, 3, 2)) CCT_D_uv = np.reshape(CCT_D_uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - uv_to_CCT_Ohno2013(uv), CCT_D_uv, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Ohno2013(uv), CCT_D_uv, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -165,22 +166,22 @@ def test_CCT_to_uv_Ohno2013(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Ohno2013(np.array([6507.47380460, 0.00322335])), np.array([0.19779997, 0.31219997]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Ohno2013(np.array([1041.68315360, -0.06737802])), np.array([0.43279885, 0.28830013]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Ohno2013(np.array([2452.15316417, -0.08437064])), np.array([0.29247364, 0.27215157]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_uv_Ohno2013(self): @@ -194,14 +195,14 @@ def test_n_dimensional_CCT_to_uv_Ohno2013(self): CCT_D_uv = np.tile(CCT_D_uv, (6, 1)) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Ohno2013(CCT_D_uv), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Ohno2013(CCT_D_uv), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT_D_uv = np.reshape(CCT_D_uv, (2, 3, 2)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Ohno2013(CCT_D_uv), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Ohno2013(CCT_D_uv), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -227,10 +228,10 @@ def test_XYZ_to_CCT_Ohno2013(self): Test :func:`colour.temperature.ohno2013.XYZ_to_CCT_Ohno2013` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_to_CCT_Ohno2013(np.array([95.04, 100.00, 108.88])), np.array([6503.30711709, 0.00321729]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_XYZ_to_CCT_Ohno2013(self): @@ -244,14 +245,14 @@ def test_n_dimensional_XYZ_to_CCT_Ohno2013(self): XYZ = np.tile(XYZ, (6, 1)) CCT_D_uv = np.tile(CCT_D_uv, (6, 1)) - np.testing.assert_array_almost_equal( - XYZ_to_CCT_Ohno2013(XYZ), CCT_D_uv, decimal=7 + np.testing.assert_allclose( + XYZ_to_CCT_Ohno2013(XYZ), CCT_D_uv, atol=TOLERANCE_ABSOLUTE_TESTS ) XYZ = np.reshape(XYZ, (2, 3, 3)) CCT_D_uv = np.reshape(CCT_D_uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - XYZ_to_CCT_Ohno2013(XYZ), CCT_D_uv, decimal=7 + np.testing.assert_allclose( + XYZ_to_CCT_Ohno2013(XYZ), CCT_D_uv, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -280,8 +281,7 @@ def test_CCT_to_XYZ_Ohno2013(self): np.testing.assert_allclose( CCT_to_XYZ_Ohno2013(np.array([6503.30711709, 0.00321729])), np.array([95.04, 100.00, 108.88]) / 100, - rtol=0.000001, - atol=0.000001, + atol=1e-6, ) def test_n_dimensional_CCT_to_XYZ_Ohno2013(self): @@ -295,14 +295,14 @@ def test_n_dimensional_CCT_to_XYZ_Ohno2013(self): CCT_D_uv = np.tile(CCT_D_uv, (6, 1)) XYZ = np.tile(XYZ, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_XYZ_Ohno2013(CCT_D_uv), XYZ, decimal=7 + np.testing.assert_allclose( + CCT_to_XYZ_Ohno2013(CCT_D_uv), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT_D_uv = np.reshape(CCT_D_uv, (2, 3, 2)) XYZ = np.reshape(XYZ, (2, 3, 3)) - np.testing.assert_array_almost_equal( - CCT_to_XYZ_Ohno2013(CCT_D_uv), XYZ, decimal=7 + np.testing.assert_allclose( + CCT_to_XYZ_Ohno2013(CCT_D_uv), XYZ, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/temperature/tests/test_planck1900.py b/colour/temperature/tests/test_planck1900.py index afaabf79de..0739e7a60a 100644 --- a/colour/temperature/tests/test_planck1900.py +++ b/colour/temperature/tests/test_planck1900.py @@ -1,11 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.temperature.planck1900` module.""" -import numpy as np import unittest from itertools import product -from colour.temperature import uv_to_CCT_Planck1900, CCT_to_uv_Planck1900 +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.temperature import CCT_to_uv_Planck1900, uv_to_CCT_Planck1900 from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" @@ -39,8 +41,7 @@ def test_uv_to_CCT_Planck1900(self): optimisation_kwargs={"method": "Nelder-Mead"}, ), 4000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -49,8 +50,7 @@ def test_uv_to_CCT_Planck1900(self): optimisation_kwargs={"method": "Nelder-Mead"}, ), 7000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) np.testing.assert_allclose( @@ -59,8 +59,7 @@ def test_uv_to_CCT_Planck1900(self): optimisation_kwargs={"method": "Nelder-Mead"}, ), 25000, - rtol=0.0000001, - atol=0.0000001, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_uv_to_CCT_Planck1900(self): @@ -74,14 +73,14 @@ def test_n_dimensional_uv_to_CCT_Planck1900(self): uv = np.tile(uv, (6, 1)) CCT = np.tile(CCT, 6) - np.testing.assert_array_almost_equal( - uv_to_CCT_Planck1900(uv), CCT, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Planck1900(uv), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) uv = np.reshape(uv, (2, 3, 2)) CCT = np.reshape(CCT, (2, 3)) - np.testing.assert_array_almost_equal( - uv_to_CCT_Planck1900(uv), CCT, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Planck1900(uv), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -108,22 +107,22 @@ def test_CCT_to_uv_Planck1900(self): definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Planck1900(4000), np.array([0.225109670227493, 0.334387366663923]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Planck1900(7000), np.array([0.198126929048352, 0.307025980523306]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( CCT_to_uv_Planck1900(25000), np.array([0.182932683590136, 0.274073232217536]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_uv_Planck1900(self): @@ -137,14 +136,14 @@ def test_n_dimensional_CCT_to_uv_Planck1900(self): CCT = np.tile(CCT, 6) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Planck1900(CCT), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Planck1900(CCT), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT = np.reshape(CCT, (2, 3)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Planck1900(CCT), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Planck1900(CCT), uv, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors diff --git a/colour/temperature/tests/test_robertson1968.py b/colour/temperature/tests/test_robertson1968.py index 6aabd8c786..e515e21867 100644 --- a/colour/temperature/tests/test_robertson1968.py +++ b/colour/temperature/tests/test_robertson1968.py @@ -3,14 +3,16 @@ from __future__ import annotations -import numpy as np import unittest from itertools import product +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.temperature import ( - mired_to_CCT, CCT_to_mired, CCT_to_uv_Robertson1968, + mired_to_CCT, uv_to_CCT_Robertson1968, ) from colour.utilities import ignore_numpy_errors @@ -145,12 +147,18 @@ def test_mired_to_CCT(self): definition. """ - self.assertAlmostEqual(CCT_to_mired(312.5), 3200, places=7) + np.testing.assert_allclose( + CCT_to_mired(312.5), 3200, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(CCT_to_mired(153.846153846154), 6500, places=7) + np.testing.assert_allclose( + CCT_to_mired(153.846153846154), 6500, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - CCT_to_mired(66.666666666666667), 15000, places=7 + np.testing.assert_allclose( + CCT_to_mired(66.666666666666667), + 15000, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_mired_to_CCT(self): @@ -164,14 +172,14 @@ def test_n_dimensional_mired_to_CCT(self): mired = np.tile(mired, (6, 1)) CCT = np.tile(CCT, (6, 1)) - np.testing.assert_array_almost_equal( - mired_to_CCT(mired), CCT, decimal=7 + np.testing.assert_allclose( + mired_to_CCT(mired), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) mired = np.reshape(mired, (2, 3, 1)) CCT = np.reshape(CCT, (2, 3, 1)) - np.testing.assert_array_almost_equal( - mired_to_CCT(mired), CCT, decimal=7 + np.testing.assert_allclose( + mired_to_CCT(mired), CCT, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -198,12 +206,18 @@ def test_CCT_to_mired(self): definition. """ - self.assertAlmostEqual(CCT_to_mired(3200), 312.5, places=7) + np.testing.assert_allclose( + CCT_to_mired(3200), 312.5, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual(CCT_to_mired(6500), 153.846153846154, places=7) + np.testing.assert_allclose( + CCT_to_mired(6500), 153.846153846154, atol=TOLERANCE_ABSOLUTE_TESTS + ) - self.assertAlmostEqual( - CCT_to_mired(15000), 66.666666666666667, places=7 + np.testing.assert_allclose( + CCT_to_mired(15000), + 66.666666666666667, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_mired(self): @@ -217,14 +231,14 @@ def test_n_dimensional_CCT_to_mired(self): CCT = np.tile(CCT, (6, 1)) mired = np.tile(mired, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_mired(CCT), mired, decimal=7 + np.testing.assert_allclose( + CCT_to_mired(CCT), mired, atol=TOLERANCE_ABSOLUTE_TESTS ) CCT = np.reshape(CCT, (2, 3, 1)) mired = np.reshape(mired, (2, 3, 1)) - np.testing.assert_array_almost_equal( - CCT_to_mired(CCT), mired, decimal=7 + np.testing.assert_allclose( + CCT_to_mired(CCT), mired, atol=TOLERANCE_ABSOLUTE_TESTS ) @ignore_numpy_errors @@ -267,14 +281,18 @@ def test_n_dimensional_uv_to_CCT_Robertson1968(self): uv = np.tile(uv, (6, 1)) CCT_D_uv = np.tile(CCT_D_uv, (6, 1)) - np.testing.assert_array_almost_equal( - uv_to_CCT_Robertson1968(uv), CCT_D_uv, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Robertson1968(uv), + CCT_D_uv, + atol=TOLERANCE_ABSOLUTE_TESTS, ) uv = np.reshape(uv, (2, 3, 2)) CCT_D_uv = np.reshape(CCT_D_uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - uv_to_CCT_Robertson1968(uv), CCT_D_uv, decimal=7 + np.testing.assert_allclose( + uv_to_CCT_Robertson1968(uv), + CCT_D_uv, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors @@ -302,8 +320,10 @@ def test_CCT_to_uv_Robertson1968(self): """ for key, value in TEMPERATURE_DUV_TO_UV.items(): - np.testing.assert_array_almost_equal( - CCT_to_uv_Robertson1968(key), value, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Robertson1968(key), + value, + atol=TOLERANCE_ABSOLUTE_TESTS, ) def test_n_dimensional_CCT_to_uv_Robertson1968(self): @@ -317,14 +337,18 @@ def test_n_dimensional_CCT_to_uv_Robertson1968(self): CCT_D_uv = np.tile(CCT_D_uv, (6, 1)) uv = np.tile(uv, (6, 1)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Robertson1968(CCT_D_uv), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Robertson1968(CCT_D_uv), + uv, + atol=TOLERANCE_ABSOLUTE_TESTS, ) CCT_D_uv = np.reshape(CCT_D_uv, (2, 3, 2)) uv = np.reshape(uv, (2, 3, 2)) - np.testing.assert_array_almost_equal( - CCT_to_uv_Robertson1968(CCT_D_uv), uv, decimal=7 + np.testing.assert_allclose( + CCT_to_uv_Robertson1968(CCT_D_uv), + uv, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/utilities/__init__.py b/colour/utilities/__init__.py index 6083d6a9d4..53fa9e4f7e 100644 --- a/colour/utilities/__init__.py +++ b/colour/utilities/__init__.py @@ -16,6 +16,9 @@ MixinCallback, ) from .common import ( + is_caching_enabled, + set_caching_enable, + caching_enable, CacheRegistry, CACHE_REGISTRY, handle_numpy_errors, @@ -64,6 +67,7 @@ usage_warning, filter_warnings, suppress_warnings, + suppress_stdout, numpy_print_options, ANCILLARY_COLOUR_SCIENCE_PACKAGES, ANCILLARY_RUNTIME_PACKAGES, @@ -140,6 +144,9 @@ "MixinCallback", ] __all__ += [ + "is_caching_enabled", + "set_caching_enable", + "caching_enable", "CacheRegistry", "CACHE_REGISTRY", "handle_numpy_errors", @@ -188,6 +195,7 @@ "usage_warning", "filter_warnings", "suppress_warnings", + "suppress_stdout", "numpy_print_options", "ANCILLARY_COLOUR_SCIENCE_PACKAGES", "ANCILLARY_RUNTIME_PACKAGES", diff --git a/colour/utilities/array.py b/colour/utilities/array.py index 7893ab0623..2d777d3692 100644 --- a/colour/utilities/array.py +++ b/colour/utilities/array.py @@ -19,14 +19,15 @@ from __future__ import annotations import functools -import numpy as np import sys from collections.abc import KeysView, ValuesView from contextlib import contextmanager from dataclasses import fields, is_dataclass, replace from operator import add, mul, pow, sub, truediv -from colour.constants import DEFAULT_FLOAT_DTYPE, DEFAULT_INT_DTYPE, EPSILON +import numpy as np + +from colour.constants import DTYPE_FLOAT_DEFAULT, DTYPE_INT_DEFAULT, EPSILON from colour.hints import ( Any, ArrayLike, @@ -37,11 +38,11 @@ DTypeFloat, DTypeInt, DTypeReal, - NDArrayFloat, Generator, - NDArrayInt, Literal, NDArray, + NDArrayFloat, + NDArrayInt, Real, Tuple, Type, @@ -51,6 +52,7 @@ CACHE_REGISTRY, attest, int_digest, + is_caching_enabled, optional, suppress_warnings, validate_method, @@ -250,7 +252,7 @@ def __array__(self, dtype: Type[DTypeReal] | None = None) -> NDArray: dtype :class:`numpy.dtype` to use for conversion to `np.ndarray`, default to the :class:`numpy.dtype` defined by - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Returns ------- @@ -258,7 +260,7 @@ def __array__(self, dtype: Type[DTypeReal] | None = None) -> NDArray: :class:`dataclass`-like class converted to :class:`numpy.ndarray`. """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) default = None for _field, value in self: @@ -553,11 +555,11 @@ def as_array( Parameters ---------- a - Variable to convert. + Variable :math:`a` to convert. dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Returns ------- @@ -568,7 +570,7 @@ def as_array( -------- >>> as_array([1, 2, 3]) # doctest: +ELLIPSIS array([1, 2, 3]...) - >>> as_array([1, 2, 3], dtype=DEFAULT_FLOAT_DTYPE) + >>> as_array([1, 2, 3], dtype=DTYPE_FLOAT_DEFAULT) array([ 1., 2., 3.]) """ @@ -589,11 +591,11 @@ def as_int(a: ArrayLike, dtype: Type[DTypeInt] | None = None) -> NDArrayInt: Parameters ---------- a - Variable to convert. + Variable :math:`a` to convert. dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_INT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_INT_DEFAULT` attribute. Returns ------- @@ -610,7 +612,7 @@ def as_int(a: ArrayLike, dtype: Type[DTypeInt] | None = None) -> NDArrayInt: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]...) """ - dtype = optional(dtype, DEFAULT_INT_DTYPE) + dtype = optional(dtype, DTYPE_INT_DEFAULT) attest( dtype in DTypeInt.__args__, # pyright: ignore @@ -631,11 +633,11 @@ def as_float( Parameters ---------- a - Variable to convert. + Variable :math:`a` to convert. dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Returns ------- @@ -652,7 +654,7 @@ def as_float( array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) attest( dtype in DTypeFloat.__args__, # pyright: ignore @@ -681,11 +683,11 @@ def as_int_array( Parameters ---------- a - Variable to convert. + Variable :math:`a` to convert. dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_INT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_INT_DEFAULT` attribute. Returns ------- @@ -698,7 +700,7 @@ def as_int_array( array([1, 2, 3]...) """ - dtype = optional(dtype, DEFAULT_INT_DTYPE) + dtype = optional(dtype, DTYPE_INT_DEFAULT) attest( dtype in DTypeInt.__args__, # pyright: ignore @@ -718,11 +720,11 @@ def as_float_array( Parameters ---------- a - Variable to convert. + Variable :math:`a` to convert. dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Returns ------- @@ -735,7 +737,7 @@ def as_float_array( array([ 1., 2., 3.]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) attest( dtype in DTypeFloat.__args__, # pyright: ignore @@ -753,11 +755,11 @@ def as_int_scalar(a: ArrayLike, dtype: Type[DTypeInt] | None = None) -> int: Parameters ---------- a - Variable to convert. + Variable :math:`a` to convert. dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_INT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_INT_DEFAULT` attribute. Returns ------- @@ -792,11 +794,11 @@ def as_float_scalar( Parameters ---------- a - Variable to convert. + Variable :math:`a` to convert. dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Returns ------- @@ -822,17 +824,17 @@ def as_float_scalar( def set_default_int_dtype( - dtype: Type[DTypeInt] = DEFAULT_INT_DTYPE, + dtype: Type[DTypeInt] = DTYPE_INT_DEFAULT, ) -> None: """ Set *Colour* default :class:`numpy.integer` precision by setting - :attr:`colour.constant.DEFAULT_INT_DTYPE` attribute with given + :attr:`colour.constant.DTYPE_INT_DEFAULT` attribute with given :class:`numpy.dtype` wherever the attribute is imported. Parameters ---------- dtype - :class:`numpy.dtype` to set :attr:`colour.constant.DEFAULT_INT_DTYPE` + :class:`numpy.dtype` to set :attr:`colour.constant.DTYPE_INT_DEFAULT` with. Notes @@ -863,24 +865,24 @@ def set_default_int_dtype( # TODO: Investigate behaviour on Windows. with suppress_warnings(colour_usage_warnings=True): for module in sys.modules.values(): - if not hasattr(module, "DEFAULT_INT_DTYPE"): + if not hasattr(module, "DTYPE_INT_DEFAULT"): continue - module.DEFAULT_INT_DTYPE = dtype # pyright: ignore + module.DTYPE_INT_DEFAULT = dtype # pyright: ignore def set_default_float_dtype( - dtype: Type[DTypeFloat] = DEFAULT_FLOAT_DTYPE, + dtype: Type[DTypeFloat] = DTYPE_FLOAT_DEFAULT, ) -> None: """ Set *Colour* default :class:`numpy.floating` precision by setting - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute with given + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute with given :class:`numpy.dtype` wherever the attribute is imported. Parameters ---------- dtype - :class:`numpy.dtype` to set :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` + :class:`numpy.dtype` to set :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` with. Warnings @@ -911,10 +913,10 @@ def set_default_float_dtype( with suppress_warnings(colour_usage_warnings=True): for module in sys.modules.values(): - if not hasattr(module, "DEFAULT_FLOAT_DTYPE"): + if not hasattr(module, "DTYPE_FLOAT_DEFAULT"): continue - module.DEFAULT_FLOAT_DTYPE = dtype # pyright: ignore + module.DTYPE_FLOAT_DEFAULT = dtype # pyright: ignore # TODO: Annotate with "Union[Literal['ignore', 'reference', '1', '100'], str]" @@ -1141,7 +1143,7 @@ def to_domain_1( array(0.01) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype).copy() @@ -1208,7 +1210,7 @@ def to_domain_10( array(0.1) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype).copy() @@ -1276,7 +1278,7 @@ def to_domain_100( array(1.0) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype).copy() @@ -1343,7 +1345,7 @@ def to_domain_degrees( array(3.6) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype).copy() @@ -1417,7 +1419,7 @@ def to_domain_int( array(2.55) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype).copy() @@ -1490,7 +1492,7 @@ def from_range_1( array(100.0) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype) @@ -1561,7 +1563,7 @@ def from_range_10( array(10.0) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype) @@ -1633,7 +1635,7 @@ def from_range_100( array(1.0) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype) @@ -1704,7 +1706,7 @@ def from_range_degrees( array(0.2777777...) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype) @@ -1782,7 +1784,7 @@ def from_range_int( array(0.3921568...) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_float_array(a, dtype) @@ -2062,7 +2064,7 @@ def interval(distribution: ArrayLike, unique: bool = True) -> NDArray: unique, ) ) - if hash_key in _CACHE_DISTRIBUTION_INTERVAL: + if is_caching_enabled() and hash_key in _CACHE_DISTRIBUTION_INTERVAL: return np.copy(_CACHE_DISTRIBUTION_INTERVAL[hash_key]) differences = np.abs(distribution[1:] - distribution[:-1]) @@ -2173,7 +2175,7 @@ def tstack( dtype :class:`numpy.dtype` to use for initial conversion to :class:`numpy.ndarray`, default to the :class:`numpy.dtype` defined by - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Returns ------- @@ -2211,7 +2213,7 @@ def tstack( [ 5., 5., 5.]]]]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_array(a, dtype) @@ -2239,7 +2241,7 @@ def tsplit( dtype :class:`numpy.dtype` to use for initial conversion to :class:`numpy.ndarray`, default to the :class:`numpy.dtype` defined by - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Returns ------- @@ -2278,7 +2280,7 @@ def tsplit( [[ 0., 1., 2., 3., 4., 5.]]]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) a = as_array(a, dtype) @@ -2346,7 +2348,7 @@ def row_as_diagonal(a: ArrayLike) -> NDArray: d = np.expand_dims(d, -2) - return np.eye(d.shape[-1]) * d # pyright: ignore + return np.eye(d.shape[-1]) * d def orient( @@ -2452,7 +2454,7 @@ def centroid(a: ArrayLike) -> NDArray: a_ci.append(np.sum(axis * a) // a_s) - return np.array(a_ci).astype(DEFAULT_INT_DTYPE) + return np.array(a_ci).astype(DTYPE_INT_DEFAULT) def fill_nan( @@ -2581,7 +2583,7 @@ def zeros( """ Wrap :func:`np.zeros` definition to create an array with the active :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Parameters ---------- @@ -2590,7 +2592,7 @@ def zeros( dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. order Whether to store multi-dimensional data in row-major (C-style) or column-major (Fortran-style) order in memory. @@ -2606,7 +2608,7 @@ def zeros( array([ 0., 0., 0.]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) return np.zeros(shape, dtype, order) @@ -2619,7 +2621,7 @@ def ones( """ Wrap :func:`np.ones` definition to create an array with the active :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Parameters ---------- @@ -2628,7 +2630,7 @@ def ones( dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. order Whether to store multi-dimensional data in row-major (C-style) or column-major (Fortran-style) order in memory. @@ -2644,7 +2646,7 @@ def ones( array([ 1., 1., 1.]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) return np.ones(shape, dtype, order) @@ -2657,7 +2659,7 @@ def full( ) -> NDArray: """ Wrap :func:`np.full` definition to create an array with the active type - defined by the:attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + defined by the:attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. Parameters ---------- @@ -2668,7 +2670,7 @@ def full( dtype :class:`numpy.dtype` to use for conversion, default to the :class:`numpy.dtype` defined by the - :attr:`colour.constant.DEFAULT_FLOAT_DTYPE` attribute. + :attr:`colour.constant.DTYPE_FLOAT_DEFAULT` attribute. order Whether to store multi-dimensional data in row-major (C-style) or column-major (Fortran-style) order in memory. @@ -2684,7 +2686,7 @@ def full( array([ 1., 1., 1.]) """ - dtype = optional(dtype, DEFAULT_FLOAT_DTYPE) + dtype = optional(dtype, DTYPE_FLOAT_DEFAULT) return np.full(shape, fill_value, dtype, order) @@ -2817,5 +2819,5 @@ def format_array_as_row( a = np.ravel(a) return separator.join( - "{1:0.{0}f}".format(decimals, x) for x in a # noqa: PLE1300 + "{1:0.{0}f}".format(decimals, x) for x in a # noqa: PLE1300, RUF100 ) diff --git a/colour/utilities/common.py b/colour/utilities/common.py index ea1978172d..69148e3667 100644 --- a/colour/utilities/common.py +++ b/colour/utilities/common.py @@ -18,18 +18,20 @@ from __future__ import annotations -import inspect import functools -import numpy as np +import inspect +import os import re import subprocess -import unicodedata import types +import unicodedata import warnings from contextlib import contextmanager from copy import copy from pprint import pformat +import numpy as np + from colour.constants import INTEGER_THRESHOLD from colour.hints import ( Any, @@ -52,6 +54,9 @@ __status__ = "Production" __all__ = [ + "is_caching_enabled", + "set_caching_enable", + "caching_enable", "CacheRegistry", "CACHE_REGISTRY", "handle_numpy_errors", @@ -90,6 +95,106 @@ "int_digest", ] +_CACHING_ENABLED: bool = not os.environ.get( + "COLOUR_SCIENCE__COLOUR__DISABLE_CACHING", False +) +""" +Global variable storing the current *Colour* caching enabled state. +""" + + +def is_caching_enabled() -> bool: + """ + Return whether *Colour* caching is enabled. + + Returns + ------- + :class:`bool` + Whether *Colour* caching is enabled. + + Examples + -------- + >>> with caching_enable(False): + ... is_caching_enabled() + ... + False + >>> with caching_enable(True): + ... is_caching_enabled() + ... + True + """ + + return _CACHING_ENABLED + + +def set_caching_enable(enable: bool): + """ + Set *Colour* caching enabled state. + + Parameters + ---------- + enable + Whether to enable *Colour* caching. + + Examples + -------- + >>> with caching_enable(True): + ... print(is_caching_enabled()) + ... set_caching_enable(False) + ... print(is_caching_enabled()) + ... + True + False + """ + + global _CACHING_ENABLED # noqa: PLW0603 + + _CACHING_ENABLED = enable + + +class caching_enable: + """ + Define a context manager and decorator temporarily setting *Colour* caching + enabled state. + + Parameters + ---------- + enable + Whether to enable or disable *Colour* caching. + """ + + def __init__(self, enable: bool) -> None: + self._enable = enable + self._previous_state = is_caching_enabled() + + def __enter__(self) -> caching_enable: + """ + Set the *Colour* caching enabled state upon entering the context + manager. + """ + + set_caching_enable(self._enable) + + return self + + def __exit__(self, *args: Any): + """ + Set the *Colour* caching enabled state upon exiting the context + manager. + """ + + set_caching_enable(self._previous_state) + + def __call__(self, function: Callable) -> Callable: + """Call the wrapped definition.""" + + @functools.wraps(function) + def wrapper(*args: Any, **kwargs: Any) -> Any: + with self: + return function(*args, **kwargs) + + return wrapper + class CacheRegistry: """ @@ -275,8 +380,6 @@ def clear_all_caches(self): """ *Colour* cache registry referencing all the caches used for repetitive or long processes. - -CACHE_REGISTRY """ @@ -698,7 +801,7 @@ def is_networkx_installed(raise_exception: bool = False) -> bool: """ try: # pragma: no cover - import networkx # noqa: F401 + import networkx as nx # noqa: F401 return True except ImportError as error: # pragma: no cover @@ -1462,6 +1565,7 @@ def slugify(object_: Any, allow_unicode: bool = False) -> str: if is_xxhash_installed(): import xxhash + from colour.utilities.documentation import is_documentation_building int_digest = xxhash.xxh3_64_intdigest diff --git a/colour/utilities/deprecation.py b/colour/utilities/deprecation.py index 061492053d..a7169b7e1e 100644 --- a/colour/utilities/deprecation.py +++ b/colour/utilities/deprecation.py @@ -8,12 +8,12 @@ from __future__ import annotations import sys -from importlib import import_module from collections import namedtuple +from importlib import import_module from operator import attrgetter -from colour.utilities import attest, optional, usage_warning from colour.hints import Any, ModuleType +from colour.utilities import attest, optional, usage_warning __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" diff --git a/colour/utilities/tests/test_array.py b/colour/utilities/tests/test_array.py index 4852ea012c..170ab5b275 100644 --- a/colour/utilities/tests/test_array.py +++ b/colour/utilities/tests/test_array.py @@ -1,64 +1,69 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.utilities.array` module.""" -import numpy as np import unittest -from dataclasses import dataclass, field, fields from copy import deepcopy +from dataclasses import dataclass, field, fields -from colour.constants import DEFAULT_FLOAT_DTYPE, DEFAULT_INT_DTYPE +import numpy as np + +from colour.constants import ( + DTYPE_FLOAT_DEFAULT, + DTYPE_INT_DEFAULT, + TOLERANCE_ABSOLUTE_TESTS, +) from colour.hints import NDArray, Optional, Type, Union from colour.utilities import ( + MixinDataclassArithmetic, + MixinDataclassArray, MixinDataclassFields, MixinDataclassIterable, - MixinDataclassArray, - MixinDataclassArithmetic, as_array, - as_int, as_float, - as_int_array, as_float_array, - as_int_scalar, as_float_scalar, - set_default_int_dtype, - set_default_float_dtype, - get_domain_range_scale, - set_domain_range_scale, + as_int, + as_int_array, + as_int_scalar, + centroid, + closest, + closest_indexes, domain_range_scale, - to_domain_1, - to_domain_10, - to_domain_100, - to_domain_degrees, - to_domain_int, + fill_nan, + format_array_as_row, from_range_1, from_range_10, from_range_100, from_range_degrees, from_range_int, - is_ndarray_copy_enabled, - set_ndarray_copy_enable, - ndarray_copy_enable, - ndarray_copy, - closest_indexes, - closest, + full, + get_domain_range_scale, + has_only_nan, + in_array, + index_along_last_axis, interval, + is_ndarray_copy_enabled, + is_networkx_installed, is_uniform, - in_array, - tstack, - tsplit, - row_as_diagonal, - orient, - centroid, - fill_nan, - has_only_nan, + ndarray_copy, + ndarray_copy_enable, ndarray_write, - zeros, ones, - full, - index_along_last_axis, - format_array_as_row, + orient, + row_as_diagonal, + set_default_float_dtype, + set_default_int_dtype, + set_domain_range_scale, + set_ndarray_copy_enable, + to_domain_1, + to_domain_10, + to_domain_100, + to_domain_degrees, + to_domain_int, + tsplit, + tstack, + zeros, ) -from colour.utilities import is_networkx_installed __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -288,8 +293,8 @@ def test__array__(self): np.testing.assert_array_equal(np.array(self._data), self._array) self.assertEqual( - np.array(self._data, dtype=DEFAULT_INT_DTYPE).dtype, - DEFAULT_INT_DTYPE, + np.array(self._data, dtype=DTYPE_INT_DEFAULT).dtype, + DTYPE_INT_DEFAULT, ) @@ -354,100 +359,110 @@ def test_arithmetical_operation(self): arithmetical_operation` method. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(self._data.arithmetical_operation(10, "+", False)), self._array + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(self._data.arithmetical_operation(10, "-", False)), self._array - 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(self._data.arithmetical_operation(10, "*", False)), self._array * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(self._data.arithmetical_operation(10, "/", False)), self._array / 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(self._data.arithmetical_operation(10, "**", False)), self._array**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - np.array(self._data + 10), self._array + 10, decimal=7 + np.testing.assert_allclose( + np.array(self._data + 10), + self._array + 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - np.array(self._data - 10), self._array - 10, decimal=7 + np.testing.assert_allclose( + np.array(self._data - 10), + self._array - 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - np.array(self._data * 10), self._array * 10, decimal=7 + np.testing.assert_allclose( + np.array(self._data * 10), + self._array * 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - np.array(self._data / 10), self._array / 10, decimal=7 + np.testing.assert_allclose( + np.array(self._data / 10), + self._array / 10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( - np.array(self._data**10), self._array**10, decimal=7 + np.testing.assert_allclose( + np.array(self._data**10), + self._array**10, + atol=TOLERANCE_ABSOLUTE_TESTS, ) data = deepcopy(self._data) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(data.arithmetical_operation(10, "+", True)), self._array + 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(data.arithmetical_operation(10, "-", True)), self._array, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(data.arithmetical_operation(10, "*", True)), self._array * 10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(data.arithmetical_operation(10, "/", True)), self._array, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(data.arithmetical_operation(10, "**", True)), self._array**10, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) data = deepcopy(self._data) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(data.arithmetical_operation(self._array, "+", False)), data + self._array, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( np.array(data.arithmetical_operation(data, "+", False)), data + data, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) data = self._factory(1, 2, 3) @@ -480,11 +495,11 @@ def test_as_array(self): np.testing.assert_equal(as_array([1, 2, 3]), np.array([1, 2, 3])) self.assertEqual( - as_array([1, 2, 3], DEFAULT_FLOAT_DTYPE).dtype, DEFAULT_FLOAT_DTYPE + as_array([1, 2, 3], DTYPE_FLOAT_DEFAULT).dtype, DTYPE_FLOAT_DEFAULT ) self.assertEqual( - as_array([1, 2, 3], DEFAULT_INT_DTYPE).dtype, DEFAULT_INT_DTYPE + as_array([1, 2, 3], DTYPE_INT_DEFAULT).dtype, DTYPE_INT_DEFAULT ) np.testing.assert_equal( @@ -507,15 +522,15 @@ def test_as_int(self): self.assertEqual(as_int(np.array([[1]])).ndim, 2) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( as_int(np.array([1.0, 2.0, 3.0])), np.array([1, 2, 3]) ) self.assertEqual( - as_int(np.array([1.0, 2.0, 3.0])).dtype, DEFAULT_INT_DTYPE + as_int(np.array([1.0, 2.0, 3.0])).dtype, DTYPE_INT_DEFAULT ) - self.assertIsInstance(as_int(1), DEFAULT_INT_DTYPE) + self.assertIsInstance(as_int(1), DTYPE_INT_DEFAULT) class TestAsFloat(unittest.TestCase): @@ -533,15 +548,17 @@ def test_as_float(self): self.assertEqual(as_float(np.array([[1]])).ndim, 2) - np.testing.assert_array_almost_equal( - as_float(np.array([1, 2, 3])), np.array([1.0, 2.0, 3.0]) + np.testing.assert_allclose( + as_float(np.array([1, 2, 3])), + np.array([1.0, 2.0, 3.0]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) self.assertEqual( - as_float(np.array([1, 2, 3])).dtype, DEFAULT_FLOAT_DTYPE + as_float(np.array([1, 2, 3])).dtype, DTYPE_FLOAT_DEFAULT ) - self.assertIsInstance(as_float(1), DEFAULT_FLOAT_DTYPE) + self.assertIsInstance(as_float(1), DTYPE_FLOAT_DEFAULT) class TestAsIntArray(unittest.TestCase): @@ -557,7 +574,7 @@ def test_as_int_array(self): as_int_array([1.0, 2.0, 3.0]), np.array([1, 2, 3]) ) - self.assertEqual(as_int_array([1, 2, 3]).dtype, DEFAULT_INT_DTYPE) + self.assertEqual(as_int_array([1, 2, 3]).dtype, DTYPE_INT_DEFAULT) class TestAsFloatArray(unittest.TestCase): @@ -571,7 +588,7 @@ def test_as_float_array(self): np.testing.assert_equal(as_float_array([1, 2, 3]), np.array([1, 2, 3])) - self.assertEqual(as_float_array([1, 2, 3]).dtype, DEFAULT_FLOAT_DTYPE) + self.assertEqual(as_float_array([1, 2, 3]).dtype, DTYPE_FLOAT_DEFAULT) class TestAsIntScalar(unittest.TestCase): @@ -585,7 +602,7 @@ def test_as_int_scalar(self): self.assertEqual(as_int_scalar(1.0), 1) - self.assertEqual(as_int_scalar(1.0).dtype, DEFAULT_INT_DTYPE) + self.assertEqual(as_int_scalar(1.0).dtype, DTYPE_INT_DEFAULT) class TestAsFloatScalar(unittest.TestCase): @@ -599,7 +616,7 @@ def test_as_float_scalar(self): self.assertEqual(as_float_scalar(1), 1.0) - self.assertEqual(as_float_scalar(1).dtype, DEFAULT_FLOAT_DTYPE) + self.assertEqual(as_float_scalar(1).dtype, DTYPE_FLOAT_DEFAULT) class TestSetDefaultIntegerDtype(unittest.TestCase): @@ -1276,10 +1293,10 @@ def test_closest(self): self.assertEqual(closest(a, 24.90), 25.40026416) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( closest(a, np.array([63.05, 51.15, 24.90])), np.array([62.70988028, 46.84480573, 25.40026416]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1292,21 +1309,22 @@ class TestInterval(unittest.TestCase): def test_interval(self): """Test :func:`colour.utilities.array.interval` definition.""" - np.testing.assert_array_almost_equal( - interval(range(0, 10, 2)), np.array([2]) - ) + np.testing.assert_array_equal(interval(range(0, 10, 2)), np.array([2])) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( interval(range(0, 10, 2), False), np.array([2, 2, 2, 2]) ) - np.testing.assert_array_almost_equal( - interval([1, 2, 3, 4, 6, 6.5]), np.array([0.5, 1.0, 2.0]) + np.testing.assert_allclose( + interval([1, 2, 3, 4, 6, 6.5]), + np.array([0.5, 1.0, 2.0]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( interval([1, 2, 3, 4, 6, 6.5], False), np.array([1.0, 1.0, 1.0, 2.0, 0.5]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1360,17 +1378,17 @@ def test_n_dimensional_in_array(self): support. """ - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( in_array(np.array([0.50, 0.60]), np.linspace(0, 10, 101)).shape, np.array([2]), ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( in_array(np.array([[0.50, 0.60]]), np.linspace(0, 10, 101)).shape, np.array([1, 2]), ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( in_array( np.array([[0.50], [0.60]]), np.linspace(0, 10, 101) ).shape, @@ -1388,12 +1406,10 @@ def test_tstack(self): """Test :func:`colour.utilities.array.tstack` definition.""" a = 0 - np.testing.assert_array_almost_equal( - tstack([a, a, a]), np.array([0, 0, 0]) - ) + np.testing.assert_array_equal(tstack([a, a, a]), np.array([0, 0, 0])) a = np.arange(0, 6) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( tstack([a, a, a]), np.array( [ @@ -1408,7 +1424,7 @@ def test_tstack(self): ) a = np.reshape(a, (1, 6)) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( tstack([a, a, a]), np.array( [ @@ -1425,7 +1441,7 @@ def test_tstack(self): ) a = np.reshape(a, (1, 2, 3)) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( tstack([a, a, a]), np.array( [ @@ -1448,7 +1464,7 @@ def test_tsplit(self): """Test :func:`colour.utilities.array.tsplit` definition.""" a = np.array([0, 0, 0]) - np.testing.assert_array_almost_equal(tsplit(a), np.array([0, 0, 0])) + np.testing.assert_array_equal(tsplit(a), np.array([0, 0, 0])) a = np.array( [ [0, 0, 0], @@ -1459,7 +1475,7 @@ def test_tsplit(self): [5, 5, 5], ] ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( tsplit(a), np.array( [ @@ -1482,7 +1498,7 @@ def test_tsplit(self): ], ] ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( tsplit(a), np.array( [ @@ -1501,7 +1517,7 @@ def test_tsplit(self): ] ] ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( tsplit(a), np.array( [ @@ -1522,7 +1538,7 @@ class TestRowAsDiagonal(unittest.TestCase): def test_row_as_diagonal(self): """Test :func:`colour.utilities.array.row_as_diagonal` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( row_as_diagonal( np.array( [ @@ -1563,6 +1579,7 @@ def test_row_as_diagonal(self): ], ] ), + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -1577,7 +1594,7 @@ def test_orient(self): a = np.tile(np.arange(5), (5, 1)) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( orient(a, "Flip"), np.array( [ @@ -1588,10 +1605,9 @@ def test_orient(self): [4, 3, 2, 1, 0], ] ), - decimal=7, ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( orient(a, "Flop"), np.array( [ @@ -1602,10 +1618,9 @@ def test_orient(self): [0, 1, 2, 3, 4], ] ), - decimal=7, ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( orient(a, "90 CW"), np.array( [ @@ -1616,10 +1631,9 @@ def test_orient(self): [4, 4, 4, 4, 4], ] ), - decimal=7, ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( orient(a, "90 CCW"), np.array( [ @@ -1630,10 +1644,9 @@ def test_orient(self): [0, 0, 0, 0, 0], ] ), - decimal=7, ) - np.testing.assert_array_almost_equal( + np.testing.assert_array_equal( orient(a, "180"), np.array( [ @@ -1644,10 +1657,9 @@ def test_orient(self): [4, 3, 2, 1, 0], ] ), - decimal=7, ) - np.testing.assert_array_almost_equal(orient(a), a, decimal=7) + np.testing.assert_array_equal(orient(a), a) class TestCentroid(unittest.TestCase): @@ -1682,14 +1694,16 @@ def test_fill_nan(self): """Test :func:`colour.utilities.array.fill_nan` definition.""" a = np.array([0.1, 0.2, np.nan, 0.4, 0.5]) - np.testing.assert_array_almost_equal( - fill_nan(a), np.array([0.1, 0.2, 0.3, 0.4, 0.5]), decimal=7 + np.testing.assert_allclose( + fill_nan(a), + np.array([0.1, 0.2, 0.3, 0.4, 0.5]), + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( fill_nan(a, method="Constant", default=8.0), np.array([0.1, 0.2, 8.0, 0.4, 0.5]), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/utilities/tests/test_common.py b/colour/utilities/tests/test_common.py index 19ff8a23e8..83d72ea6d8 100644 --- a/colour/utilities/tests/test_common.py +++ b/colour/utilities/tests/test_common.py @@ -3,31 +3,35 @@ from __future__ import annotations -import numpy as np import platform -import unittest import unicodedata +import unittest from functools import partial +import numpy as np + from colour.hints import Any, Real, Tuple from colour.utilities import ( CacheRegistry, CanonicalMapping, attest, batch, - multiprocessing_pool, - is_iterable, - is_string, - is_numeric, - is_integer, - is_sibling, + caching_enable, filter_kwargs, filter_mapping, first_item, - validate_method, + int_digest, + is_caching_enabled, + is_integer, + is_iterable, + is_numeric, + is_sibling, + is_string, + multiprocessing_pool, optional, + set_caching_enable, slugify, - int_digest, + validate_method, ) __author__ = "Colour Developers" @@ -38,6 +42,9 @@ __status__ = "Production" __all__ = [ + "TestIsCachingEnabled", + "TestSetCachingEnabled", + "TestCachingEnable", "TestCacheRegistry", "TestAttest", "TestBatch", @@ -56,6 +63,72 @@ ] +class TestIsCachingEnabled(unittest.TestCase): + """ + Define :func:`colour.utilities.common.is_caching_enabled` definition unit + tests methods. + """ + + def test_is_caching_enabled(self): + """Test :func:`colour.utilities.common.is_caching_enabled` definition.""" + + with caching_enable(True): + self.assertTrue(is_caching_enabled()) + + with caching_enable(False): + self.assertFalse(is_caching_enabled()) + + +class TestSetCachingEnabled(unittest.TestCase): + """ + Define :func:`colour.utilities.common.set_caching_enable` definition unit + tests methods. + """ + + def test_set_caching_enable(self): + """Test :func:`colour.utilities.common.set_caching_enable` definition.""" + + with caching_enable(is_caching_enabled()): + set_caching_enable(True) + self.assertTrue(is_caching_enabled()) + + with caching_enable(is_caching_enabled()): + set_caching_enable(False) + self.assertFalse(is_caching_enabled()) + + +class TestCachingEnable(unittest.TestCase): + """ + Define :func:`colour.utilities.common.caching_enable` definition unit + tests methods. + """ + + def test_caching_enable(self): + """Test :func:`colour.utilities.common.caching_enable` definition.""" + + with caching_enable(True): + self.assertTrue(is_caching_enabled()) + + with caching_enable(False): + self.assertFalse(is_caching_enabled()) + + @caching_enable(True) + def fn_a(): + """:func:`caching_enable` unit tests :func:`fn_a` definition.""" + + self.assertTrue(is_caching_enabled()) + + fn_a() + + @caching_enable(False) + def fn_b(): + """:func:`caching_enable` unit tests :func:`fn_b` definition.""" + + self.assertFalse(is_caching_enabled()) + + fn_b() + + class TestCacheRegistry(unittest.TestCase): """ Define :class:`colour.utilities.common.CacheRegistry` class unit diff --git a/colour/utilities/tests/test_data_structures.py b/colour/utilities/tests/test_data_structures.py index 3317d5cfcf..6d29934929 100644 --- a/colour/utilities/tests/test_data_structures.py +++ b/colour/utilities/tests/test_data_structures.py @@ -1,18 +1,19 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.utilities.data_structures` module.""" -import numpy as np import operator import pickle import unittest +import numpy as np + from colour.utilities import ( - ColourUsageWarning, - Structure, - Lookup, CanonicalMapping, + ColourUsageWarning, LazyCanonicalMapping, + Lookup, Node, + Structure, ) __author__ = "Colour Developers" @@ -70,10 +71,10 @@ def test_Structure(self): self.assertEqual(structure.John, "Doe") self.assertEqual(structure["John"], "Doe") - def test_Structure_pickle(self): + def test_pickling(self): """ - Test :class:`colour.utilities.data_structures.Structure` class - pickling. + Test whether :class:`colour.utilities.data_structures.Structure` class + can be pickled. """ structure = Structure(John="Doe", Jane="Doe") diff --git a/colour/utilities/tests/test_deprecated.py b/colour/utilities/tests/test_deprecated.py index b04bd25554..898031f6a0 100644 --- a/colour/utilities/tests/test_deprecated.py +++ b/colour/utilities/tests/test_deprecated.py @@ -6,8 +6,8 @@ from colour.hints import Any from colour.utilities.deprecation import ( ModuleAPI, - ObjectRenamed, ObjectRemoved, + ObjectRenamed, ) diff --git a/colour/utilities/tests/test_deprecation.py b/colour/utilities/tests/test_deprecation.py index 6988cc0914..22c95744df 100644 --- a/colour/utilities/tests/test_deprecation.py +++ b/colour/utilities/tests/test_deprecation.py @@ -6,19 +6,19 @@ from colour.utilities import ColourUsageWarning from colour.utilities.deprecation import ( - ObjectRenamed, - ObjectRemoved, - ObjectFutureRename, - ObjectFutureRemove, - ObjectFutureAccessChange, - ObjectFutureAccessRemove, - ArgumentRenamed, - ArgumentRemoved, - ArgumentFutureRename, ArgumentFutureRemove, + ArgumentFutureRename, + ArgumentRemoved, + ArgumentRenamed, ModuleAPI, - get_attribute, + ObjectFutureAccessChange, + ObjectFutureAccessRemove, + ObjectFutureRemove, + ObjectFutureRename, + ObjectRemoved, + ObjectRenamed, build_API_changes, + get_attribute, handle_arguments_deprecation, ) diff --git a/colour/utilities/tests/test_metrics.py b/colour/utilities/tests/test_metrics.py index f118f911a1..3d6e0ec47b 100644 --- a/colour/utilities/tests/test_metrics.py +++ b/colour/utilities/tests/test_metrics.py @@ -1,9 +1,11 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.utilities.metrics` module.""" -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import metric_mse, metric_psnr __author__ = "Colour Developers" @@ -32,13 +34,17 @@ def test_metric_mse(self): self.assertEqual(metric_mse(a, a), 0) b = a * 0.9 - self.assertAlmostEqual( - metric_mse(a, b), 0.0012714955474297446, places=7 + np.testing.assert_allclose( + metric_mse(a, b), + 0.0012714955474297446, + atol=TOLERANCE_ABSOLUTE_TESTS, ) b = a * 1.1 - self.assertAlmostEqual( - metric_mse(a, b), 0.0012714955474297446, places=7 + np.testing.assert_allclose( + metric_mse(a, b), + 0.0012714955474297446, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -55,10 +61,18 @@ def test_metric_psnr(self): self.assertEqual(metric_psnr(a, a), 0) b = a * 0.9 - self.assertAlmostEqual(metric_psnr(a, b), 28.956851563141299, places=7) + np.testing.assert_allclose( + metric_psnr(a, b), + 28.956851563141299, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) b = a * 1.1 - self.assertAlmostEqual(metric_psnr(a, b), 28.956851563141296, places=7) + np.testing.assert_allclose( + metric_psnr(a, b), + 28.956851563141296, + atol=TOLERANCE_ABSOLUTE_TESTS, + ) if __name__ == "__main__": diff --git a/colour/utilities/tests/test_verbose.py b/colour/utilities/tests/test_verbose.py index 2842406754..3c39d5ed51 100644 --- a/colour/utilities/tests/test_verbose.py +++ b/colour/utilities/tests/test_verbose.py @@ -3,17 +3,19 @@ import os import sys -import unittest import textwrap +import unittest +from colour.hints import Optional from colour.utilities import ( - show_warning, - suppress_warnings, describe_environment, - multiline_str, multiline_repr, + multiline_str, + show_warning, + suppress_stdout, + suppress_warnings, + warning, ) -from colour.utilities import warning __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -25,6 +27,7 @@ __all__ = [ "TestShowWarning", "TestSuppressWarnings", + "TestSuppressStdout", "TestDescribeEnvironment", "TestMultilineStr", "TestMultilineRepr", @@ -68,6 +71,19 @@ def test_suppress_warnings(self): warning("This is a suppressed unit test warning!") +class TestSuppressStdout(unittest.TestCase): + """ + Define :func:`colour.utilities.verbose.suppress_stdout` definition unit + tests methods. + """ + + def test_suppress_stdout(self): + """Test :func:`colour.utilities.verbose.suppress_stdout` definition.""" + + with suppress_stdout(): + print("This is a suppressed message!") # noqa: T201 + + class TestDescribeEnvironment(unittest.TestCase): """ Define :func:`colour.utilities.verbose.describe_environment` definition @@ -184,10 +200,13 @@ def test_multiline_repr(self): """Test :func:`colour.utilities.verbose.multiline_repr` definition.""" class Data: - def __init__(self, a: str, b: int, c: list) -> None: + def __init__( + self, a: str, b: int, c: list, d: Optional[str] = None + ) -> None: self._a = a self._b = b self._c = c + self._d = d def __repr__(self) -> str: return multiline_repr( @@ -201,6 +220,10 @@ def __repr__(self) -> str: .replace("[", "(") .replace("]", ")"), }, + { + "name": "_d", + "formatter": lambda x: None, # noqa: ARG005 + }, ], ) @@ -210,7 +233,8 @@ def __repr__(self) -> str: """ Data('Foo', 1, - ('John', 'Doe')) + ('John', 'Doe'), + None) """ ).strip(), ) diff --git a/colour/utilities/verbose.py b/colour/utilities/verbose.py index 78cecdbbbf..ce1eff1d10 100644 --- a/colour/utilities/verbose.py +++ b/colour/utilities/verbose.py @@ -7,7 +7,7 @@ from __future__ import annotations -import numpy as np +import functools import os import sys import traceback @@ -18,19 +18,21 @@ from textwrap import TextWrapper from warnings import filterwarnings, formatwarning, warn -from colour.utilities import is_string, optional +import numpy as np + from colour.hints import ( Any, Callable, Dict, + Generator, List, LiteralWarning, Mapping, - Generator, TextIO, Type, cast, ) +from colour.utilities import is_string, optional __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -50,6 +52,7 @@ "usage_warning", "filter_warnings", "suppress_warnings", + "suppress_stdout", "numpy_print_options", "ANCILLARY_COLOUR_SCIENCE_PACKAGES", "ANCILLARY_RUNTIME_PACKAGES", @@ -448,6 +451,45 @@ def suppress_warnings( warnings.showwarning = show_warnings +class suppress_stdout: + """ + Define a context manager and decorator temporarily suppressing standard + output. + + Examples + -------- + >>> with suppress_stdout(): + ... print("Hello World!") + ... + >>> print("Hello World!") + Hello World! + """ + + def __enter__(self) -> suppress_stdout: + """Redirect the standard output upon entering the context manager.""" + + self._stdout = sys.stdout + sys.stdout = open(os.devnull, "w") # noqa: SIM115 + + return self + + def __exit__(self, *args: Any): + """Restore the standard output upon exiting the context manager.""" + + sys.stdout.close() + sys.stdout = self._stdout + + def __call__(self, function: Callable) -> Callable: + """Call the wrapped definition.""" + + @functools.wraps(function) + def wrapper(*args: Any, **kwargs: Any) -> Callable: + with self: + return function(*args, **kwargs) + + return wrapper + + @contextmanager def numpy_print_options(*args: Any, **kwargs: Any) -> Generator: """ @@ -626,7 +668,6 @@ def describe_environment( # TODO: Implement support for "pyproject.toml" file whenever "TOML" is # supported in the standard library. - # NOTE: A few clauses are not reached and a few packages are not available # during continuous integration and are thus ignored for coverage. try: # pragma: no cover @@ -983,6 +1024,9 @@ def _format(attribute: dict) -> str: else: value = attribute["formatter"](None) + if value is None: + return str(None) + if reduce_array_representation and value.startswith("array("): lines = value.splitlines() for i, line in enumerate(lines): @@ -1006,4 +1050,4 @@ def _format(attribute: dict) -> str: representation.append(f"{'':{justify}}{_format(attribute)}") - return "{})".format(",\n".join(representation)) + return "{})".format(",\n".join(representation)) # noqa: flynt diff --git a/colour/volume/macadam_limits.py b/colour/volume/macadam_limits.py index ef0dd0655c..e081ac5918 100644 --- a/colour/volume/macadam_limits.py +++ b/colour/volume/macadam_limits.py @@ -13,8 +13,12 @@ from colour.constants import EPSILON from colour.hints import ArrayLike, Literal, NDArrayFloat from colour.models import xyY_to_XYZ +from colour.utilities import ( + CACHE_REGISTRY, + is_caching_enabled, + validate_method, +) from colour.volume import OPTIMAL_COLOUR_STIMULI_ILLUMINANTS -from colour.utilities import CACHE_REGISTRY, validate_method __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -66,10 +70,12 @@ def _XYZ_optimal_colour_stimuli( vertices = _CACHE_OPTIMAL_COLOUR_STIMULI_XYZ.get(illuminant) - if vertices is None: - _CACHE_OPTIMAL_COLOUR_STIMULI_XYZ[illuminant] = vertices = ( - xyY_to_XYZ(optimal_colour_stimuli) / 100 - ) + if is_caching_enabled() and vertices is not None: + return vertices + + _CACHE_OPTIMAL_COLOUR_STIMULI_XYZ[illuminant] = vertices = ( + xyY_to_XYZ(optimal_colour_stimuli) / 100 + ) return vertices diff --git a/colour/volume/pointer_gamut.py b/colour/volume/pointer_gamut.py index 8a508675f7..b0216f615b 100644 --- a/colour/volume/pointer_gamut.py +++ b/colour/volume/pointer_gamut.py @@ -10,10 +10,10 @@ from colour.constants import EPSILON from colour.hints import ArrayLike, NDArrayFloat from colour.models import ( + CCS_ILLUMINANT_POINTER_GAMUT, + DATA_POINTER_GAMUT_VOLUME, Lab_to_XYZ, LCHab_to_Lab, - DATA_POINTER_GAMUT_VOLUME, - CCS_ILLUMINANT_POINTER_GAMUT, ) from colour.volume import is_within_mesh_volume @@ -46,7 +46,7 @@ def is_within_pointer_gamut( Returns ------- :class:`numpy.ndarray` - Wether given *CIE XYZ* tristimulus values are within Pointer's Gamut + Whether given *CIE XYZ* tristimulus values are within Pointer's Gamut volume. Notes diff --git a/colour/volume/rgb.py b/colour/volume/rgb.py index 627d0ded04..68e70e635c 100644 --- a/colour/volume/rgb.py +++ b/colour/volume/rgb.py @@ -14,15 +14,16 @@ from __future__ import annotations import itertools + import numpy as np from colour.algebra import random_triplet_generator from colour.colorimetry import CCS_ILLUMINANTS -from colour.constants import DEFAULT_INT_DTYPE +from colour.constants import DTYPE_INT_DEFAULT from colour.hints import ( ArrayLike, Callable, - Literal, + LiteralChromaticAdaptationTransform, NDArrayFloat, ) from colour.models import ( @@ -32,8 +33,8 @@ XYZ_to_Lab, XYZ_to_RGB, ) -from colour.volume import is_within_pointer_gamut, is_within_visible_spectrum from colour.utilities import as_float_array, multiprocessing_pool +from colour.volume import is_within_pointer_gamut, is_within_visible_spectrum __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -78,20 +79,7 @@ def sample_RGB_colourspace_volume_MonteCarlo( illuminant_Lab: ArrayLike = CCS_ILLUMINANTS[ "CIE 1931 2 Degree Standard Observer" ]["D65"], - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", random_generator: Callable = random_triplet_generator, @@ -149,7 +137,7 @@ def sample_RGB_colourspace_volume_MonteCarlo( random_state if random_state is not None else np.random.RandomState() ) - Lab = random_generator(DEFAULT_INT_DTYPE(samples), limits, random_state) + Lab = random_generator(DTYPE_INT_DEFAULT(samples), limits, random_state) RGB = XYZ_to_RGB( Lab_to_XYZ(Lab, illuminant_Lab), colourspace, @@ -219,20 +207,7 @@ def RGB_colourspace_volume_MonteCarlo( illuminant_Lab: ArrayLike = CCS_ILLUMINANTS[ "CIE 1931 2 Degree Standard Observer" ]["D65"], - chromatic_adaptation_transform: Literal[ - "Bianco 2010", - "Bianco PC 2010", - "Bradford", - "CAT02 Brill 2008", - "CAT02", - "CAT16", - "CMCCAT2000", - "CMCCAT97", - "Fairchild", - "Sharp", - "Von Kries", - "XYZ Scaling", - ] + chromatic_adaptation_transform: LiteralChromaticAdaptationTransform | str | None = "CAT02", random_generator: Callable = random_triplet_generator, @@ -292,7 +267,7 @@ def RGB_colourspace_volume_MonteCarlo( import multiprocessing processes = multiprocessing.cpu_count() - process_samples = DEFAULT_INT_DTYPE(np.round(samples / processes)) + process_samples = DTYPE_INT_DEFAULT(np.round(samples / processes)) arguments = ( colourspace, @@ -360,7 +335,7 @@ def RGB_colourspace_volume_coverage_MonteCarlo( ) XYZ = random_generator( - DEFAULT_INT_DTYPE(samples), random_state=random_state + DTYPE_INT_DEFAULT(samples), random_state=random_state ) XYZ_vs = XYZ[coverage_sampler(XYZ)] diff --git a/colour/volume/spectrum.py b/colour/volume/spectrum.py index 0dc6e3a674..2e4ac4cd06 100644 --- a/colour/volume/spectrum.py +++ b/colour/volume/spectrum.py @@ -31,15 +31,20 @@ handle_spectral_arguments, msds_to_XYZ, ) -from colour.constants import DEFAULT_FLOAT_DTYPE, EPSILON +from colour.constants import DTYPE_FLOAT_DEFAULT, EPSILON from colour.hints import ( Any, ArrayLike, Literal, NDArrayFloat, ) +from colour.utilities import ( + CACHE_REGISTRY, + is_caching_enabled, + validate_method, + zeros, +) from colour.volume import is_within_mesh_volume -from colour.utilities import CACHE_REGISTRY, zeros, validate_method __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -214,7 +219,7 @@ def generate_pulse_waves( square_waves = [] square_waves_basis = np.tril( - np.ones((bins, bins), dtype=DEFAULT_FLOAT_DTYPE) + np.ones((bins, bins), dtype=DTYPE_FLOAT_DEFAULT) )[0:-1, :] if pulse_order.lower() == "bins": @@ -233,7 +238,7 @@ def generate_pulse_waves( [ zeros(bins), np.vstack(square_waves), - np.ones(bins, dtype=DEFAULT_FLOAT_DTYPE), + np.ones(bins, dtype=DTYPE_FLOAT_DEFAULT), ] ) @@ -359,18 +364,20 @@ def XYZ_outer_surface( ) XYZ = _CACHE_OUTER_SURFACE_XYZ.get(key) - if XYZ is None: - pulse_waves = generate_pulse_waves( - len(cmfs.wavelengths), point_order, filter_jagged_points - ) - XYZ = ( - msds_to_XYZ( - pulse_waves, cmfs, illuminant, method="Integration", **settings - ) - / 100 + if is_caching_enabled() and XYZ is not None: + return XYZ + + pulse_waves = generate_pulse_waves( + len(cmfs.wavelengths), point_order, filter_jagged_points + ) + XYZ = ( + msds_to_XYZ( + pulse_waves, cmfs, illuminant, method="Integration", **settings ) + / 100 + ) - _CACHE_OUTER_SURFACE_XYZ[key] = XYZ + _CACHE_OUTER_SURFACE_XYZ[key] = XYZ return XYZ diff --git a/colour/volume/tests/test_macadam_limits.py b/colour/volume/tests/test_macadam_limits.py index fa7cdd3d03..346beff718 100644 --- a/colour/volume/tests/test_macadam_limits.py +++ b/colour/volume/tests/test_macadam_limits.py @@ -1,12 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.volume.macadam_limits` module.""" -import numpy as np import unittest from itertools import product -from colour.volume import is_within_macadam_limits +import numpy as np + from colour.utilities import ignore_numpy_errors +from colour.volume import is_within_macadam_limits __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -59,15 +60,11 @@ def test_n_dimensional_is_within_macadam_limits(self): a = np.tile(a, (6, 1)) b = np.tile(b, 6) - np.testing.assert_array_almost_equal( - is_within_macadam_limits(a, "A"), b - ) + np.testing.assert_allclose(is_within_macadam_limits(a, "A"), b) a = np.reshape(a, (2, 3, 3)) b = np.reshape(b, (2, 3)) - np.testing.assert_array_almost_equal( - is_within_macadam_limits(a, "A"), b - ) + np.testing.assert_allclose(is_within_macadam_limits(a, "A"), b) @ignore_numpy_errors def test_nan_is_within_macadam_limits(self): diff --git a/colour/volume/tests/test_mesh.py b/colour/volume/tests/test_mesh.py index ec64bbe0d7..8f9a45a422 100644 --- a/colour/volume/tests/test_mesh.py +++ b/colour/volume/tests/test_mesh.py @@ -1,12 +1,14 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.volume.mesh` module.""" -import numpy as np import unittest from itertools import product -from colour.volume import is_within_mesh_volume +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.utilities import ignore_numpy_errors +from colour.volume import is_within_mesh_volume __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -77,14 +79,18 @@ def test_n_dimensional_is_within_mesh_volume(self): a = np.tile(a, (6, 1)) b = np.tile(b, 6) - np.testing.assert_array_almost_equal( - is_within_mesh_volume(a, self._mesh), b + np.testing.assert_allclose( + is_within_mesh_volume(a, self._mesh), + b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) a = np.reshape(a, (2, 3, 3)) b = np.reshape(b, (2, 3)) - np.testing.assert_array_almost_equal( - is_within_mesh_volume(a, self._mesh), b + np.testing.assert_allclose( + is_within_mesh_volume(a, self._mesh), + b, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @ignore_numpy_errors diff --git a/colour/volume/tests/test_pointer_gamut.py b/colour/volume/tests/test_pointer_gamut.py index 0a3def0296..01fd3d3c50 100644 --- a/colour/volume/tests/test_pointer_gamut.py +++ b/colour/volume/tests/test_pointer_gamut.py @@ -1,12 +1,13 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.volume.pointer_gamut` module.""" -import numpy as np import unittest from itertools import product -from colour.volume import is_within_pointer_gamut +import numpy as np + from colour.utilities import ignore_numpy_errors +from colour.volume import is_within_pointer_gamut __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -59,11 +60,11 @@ def test_n_dimensional_is_within_pointer_gamut(self): a = np.tile(a, (6, 1)) b = np.tile(b, 6) - np.testing.assert_array_almost_equal(is_within_pointer_gamut(a), b) + np.testing.assert_allclose(is_within_pointer_gamut(a), b) a = np.reshape(a, (2, 3, 3)) b = np.reshape(b, (2, 3)) - np.testing.assert_array_almost_equal(is_within_pointer_gamut(a), b) + np.testing.assert_allclose(is_within_pointer_gamut(a), b) @ignore_numpy_errors def test_nan_is_within_pointer_gamut(self): diff --git a/colour/volume/tests/test_rgb.py b/colour/volume/tests/test_rgb.py index cd381b7bd3..bac97a1923 100644 --- a/colour/volume/tests/test_rgb.py +++ b/colour/volume/tests/test_rgb.py @@ -18,23 +18,25 @@ reproducibility-of-python-pseudo-random-numbers-across-systems-and-versions """ -import numpy as np import unittest +import numpy as np + +from colour.constants import TOLERANCE_ABSOLUTE_TESTS from colour.models import ( RGB_COLOURSPACE_ACES2065_1, - RGB_COLOURSPACE_BT2020, RGB_COLOURSPACE_BT709, + RGB_COLOURSPACE_BT2020, ) +from colour.utilities import disable_multiprocessing from colour.volume import ( RGB_colourspace_limits, - RGB_colourspace_volume_MonteCarlo, - RGB_colourspace_volume_coverage_MonteCarlo, RGB_colourspace_pointer_gamut_coverage_MonteCarlo, RGB_colourspace_visible_spectrum_coverage_MonteCarlo, + RGB_colourspace_volume_coverage_MonteCarlo, + RGB_colourspace_volume_MonteCarlo, is_within_pointer_gamut, ) -from colour.utilities import disable_multiprocessing __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -61,7 +63,7 @@ class TestRGB_colourspaceLimits(unittest.TestCase): def test_RGB_colourspace_limits(self): """Test :func:`colour.volume.rgb.RGB_colourspace_limits` definition.""" - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_colourspace_limits(RGB_COLOURSPACE_BT709), np.array( [ @@ -70,10 +72,10 @@ def test_RGB_colourspace_limits(self): [-107.85546554, 94.48384002], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_colourspace_limits(RGB_COLOURSPACE_BT2020), np.array( [ @@ -82,10 +84,10 @@ def test_RGB_colourspace_limits(self): [-120.27412558, 136.88564561], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_colourspace_limits(RGB_COLOURSPACE_ACES2065_1), np.array( [ @@ -94,7 +96,7 @@ def test_RGB_colourspace_limits(self): [-284.75355519, 177.11142683], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -115,7 +117,7 @@ def test_RGB_colourspace_volume_MonteCarlo(self): definition. """ - self.assertAlmostEqual( + np.testing.assert_allclose( RGB_colourspace_volume_MonteCarlo( RGB_COLOURSPACE_BT709, 10e3, @@ -123,7 +125,7 @@ def test_RGB_colourspace_volume_MonteCarlo(self): ) * 1e-6, 821700.0 * 1e-6, - places=1, + atol=1, ) @@ -143,7 +145,7 @@ def test_RGB_colourspace_volume_coverage_MonteCarlo(self): RGB_colourspace_volume_coverage_MonteCarlo` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_colourspace_volume_coverage_MonteCarlo( RGB_COLOURSPACE_BT709, is_within_pointer_gamut, @@ -151,7 +153,7 @@ def test_RGB_colourspace_volume_coverage_MonteCarlo(self): random_state=np.random.RandomState(2), ), 81.044349070100140, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -172,14 +174,14 @@ def test_RGB_colourspace_pointer_gamut_coverage_MonteCarlo(self): RGB_colourspace_pointer_gamut_coverage_MonteCarlo` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_colourspace_pointer_gamut_coverage_MonteCarlo( RGB_COLOURSPACE_BT709, 10e3, random_state=np.random.RandomState(2), ), 81.044349070100140, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -200,14 +202,14 @@ def test_RGB_colourspace_visible_spectrum_coverage_MonteCarlo(self): RGB_colourspace_visible_spectrum_coverage_MonteCarlo` definition. """ - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( RGB_colourspace_visible_spectrum_coverage_MonteCarlo( RGB_COLOURSPACE_BT709, 10e3, random_state=np.random.RandomState(2), ), 46.931407942238266, - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) diff --git a/colour/volume/tests/test_spectrum.py b/colour/volume/tests/test_spectrum.py index 115891545a..fa6db65298 100644 --- a/colour/volume/tests/test_spectrum.py +++ b/colour/volume/tests/test_spectrum.py @@ -1,22 +1,24 @@ # !/usr/bin/env python """Define the unit tests for the :mod:`colour.volume.spectrum` module.""" -import numpy as np import unittest from itertools import product +import numpy as np + from colour.colorimetry import ( MSDS_CMFS, SPECTRAL_SHAPE_DEFAULT, SpectralShape, reshape_msds, ) +from colour.constants import TOLERANCE_ABSOLUTE_TESTS +from colour.utilities import ignore_numpy_errors from colour.volume import ( - generate_pulse_waves, XYZ_outer_surface, + generate_pulse_waves, is_within_visible_spectrum, ) -from colour.utilities import ignore_numpy_errors __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -147,7 +149,7 @@ def test_XYZ_outer_surface(self): ) cmfs = MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] - np.testing.assert_array_almost_equal( + np.testing.assert_allclose( XYZ_outer_surface(reshape_msds(cmfs, shape)), np.array( [ @@ -185,7 +187,7 @@ def test_XYZ_outer_surface(self): [1.10229434e00, 1.00000000e00, 1.35683013e00], ] ), - decimal=7, + atol=TOLERANCE_ABSOLUTE_TESTS, ) @@ -228,11 +230,11 @@ def test_n_dimensional_is_within_visible_spectrum(self): a = np.tile(a, (6, 1)) b = np.tile(b, 6) - np.testing.assert_array_almost_equal(is_within_visible_spectrum(a), b) + np.testing.assert_allclose(is_within_visible_spectrum(a), b) a = np.reshape(a, (2, 3, 3)) b = np.reshape(b, (2, 3)) - np.testing.assert_array_almost_equal(is_within_visible_spectrum(a), b) + np.testing.assert_allclose(is_within_visible_spectrum(a), b) @ignore_numpy_errors def test_nan_is_within_visible_spectrum(self): diff --git a/docs/advanced.rst b/docs/advanced.rst index 8c046cefa3..597d686a7a 100644 --- a/docs/advanced.rst +++ b/docs/advanced.rst @@ -9,16 +9,23 @@ Environment Various environment variables can be used to modify **Colour** behaviour at runtime: -- `COLOUR_SCIENCE__DEFAULT_INT_DTYPE`: Set the default integer dtype for +- ``COLOUR_SCIENCE__DEFAULT_INT_DTYPE``: Set the default integer dtype for most of **Colour** computations. Possible values are `int32` and `int64` (default). Changing the integer dtype *will almost certainly break* **Colour**! *With great power comes great responsibility*. -- `COLOUR_SCIENCE__DEFAULT_FLOAT_DTYPE`: Set the float dtype for most of +- ``COLOUR_SCIENCE__DEFAULT_FLOAT_DTYPE``: Set the float dtype for most of **Colour** computations. Possible values are `float16`, `float32` and `float64` (default). Changing the float dtype might result in various **Colour** `functionality breaking entirely `__. *With great power comes great responsibility*. -- `COLOUR_SCIENCE__COLOUR__SHOW_WARNINGS_WITH_TRACEBACK`: Result in the +- ``COLOUR_SCIENCE__COLOUR__DISABLE_CACHING``: Disable the caches that can + be disabled, useful for debugging purposes. +- ``COLOUR_SCIENCE__COLOUR__IMPORT_VAAB_COLOUR``: Import + `vaab/colour `__ injection into + **Colour** namespace. This solves the clash with + `vaab/colour `__ by loading a known subset + of the objects given by vaab/colour-0.1.5 into our namespace. +- ``COLOUR_SCIENCE__COLOUR__SHOW_WARNINGS_WITH_TRACEBACK``: Result in the :func:`warnings.showwarning` definition to be replaced with the :func:`colour.utilities.show_warning` definition and thus providing complete traceback from the point where the warning occurred. @@ -29,7 +36,7 @@ Caching **Colour** uses various internal caches to improve speed and prevent redundant processes, notably for spectral related computations. -The internal caches are managed with the `colour.utilities.CACHE_REGISTRY` +The internal caches are managed with the :attr:`colour.utilities.CACHE_REGISTRY` cache registry object: .. code-block:: python @@ -53,20 +60,20 @@ cache registry object: 'colour.volume.spectrum._CACHE_OUTER_SURFACE_XYZ': '0 item(s)', 'colour.volume.spectrum._CACHE_OUTER_SURFACE_XYZ_POINTS': '0 item(s)'} -See `colour.utilities.CacheRegistry` class documentation for more information +See :class:`colour.utilities.CacheRegistry` class documentation for more information on how to manage the cache registry. Using Colour without Scipy -------------------------- With the release of `Colour 0.3.8 `__, -`SciPy `__ became a requirement. +`SciPy `__ became a requirement. **Scipy** is notoriously hard to compile, especially -`on Windows `__. +`on Windows `__. Some Digital Content Creation (DCC) applications are shipping Python interpreters compiled with versions of -`Visual Studio `__ such as 2011 or 2015. +`Visual Studio `__ such as 2011 or 2015. Those are incompatible with the Python Wheels commonly built with `Visual Studio 2008 (Python 2.7) or Visual Studio 2017 (Python 3.6) `__. diff --git a/docs/basics.rst b/docs/basics.rst index 9372e10fdf..99d936f4b3 100644 --- a/docs/basics.rst +++ b/docs/basics.rst @@ -10,11 +10,11 @@ Object Name Categorisation The API tries to bundle the objects by categories by naming them with common prefixes which makes introspection and auto-completion easier. -For example, in `IPython `__ or `Jupyter Notebook `__, +For example, in `IPython `__ or `Jupyter Notebook `__, most of the definitions pertaining to the spectral distribution handling can be found as follows: -.. code:: python +.. code:: text In [1]: import colour @@ -26,7 +26,7 @@ be found as follows: Likewise, for the spectral distribution handling related attributes: -.. code:: python +.. code:: text In [2]: colour.SD SD_GAUSSIAN_METHODS SD_TO_XYZ_METHODS SDS_ILLUMINANTS SDS_LIGHT_SOURCES @@ -36,7 +36,7 @@ Likewise, for the spectral distribution handling related attributes: Similarly, all the RGB colourspaces can be individually accessed from the ``colour.models`` namespace: -.. code:: python +.. code:: text In [2]: colour.models.RGB_COLOURSPACE RGB_COLOURSPACE_ACES2065_1 RGB_COLOURSPACE_ACESPROXY RGB_COLOURSPACE_APPLE_RGB RGB_COLOURSPACE_BT470_525 @@ -47,7 +47,7 @@ Similarly, all the RGB colourspaces can be individually accessed from the Abbreviations ------------- -The following abbreviations are in use in `Colour `__: +The following abbreviations are in use in `Colour `__: - **CAM** : Colour Appearance Model - **CCS** : Chromaticity Coordinates @@ -69,7 +69,7 @@ N-Dimensional Array Support --------------------------- Most of **Colour** definitions are fully vectorised and support n-dimensional -array by leveraging `Numpy `__. +array by leveraging `Numpy `__. While it is recommended to use `ndarray `__ @@ -171,7 +171,7 @@ to support floating point wavelengths. Wavelengths should not have to be defined as integer values and it is effectively common to get data from instruments whose domain is returned as floating point values. -For example, the data from an `Ocean Insight (Optics) STS-VIS `__ +For example, the data from an `Ocean Insight (Optics) STS-VIS `__ spectrometer is typically saved with 3 digits decimal precision: .. code-block:: text @@ -415,24 +415,24 @@ Domain-Range Scales **Colour** adopts 4 main input domains and output ranges: -- *Scalars* usually in domain-range `[0, 1]` (or `[0, 10]` for +- *Scalars* usually in domain-range ``[0, 1]`` (or ``[0, 10]`` for *Munsell Value*). -- *Percentages* usually in domain-range `[0, 100]`. -- *Degrees* usually in domain-range `[0, 360]`. -- *Integers* usually in domain-range `[0, 2**n -1]` where `n` is the bit +- *Percentages* usually in domain-range ``[0, 100]``. +- *Degrees* usually in domain-range ``[0, 360]``. +- *Integers* usually in domain-range ``[0, 2**n -1]`` where ``n`` is the bit depth. It is error prone but it is also a direct consequence of the inconsistency of the colour science field itself. We have discussed at length about this and we -were leaning toward normalisation of the whole API to domain-range `[0, 1]`, we -never committed for reasons highlighted by the following points: +were leaning toward normalisation of the whole API to domain-range ``[0, 1]``, +we never committed for reasons highlighted by the following points: - Colour Scientist performing computations related to Munsell Renotation System would be very surprised if the output *Munsell Value* was in range - `[0, 1]` or `[0, 100]`. + ``[0, 1]`` or ``[0, 100]``. - A Visual Effect Industry artist would be astonished to find out that conversion from *CIE XYZ* to *sRGB* was yielding values in range - `[0, 100]`. + ``[0, 100]``. However benefits of having a consistent and predictable domain-range scale are numerous thus with `Colour 0.3.12 `__ @@ -446,25 +446,25 @@ Scale - Reference the implemented reference, i.e. paper, publication, etc.., domain-range scale. The **'Reference'** domain-range scale is inconsistent, e.g. colour appearance -models, spectral conversions are typically in domain-range `[0, 100]` while RGB -models will operate in domain-range `[0, 1]`. Some objects, e.g. -:func:`colour.colorimetry.lightness_Fairchild2011` definition have mismatched -domain-range: input domain `[0, 1]` and output range `[0, 100]`. +models, spectral conversions are typically in domain-range ``[0, 100]`` while RGB +models will operate in domain-range ``[0, 1]``. Some objects, e.g. +:func:``colour.colorimetry.lightness_Fairchild2011`` definition have mismatched +domain-range: input domain ``[0, 1]`` and output range ``[0, 100]``. Scale - 1 ~~~~~~~~~ **'1'** is a domain-range scale converting all the relevant objects from -**Colour** public API to domain-range `[0, 1]`: +**Colour** public API to domain-range ``[0, 1]``: -- *Scalars* in domain-range `[0, 10]`, e.g *Munsell Value* are +- *Scalars* in domain-range ``[0, 10]``, e.g *Munsell Value* are scaled by *10*. -- *Percentages* in domain-range `[0, 100]` are scaled by *100*. -- *Degrees* in domain-range `[0, 360]` are scaled by *360*. -- *Integers* in domain-range `[0, 2**n -1]` where `n` is the bit +- *Percentages* in domain-range ``[0, 100]`` are scaled by *100*. +- *Degrees* in domain-range ``[0, 360]`` are scaled by *360*. +- *Integers* in domain-range ``[0, 2**n -1]`` where ``n`` is the bit depth are scaled by *2**n -1*. -- *Dimensionless* values are unaffected and are indicated with `DN`. -- *Unaffected* values are unaffected and are indicated with `UN`. +- *Dimensionless* values are unaffected and are indicated with ``DN``. +- *Unaffected* values are unaffected and are indicated with ``UN``. .. warning:: @@ -529,9 +529,7 @@ with the :func:`colour.set_domain_range_scale` definition: Y_o = 20 E_o1 = 1000 E_o2 = 1000 - colour.adaptation.chromatic_adaptation_CIE1994( - XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2 - ) + colour.adaptation.chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2) .. code-block:: text @@ -543,9 +541,7 @@ with the :func:`colour.set_domain_range_scale` definition: XYZ_1 = [0.2800, 0.2126, 0.0527] Y_o = 0.2 - colour.adaptation.chromatic_adaptation_CIE1994( - XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2 - ) + colour.adaptation.chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2) .. code-block:: text @@ -562,9 +558,7 @@ would result in unexpected values and a warning in that case: colour.set_domain_range_scale("Reference") - colour.adaptation.chromatic_adaptation_CIE1994( - XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2 - ) + colour.adaptation.chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2) .. code-block:: text @@ -579,12 +573,12 @@ would result in unexpected values and a warning in that case: Setting the **'1'** domain-range scale has the following effect on the :func:`colour.adaptation.chromatic_adaptation_CIE1994` definition: -As it expects values in domain `[0, 100]`, scaling occurs and the +As it expects values in domain ``[0, 100]``, scaling occurs and the relevant input values, i.e. the values listed in the domain table, ``XYZ_1`` -and ``Y_o`` are converted from domain `[0, 1]` to domain `[0, 100]` by +and ``Y_o`` are converted from domain ``[0, 1]`` to domain ``[0, 100]`` by :func:`colour.utilities.to_domain_100` definition and conversely -return value ``XYZ_2`` is converted from range `[0, 100]` to range `[0, 1]` by -:func:`colour.utilities.from_range_100` definition. +return value ``XYZ_2`` is converted from range ``[0, 100]`` to range ``[0, 1]`` +by :func:`colour.utilities.from_range_100` definition. A convenient alternative to the :func:`colour.set_domain_range_scale` definition is the :class:`colour.domain_range_scale` context manager and @@ -594,9 +588,7 @@ scale value: .. code:: python with colour.domain_range_scale("1"): - colour.adaptation.chromatic_adaptation_CIE1994( - XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2 - ) + colour.adaptation.chromatic_adaptation_CIE1994(XYZ_1, xy_o1, xy_o2, Y_o, E_o1, E_o2) .. code-block:: text @@ -623,7 +615,7 @@ Safe Power and Division ----------------------- **Colour** default handling of fractional power and zero-division occurring -during practical applications is managed via varous definitions and context +during practical applications is managed via various definitions and context managers. Safe Power diff --git a/docs/bibliography.rst b/docs/bibliography.rst index 55aacb35b6..41a68a609e 100644 --- a/docs/bibliography.rst +++ b/docs/bibliography.rst @@ -41,4 +41,4 @@ Some extra references used in the codebase but not directly part of the public a - :cite:`Wyszecki2000` - :cite:`Wyszecki2000bb` - :cite:`Wyszecki2000bh` -- :cite:`Wyszecki2000x` \ No newline at end of file +- :cite:`Wyszecki2000x` diff --git a/docs/colour.blindness.rst b/docs/colour.blindness.rst index 61326dad0b..788bc572c0 100644 --- a/docs/colour.blindness.rst +++ b/docs/colour.blindness.rst @@ -24,4 +24,4 @@ Machado, Oliveira and Fernandes (2009) .. autosummary:: :toctree: generated/ - CVD_MATRICES_MACHADO2010 \ No newline at end of file + CVD_MATRICES_MACHADO2010 diff --git a/docs/colour.constants.rst b/docs/colour.constants.rst index e812bb901c..83cc16df06 100644 --- a/docs/colour.constants.rst +++ b/docs/colour.constants.rst @@ -39,8 +39,12 @@ Common .. autosummary:: :toctree: generated/ - DEFAULT_INT_DTYPE - DEFAULT_FLOAT_DTYPE - EPSILON FLOATING_POINT_NUMBER_PATTERN INTEGER_THRESHOLD + EPSILON + DTYPE_INT_DEFAULT + DTYPE_FLOAT_DEFAULT + TOLERANCE_ABSOLUTE_DEFAULT + TOLERANCE_RELATIVE_DEFAULT + TOLERANCE_ABSOLUTE_TESTS + TOLERANCE_RELATIVE_TESTS diff --git a/docs/colour.continuous.rst b/docs/colour.continuous.rst index 1410c8746a..72a30910ec 100644 --- a/docs/colour.continuous.rst +++ b/docs/colour.continuous.rst @@ -14,4 +14,4 @@ Continuous Signal AbstractContinuousFunction Signal - MultiSignals \ No newline at end of file + MultiSignals diff --git a/docs/colour.difference.rst b/docs/colour.difference.rst index 1daa88d40c..bace5888a1 100644 --- a/docs/colour.difference.rst +++ b/docs/colour.difference.rst @@ -147,4 +147,4 @@ Huang et al. (2015) Power-Functions .. autosummary:: :toctree: generated/ - power_function_Huang2015 \ No newline at end of file + power_function_Huang2015 diff --git a/docs/colour.hints.rst b/docs/colour.hints.rst index a1eb5064ba..deed025bf8 100644 --- a/docs/colour.hints.rst +++ b/docs/colour.hints.rst @@ -13,6 +13,7 @@ Annotation Type Hints ModuleType Any Callable + ClassVar Dict Generator Iterable @@ -55,46 +56,22 @@ Annotation Type Hints ProtocolExtrapolator ProtocolLUTSequenceItem LiteralWarning - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + LiteralChromaticAdaptationTransform + LiteralColourspaceModel + LiteralRGBColourspace + LiteralLogEncoding + LiteralLogDecoding + LiteralOETF + LiteralOETFInverse + LiteralEOTF + LiteralEOTFInverse + LiteralCCTFEncoding + LiteralCCTFDecoding + LiteralOOTF + LiteralOOTFInverse + LiteralLUTReadMethod + LiteralLUTWriteMethod + + + + LiteralFontScaling diff --git a/docs/colour.models.rst b/docs/colour.models.rst index dc39ca2ffa..f6374fe47a 100644 --- a/docs/colour.models.rst +++ b/docs/colour.models.rst @@ -455,15 +455,18 @@ RGB Colourspaces RGB_COLOURSPACE_DCI_P3 RGB_COLOURSPACE_DCI_P3_P RGB_COLOURSPACE_DISPLAY_P3 + RGB_COLOURSPACE_DJI_D_GAMUT RGB_COLOURSPACE_DON_RGB_4 RGB_COLOURSPACE_EBU_3213_E RGB_COLOURSPACE_ECI_RGB_V2 RGB_COLOURSPACE_EKTA_SPACE_PS_5 RGB_COLOURSPACE_F_GAMUT + RGB_COLOURSPACE_FILMLIGHT_E_GAMUT RGB_COLOURSPACE_H273_GENERIC_FILM RGB_COLOURSPACE_H273_22_UNSPECIFIED RGB_COLOURSPACE_PROTUNE_NATIVE RGB_COLOURSPACE_MAX_RGB + RGB_COLOURSPACE_N_GAMUT RGB_COLOURSPACE_NTSC1953 RGB_COLOURSPACE_NTSC1987 RGB_COLOURSPACE_P3_D65 @@ -481,6 +484,7 @@ RGB Colourspaces RGB_COLOURSPACE_PROPHOTO_RGB RGB_COLOURSPACE_PLASA_ANSI_E154 RGB_COLOURSPACE_RUSSELL_RGB + RGB_COLOURSPACE_SHARP_RGB RGB_COLOURSPACE_SMPTE_240M RGB_COLOURSPACE_SMPTE_C RGB_COLOURSPACE_S_GAMUT @@ -694,6 +698,8 @@ Log Encoding and Decoding log_decoding_ACEScct log_encoding_ACESproxy log_decoding_ACESproxy + log_encoding_AppleLogProfile + log_decoding_AppleLogProfile log_encoding_ARRILogC3 log_decoding_ARRILogC3 log_encoding_CanonLog2 diff --git a/docs/colour.notation.rst b/docs/colour.notation.rst index 5ca3eadf9b..d63a0e66f8 100644 --- a/docs/colour.notation.rst +++ b/docs/colour.notation.rst @@ -149,4 +149,3 @@ Web Colours CSS_COLOR_3_EXTENDED CSS_COLOR_3 keyword_to_RGB_CSSColor3 - diff --git a/docs/colour.plotting.rst b/docs/colour.plotting.rst index be1e7abbf7..442a20e71b 100644 --- a/docs/colour.plotting.rst +++ b/docs/colour.plotting.rst @@ -18,8 +18,9 @@ Common .. autosummary:: :toctree: generated/ -z + colour_style + override_style colour_cycle artist camera @@ -44,6 +45,7 @@ z KwargsArtist KwargsCamera KwargsRender + font_scaling filter_passthrough filter_RGB_colourspaces filter_cmfs @@ -122,6 +124,9 @@ CIE Chromaticity Diagrams .. autosummary:: :toctree: generated/ + METHODS_CHROMATICITY_DIAGRAM + LABELS_CHROMATICITY_DIAGRAM_DEFAULT + lines_spectral_locus plot_chromaticity_diagram_CIE1931 plot_chromaticity_diagram_CIE1960UCS plot_chromaticity_diagram_CIE1976UCS @@ -176,6 +181,7 @@ Colour Models :toctree: generated/ colourspace_model_axis_reorder + lines_pointer_gamut plot_pointer_gamut plot_RGB_colourspaces_in_chromaticity_diagram plot_RGB_chromaticities_in_chromaticity_diagram @@ -268,6 +274,9 @@ Colour Temperature & Correlated Colour Temperature .. autosummary:: :toctree: generated/ + lines_daylight_locus + LABELS_PLANCKIAN_LOCUS_DEFAULT + lines_planckian_locus plot_planckian_locus_in_chromaticity_diagram_CIE1931 plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS plot_planckian_locus_in_chromaticity_diagram_CIE1976UCS @@ -333,4 +342,4 @@ Automatic Colour Conversion Graph .. autosummary:: :toctree: generated/ - plot_automatic_colour_conversion_graph \ No newline at end of file + plot_automatic_colour_conversion_graph diff --git a/docs/colour.rst b/docs/colour.rst index fbe1535237..d6d10103cc 100644 --- a/docs/colour.rst +++ b/docs/colour.rst @@ -28,4 +28,4 @@ Colour colour.recovery colour.temperature colour.utilities - colour.volume \ No newline at end of file + colour.volume diff --git a/docs/colour.utilities.rst b/docs/colour.utilities.rst index 1c436aa6bd..5a4134826f 100644 --- a/docs/colour.utilities.rst +++ b/docs/colour.utilities.rst @@ -48,6 +48,9 @@ Common .. autosummary:: :toctree: generated/ + is_caching_enabled + set_caching_enable + caching_enable CACHE_REGISTRY handle_numpy_errors ignore_numpy_errors @@ -190,6 +193,7 @@ Verbose warning filter_warnings suppress_warnings + suppress_stdout numpy_print_options describe_environment multiline_str diff --git a/docs/conf.py b/docs/conf.py index 83d362e8cd..ce4b09afd3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -5,12 +5,13 @@ import os import re -import setuptools.archive_util +import sys import urllib.parse import urllib.request -import sys from pathlib import Path +import setuptools.archive_util + sys.path.append(str(Path(__file__).parent.parent)) import colour as package # noqa: E402 @@ -56,11 +57,11 @@ ] intersphinx_mapping = { - "python": ("https://docs.python.org/3.11", None), + "python": ("https://docs.python.org/3/", None), "matplotlib": ("https://matplotlib.org/stable", None), "numpy": ("https://numpy.org/doc/stable", None), - "pandas": ("https://pandas.pydata.org/pandas-docs/dev", None), - "scipy": ("https://docs.scipy.org/doc/scipy-1.8.0/", None), + "pandas": ("https://pandas.pydata.org/pandas-docs/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy/", None), } autodoc_member_order = "bysource" diff --git a/docs/index.rst b/docs/index.rst index 35ab67e48f..4b8feaf643 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,15 +1,21 @@ -.. image:: https://raw.githubusercontent.com/colour-science/colour-branding/master/images/Colour_Logo_001.png +.. raw:: html + + + + + + | `Colour `__ is an open-source -`Python `__ package providing a comprehensive number +`Python `__ package providing a comprehensive number of algorithms and datasets for colour science. It is freely available under the `BSD-3-Clause `__ terms. -**Colour** is an affiliated project of `NumFOCUS `__, a +**Colour** is an affiliated project of `NumFOCUS `__, a 501(c)(3) nonprofit in the United States. .. sectnum:: @@ -37,7 +43,7 @@ Most of the objects are available from the ``colour`` namespace: .. code-block:: python - >>> import colour + import colour Automatic Colour Conversion Graph - ``colour.graph`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -49,12 +55,10 @@ conversion graph enabling easier colour conversions. .. code-block:: python - >>> sd = colour.SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] - >>> colour.convert( - ... sd, "Spectral Distribution", "sRGB", verbose={"mode": "Short"} - ... ) + sd = colour.SDS_COLOURCHECKERS["ColorChecker N Ohta"]["dark skin"] + colour.convert(sd, "Spectral Distribution", "sRGB", verbose={"mode": "Short"}) -:: +.. code-block:: text =============================================================================== * * @@ -67,13 +71,16 @@ conversion graph enabling easier colour conversions. .. code-block:: python - >>> illuminant = colour.SDS_ILLUMINANTS["FL2"] - >>> colour.convert( - ... sd, - ... "Spectral Distribution", - ... "sRGB", - ... sd_to_XYZ={"illuminant": illuminant}, - ... ) + illuminant = colour.SDS_ILLUMINANTS["FL2"] + colour.convert( + sd, + "Spectral Distribution", + "sRGB", + sd_to_XYZ={"illuminant": illuminant}, + ) + +.. code-block:: text + array([ 0.47924575, 0.31676968, 0.17362725]) Chromatic Adaptation - ``colour.adaptation`` @@ -81,16 +88,21 @@ Chromatic Adaptation - ``colour.adaptation`` .. code-block:: python - >>> XYZ = [0.20654008, 0.12197225, 0.05136952] - >>> D65 = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"][ - ... "D65" - ... ] - >>> A = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["A"] - >>> colour.chromatic_adaptation( - ... XYZ, colour.xy_to_XYZ(D65), colour.xy_to_XYZ(A) - ... ) + XYZ = [0.20654008, 0.12197225, 0.05136952] + D65 = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["D65"] + A = colour.CCS_ILLUMINANTS["CIE 1931 2 Degree Standard Observer"]["A"] + colour.chromatic_adaptation(XYZ, colour.xy_to_XYZ(D65), colour.xy_to_XYZ(A)) + +.. code-block:: text + array([ 0.2533053 , 0.13765138, 0.01543307]) - >>> sorted(colour.CHROMATIC_ADAPTATION_METHODS) + +.. code-block:: python + + sorted(colour.CHROMATIC_ADAPTATION_METHODS) + +.. code-block:: text + ['CIE 1994', 'CMCCAT2000', 'Fairchild 1990', 'Von Kries', 'Zhai 2018'] Algebra - ``colour.algebra`` @@ -101,9 +113,12 @@ Kernel Interpolation .. code-block:: python - >>> y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] - >>> x = range(len(y)) - >>> colour.KernelInterpolator(x, y)([0.25, 0.75, 5.50]) + y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] + x = range(len(y)) + colour.KernelInterpolator(x, y)([0.25, 0.75, 5.50]) + +.. code-block:: text + array([ 6.18062083, 8.08238488, 57.85783403]) Sprague (1880) Interpolation @@ -111,9 +126,12 @@ Sprague (1880) Interpolation .. code-block:: python - >>> y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] - >>> x = range(len(y)) - >>> colour.SpragueInterpolator(x, y)([0.25, 0.75, 5.50]) + y = [5.9200, 9.3700, 10.8135, 4.5100, 69.5900, 27.8007, 86.0500] + x = range(len(y)) + colour.SpragueInterpolator(x, y)([0.25, 0.75, 5.50]) + +.. code-block:: text + array([ 6.72951612, 7.81406251, 43.77379185]) Colour Appearance Models - ``colour.appearance`` @@ -121,21 +139,54 @@ Colour Appearance Models - ``colour.appearance`` .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> XYZ_w = [95.05, 100.00, 108.88] - >>> L_A = 318.31 - >>> Y_b = 20.0 - >>> colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + XYZ_w = [95.05, 100.00, 108.88] + L_A = 318.31 + Y_b = 20.0 + colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_CIECAM02(J=34.434525727858997, C=67.365010921125943, h=22.279164147957065, s=62.81485585332716, Q=177.47124941102123, M=70.024939419291414, H=2.6896085344238898, HC=None) - >>> colour.XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: python + + colour.XYZ_to_CIECAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_CIECAM16(J=34.434525727858997, C=67.365010921125943, h=22.279164147957065, s=62.81485585332716, Q=177.47124941102123, M=70.024939419291414, H=2.6896085344238898, HC=None) - >>> colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: python + + colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_CAM16(J=33.880368498111686, C=69.444353357408033, h=19.510887327451748, s=64.03612114840314, Q=176.03752758512178, M=72.18638534116765, H=399.52975599115319, HC=None) - >>> colour.XYZ_to_Hellwig2022(XYZ, XYZ_w, L_A) + +.. code-block:: python + + colour.XYZ_to_Hellwig2022(XYZ, XYZ_w, L_A) + +.. code-block:: text + CAM_Specification_Hellwig2022(J=33.880368498111686, C=40.347043294550311, h=19.510887327451748, s=117.38555017188679, Q=45.34489577734751, M=53.228355383108031, H=399.52975599115319, HC=None) - >>> colour.XYZ_to_Kim2009(XYZ, XYZ_w, L_A) + +.. code-block:: python + + colour.XYZ_to_Kim2009(XYZ, XYZ_w, L_A) + +.. code-block:: text + CAM_Specification_Kim2009(J=19.879918542450902, C=55.839055250876946, h=22.013388165090046, s=112.97979354939129, Q=36.309026130161449, M=46.346415858227864, H=2.3543198369639931, HC=None) - >>> colour.XYZ_to_ZCAM(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: python + + colour.XYZ_to_ZCAM(XYZ, XYZ_w, L_A, Y_b) + +.. code-block:: text + CAM_Specification_ZCAM(J=38.347186278956357, C=21.12138989208518, h=33.711578931095197, s=81.444585609489536, Q=76.986725284523772, M=42.403805833900506, H=0.45779200212219573, HC=None, V=43.623590687423544, K=43.20894953152817, W=34.829588380192149) Colour Blindness - ``colour.blindness`` @@ -143,15 +194,23 @@ Colour Blindness - ``colour.blindness`` .. code-block:: python - >>> import numpy as np - >>> cmfs = colour.LMS_CMFS["Stockman & Sharpe 2 Degree Cone Fundamentals"] - >>> colour.msds_cmfs_anomalous_trichromacy_Machado2009( - ... cmfs, np.array([15, 0, 0]) - ... )[450] + import numpy as np + + cmfs = colour.LMS_CMFS["Stockman & Sharpe 2 Degree Cone Fundamentals"] + colour.msds_cmfs_anomalous_trichromacy_Machado2009(cmfs, np.array([15, 0, 0]))[450] + +.. code-block:: text + array([ 0.08912884, 0.0870524 , 0.955393 ]) - >>> primaries = colour.MSDS_DISPLAY_PRIMARIES["Apple Studio Display"] - >>> d_LMS = (15, 0, 0) - >>> colour.matrix_anomalous_trichromacy_Machado2009(cmfs, primaries, d_LMS) + +.. code-block:: python + + primaries = colour.MSDS_DISPLAY_PRIMARIES["Apple Studio Display"] + d_LMS = (15, 0, 0) + colour.matrix_anomalous_trichromacy_Machado2009(cmfs, primaries, d_LMS) + +.. code-block:: text + array([[-0.27774652, 2.65150084, -1.37375432], [ 0.27189369, 0.20047862, 0.52762768], [ 0.00644047, 0.25921579, 0.73434374]]) @@ -161,13 +220,23 @@ Colour Correction - ``colour characterisation`` .. code-block:: python - >>> import numpy as np - >>> RGB = [0.17224810, 0.09170660, 0.06416938] - >>> M_T = np.random.random((24, 3)) - >>> M_R = M_T + (np.random.random((24, 3)) - 0.5) * 0.5 - >>> colour.colour_correction(RGB, M_T, M_R) + import numpy as np + + RGB = [0.17224810, 0.09170660, 0.06416938] + M_T = np.random.random((24, 3)) + M_R = M_T + (np.random.random((24, 3)) - 0.5) * 0.5 + colour.colour_correction(RGB, M_T, M_R) + +.. code-block:: text + array([ 0.1806237 , 0.07234791, 0.07848845]) - >>> sorted(colour.COLOUR_CORRECTION_METHODS) + +.. code-block:: python + + sorted(colour.COLOUR_CORRECTION_METHODS) + +.. code-block:: text + ['Cheung 2004', 'Finlayson 2015', 'Vandermonde'] ACES Input Transform - ``colour characterisation`` @@ -175,9 +244,12 @@ ACES Input Transform - ``colour characterisation`` .. code-block:: python - >>> sensitivities = colour.MSDS_CAMERA_SENSITIVITIES["Nikon 5100 (NPL)"] - >>> illuminant = colour.SDS_ILLUMINANTS["D55"] - >>> colour.matrix_idt(sensitivities, illuminant) + sensitivities = colour.MSDS_CAMERA_SENSITIVITIES["Nikon 5100 (NPL)"] + illuminant = colour.SDS_ILLUMINANTS["D55"] + colour.matrix_idt(sensitivities, illuminant) + +.. code-block:: text + (array([[ 0.59368175, 0.30418371, 0.10213454], [ 0.00457979, 1.14946003, -0.15403982], [ 0.03552213, -0.16312291, 1.12760077]]), array([ 1.58214188, 1. , 1.28910346])) @@ -190,9 +262,18 @@ Spectral Computations .. code-block:: python - >>> colour.sd_to_XYZ(colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"]) + colour.sd_to_XYZ(colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"]) + +.. code-block:: text + array([ 36.94726204, 32.62076174, 13.0143849 ]) - >>> sorted(colour.SPECTRAL_TO_XYZ_METHODS) + +.. code-block:: python + + sorted(colour.SPECTRAL_TO_XYZ_METHODS) + +.. code-block:: text + ['ASTM E308', 'Integration', 'astm2015'] @@ -201,119 +282,122 @@ Multi-Spectral Computations .. code-block:: python - >>> msds = np.array( - ... [ - ... [ - ... [ - ... 0.01367208, - ... 0.09127947, - ... 0.01524376, - ... 0.02810712, - ... 0.19176012, - ... 0.04299992, - ... ], - ... [ - ... 0.00959792, - ... 0.25822842, - ... 0.41388571, - ... 0.22275120, - ... 0.00407416, - ... 0.37439537, - ... ], - ... [ - ... 0.01791409, - ... 0.29707789, - ... 0.56295109, - ... 0.23752193, - ... 0.00236515, - ... 0.58190280, - ... ], - ... ], - ... [ - ... [ - ... 0.01492332, - ... 0.10421912, - ... 0.02240025, - ... 0.03735409, - ... 0.57663846, - ... 0.32416266, - ... ], - ... [ - ... 0.04180972, - ... 0.26402685, - ... 0.03572137, - ... 0.00413520, - ... 0.41808194, - ... 0.24696727, - ... ], - ... [ - ... 0.00628672, - ... 0.11454948, - ... 0.02198825, - ... 0.39906919, - ... 0.63640803, - ... 0.01139849, - ... ], - ... ], - ... [ - ... [ - ... 0.04325933, - ... 0.26825359, - ... 0.23732357, - ... 0.05175860, - ... 0.01181048, - ... 0.08233768, - ... ], - ... [ - ... 0.02484169, - ... 0.12027161, - ... 0.00541695, - ... 0.00654612, - ... 0.18603799, - ... 0.36247808, - ... ], - ... [ - ... 0.03102159, - ... 0.16815442, - ... 0.37186235, - ... 0.08610666, - ... 0.00413520, - ... 0.78492409, - ... ], - ... ], - ... [ - ... [ - ... 0.11682307, - ... 0.78883040, - ... 0.74468607, - ... 0.83375293, - ... 0.90571451, - ... 0.70054168, - ... ], - ... [ - ... 0.06321812, - ... 0.41898224, - ... 0.15190357, - ... 0.24591440, - ... 0.55301750, - ... 0.00657664, - ... ], - ... [ - ... 0.00305180, - ... 0.11288624, - ... 0.11357290, - ... 0.12924391, - ... 0.00195315, - ... 0.21771573, - ... ], - ... ], - ... ] - ... ) - >>> colour.msds_to_XYZ( - ... msds, - ... method="Integration", - ... shape=colour.SpectralShape(400, 700, 60), - ... ) + msds = np.array( + [ + [ + [ + 0.01367208, + 0.09127947, + 0.01524376, + 0.02810712, + 0.19176012, + 0.04299992, + ], + [ + 0.00959792, + 0.25822842, + 0.41388571, + 0.22275120, + 0.00407416, + 0.37439537, + ], + [ + 0.01791409, + 0.29707789, + 0.56295109, + 0.23752193, + 0.00236515, + 0.58190280, + ], + ], + [ + [ + 0.01492332, + 0.10421912, + 0.02240025, + 0.03735409, + 0.57663846, + 0.32416266, + ], + [ + 0.04180972, + 0.26402685, + 0.03572137, + 0.00413520, + 0.41808194, + 0.24696727, + ], + [ + 0.00628672, + 0.11454948, + 0.02198825, + 0.39906919, + 0.63640803, + 0.01139849, + ], + ], + [ + [ + 0.04325933, + 0.26825359, + 0.23732357, + 0.05175860, + 0.01181048, + 0.08233768, + ], + [ + 0.02484169, + 0.12027161, + 0.00541695, + 0.00654612, + 0.18603799, + 0.36247808, + ], + [ + 0.03102159, + 0.16815442, + 0.37186235, + 0.08610666, + 0.00413520, + 0.78492409, + ], + ], + [ + [ + 0.11682307, + 0.78883040, + 0.74468607, + 0.83375293, + 0.90571451, + 0.70054168, + ], + [ + 0.06321812, + 0.41898224, + 0.15190357, + 0.24591440, + 0.55301750, + 0.00657664, + ], + [ + 0.00305180, + 0.11288624, + 0.11357290, + 0.12924391, + 0.00195315, + 0.21771573, + ], + ], + ] + ) + colour.msds_to_XYZ( + msds, + method="Integration", + shape=colour.SpectralShape(400, 700, 60), + ) + +.. code-block:: text + array([[[ 7.68544647, 4.09414317, 8.49324254], [ 17.12567298, 27.77681821, 25.52573685], [ 19.10280411, 34.45851476, 29.76319628]], @@ -326,7 +410,13 @@ Multi-Spectral Computations [[ 80.00969553, 80.39810464, 76.08184429], [ 33.27611427, 24.38947838, 39.34919287], [ 8.89425686, 11.05185138, 10.86767594]]]) - >>> sorted(colour.MSDS_TO_XYZ_METHODS) + +.. code-block:: python + + sorted(colour.MSDS_TO_XYZ_METHODS) + +.. code-block:: text + ['ASTM E308', 'Integration', 'astm2015'] Blackbody Spectral Radiance Computation @@ -334,7 +424,10 @@ Blackbody Spectral Radiance Computation .. code-block:: python - >>> colour.sd_blackbody(5000) + colour.sd_blackbody(5000) + +.. code-block:: text + SpectralDistribution([[ 3.60000000e+02, 6.65427827e+12], [ 3.61000000e+02, 6.70960528e+12], [ 3.62000000e+02, 6.76482512e+12], @@ -352,9 +445,12 @@ Dominant, Complementary Wavelength & Colour Purity Computation .. code-block:: python - >>> xy = [0.54369557, 0.32107944] - >>> xy_n = [0.31270000, 0.32900000] - >>> colour.dominant_wavelength(xy, xy_n) + xy = [0.54369557, 0.32107944] + xy_n = [0.31270000, 0.32900000] + colour.dominant_wavelength(xy, xy_n) + +.. code-block:: text + (array(616.0), array([ 0.68354746, 0.31628409]), array([ 0.68354746, 0.31628409])) @@ -364,9 +460,18 @@ Lightness Computation .. code-block:: python - >>> colour.lightness(12.19722535) + colour.lightness(12.19722535) + +.. code-block:: text + 41.527875844653451 - >>> sorted(colour.LIGHTNESS_METHODS) + +.. code-block:: python + + sorted(colour.LIGHTNESS_METHODS) + +.. code-block:: text + ['Abebe 2017', 'CIE 1976', 'Fairchild 2010', @@ -380,9 +485,18 @@ Luminance Computation .. code-block:: python - >>> colour.luminance(41.52787585) + colour.luminance(41.52787585) + +.. code-block:: text + 12.197225353400775 - >>> sorted(colour.LUMINANCE_METHODS) + +.. code-block:: python + + sorted(colour.LUMINANCE_METHODS) + +.. code-block:: text + ['ASTM D1535', 'CIE 1976', 'Fairchild 2010', @@ -396,11 +510,20 @@ Whiteness Computation .. code-block:: python - >>> XYZ = [95.00000000, 100.00000000, 105.00000000] - >>> XYZ_0 = [94.80966767, 100.00000000, 107.30513595] - >>> colour.whiteness(XYZ, XYZ_0) + XYZ = [95.00000000, 100.00000000, 105.00000000] + XYZ_0 = [94.80966767, 100.00000000, 107.30513595] + colour.whiteness(XYZ, XYZ_0) + +.. code-block:: text + array([ 93.756 , -1.33000001]) - >>> sorted(colour.WHITENESS_METHODS) + +.. code-block:: python + + sorted(colour.WHITENESS_METHODS) + +.. code-block:: text + ['ASTM E313', 'Berger 1959', 'CIE 2004', @@ -414,10 +537,19 @@ Yellowness Computation .. code-block:: python - >>> XYZ = [95.00000000, 100.00000000, 105.00000000] - >>> colour.yellowness(XYZ) + XYZ = [95.00000000, 100.00000000, 105.00000000] + colour.yellowness(XYZ) + +.. code-block:: text + 4.3400000000000034 - >>> sorted(colour.YELLOWNESS_METHODS) + +.. code-block:: python + + sorted(colour.YELLOWNESS_METHODS) + +.. code-block:: text + ['ASTM D1925', 'ASTM E313', 'ASTM E313 Alternative'] Luminous Flux, Efficiency & Efficacy Computation @@ -425,14 +557,29 @@ Luminous Flux, Efficiency & Efficacy Computation .. code-block:: python - >>> sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] - >>> colour.luminous_flux(sd) + sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] + colour.luminous_flux(sd) + +.. code-block:: text + 23807.655527367202 - >>> sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] - >>> colour.luminous_efficiency(sd) + +.. code-block:: python + + sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] + colour.luminous_efficiency(sd) + +.. code-block:: text + 0.19943935624521045 - >>> sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] - >>> colour.luminous_efficacy(sd) + +.. code-block:: python + + sd = colour.SDS_LIGHT_SOURCES["Neodimium Incandescent"] + colour.luminous_efficacy(sd) + +.. code-block:: text + 136.21708031547874 Contrast Sensitivity Function - ``colour.contrast`` @@ -440,22 +587,39 @@ Contrast Sensitivity Function - ``colour.contrast`` .. code-block:: python - >>> colour.contrast_sensitivity_function(u=4, X_0=60, E=65) + colour.contrast_sensitivity_function(u=4, X_0=60, E=65) + +.. code-block:: text + 358.51180789884984 - >>> sorted(colour.CONTRAST_SENSITIVITY_METHODS) - ['Barten 1999'] +.. code-block:: python + + sorted(colour.CONTRAST_SENSITIVITY_METHODS) + +.. code-block:: text + + ['Barten 1999'] Colour Difference - ``colour.difference`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. code-block:: python - >>> Lab_1 = [100.00000000, 21.57210357, 272.22819350] - >>> Lab_2 = [100.00000000, 426.67945353, 72.39590835] - >>> colour.delta_E(Lab_1, Lab_2) + Lab_1 = [100.00000000, 21.57210357, 272.22819350] + Lab_2 = [100.00000000, 426.67945353, 72.39590835] + colour.delta_E(Lab_1, Lab_2) + +.. code-block:: text + 94.035649026659485 - >>> sorted(colour.DELTA_E_METHODS) + +.. code-block:: python + + sorted(colour.DELTA_E_METHODS) + +.. code-block:: text + ['CAM02-LCD', 'CAM02-SCD', 'CAM02-UCS', @@ -480,8 +644,11 @@ Images .. code-block:: python - >>> RGB = colour.read_image("Ishihara_Colour_Blindness_Test_Plate_3.png") - >>> RGB.shape + RGB = colour.read_image("Ishihara_Colour_Blindness_Test_Plate_3.png") + RGB.shape + +.. code-block:: text + (276, 281, 3) Look Up Table (LUT) Data @@ -489,10 +656,10 @@ Look Up Table (LUT) Data .. code-block:: python - >>> LUT = colour.read_LUT("ACES_Proxy_10_to_ACES.cube") - >>> print(LUT) + LUT = colour.read_LUT("ACES_Proxy_10_to_ACES.cube") + print(LUT) -:: +.. code-block:: text LUT3x1D - ACES Proxy 10 to ACES ------------------------------- @@ -503,8 +670,11 @@ Look Up Table (LUT) Data .. code-block:: python - >>> RGB = [0.17224810, 0.09170660, 0.06416938] - >>> LUT.apply(RGB) + RGB = [0.17224810, 0.09170660, 0.06416938] + LUT.apply(RGB) + +.. code-block:: text + array([ 0.00575674, 0.00181493, 0.00121419]) Colour Models - ``colour.models`` @@ -515,7 +685,10 @@ CIE xyY Colourspace .. code-block:: python - >>> colour.XYZ_to_xyY([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_xyY([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.54369557, 0.32107944, 0.12197225]) CIE L*a*b* Colourspace @@ -523,7 +696,10 @@ CIE L*a*b* Colourspace .. code-block:: python - >>> colour.XYZ_to_Lab([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Lab([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 41.52787529, 52.63858304, 26.92317922]) CIE L*u*v* Colourspace @@ -531,7 +707,10 @@ CIE L*u*v* Colourspace .. code-block:: python - >>> colour.XYZ_to_Luv([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Luv([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 41.52787529, 96.83626054, 17.75210149]) CIE 1960 UCS Colourspace @@ -539,7 +718,10 @@ CIE 1960 UCS Colourspace .. code-block:: python - >>> colour.XYZ_to_UCS([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_UCS([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.13769339, 0.12197225, 0.1053731 ]) CIE 1964 U*V*W* Colourspace @@ -547,8 +729,11 @@ CIE 1964 U*V*W* Colourspace .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_UVW(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_UVW(XYZ) + +.. code-block:: text + array([ 94.55035725, 11.55536523, 40.54757405]) CAM02-LCD, CAM02-SCD, and CAM02-UCS Colourspaces - Luo, Cui and Li (2006) @@ -556,18 +741,27 @@ CAM02-LCD, CAM02-SCD, and CAM02-UCS Colourspaces - Luo, Cui and Li (2006) .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> XYZ_w = [95.05, 100.00, 108.88] - >>> L_A = 318.31 - >>> Y_b = 20.0 - >>> surround = colour.VIEWING_CONDITIONS_CIECAM02["Average"] - >>> specification = colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround) - >>> JMh = (specification.J, specification.M, specification.h) - >>> colour.JMh_CIECAM02_to_CAM02UCS(JMh) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + XYZ_w = [95.05, 100.00, 108.88] + L_A = 318.31 + Y_b = 20.0 + surround = colour.VIEWING_CONDITIONS_CIECAM02["Average"] + specification = colour.XYZ_to_CIECAM02(XYZ, XYZ_w, L_A, Y_b, surround) + JMh = (specification.J, specification.M, specification.h) + colour.JMh_CIECAM02_to_CAM02UCS(JMh) + +.. code-block:: text + array([ 47.16899898, 38.72623785, 15.8663383 ]) - >>> XYZ = [0.20654008, 0.12197225, 0.05136952] - >>> XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] - >>> colour.XYZ_to_CAM02UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + +.. code-block:: python + + XYZ = [0.20654008, 0.12197225, 0.05136952] + XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] + colour.XYZ_to_CAM02UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + +.. code-block:: text + array([ 47.16899898, 38.72623785, 15.8663383 ]) CAM16-LCD, CAM16-SCD, and CAM16-UCS Colourspaces - Li et al. (2017) @@ -575,18 +769,27 @@ CAM16-LCD, CAM16-SCD, and CAM16-UCS Colourspaces - Li et al. (2017) .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> XYZ_w = [95.05, 100.00, 108.88] - >>> L_A = 318.31 - >>> Y_b = 20.0 - >>> surround = colour.VIEWING_CONDITIONS_CAM16["Average"] - >>> specification = colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround) - >>> JMh = (specification.J, specification.M, specification.h) - >>> colour.JMh_CAM16_to_CAM16UCS(JMh) - array([ 46.55542238, 40.22460974, 14.25288392] - >>> XYZ = [0.20654008, 0.12197225, 0.05136952] - >>> XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] - >>> colour.XYZ_to_CAM16UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + XYZ_w = [95.05, 100.00, 108.88] + L_A = 318.31 + Y_b = 20.0 + surround = colour.VIEWING_CONDITIONS_CAM16["Average"] + specification = colour.XYZ_to_CAM16(XYZ, XYZ_w, L_A, Y_b, surround) + JMh = (specification.J, specification.M, specification.h) + colour.JMh_CAM16_to_CAM16UCS(JMh) + +.. code-block:: text + + array([ 46.55542238, 40.22460974, 14.25288392]) + +.. code-block:: python + + XYZ = [0.20654008, 0.12197225, 0.05136952] + XYZ_w = [95.05 / 100, 100.00 / 100, 108.88 / 100] + colour.XYZ_to_CAM16UCS(XYZ, XYZ_w=XYZ_w, L_A=L_A, Y_b=Y_b) + +.. code-block:: text + array([ 46.55542238, 40.22460974, 14.25288392]) DIN99 Colourspace and DIN99b, DIN99c, DIN99d Refined Formulas @@ -594,8 +797,11 @@ DIN99 Colourspace and DIN99b, DIN99c, DIN99d Refined Formulas .. code-block:: python - >>> Lab = [41.52787529, 52.63858304, 26.92317922] - >>> colour.Lab_to_DIN99(Lab) + Lab = [41.52787529, 52.63858304, 26.92317922] + colour.Lab_to_DIN99(Lab) + +.. code-block:: text + array([ 53.22821988, 28.41634656, 3.89839552]) ICaCb Colourspace @@ -603,7 +809,10 @@ ICaCb Colourspace .. code-block:: python - >>> XYZ_to_ICaCb(np.array([0.20654008, 0.12197225, 0.05136952])) + XYZ_to_ICaCb(np.array([0.20654008, 0.12197225, 0.05136952])) + +.. code-block:: text + array([ 0.06875297, 0.05753352, 0.02081548]) IgPgTg Colourspace @@ -611,7 +820,10 @@ IgPgTg Colourspace .. code-block:: python - >>> colour.XYZ_to_IgPgTg([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_IgPgTg([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.42421258, 0.18632491, 0.10689223]) IPT Colourspace @@ -619,7 +831,10 @@ IPT Colourspace .. code-block:: python - >>> colour.XYZ_to_IPT([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_IPT([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.38426191, 0.38487306, 0.18886838]) Jzazbz Colourspace @@ -627,7 +842,10 @@ Jzazbz Colourspace .. code-block:: python - >>> colour.XYZ_to_Jzazbz([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Jzazbz([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.00535048, 0.00924302, 0.00526007]) hdr-CIELAB Colourspace @@ -635,7 +853,10 @@ hdr-CIELAB Colourspace .. code-block:: python - >>> colour.XYZ_to_hdr_CIELab([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_hdr_CIELab([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 51.87002062, 60.4763385 , 32.14551912]) hdr-IPT Colourspace @@ -643,7 +864,10 @@ hdr-IPT Colourspace .. code-block:: python - >>> colour.XYZ_to_hdr_IPT([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_hdr_IPT([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 25.18261761, -22.62111297, 3.18511729]) Hunter L,a,b Colour Scale @@ -651,8 +875,11 @@ Hunter L,a,b Colour Scale .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_Hunter_Lab(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_Hunter_Lab(XYZ) + +.. code-block:: text + array([ 34.92452577, 47.06189858, 14.38615107]) Hunter Rd,a,b Colour Scale @@ -660,8 +887,11 @@ Hunter Rd,a,b Colour Scale .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_Hunter_Rdab(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_Hunter_Rdab(XYZ) + +.. code-block:: text + array([ 12.197225 , 57.12537874, 17.46241341]) Oklab Colourspace @@ -669,7 +899,10 @@ Oklab Colourspace .. code-block:: python - >>> colour.XYZ_to_Oklab([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Oklab([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.51634019, 0.154695 , 0.06289579]) OSA UCS Colourspace @@ -677,8 +910,11 @@ OSA UCS Colourspace .. code-block:: python - >>> XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] - >>> colour.XYZ_to_OSA_UCS(XYZ) + XYZ = [0.20654008 * 100, 0.12197225 * 100, 0.05136952 * 100] + colour.XYZ_to_OSA_UCS(XYZ) + +.. code-block:: text + array([-3.0049979 , 2.99713697, -9.66784231]) ProLab Colourspace @@ -686,7 +922,10 @@ ProLab Colourspace .. code-block:: python - >>> colour.XYZ_to_ProLab([0.51634019, 0.15469500, 0.06289579]) + colour.XYZ_to_ProLab([0.51634019, 0.15469500, 0.06289579]) + +.. code-block:: text + array([1.24610688, 2.39525236, 0.41902126]) Ragoo and Farup (2021) Optimised IPT Colourspace @@ -694,7 +933,10 @@ Ragoo and Farup (2021) Optimised IPT Colourspace .. code-block:: python - >>> colour.XYZ_to_IPT_Ragoo2021([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_IPT_Ragoo2021([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.42248243, 0.2910514 , 0.20410663]) Yrg Colourspace - Kirk (2019) @@ -702,7 +944,10 @@ Yrg Colourspace - Kirk (2019) .. code-block:: python - >>> colour.XYZ_to_Yrg([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_Yrg([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + array([ 0.13137801, 0.49037645, 0.37777388]) Y'CbCr Colour Encoding @@ -710,7 +955,10 @@ Y'CbCr Colour Encoding .. code-block:: python - >>> colour.RGB_to_YCbCr([1.0, 1.0, 1.0]) + colour.RGB_to_YCbCr([1.0, 1.0, 1.0]) + +.. code-block:: text + array([ 0.92156863, 0.50196078, 0.50196078]) YCoCg Colour Encoding @@ -718,7 +966,10 @@ YCoCg Colour Encoding .. code-block:: python - >>> colour.RGB_to_YCoCg([0.75, 0.75, 0.0]) + colour.RGB_to_YCoCg([0.75, 0.75, 0.0]) + +.. code-block:: text + array([ 0.5625, 0.375 , 0.1875]) ICtCp Colour Encoding @@ -726,7 +977,10 @@ ICtCp Colour Encoding .. code-block:: python - >>> colour.RGB_to_ICtCp([0.45620519, 0.03081071, 0.04091952]) + colour.RGB_to_ICtCp([0.45620519, 0.03081071, 0.04091952]) + +.. code-block:: text + array([ 0.07351364, 0.00475253, 0.09351596]) HSV Colourspace @@ -734,7 +988,10 @@ HSV Colourspace .. code-block:: python - >>> colour.RGB_to_HSV([0.45620519, 0.03081071, 0.04091952]) + colour.RGB_to_HSV([0.45620519, 0.03081071, 0.04091952]) + +.. code-block:: text + array([ 0.99603944, 0.93246304, 0.45620519]) IHLS Colourspace @@ -742,7 +999,10 @@ IHLS Colourspace .. code-block:: python - >>> colour.RGB_to_IHLS([0.45620519, 0.03081071, 0.04091952]) + colour.RGB_to_IHLS([0.45620519, 0.03081071, 0.04091952]) + +.. code-block:: text + array([ 6.26236117, 0.12197943, 0.42539448]) Prismatic Colourspace @@ -750,7 +1010,10 @@ Prismatic Colourspace .. code-block:: python - >>> colour.RGB_to_Prismatic([0.25, 0.50, 0.75]) + colour.RGB_to_Prismatic([0.25, 0.50, 0.75]) + +.. code-block:: text + array([ 0.75 , 0.16666667, 0.33333333, 0.5 ]) RGB Colourspace and Transformations @@ -758,22 +1021,25 @@ RGB Colourspace and Transformations .. code-block:: python - >>> XYZ = [0.21638819, 0.12570000, 0.03847493] - >>> illuminant_XYZ = [0.34570, 0.35850] - >>> illuminant_RGB = [0.31270, 0.32900] - >>> chromatic_adaptation_transform = "Bradford" - >>> matrix_XYZ_to_RGB = [ - ... [3.24062548, -1.53720797, -0.49862860], - ... [-0.96893071, 1.87575606, 0.04151752], - ... [0.05571012, -0.20402105, 1.05699594], - ... ] - >>> colour.XYZ_to_RGB( - ... XYZ, - ... illuminant_XYZ, - ... illuminant_RGB, - ... matrix_XYZ_to_RGB, - ... chromatic_adaptation_transform, - ... ) + XYZ = [0.21638819, 0.12570000, 0.03847493] + illuminant_XYZ = [0.34570, 0.35850] + illuminant_RGB = [0.31270, 0.32900] + chromatic_adaptation_transform = "Bradford" + matrix_XYZ_to_RGB = [ + [3.24062548, -1.53720797, -0.49862860], + [-0.96893071, 1.87575606, 0.04151752], + [0.05571012, -0.20402105, 1.05699594], + ] + colour.XYZ_to_RGB( + XYZ, + illuminant_XYZ, + illuminant_RGB, + matrix_XYZ_to_RGB, + chromatic_adaptation_transform, + ) + +.. code-block:: text + array([ 0.45595571, 0.03039702, 0.04087245]) RGB Colourspace Derivation @@ -781,9 +1047,12 @@ RGB Colourspace Derivation .. code-block:: python - >>> p = [0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700] - >>> w = [0.32168, 0.33767] - >>> colour.normalised_primary_matrix(p, w) + p = [0.73470, 0.26530, 0.00000, 1.00000, 0.00010, -0.07700] + w = [0.32168, 0.33767] + colour.normalised_primary_matrix(p, w) + +.. code-block:: text + array([[ 9.52552396e-01, 0.00000000e+00, 9.36786317e-05], [ 3.43966450e-01, 7.28166097e-01, -7.21325464e-02], [ 0.00000000e+00, 0.00000000e+00, 1.00882518e+00]]) @@ -793,7 +1062,10 @@ RGB Colourspaces .. code-block:: python - >>> sorted(colour.RGB_COLOURSPACES) + sorted(colour.RGB_COLOURSPACES) + +.. code-block:: text + ['ACES2065-1', 'ACEScc', 'ACEScct', @@ -869,7 +1141,10 @@ OETFs .. code-block:: python - >>> sorted(colour.OETFS) + sorted(colour.OETFS) + +.. code-block:: text + ['ARIB STD-B67', 'Blackmagic Film Generation 5', 'DaVinci Intermediate', @@ -889,7 +1164,10 @@ EOTFs .. code-block:: python - >>> sorted(colour.EOTFS) + sorted(colour.EOTFS) + +.. code-block:: text + ['DCDM', 'DICOM GSDF', 'ITU-R BT.1886', @@ -905,7 +1183,10 @@ OOTFs .. code-block:: python - >>> sorted(colour.OOTFS) + sorted(colour.OOTFS) + +.. code-block:: text + ['ITU-R BT.2100 HLG', 'ITU-R BT.2100 PQ'] @@ -914,7 +1195,10 @@ Log Encoding / Decoding .. code-block:: python - >>> sorted(colour.LOG_ENCODINGS) + sorted(colour.LOG_ENCODINGS) + +.. code-block:: text + ['ACEScc', 'ACEScct', 'ACESproxy', @@ -951,10 +1235,14 @@ CCTFs Encoding / Decoding .. code-block:: python - >>> sorted(colour.CCTF_ENCODINGS) + sorted(colour.CCTF_ENCODINGS) + +.. code-block:: text + ['ACEScc', 'ACEScct', 'ACESproxy', + 'Apple Log Profile', 'ARRI LogC3', 'ARRI LogC4', 'ARIB STD-B67', @@ -1004,10 +1292,18 @@ Recommendation ITU-T H.273 Code points for Video Signal Type Identification .. code-block:: python - >>> colour.COLOUR_PRIMARIES_ITUTH273.keys() + colour.COLOUR_PRIMARIES_ITUTH273.keys() + +.. code-block:: text + dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 22, 23]) - >>> colour.COLOUR_PRIMARIES_ITUTH273.keys() - >>> description = colour.models.describe_video_signal_colour_primaries(1) + +.. code-block:: python + + colour.models.describe_video_signal_colour_primaries(1) + +.. code-block:: text + =============================================================================== * * * Colour Primaries: 1 * @@ -1027,11 +1323,21 @@ Recommendation ITU-T H.273 Code points for Video Signal Type Identification * FFmpeg Constants : ['AVCOL_PRI_BT709', 'BT709'] * * * =============================================================================== - >>> colour.TRANSFER_CHARACTERISTICS_ITUTH273.keys() + +.. code-block:: python + + colour.TRANSFER_CHARACTERISTICS_ITUTH273.keys() + +.. code-block:: text + dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]) - >>> description = ( - ... colour.models.describe_video_signal_transfer_characteristics(1) - ... ) + +.. code-block:: python + + colour.models.describe_video_signal_transfer_characteristics(1) + +.. code-block:: text + =============================================================================== * * * Transfer Characteristics: 1 * @@ -1041,11 +1347,21 @@ Recommendation ITU-T H.273 Code points for Video Signal Type Identification * FFmpeg Constants : ['AVCOL_TRC_BT709', 'BT709'] * * * =============================================================================== - >>> colour.MATRIX_COEFFICIENTS_ITUTH273.keys() + +.. code-block:: python + + colour.MATRIX_COEFFICIENTS_ITUTH273.keys() + +.. code-block:: text + dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) - >>> description = colour.models.describe_video_signal_matrix_coefficients( - ... 1 - ... ) + +.. code-block:: python + + colour.models.describe_video_signal_matrix_coefficients(1) + +.. code-block:: text + =============================================================================== * * * Matrix Coefficients: 1 * @@ -1064,9 +1380,18 @@ Munsell Value .. code-block:: python - >>> colour.munsell_value(12.23634268) + colour.munsell_value(12.23634268) + +.. code-block:: text + 4.0824437076525664 - >>> sorted(colour.MUNSELL_VALUE_METHODS) + +.. code-block:: python + + sorted(colour.MUNSELL_VALUE_METHODS) + +.. code-block:: text + ['ASTM D1535', 'Ladd 1955', 'McCamy 1987', @@ -1081,9 +1406,18 @@ Munsell Colour .. code-block:: python - >>> colour.xyY_to_munsell_colour([0.38736945, 0.35751656, 0.59362000]) + colour.xyY_to_munsell_colour([0.38736945, 0.35751656, 0.59362000]) + +.. code-block:: text + '4.2YR 8.1/5.3' - >>> colour.munsell_colour_to_xyY("4.2YR 8.1/5.3") + +.. code-block:: python + + colour.munsell_colour_to_xyY("4.2YR 8.1/5.3") + +.. code-block:: text + array([ 0.38736945, 0.35751656, 0.59362 ]) Optical Phenomena - ``colour.phenomena`` @@ -1091,7 +1425,10 @@ Optical Phenomena - ``colour.phenomena`` .. code-block:: python - >>> colour.rayleigh_scattering_sd() + colour.rayleigh_scattering_sd() + +.. code-block:: text + SpectralDistribution([[ 3.60000000e+02, 5.99101337e-01], [ 3.61000000e+02, 5.92170690e-01], [ 3.62000000e+02, 5.85341006e-01], @@ -1112,9 +1449,18 @@ Colour Fidelity Index .. code-block:: python - >>> colour.colour_fidelity_index(colour.SDS_ILLUMINANTS["FL2"]) + colour.colour_fidelity_index(colour.SDS_ILLUMINANTS["FL2"]) + +.. code-block:: text + 70.120825477833037 - >>> sorted(colour.COLOUR_FIDELITY_INDEX_METHODS) + +.. code-block:: python + + sorted(colour.COLOUR_FIDELITY_INDEX_METHODS) + +.. code-block:: text + ['ANSI/IES TM-30-18', 'CIE 2017'] Colour Quality Scale @@ -1122,9 +1468,18 @@ Colour Quality Scale .. code-block:: python - >>> colour.colour_quality_scale(colour.SDS_ILLUMINANTS["FL2"]) + colour.colour_quality_scale(colour.SDS_ILLUMINANTS["FL2"]) + +.. code-block:: text + 64.111703163816699 - >>> sorted(colour.COLOUR_QUALITY_SCALE_METHODS) + +.. code-block:: python + + sorted(colour.COLOUR_QUALITY_SCALE_METHODS) + +.. code-block:: text + ['NIST CQS 7.4', 'NIST CQS 9.0'] Colour Rendering Index @@ -1132,7 +1487,10 @@ Colour Rendering Index .. code-block:: python - >>> colour.colour_rendering_index(colour.SDS_ILLUMINANTS["FL2"]) + colour.colour_rendering_index(colour.SDS_ILLUMINANTS["FL2"]) + +.. code-block:: text + 64.233724121664807 Academy Spectral Similarity Index (SSI) @@ -1140,9 +1498,12 @@ Academy Spectral Similarity Index (SSI) .. code-block:: python - >>> colour.spectral_similarity_index( - ... colour.SDS_ILLUMINANTS["C"], colour.SDS_ILLUMINANTS["D65"] - ... ) + colour.spectral_similarity_index( + colour.SDS_ILLUMINANTS["C"], colour.SDS_ILLUMINANTS["D65"] + ) + +.. code-block:: text + 94.0 Spectral Up-Sampling & Recovery - ``colour.recovery`` @@ -1153,7 +1514,10 @@ Reflectance Recovery .. code-block:: python - >>> colour.XYZ_to_sd([0.20654008, 0.12197225, 0.05136952]) + colour.XYZ_to_sd([0.20654008, 0.12197225, 0.05136952]) + +.. code-block:: text + SpectralDistribution([[ 3.60000000e+02, 8.40144095e-02], [ 3.65000000e+02, 8.41264236e-02], [ 3.70000000e+02, 8.40057597e-02], @@ -1166,40 +1530,44 @@ Reflectance Recovery Extrapolator, {'method': 'Constant', 'left': None, 'right': None}) - >>> sorted(colour.REFLECTANCE_RECOVERY_METHODS) +.. code-block:: python + + sorted(colour.REFLECTANCE_RECOVERY_METHODS) + +.. code-block:: text + ['Jakob 2019', 'Mallett 2019', 'Meng 2015', 'Otsu 2018', 'Smits 1999'] Camera RGB Sensitivities Recovery ********************************* - >>> illuminant = colour.colorimetry.SDS_ILLUMINANTS["D65"] - >>> sensitivities = colour.characterisation.MSDS_CAMERA_SENSITIVITIES[ - ... "Nikon 5100 (NPL)" - ... ] - >>> reflectances = [ - ... sd.copy().align( - ... colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017 - ... ) - ... for sd in colour.characterisation.SDS_COLOURCHECKERS[ - ... "BabelColor Average" - ... ].values() - ... ] - >>> reflectances = colour.colorimetry.sds_and_msds_to_msds(reflectances) - >>> RGB = colour.colorimetry.msds_to_XYZ( - ... reflectances, - ... method="Integration", - ... cmfs=sensitivities, - ... illuminant=illuminant, - ... k=0.01, - ... shape=colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, - ... ) - >>> colour.recovery.RGB_to_msds_camera_sensitivities_Jiang2013( - ... RGB, - ... illuminant, - ... reflectances, - ... colour.recovery.BASIS_FUNCTIONS_DYER2017, - ... colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, - ... ) +.. code-block:: python + + illuminant = colour.colorimetry.SDS_ILLUMINANTS["D65"] + sensitivities = colour.characterisation.MSDS_CAMERA_SENSITIVITIES["Nikon 5100 (NPL)"] + reflectances = [ + sd.copy().align(colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017) + for sd in colour.characterisation.SDS_COLOURCHECKERS["BabelColor Average"].values() + ] + reflectances = colour.colorimetry.sds_and_msds_to_msds(reflectances) + RGB = colour.colorimetry.msds_to_XYZ( + reflectances, + method="Integration", + cmfs=sensitivities, + illuminant=illuminant, + k=0.01, + shape=colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, + ) + colour.recovery.RGB_to_msds_camera_sensitivities_Jiang2013( + RGB, + illuminant, + reflectances, + colour.recovery.BASIS_FUNCTIONS_DYER2017, + colour.recovery.SPECTRAL_SHAPE_BASIS_FUNCTIONS_DYER2017, + ) + +.. code-block:: text + RGB_CameraSensitivities([[ 4.00000000e+02, 7.22815777e-03, 9.22506480e-03, -9.88368972e-03], [ 4.10000000e+02, -8.50457609e-03, 1.12777480e-02, @@ -1224,11 +1592,26 @@ Correlated Colour Temperature Computation Methods - ``colour.temperature`` .. code-block:: python - >>> colour.uv_to_CCT([0.1978, 0.3122]) + colour.uv_to_CCT([0.1978, 0.3122]) + +.. code-block:: text + array([ 6.50751282e+03, 3.22335875e-03]) - >>> sorted(colour.UV_TO_CCT_METHODS) + +.. code-block:: python + + sorted(colour.UV_TO_CCT_METHODS) + +.. code-block:: text + ['Krystek 1985', 'Ohno 2013', 'Planck 1900', 'Robertson 1968', 'ohno2013', 'robertson1968'] - >>> sorted(colour.XY_TO_CCT_METHODS) + +.. code-block:: python + + sorted(colour.XY_TO_CCT_METHODS) + +.. code-block:: text + ['CIE Illuminant D Series', 'Hernandez 1999', 'Kang 2002', @@ -1243,9 +1626,10 @@ Colour Volume - ``colour.volume`` .. code-block:: python - >>> colour.RGB_colourspace_volume_MonteCarlo( - ... colour.RGB_COLOURSPACE_RGB["sRGB"] - ... ) + colour.RGB_colourspace_volume_MonteCarlo(colour.RGB_COLOURSPACE_RGB["sRGB"]) + +.. code-block:: text + 821958.30000000005 Geometry Primitives Generation - ``colour.geometry`` @@ -1253,8 +1637,11 @@ Geometry Primitives Generation - ``colour.geometry`` .. code-block:: python - >>> colour.primitive("Grid") - (array([ ([-0.5, 0.5, 0. ], [ 0., 1.], [ 0., 0., 1.], [ 0., 1., 0., 1.]), + colour.primitive("Grid") + +.. code-block:: text + + (array([ ([-0.5, 0.5, 0. ], [ 0., 1.], [ 0., 0., 1.], [ 0., 1., 0., 1.]), ([ 0.5, 0.5, 0. ], [ 1., 1.], [ 0., 0., 1.], [ 1., 1., 0., 1.]), ([-0.5, -0.5, 0. ], [ 0., 0.], [ 0., 0., 1.], [ 0., 0., 0., 1.]), ([ 0.5, -0.5, 0. ], [ 1., 0.], [ 0., 0., 1.], [ 1., 0., 0., 1.])], @@ -1263,14 +1650,26 @@ Geometry Primitives Generation - ``colour.geometry`` [2, 3], [3, 1], [1, 0]], dtype=uint32)) - >>> sorted(colour.PRIMITIVE_METHODS) + +.. code-block:: python + + sorted(colour.PRIMITIVE_METHODS) + +.. code-block:: text + ['Cube', 'Grid'] - >>> colour.primitive_vertices("Quad MPL") + +.. code-block:: python + + colour.primitive_vertices("Quad MPL") + +.. code-block:: text + array([[ 0., 0., 0.], [ 1., 0., 0.], [ 1., 1., 0.], [ 0., 1., 0.]]) - >>> sorted(colour.PRIMITIVE_VERTICES_METHODS) + sorted(colour.PRIMITIVE_VERTICES_METHODS) ['Cube MPL', 'Grid MPL', 'Quad MPL', 'Sphere'] Plotting - ``colour.plotting`` @@ -1280,15 +1679,16 @@ Most of the objects are available from the ``colour.plotting`` namespace: .. code-block:: python - >>> from colour.plotting import * - >>> colour_style() + from colour.plotting import * + + colour_style() Visible Spectrum **************** .. code-block:: python - >>> plot_visible_spectrum("CIE 1931 2 Degree Standard Observer") + plot_visible_spectrum("CIE 1931 2 Degree Standard Observer") .. image:: _static/Examples_Plotting_Visible_Spectrum.png @@ -1297,7 +1697,7 @@ Spectral Distribution .. code-block:: python - >>> plot_single_illuminant_sd("FL1") + plot_single_illuminant_sd("FL1") .. image:: _static/Examples_Plotting_Illuminant_F1_SD.png @@ -1306,17 +1706,17 @@ Blackbody .. code-block:: python - >>> blackbody_sds = [ - ... colour.sd_blackbody(i, colour.SpectralShape(0, 10000, 10)) - ... for i in range(1000, 15000, 1000) - ... ] - >>> plot_multi_sds( - ... blackbody_sds, - ... y_label="W / (sr m$^2$) / m", - ... plot_kwargs={"use_sd_colours": True, "normalise_sd_colours": True}, - ... legend_location="upper right", - ... bounding_box=(0, 1250, 0, 2.5e6), - ... ) + blackbody_sds = [ + colour.sd_blackbody(i, colour.SpectralShape(0, 10000, 10)) + for i in range(1000, 15000, 1000) + ] + plot_multi_sds( + blackbody_sds, + y_label="W / (sr m$^2$) / m", + plot_kwargs={"use_sd_colours": True, "normalise_sd_colours": True}, + legend_location="upper right", + bounding_box=(0, 1250, 0, 2.5e6), + ) .. image:: _static/Examples_Plotting_Blackbodies.png Colour Matching Functions @@ -1324,11 +1724,11 @@ Colour Matching Functions .. code-block:: python - >>> plot_single_cmfs( - ... "Stockman & Sharpe 2 Degree Cone Fundamentals", - ... y_label="Sensitivity", - ... bounding_box=(390, 870, 0, 1.1), - ... ) + plot_single_cmfs( + "Stockman & Sharpe 2 Degree Cone Fundamentals", + y_label="Sensitivity", + bounding_box=(390, 870, 0, 1.1), + ) .. image:: _static/Examples_Plotting_Cone_Fundamentals.png @@ -1337,20 +1737,20 @@ Luminous Efficiency .. code-block:: python - >>> sd_mesopic_luminous_efficiency_function = ( - ... colour.sd_mesopic_luminous_efficiency_function(0.2) - ... ) - >>> plot_multi_sds( - ... ( - ... sd_mesopic_luminous_efficiency_function, - ... colour.PHOTOPIC_LEFS["CIE 1924 Photopic Standard Observer"], - ... colour.SCOTOPIC_LEFS["CIE 1951 Scotopic Standard Observer"], - ... ), - ... y_label="Luminous Efficiency", - ... legend_location="upper right", - ... y_tighten=True, - ... margins=(0, 0, 0, 0.1), - ... ) + sd_mesopic_luminous_efficiency_function = ( + colour.sd_mesopic_luminous_efficiency_function(0.2) + ) + plot_multi_sds( + ( + sd_mesopic_luminous_efficiency_function, + colour.PHOTOPIC_LEFS["CIE 1924 Photopic Standard Observer"], + colour.SCOTOPIC_LEFS["CIE 1951 Scotopic Standard Observer"], + ), + y_label="Luminous Efficiency", + legend_location="upper right", + y_tighten=True, + margins=(0, 0, 0, 0.1), + ) .. image:: _static/Examples_Plotting_Luminous_Efficiency.png @@ -1359,29 +1759,26 @@ Colour Checker .. code-block:: python - >>> from colour.characterisation.dataset.colour_checkers.sds import ( - ... COLOURCHECKER_INDEXES_TO_NAMES_MAPPING, - ... ) - >>> plot_multi_sds( - ... [ - ... colour.SDS_COLOURCHECKERS["BabelColor Average"][value] - ... for key, value in sorted( - ... COLOURCHECKER_INDEXES_TO_NAMES_MAPPING.items() - ... ) - ... ], - ... plot_kwargs={ - ... "use_sd_colours": True, - ... }, - ... title=("BabelColor Average - " "Spectral Distributions"), - ... ) + from colour.characterisation.dataset.colour_checkers.sds import ( + COLOURCHECKER_INDEXES_TO_NAMES_MAPPING, + ) + + plot_multi_sds( + [ + colour.SDS_COLOURCHECKERS["BabelColor Average"][value] + for key, value in sorted(COLOURCHECKER_INDEXES_TO_NAMES_MAPPING.items()) + ], + plot_kwargs={ + "use_sd_colours": True, + }, + title=("BabelColor Average - " "Spectral Distributions"), + ) .. image:: _static/Examples_Plotting_BabelColor_Average.png .. code-block:: python - >>> plot_single_colour_checker( - ... "ColorChecker 2005", text_kwargs={"visible": False} - ... ) + plot_single_colour_checker("ColorChecker 2005", text_kwargs={"visible": False}) .. image:: _static/Examples_Plotting_ColorChecker_2005.png @@ -1390,9 +1787,7 @@ Chromaticities Prediction .. code-block:: python - >>> plot_corresponding_chromaticities_prediction( - ... 2, "Von Kries", "Bianco 2010" - ... ) + plot_corresponding_chromaticities_prediction(2, "Von Kries", "Bianco 2010") .. image:: _static/Examples_Plotting_Chromaticities_Prediction.png @@ -1401,25 +1796,24 @@ Chromaticities .. code-block:: python - >>> import numpy as np - >>> RGB = np.random.random((32, 32, 3)) - >>> plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931( - ... RGB, - ... "ITU-R BT.709", - ... colourspaces=["ACEScg", "S-Gamut"], - ... show_pointer_gamut=True, - ... ) + import numpy as np + + RGB = np.random.random((32, 32, 3)) + plot_RGB_chromaticities_in_chromaticity_diagram_CIE1931( + RGB, + "ITU-R BT.709", + colourspaces=["ACEScg", "S-Gamut"], + show_pointer_gamut=True, + ) .. image:: _static/Examples_Plotting_Chromaticities_CIE_1931_Chromaticity_Diagram.png -Colour Rendering Index -********************** +Colour Rendering Index Bars +*************************** .. code-block:: python - >>> plot_single_sd_colour_rendering_index_bars( - ... colour.SDS_ILLUMINANTS["FL2"] - ... ) + plot_single_sd_colour_rendering_index_bars(colour.SDS_ILLUMINANTS["FL2"]) .. image:: _static/Examples_Plotting_CRI.png @@ -1428,7 +1822,7 @@ ANSI/IES TM-30-18 Colour Rendition Report .. code-block:: python - >>> plot_single_sd_colour_rendition_report(colour.SDS_ILLUMINANTS["FL2"]) + plot_single_sd_colour_rendition_report(colour.SDS_ILLUMINANTS["FL2"]) .. image:: _static/Examples_Plotting_Colour_Rendition_Report.png @@ -1437,17 +1831,13 @@ Gamut Section .. code-block:: python - >>> plot_visible_spectrum_section( - ... section_colours="RGB", section_opacity=0.15 - ... ) + plot_visible_spectrum_section(section_colours="RGB", section_opacity=0.15) .. image:: _static/Examples_Plotting_Plot_Visible_Spectrum_Section.png .. code-block:: python - >>> plot_RGB_colourspace_section( - ... "sRGB", section_colours="RGB", section_opacity=0.15 - ... ) + plot_RGB_colourspace_section("sRGB", section_colours="RGB", section_opacity=0.15) .. image:: _static/Examples_Plotting_Plot_RGB_Colourspace_Section.png @@ -1456,9 +1846,7 @@ Colour Temperature .. code-block:: python - >>> plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS( - ... ["A", "B", "C"] - ... ) + plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS(["A", "B", "C"]) .. image:: _static/Examples_Plotting_CCT_CIE_1960_UCS_Chromaticity_Diagram.png @@ -1487,12 +1875,12 @@ Software **Python** - `ColorPy `__ by Kness, M. -- `Colorspacious `__ by Smith, N. J., et al. -- `python-colormath `__ by Taylor, G., et al. +- `Colorspacious `__ by Smith, N. J., et al. +- `python-colormath `__ by Taylor, G., et al. **Go** -- `go-colorful `__ by Beyer, L., et al. +- `go-colorful `__ by Beyer, L., et al. **.NET** @@ -1505,14 +1893,14 @@ Software **Matlab & Octave** - `COLORLAB `__ by Malo, J., et al. -- `Psychtoolbox `__ by Brainard, D., et al. +- `Psychtoolbox `__ by Brainard, D., et al. - `The Munsell and Kubelka-Munk Toolbox `__ by Centore, P. Code of Conduct --------------- The *Code of Conduct*, adapted from the `Contributor Covenant 1.4 `__, -is available on the `Code of Conduct `__ page. +is available on the `Code of Conduct `__ page. Contact & Social ---------------- diff --git a/docs/requirements.txt b/docs/requirements.txt index 4efa1dbe0c..ecee497807 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,57 +1,57 @@ -accessible-pygments==0.0.4 ; python_version >= "3.9" and python_version < "3.12" -alabaster==0.7.13 ; python_version >= "3.9" and python_version < "3.12" -babel==2.12.1 ; python_version >= "3.9" and python_version < "3.12" -beautifulsoup4==4.12.2 ; python_version >= "3.9" and python_version < "3.12" -biblib-simple==0.1.2 ; python_version >= "3.9" and python_version < "3.12" -certifi==2023.7.22 ; python_version >= "3.9" and python_version < "3.12" -charset-normalizer==3.2.0 ; python_version >= "3.9" and python_version < "3.12" -colorama==0.4.6 ; python_version >= "3.9" and python_version < "3.12" and (platform_system == "Windows" or sys_platform == "win32") -contourpy==1.1.0 ; python_version >= "3.9" and python_version < "3.12" -cycler==0.11.0 ; python_version >= "3.9" and python_version < "3.12" -docutils==0.17.1 ; python_version >= "3.9" and python_version < "3.12" -fonttools==4.42.1 ; python_version >= "3.9" and python_version < "3.12" -idna==3.4 ; python_version >= "3.9" and python_version < "3.12" -imageio==2.31.1 ; python_version >= "3.9" and python_version < "3.12" -imagesize==1.4.1 ; python_version >= "3.9" and python_version < "3.12" -importlib-metadata==6.8.0 ; python_version >= "3.9" and python_version < "3.10" -importlib-resources==6.0.1 ; python_version >= "3.9" and python_version < "3.10" -jinja2==3.1.2 ; python_version >= "3.9" and python_version < "3.12" -kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "3.12" -latexcodec==2.0.1 ; python_version >= "3.9" and python_version < "3.12" -markupsafe==2.1.3 ; python_version >= "3.9" and python_version < "3.12" -matplotlib==3.7.2 ; python_version >= "3.9" and python_version < "3.12" -networkx==2.8.8 ; python_version >= "3.9" and python_version < "3.12" -numpy==1.25.2 ; python_version >= "3.9" and python_version < "3.12" -opencolorio==2.2.1 ; python_version >= "3.9" and python_version < "3.12" -packaging==23.1 ; python_version >= "3.9" and python_version < "3.12" -pandas==1.5.3 ; python_version >= "3.9" and python_version < "3.12" -pillow==10.0.0 ; python_version >= "3.9" and python_version < "3.12" -pybtex-docutils==1.0.3 ; python_version >= "3.9" and python_version < "3.12" -pybtex==0.24.0 ; python_version >= "3.9" and python_version < "3.12" -pydata-sphinx-theme==0.13.3 ; python_version >= "3.9" and python_version < "3.12" -pygments==2.16.1 ; python_version >= "3.9" and python_version < "3.12" +accessible-pygments==0.0.4 ; python_version >= "3.9" and python_version < "3.13" +alabaster==0.7.13 ; python_version >= "3.9" and python_version < "3.13" +babel==2.14.0 ; python_version >= "3.9" and python_version < "3.13" +beautifulsoup4==4.12.2 ; python_version >= "3.9" and python_version < "3.13" +biblib-simple==0.1.2 ; python_version >= "3.9" and python_version < "3.13" +certifi==2023.11.17 ; python_version >= "3.9" and python_version < "3.13" +charset-normalizer==3.3.2 ; python_version >= "3.9" and python_version < "3.13" +colorama==0.4.6 ; python_version >= "3.9" and python_version < "3.13" and (platform_system == "Windows" or sys_platform == "win32") +contourpy==1.2.0 ; python_version >= "3.9" and python_version < "3.13" +cycler==0.12.1 ; python_version >= "3.9" and python_version < "3.13" +docutils==0.20.1 ; python_version >= "3.9" and python_version < "3.13" +fonttools==4.46.0 ; python_version >= "3.9" and python_version < "3.13" +idna==3.6 ; python_version >= "3.9" and python_version < "3.13" +imageio==2.33.1 ; python_version >= "3.9" and python_version < "3.13" +imagesize==1.4.1 ; python_version >= "3.9" and python_version < "3.13" +importlib-metadata==7.0.0 ; python_version >= "3.9" and python_version < "3.10" +importlib-resources==6.1.1 ; python_version >= "3.9" and python_version < "3.10" +jinja2==3.1.2 ; python_version >= "3.9" and python_version < "3.13" +kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "3.13" +latexcodec==2.0.1 ; python_version >= "3.9" and python_version < "3.13" +markupsafe==2.1.3 ; python_version >= "3.9" and python_version < "3.13" +matplotlib==3.8.2 ; python_version >= "3.9" and python_version < "3.13" +networkx==2.8.8 ; python_version >= "3.9" and python_version < "3.13" +numpy==1.26.2 ; python_version >= "3.9" and python_version < "3.13" +opencolorio==2.3.1 ; python_version >= "3.9" and python_version < "3.13" +packaging==23.2 ; python_version >= "3.9" and python_version < "3.13" +pandas==1.5.3 ; python_version >= "3.9" and python_version < "3.13" +pillow==10.1.0 ; python_version >= "3.9" and python_version < "3.13" +pybtex==0.24.0 ; python_version >= "3.9" and python_version < "3.13" +pybtex-docutils==1.0.3 ; python_version >= "3.9" and python_version < "3.13" +pydata-sphinx-theme==0.14.4 ; python_version >= "3.9" and python_version < "3.13" +pygments==2.17.2 ; python_version >= "3.9" and python_version < "3.13" pygraphviz==1.11 ; python_version >= "3.9" and python_version < "3.12" -pyparsing==3.0.9 ; python_version >= "3.9" and python_version < "3.12" -python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "3.12" -pytz==2023.3 ; python_version >= "3.9" and python_version < "3.12" -pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "3.12" -requests==2.31.0 ; python_version >= "3.9" and python_version < "3.12" -restructuredtext-lint==1.4.0 ; python_version >= "3.9" and python_version < "3.12" -scipy==1.11.2 ; python_version >= "3.9" and python_version < "3.12" -six==1.16.0 ; python_version >= "3.9" and python_version < "3.12" -snowballstemmer==2.2.0 ; python_version >= "3.9" and python_version < "3.12" -soupsieve==2.4.1 ; python_version >= "3.9" and python_version < "3.12" -sphinx==4.5.0 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-applehelp==1.0.4 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-bibtex==2.6.0 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-devhelp==1.0.2 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-htmlhelp==2.0.1 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.9" and python_version < "3.12" -tqdm==4.66.1 ; python_version >= "3.9" and python_version < "3.12" -trimesh==3.23.5 ; python_version >= "3.9" and python_version < "3.12" -typing-extensions==4.7.1 ; python_version >= "3.9" and python_version < "3.12" -urllib3==2.0.4 ; python_version >= "3.9" and python_version < "3.12" -xxhash==3.3.0 ; python_version >= "3.9" and python_version < "3.12" -zipp==3.16.2 ; python_version >= "3.9" and python_version < "3.10" +pyparsing==3.1.1 ; python_version >= "3.9" and python_version < "3.13" +python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "3.13" +pytz==2023.3.post1 ; python_version >= "3.9" and python_version < "3.13" +pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "3.13" +requests==2.31.0 ; python_version >= "3.9" and python_version < "3.13" +restructuredtext-lint==1.4.0 ; python_version >= "3.9" and python_version < "3.13" +scipy==1.11.4 ; python_version >= "3.9" and python_version < "3.13" +six==1.16.0 ; python_version >= "3.9" and python_version < "3.13" +snowballstemmer==2.2.0 ; python_version >= "3.9" and python_version < "3.13" +soupsieve==2.5 ; python_version >= "3.9" and python_version < "3.13" +sphinx==7.2.6 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-applehelp==1.0.7 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-bibtex==2.6.1 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-devhelp==1.0.5 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-htmlhelp==2.0.4 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-qthelp==1.0.6 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-serializinghtml==1.1.9 ; python_version >= "3.9" and python_version < "3.13" +tqdm==4.66.1 ; python_version >= "3.9" and python_version < "3.13" +trimesh==3.23.5 ; python_version >= "3.9" and python_version < "3.13" +typing-extensions==4.9.0 ; python_version >= "3.9" and python_version < "3.13" +urllib3==2.1.0 ; python_version >= "3.9" and python_version < "3.13" +xxhash==3.4.1 ; python_version >= "3.9" and python_version < "3.13" +zipp==3.17.0 ; python_version >= "3.9" and python_version < "3.10" diff --git a/docs/tutorial.rst b/docs/tutorial.rst index d81eeaab6d..9fb7363c23 100644 --- a/docs/tutorial.rst +++ b/docs/tutorial.rst @@ -6,7 +6,7 @@ Tutorial An interactive version of the tutorial is available via `Google Colab `__. -`Colour `__ spreads over +`Colour `__ spreads over various domains of Colour Science, from colour models to optical phenomena, this tutorial does not give a complete overview of the API but is a good introduction to the main concepts. @@ -360,14 +360,14 @@ The codebase is documented and most docstrings have usage examples: Examples -------- - >>> from colour import MSDS_CMFS, SPECTRAL_SHAPE_DEFAULT - >>> cmfs = ( - ... MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] - ... .copy() - ... .align(SPECTRAL_SHAPE_DEFAULT) - ... ) - >>> CCT_D_uv = np.array([6507.4342201047066, 0.003223690901513]) - >>> CCT_to_uv_Ohno2013(CCT_D_uv, cmfs) # doctest: +ELLIPSIS + from colour import MSDS_CMFS, SPECTRAL_SHAPE_DEFAULT + cmfs = ( + MSDS_CMFS["CIE 1931 2 Degree Standard Observer"] + .copy() + .align(SPECTRAL_SHAPE_DEFAULT) + ) + CCT_D_uv = np.array([6507.4342201047066, 0.003223690901513]) + CCT_to_uv_Ohno2013(CCT_D_uv, cmfs) # doctest: +ELLIPSIS array([ 0.1977999..., 0.3122004...]) At the core of **Colour** is the ``colour.colorimetry`` sub-package, it defines @@ -1054,13 +1054,7 @@ operations like *addition*, *subtraction*, *multiplication*, *division* or print((sd.copy() + 1).values) print((sd.copy() * 2).values) print((sd * [0.35, 1.55, 0.75, 2.55, 0.95, 0.65, 0.15]).values) - print( - ( - sd - * colour.sd_constant(2, sd.shape) - * colour.sd_constant(3, sd.shape) - ).values - ) + print((sd * colour.sd_constant(2, sd.shape) * colour.sd_constant(3, sd.shape)).values) .. code-block:: text @@ -1215,9 +1209,7 @@ values in order to display them on screen: .. code:: python # Plotting the *sRGB* colourspace colour of the *Sample* spectral distribution. - plot_single_colour_swatch( - ColourSwatch(RGB, "Sample"), text_kwargs={"size": "x-large"} - ) + plot_single_colour_swatch(ColourSwatch(RGB, "Sample"), text_kwargs={"size": "x-large"}) .. image:: _static/Tutorial_Sample_Swatch.png diff --git a/pyproject.toml b/pyproject.toml index fcaa74c3de..0568faf2a3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "colour-science" packages = [{ include = "colour" }] -version = "0.4.3" +version = "0.4.4" description = "Colour Science for Python" license = "BSD-3-Clause" authors = ["Colour Developers "] @@ -28,7 +28,7 @@ keywords = [ "python", "spectral-data", "spectral-dataset", - "spectral-datasets" + "spectral-datasets", ] classifiers = [ "Development Status :: 3 - Alpha", @@ -40,11 +40,11 @@ classifiers = [ "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering", - "Topic :: Software Development" + "Topic :: Software Development", ] [tool.poetry.dependencies] -python = ">= 3.9, < 3.12" +python = ">= 3.9, < 3.13" imageio = ">= 2, < 3" numpy = ">= 1.22, < 2" scipy = ">= 1.8, < 2" @@ -59,25 +59,21 @@ tqdm = ">= 4, < 5" xxhash = ">= 3.2, < 4" [tool.poetry.group.graphviz.dependencies] -pygraphviz = ">= 1, < 2" +pygraphviz = { version = ">= 1, < 2", python = "< 3.12" } [tool.poetry.group.meshing.dependencies] trimesh = ">= 3, < 4" [tool.poetry.group.dev.dependencies] -black = "*" -blackdoc = "*" coverage = "!= 6.3" coveralls = "*" -flynt = "*" invoke = "*" jupyter = "*" -pre-commit = "*" +pre-commit = ">= 3.5" pyright = "*" pytest = "*" pytest-cov = "*" pytest-xdist = "*" -ruff = "*" toml = "*" twine = "*" @@ -85,28 +81,36 @@ twine = "*" biblib-simple = "*" pydata-sphinx-theme = "*" restructuredtext-lint = "*" -sphinx = ">= 4, < 5" +sphinx = "*" sphinxcontrib-bibtex = "*" [tool.black] line-length = 79 -exclude = ''' -/( - \.git - | build - | dist -)/ -''' +exclude = '''/(\.git|build|dist)/''' + +[tool.codespell] +ignore-words-list = 'co-ordinates,exitance,hart,ist' +skip = 'BIBLIOGRAPHY.bib,CONTRIBUTORS.rst' [tool.flynt] line_length = 999 +[tool.isort] +ensure_newline_before_comments = true +force_grid_wrap = 0 +include_trailing_comma = true +line_length = 88 +multi_line_output = 3 +skip_glob = ["colour/**/__init__.py"] +split_on_trailing_comma = true +use_parentheses = true + [tool.pyright] reportMissingImports = false reportMissingModuleSource = false reportUnboundVariable = false reportUnnecessaryCast = true -reportUnnecessaryTypeIgnoreComment = true +reportUnnecessaryTypeIgnorComment = true reportUnsupportedDunderAll = false reportUnusedExpression = false @@ -134,7 +138,7 @@ filterwarnings = [ target-version = "py39" line-length = 88 select = [ - "A", # flake8-builtins + "A", # flake8-builtins "ARG", # flake8-unused-arguments # "ANN", # flake8-annotations "B", # flake8-bugbear @@ -143,38 +147,37 @@ select = [ # "C90", # mccabe # "COM", # flake8-commas "DTZ", # flake8-datetimez - "D", # pydocstyle - "E", # pydocstyle + "D", # pydocstyle + "E", # pydocstyle # "ERA", # eradicate # "EM", # flake8-errmsg "EXE", # flake8-executable - "F", # flake8 + "F", # flake8 # "FBT", # flake8-boolean-trap - "G", # flake8-logging-format - "I", # isort + "G", # flake8-logging-format + "I", # isort "ICN", # flake8-import-conventions "INP", # flake8-no-pep420 "ISC", # flake8-implicit-str-concat - "N", # pep8-naming + "N", # pep8-naming # "PD", # pandas-vet "PIE", # flake8-pie "PGH", # pygrep-hooks - "PL", # pylint + "PL", # pylint # "PT", # flake8-pytest-style - # "PTH", # flake8-use-pathlib [Enable] - "Q", # flake8-quotes + # "PTH", # flake8-use-pathlib [Enable] "Q", # flake8-quotes "RET", # flake8-return "RUF", # Ruff - "S", # flake8-bandit + "S", # flake8-bandit "SIM", # flake8-simplify "T10", # flake8-debugger "T20", # flake8-print # "TCH", # flake8-type-checking "TID", # flake8-tidy-imports "TRY", # tryceratops - "UP", # pyupgrade - "W", # pydocstyle - "YTT" # flake8-2020 + "UP", # pyupgrade + "W", # pydocstyle + "YTT", # flake8-2020 ] ignore = [ "B008", @@ -218,7 +221,6 @@ convention = "numpy" [tool.ruff.per-file-ignores] "colour/examples/*" = ["INP", "T201", "T203"] "docs/*" = ["INP"] -"setup.py" = ["INP"] "tasks.py" = ["INP"] "utilities/*" = ["EXE001", "INP"] "utilities/unicode_to_ascii.py" = ["RUF001"] diff --git a/requirements.txt b/requirements.txt index ee208ea944..976085b2fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,187 +1,178 @@ -accessible-pygments==0.0.4 ; python_version >= "3.9" and python_version < "3.12" -alabaster==0.7.13 ; python_version >= "3.9" and python_version < "3.12" -anyio==3.7.1 ; python_version >= "3.9" and python_version < "3.12" -appnope==0.1.3 ; python_version >= "3.9" and python_version < "3.12" and (platform_system == "Darwin" or sys_platform == "darwin") -argon2-cffi-bindings==21.2.0 ; python_version >= "3.9" and python_version < "3.12" -argon2-cffi==23.1.0 ; python_version >= "3.9" and python_version < "3.12" -arrow==1.2.3 ; python_version >= "3.9" and python_version < "3.12" -astor==0.8.1 ; python_version >= "3.9" and python_version < "3.12" -asttokens==2.2.1 ; python_version >= "3.9" and python_version < "3.12" -async-lru==2.0.4 ; python_version >= "3.9" and python_version < "3.12" -attrs==23.1.0 ; python_version >= "3.9" and python_version < "3.12" -babel==2.12.1 ; python_version >= "3.9" and python_version < "3.12" -backcall==0.2.0 ; python_version >= "3.9" and python_version < "3.12" -beautifulsoup4==4.12.2 ; python_version >= "3.9" and python_version < "3.12" -biblib-simple==0.1.2 ; python_version >= "3.9" and python_version < "3.12" -black==23.7.0 ; python_version >= "3.9" and python_version < "3.12" -blackdoc==0.3.8 ; python_version >= "3.9" and python_version < "3.12" -bleach==6.0.0 ; python_version >= "3.9" and python_version < "3.12" -certifi==2023.7.22 ; python_version >= "3.9" and python_version < "3.12" -cffi==1.15.1 ; python_version >= "3.9" and python_version < "3.12" -cfgv==3.4.0 ; python_version >= "3.9" and python_version < "3.12" -charset-normalizer==3.2.0 ; python_version >= "3.9" and python_version < "3.12" -click==8.1.7 ; python_version >= "3.9" and python_version < "3.12" -colorama==0.4.6 ; python_version >= "3.9" and python_version < "3.12" and (platform_system == "Windows" or sys_platform == "win32") -comm==0.1.4 ; python_version >= "3.9" and python_version < "3.12" -contourpy==1.1.0 ; python_version >= "3.9" and python_version < "3.12" -coverage==6.5.0 ; python_version >= "3.9" and python_version < "3.12" -coverage[toml]==6.5.0 ; python_version >= "3.9" and python_version < "3.12" -coveralls==3.3.1 ; python_version >= "3.9" and python_version < "3.12" -cryptography==41.0.3 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "linux" -cycler==0.11.0 ; python_version >= "3.9" and python_version < "3.12" -debugpy==1.6.7.post1 ; python_version >= "3.9" and python_version < "3.12" -decorator==5.1.1 ; python_version >= "3.9" and python_version < "3.12" -defusedxml==0.7.1 ; python_version >= "3.9" and python_version < "3.12" -distlib==0.3.7 ; python_version >= "3.9" and python_version < "3.12" -docopt==0.6.2 ; python_version >= "3.9" and python_version < "3.12" -docutils==0.17.1 ; python_version >= "3.9" and python_version < "3.12" -exceptiongroup==1.1.3 ; python_version >= "3.9" and python_version < "3.11" -execnet==2.0.2 ; python_version >= "3.9" and python_version < "3.12" -executing==1.2.0 ; python_version >= "3.9" and python_version < "3.12" -fastjsonschema==2.18.0 ; python_version >= "3.9" and python_version < "3.12" -filelock==3.12.2 ; python_version >= "3.9" and python_version < "3.12" -flynt==1.0.1 ; python_version >= "3.9" and python_version < "3.12" -fonttools==4.42.1 ; python_version >= "3.9" and python_version < "3.12" -fqdn==1.5.1 ; python_version >= "3.9" and python_version < "3.12" -identify==2.5.27 ; python_version >= "3.9" and python_version < "3.12" -idna==3.4 ; python_version >= "3.9" and python_version < "3.12" -imageio==2.31.1 ; python_version >= "3.9" and python_version < "3.12" -imagesize==1.4.1 ; python_version >= "3.9" and python_version < "3.12" -importlib-metadata==6.8.0 ; python_version >= "3.9" and python_version < "3.12" -importlib-resources==6.0.1 ; python_version >= "3.9" and python_version < "3.10" -iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "3.12" -invoke==2.2.0 ; python_version >= "3.9" and python_version < "3.12" -ipykernel==6.25.1 ; python_version >= "3.9" and python_version < "3.12" -ipython-genutils==0.2.0 ; python_version >= "3.9" and python_version < "3.12" -ipython==8.14.0 ; python_version >= "3.9" and python_version < "3.12" -ipywidgets==8.1.0 ; python_version >= "3.9" and python_version < "3.12" -isoduration==20.11.0 ; python_version >= "3.9" and python_version < "3.12" -jaraco-classes==3.3.0 ; python_version >= "3.9" and python_version < "3.12" -jedi==0.19.0 ; python_version >= "3.9" and python_version < "3.12" -jeepney==0.8.0 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "linux" -jinja2==3.1.2 ; python_version >= "3.9" and python_version < "3.12" -json5==0.9.14 ; python_version >= "3.9" and python_version < "3.12" -jsonpointer==2.4 ; python_version >= "3.9" and python_version < "3.12" -jsonschema-specifications==2023.7.1 ; python_version >= "3.9" and python_version < "3.12" -jsonschema==4.19.0 ; python_version >= "3.9" and python_version < "3.12" -jsonschema[format-nongpl]==4.19.0 ; python_version >= "3.9" and python_version < "3.12" -jupyter-client==8.3.0 ; python_version >= "3.9" and python_version < "3.12" -jupyter-console==6.6.3 ; python_version >= "3.9" and python_version < "3.12" -jupyter-core==5.3.1 ; python_version >= "3.9" and python_version < "3.12" -jupyter-events==0.7.0 ; python_version >= "3.9" and python_version < "3.12" -jupyter-lsp==2.2.0 ; python_version >= "3.9" and python_version < "3.12" -jupyter-server-terminals==0.4.4 ; python_version >= "3.9" and python_version < "3.12" -jupyter-server==2.7.2 ; python_version >= "3.9" and python_version < "3.12" -jupyter==1.0.0 ; python_version >= "3.9" and python_version < "3.12" -jupyterlab-pygments==0.2.2 ; python_version >= "3.9" and python_version < "3.12" -jupyterlab-server==2.24.0 ; python_version >= "3.9" and python_version < "3.12" -jupyterlab-widgets==3.0.8 ; python_version >= "3.9" and python_version < "3.12" -jupyterlab==4.0.5 ; python_version >= "3.9" and python_version < "3.12" -keyring==24.2.0 ; python_version >= "3.9" and python_version < "3.12" -kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "3.12" -latexcodec==2.0.1 ; python_version >= "3.9" and python_version < "3.12" -markdown-it-py==3.0.0 ; python_version >= "3.9" and python_version < "3.12" -markupsafe==2.1.3 ; python_version >= "3.9" and python_version < "3.12" -matplotlib-inline==0.1.6 ; python_version >= "3.9" and python_version < "3.12" -matplotlib==3.7.2 ; python_version >= "3.9" and python_version < "3.12" -mdurl==0.1.2 ; python_version >= "3.9" and python_version < "3.12" -mistune==3.0.1 ; python_version >= "3.9" and python_version < "3.12" -more-itertools==10.1.0 ; python_version >= "3.9" and python_version < "3.12" -mypy-extensions==1.0.0 ; python_version >= "3.9" and python_version < "3.12" -nbclient==0.8.0 ; python_version >= "3.9" and python_version < "3.12" -nbconvert==7.7.4 ; python_version >= "3.9" and python_version < "3.12" -nbformat==5.9.2 ; python_version >= "3.9" and python_version < "3.12" -nest-asyncio==1.5.7 ; python_version >= "3.9" and python_version < "3.12" -networkx==2.8.8 ; python_version >= "3.9" and python_version < "3.12" -nodeenv==1.8.0 ; python_version >= "3.9" and python_version < "3.12" -notebook-shim==0.2.3 ; python_version >= "3.9" and python_version < "3.12" -notebook==7.0.2 ; python_version >= "3.9" and python_version < "3.12" -numpy==1.25.2 ; python_version >= "3.9" and python_version < "3.12" -opencolorio==2.2.1 ; python_version >= "3.9" and python_version < "3.12" -overrides==7.4.0 ; python_version >= "3.9" and python_version < "3.12" -packaging==23.1 ; python_version >= "3.9" and python_version < "3.12" -pandas==1.5.3 ; python_version >= "3.9" and python_version < "3.12" -pandocfilters==1.5.0 ; python_version >= "3.9" and python_version < "3.12" -parso==0.8.3 ; python_version >= "3.9" and python_version < "3.12" -pathspec==0.11.2 ; python_version >= "3.9" and python_version < "3.12" -pexpect==4.8.0 ; python_version >= "3.9" and python_version < "3.12" and sys_platform != "win32" -pickleshare==0.7.5 ; python_version >= "3.9" and python_version < "3.12" -pillow==10.0.0 ; python_version >= "3.9" and python_version < "3.12" -pkginfo==1.9.6 ; python_version >= "3.9" and python_version < "3.12" -platformdirs==3.10.0 ; python_version >= "3.9" and python_version < "3.12" -pluggy==1.2.0 ; python_version >= "3.9" and python_version < "3.12" -pre-commit==3.3.3 ; python_version >= "3.9" and python_version < "3.12" -prometheus-client==0.17.1 ; python_version >= "3.9" and python_version < "3.12" -prompt-toolkit==3.0.39 ; python_version >= "3.9" and python_version < "3.12" -psutil==5.9.5 ; python_version >= "3.9" and python_version < "3.12" -ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "3.12" and (sys_platform != "win32" or os_name != "nt") -pure-eval==0.2.2 ; python_version >= "3.9" and python_version < "3.12" -pybtex-docutils==1.0.3 ; python_version >= "3.9" and python_version < "3.12" -pybtex==0.24.0 ; python_version >= "3.9" and python_version < "3.12" -pycparser==2.21 ; python_version >= "3.9" and python_version < "3.12" -pydata-sphinx-theme==0.13.3 ; python_version >= "3.9" and python_version < "3.12" -pygments==2.16.1 ; python_version >= "3.9" and python_version < "3.12" +accessible-pygments==0.0.4 ; python_version >= "3.9" and python_version < "3.13" +alabaster==0.7.13 ; python_version >= "3.9" and python_version < "3.13" +anyio==4.2.0 ; python_version >= "3.9" and python_version < "3.13" +appnope==0.1.3 ; python_version >= "3.9" and python_version < "3.13" and platform_system == "Darwin" +argon2-cffi==23.1.0 ; python_version >= "3.9" and python_version < "3.13" +argon2-cffi-bindings==21.2.0 ; python_version >= "3.9" and python_version < "3.13" +arrow==1.3.0 ; python_version >= "3.9" and python_version < "3.13" +asttokens==2.4.1 ; python_version >= "3.9" and python_version < "3.13" +async-lru==2.0.4 ; python_version >= "3.9" and python_version < "3.13" +attrs==23.1.0 ; python_version >= "3.9" and python_version < "3.13" +babel==2.14.0 ; python_version >= "3.9" and python_version < "3.13" +beautifulsoup4==4.12.2 ; python_version >= "3.9" and python_version < "3.13" +biblib-simple==0.1.2 ; python_version >= "3.9" and python_version < "3.13" +bleach==6.1.0 ; python_version >= "3.9" and python_version < "3.13" +certifi==2023.11.17 ; python_version >= "3.9" and python_version < "3.13" +cffi==1.16.0 ; python_version >= "3.9" and python_version < "3.13" +cfgv==3.4.0 ; python_version >= "3.9" and python_version < "3.13" +charset-normalizer==3.3.2 ; python_version >= "3.9" and python_version < "3.13" +colorama==0.4.6 ; python_version >= "3.9" and python_version < "3.13" and (platform_system == "Windows" or sys_platform == "win32") +comm==0.2.0 ; python_version >= "3.9" and python_version < "3.13" +contourpy==1.2.0 ; python_version >= "3.9" and python_version < "3.13" +coverage==7.3.3 ; python_version >= "3.9" and python_version < "3.13" +coverage[toml]==7.3.3 ; python_version >= "3.9" and python_version < "3.13" +coveralls==1.8.0 ; python_version >= "3.9" and python_version < "3.13" +cryptography==41.0.7 ; python_version >= "3.9" and python_version < "3.13" and sys_platform == "linux" +cycler==0.12.1 ; python_version >= "3.9" and python_version < "3.13" +debugpy==1.8.0 ; python_version >= "3.9" and python_version < "3.13" +decorator==5.1.1 ; python_version >= "3.9" and python_version < "3.13" +defusedxml==0.7.1 ; python_version >= "3.9" and python_version < "3.13" +distlib==0.3.8 ; python_version >= "3.9" and python_version < "3.13" +docopt==0.6.2 ; python_version >= "3.9" and python_version < "3.13" +docutils==0.20.1 ; python_version >= "3.9" and python_version < "3.13" +exceptiongroup==1.2.0 ; python_version >= "3.9" and python_version < "3.11" +execnet==2.0.2 ; python_version >= "3.9" and python_version < "3.13" +executing==2.0.1 ; python_version >= "3.9" and python_version < "3.13" +fastjsonschema==2.19.0 ; python_version >= "3.9" and python_version < "3.13" +filelock==3.13.1 ; python_version >= "3.9" and python_version < "3.13" +fonttools==4.46.0 ; python_version >= "3.9" and python_version < "3.13" +fqdn==1.5.1 ; python_version >= "3.9" and python_version < "3.13" +identify==2.5.33 ; python_version >= "3.9" and python_version < "3.13" +idna==3.6 ; python_version >= "3.9" and python_version < "3.13" +imageio==2.33.1 ; python_version >= "3.9" and python_version < "3.13" +imagesize==1.4.1 ; python_version >= "3.9" and python_version < "3.13" +importlib-metadata==7.0.0 ; python_version >= "3.9" and python_version < "3.13" +importlib-resources==6.1.1 ; python_version >= "3.9" and python_version < "3.10" +iniconfig==2.0.0 ; python_version >= "3.9" and python_version < "3.13" +invoke==2.2.0 ; python_version >= "3.9" and python_version < "3.13" +ipykernel==6.27.1 ; python_version >= "3.9" and python_version < "3.13" +ipython==8.18.1 ; python_version >= "3.9" and python_version < "3.13" +ipywidgets==8.1.1 ; python_version >= "3.9" and python_version < "3.13" +isoduration==20.11.0 ; python_version >= "3.9" and python_version < "3.13" +jaraco-classes==3.3.0 ; python_version >= "3.9" and python_version < "3.13" +jedi==0.19.1 ; python_version >= "3.9" and python_version < "3.13" +jeepney==0.8.0 ; python_version >= "3.9" and python_version < "3.13" and sys_platform == "linux" +jinja2==3.1.2 ; python_version >= "3.9" and python_version < "3.13" +json5==0.9.14 ; python_version >= "3.9" and python_version < "3.13" +jsonpointer==2.4 ; python_version >= "3.9" and python_version < "3.13" +jsonschema==4.20.0 ; python_version >= "3.9" and python_version < "3.13" +jsonschema-specifications==2023.11.2 ; python_version >= "3.9" and python_version < "3.13" +jsonschema[format-nongpl]==4.20.0 ; python_version >= "3.9" and python_version < "3.13" +jupyter==1.0.0 ; python_version >= "3.9" and python_version < "3.13" +jupyter-client==8.6.0 ; python_version >= "3.9" and python_version < "3.13" +jupyter-console==6.6.3 ; python_version >= "3.9" and python_version < "3.13" +jupyter-core==5.5.0 ; python_version >= "3.9" and python_version < "3.13" +jupyter-events==0.9.0 ; python_version >= "3.9" and python_version < "3.13" +jupyter-lsp==2.2.1 ; python_version >= "3.9" and python_version < "3.13" +jupyter-server==2.12.1 ; python_version >= "3.9" and python_version < "3.13" +jupyter-server-terminals==0.5.0 ; python_version >= "3.9" and python_version < "3.13" +jupyterlab==4.0.9 ; python_version >= "3.9" and python_version < "3.13" +jupyterlab-pygments==0.3.0 ; python_version >= "3.9" and python_version < "3.13" +jupyterlab-server==2.25.2 ; python_version >= "3.9" and python_version < "3.13" +jupyterlab-widgets==3.0.9 ; python_version >= "3.9" and python_version < "3.13" +keyring==24.3.0 ; python_version >= "3.9" and python_version < "3.13" +kiwisolver==1.4.5 ; python_version >= "3.9" and python_version < "3.13" +latexcodec==2.0.1 ; python_version >= "3.9" and python_version < "3.13" +markdown-it-py==3.0.0 ; python_version >= "3.9" and python_version < "3.13" +markupsafe==2.1.3 ; python_version >= "3.9" and python_version < "3.13" +matplotlib==3.8.2 ; python_version >= "3.9" and python_version < "3.13" +matplotlib-inline==0.1.6 ; python_version >= "3.9" and python_version < "3.13" +mdurl==0.1.2 ; python_version >= "3.9" and python_version < "3.13" +mistune==3.0.2 ; python_version >= "3.9" and python_version < "3.13" +more-itertools==10.1.0 ; python_version >= "3.9" and python_version < "3.13" +nbclient==0.9.0 ; python_version >= "3.9" and python_version < "3.13" +nbconvert==7.12.0 ; python_version >= "3.9" and python_version < "3.13" +nbformat==5.9.2 ; python_version >= "3.9" and python_version < "3.13" +nest-asyncio==1.5.8 ; python_version >= "3.9" and python_version < "3.13" +networkx==2.8.8 ; python_version >= "3.9" and python_version < "3.13" +nh3==0.2.15 ; python_version >= "3.9" and python_version < "3.13" +nodeenv==1.8.0 ; python_version >= "3.9" and python_version < "3.13" +notebook==7.0.6 ; python_version >= "3.9" and python_version < "3.13" +notebook-shim==0.2.3 ; python_version >= "3.9" and python_version < "3.13" +numpy==1.26.2 ; python_version >= "3.9" and python_version < "3.13" +opencolorio==2.3.1 ; python_version >= "3.9" and python_version < "3.13" +overrides==7.4.0 ; python_version >= "3.9" and python_version < "3.13" +packaging==23.2 ; python_version >= "3.9" and python_version < "3.13" +pandas==1.5.3 ; python_version >= "3.9" and python_version < "3.13" +pandocfilters==1.5.0 ; python_version >= "3.9" and python_version < "3.13" +parso==0.8.3 ; python_version >= "3.9" and python_version < "3.13" +pexpect==4.9.0 ; python_version >= "3.9" and python_version < "3.13" and sys_platform != "win32" +pillow==10.1.0 ; python_version >= "3.9" and python_version < "3.13" +pkginfo==1.9.6 ; python_version >= "3.9" and python_version < "3.13" +platformdirs==4.1.0 ; python_version >= "3.9" and python_version < "3.13" +pluggy==1.3.0 ; python_version >= "3.9" and python_version < "3.13" +pre-commit==3.6.0 ; python_version >= "3.9" and python_version < "3.13" +prometheus-client==0.19.0 ; python_version >= "3.9" and python_version < "3.13" +prompt-toolkit==3.0.43 ; python_version >= "3.9" and python_version < "3.13" +psutil==5.9.6 ; python_version >= "3.9" and python_version < "3.13" +ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "3.13" and (sys_platform != "win32" or os_name != "nt") +pure-eval==0.2.2 ; python_version >= "3.9" and python_version < "3.13" +pybtex==0.24.0 ; python_version >= "3.9" and python_version < "3.13" +pybtex-docutils==1.0.3 ; python_version >= "3.9" and python_version < "3.13" +pycparser==2.21 ; python_version >= "3.9" and python_version < "3.13" +pydata-sphinx-theme==0.14.4 ; python_version >= "3.9" and python_version < "3.13" +pygments==2.17.2 ; python_version >= "3.9" and python_version < "3.13" pygraphviz==1.11 ; python_version >= "3.9" and python_version < "3.12" -pyparsing==3.0.9 ; python_version >= "3.9" and python_version < "3.12" -pyright==1.1.324 ; python_version >= "3.9" and python_version < "3.12" -pytest-cov==4.1.0 ; python_version >= "3.9" and python_version < "3.12" -pytest-xdist==3.3.1 ; python_version >= "3.9" and python_version < "3.12" -pytest==7.4.0 ; python_version >= "3.9" and python_version < "3.12" -python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "3.12" -python-json-logger==2.0.7 ; python_version >= "3.9" and python_version < "3.12" -pytz==2023.3 ; python_version >= "3.9" and python_version < "3.12" -pywin32-ctypes==0.2.2 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "win32" -pywin32==306 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.9" and python_version < "3.12" -pywinpty==2.0.11 ; python_version >= "3.9" and python_version < "3.12" and os_name == "nt" -pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "3.12" -pyzmq==25.1.1 ; python_version >= "3.9" and python_version < "3.12" -qtconsole==5.4.3 ; python_version >= "3.9" and python_version < "3.12" -qtpy==2.3.1 ; python_version >= "3.9" and python_version < "3.12" -readme-renderer==41.0 ; python_version >= "3.9" and python_version < "3.12" -referencing==0.30.2 ; python_version >= "3.9" and python_version < "3.12" -requests-toolbelt==1.0.0 ; python_version >= "3.9" and python_version < "3.12" -requests==2.31.0 ; python_version >= "3.9" and python_version < "3.12" -restructuredtext-lint==1.4.0 ; python_version >= "3.9" and python_version < "3.12" -rfc3339-validator==0.1.4 ; python_version >= "3.9" and python_version < "3.12" -rfc3986-validator==0.1.1 ; python_version >= "3.9" and python_version < "3.12" -rfc3986==2.0.0 ; python_version >= "3.9" and python_version < "3.12" -rich==13.5.2 ; python_version >= "3.9" and python_version < "3.12" -rpds-py==0.9.2 ; python_version >= "3.9" and python_version < "3.12" -ruff==0.0.286 ; python_version >= "3.9" and python_version < "3.12" -scipy==1.11.2 ; python_version >= "3.9" and python_version < "3.12" -secretstorage==3.3.3 ; python_version >= "3.9" and python_version < "3.12" and sys_platform == "linux" -send2trash==1.8.2 ; python_version >= "3.9" and python_version < "3.12" -setuptools==68.1.2 ; python_version >= "3.9" and python_version < "3.12" -six==1.16.0 ; python_version >= "3.9" and python_version < "3.12" -sniffio==1.3.0 ; python_version >= "3.9" and python_version < "3.12" -snowballstemmer==2.2.0 ; python_version >= "3.9" and python_version < "3.12" -soupsieve==2.4.1 ; python_version >= "3.9" and python_version < "3.12" -sphinx==4.5.0 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-applehelp==1.0.4 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-bibtex==2.6.0 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-devhelp==1.0.2 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-htmlhelp==2.0.1 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-qthelp==1.0.3 ; python_version >= "3.9" and python_version < "3.12" -sphinxcontrib-serializinghtml==1.1.5 ; python_version >= "3.9" and python_version < "3.12" -stack-data==0.6.2 ; python_version >= "3.9" and python_version < "3.12" -terminado==0.17.1 ; python_version >= "3.9" and python_version < "3.12" -tinycss2==1.2.1 ; python_version >= "3.9" and python_version < "3.12" -toml==0.10.2 ; python_version >= "3.9" and python_version < "3.12" -tomli==2.0.1 ; python_version >= "3.9" and python_version < "3.12" -tornado==6.3.3 ; python_version >= "3.9" and python_version < "3.12" -tqdm==4.66.1 ; python_version >= "3.9" and python_version < "3.12" -traitlets==5.9.0 ; python_version >= "3.9" and python_version < "3.12" -trimesh==3.23.5 ; python_version >= "3.9" and python_version < "3.12" -twine==4.0.2 ; python_version >= "3.9" and python_version < "3.12" -typing-extensions==4.7.1 ; python_version >= "3.9" and python_version < "3.12" -uri-template==1.3.0 ; python_version >= "3.9" and python_version < "3.12" -urllib3==2.0.4 ; python_version >= "3.9" and python_version < "3.12" -virtualenv==20.24.3 ; python_version >= "3.9" and python_version < "3.12" -wcwidth==0.2.6 ; python_version >= "3.9" and python_version < "3.12" -webcolors==1.13 ; python_version >= "3.9" and python_version < "3.12" -webencodings==0.5.1 ; python_version >= "3.9" and python_version < "3.12" -websocket-client==1.6.2 ; python_version >= "3.9" and python_version < "3.12" -widgetsnbextension==4.0.8 ; python_version >= "3.9" and python_version < "3.12" -xxhash==3.3.0 ; python_version >= "3.9" and python_version < "3.12" -zipp==3.16.2 ; python_version >= "3.9" and python_version < "3.12" +pyparsing==3.1.1 ; python_version >= "3.9" and python_version < "3.13" +pyright==1.1.341 ; python_version >= "3.9" and python_version < "3.13" +pytest==7.4.3 ; python_version >= "3.9" and python_version < "3.13" +pytest-cov==4.1.0 ; python_version >= "3.9" and python_version < "3.13" +pytest-xdist==3.5.0 ; python_version >= "3.9" and python_version < "3.13" +python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "3.13" +python-json-logger==2.0.7 ; python_version >= "3.9" and python_version < "3.13" +pytz==2023.3.post1 ; python_version >= "3.9" and python_version < "3.13" +pywin32==306 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.9" and python_version < "3.13" +pywin32-ctypes==0.2.2 ; python_version >= "3.9" and python_version < "3.13" and sys_platform == "win32" +pywinpty==2.0.12 ; python_version >= "3.9" and python_version < "3.13" and os_name == "nt" +pyyaml==6.0.1 ; python_version >= "3.9" and python_version < "3.13" +pyzmq==25.1.2 ; python_version >= "3.9" and python_version < "3.13" +qtconsole==5.5.1 ; python_version >= "3.9" and python_version < "3.13" +qtpy==2.4.1 ; python_version >= "3.9" and python_version < "3.13" +readme-renderer==42.0 ; python_version >= "3.9" and python_version < "3.13" +referencing==0.32.0 ; python_version >= "3.9" and python_version < "3.13" +requests==2.31.0 ; python_version >= "3.9" and python_version < "3.13" +requests-toolbelt==1.0.0 ; python_version >= "3.9" and python_version < "3.13" +restructuredtext-lint==1.4.0 ; python_version >= "3.9" and python_version < "3.13" +rfc3339-validator==0.1.4 ; python_version >= "3.9" and python_version < "3.13" +rfc3986==2.0.0 ; python_version >= "3.9" and python_version < "3.13" +rfc3986-validator==0.1.1 ; python_version >= "3.9" and python_version < "3.13" +rich==13.7.0 ; python_version >= "3.9" and python_version < "3.13" +rpds-py==0.14.1 ; python_version >= "3.9" and python_version < "3.13" +scipy==1.11.4 ; python_version >= "3.9" and python_version < "3.13" +secretstorage==3.3.3 ; python_version >= "3.9" and python_version < "3.13" and sys_platform == "linux" +send2trash==1.8.2 ; python_version >= "3.9" and python_version < "3.13" +setuptools==69.0.2 ; python_version >= "3.9" and python_version < "3.13" +six==1.16.0 ; python_version >= "3.9" and python_version < "3.13" +sniffio==1.3.0 ; python_version >= "3.9" and python_version < "3.13" +snowballstemmer==2.2.0 ; python_version >= "3.9" and python_version < "3.13" +soupsieve==2.5 ; python_version >= "3.9" and python_version < "3.13" +sphinx==7.2.6 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-applehelp==1.0.7 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-bibtex==2.6.1 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-devhelp==1.0.5 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-htmlhelp==2.0.4 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-jsmath==1.0.1 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-qthelp==1.0.6 ; python_version >= "3.9" and python_version < "3.13" +sphinxcontrib-serializinghtml==1.1.9 ; python_version >= "3.9" and python_version < "3.13" +stack-data==0.6.3 ; python_version >= "3.9" and python_version < "3.13" +terminado==0.18.0 ; python_version >= "3.9" and python_version < "3.13" +tinycss2==1.2.1 ; python_version >= "3.9" and python_version < "3.13" +toml==0.10.2 ; python_version >= "3.9" and python_version < "3.13" +tomli==2.0.1 ; python_version >= "3.9" and python_full_version <= "3.11.0a6" +tornado==6.4 ; python_version >= "3.9" and python_version < "3.13" +tqdm==4.66.1 ; python_version >= "3.9" and python_version < "3.13" +traitlets==5.14.0 ; python_version >= "3.9" and python_version < "3.13" +trimesh==3.23.5 ; python_version >= "3.9" and python_version < "3.13" +twine==4.0.2 ; python_version >= "3.9" and python_version < "3.13" +types-python-dateutil==2.8.19.14 ; python_version >= "3.9" and python_version < "3.13" +typing-extensions==4.9.0 ; python_version >= "3.9" and python_version < "3.13" +uri-template==1.3.0 ; python_version >= "3.9" and python_version < "3.13" +urllib3==2.1.0 ; python_version >= "3.9" and python_version < "3.13" +virtualenv==20.25.0 ; python_version >= "3.9" and python_version < "3.13" +wcwidth==0.2.12 ; python_version >= "3.9" and python_version < "3.13" +webcolors==1.13 ; python_version >= "3.9" and python_version < "3.13" +webencodings==0.5.1 ; python_version >= "3.9" and python_version < "3.13" +websocket-client==1.7.0 ; python_version >= "3.9" and python_version < "3.13" +widgetsnbextension==4.0.9 ; python_version >= "3.9" and python_version < "3.13" +xxhash==3.4.1 ; python_version >= "3.9" and python_version < "3.13" +zipp==3.17.0 ; python_version >= "3.9" and python_version < "3.13" diff --git a/tasks.py b/tasks.py index aee325c382..45c67d649b 100644 --- a/tasks.py +++ b/tasks.py @@ -5,23 +5,23 @@ from __future__ import annotations -import biblib.bib import contextlib import fnmatch +import inspect import os import re import uuid +import biblib.bib + import colour from colour.utilities import message_box -import inspect - if not hasattr(inspect, "getargspec"): inspect.getargspec = inspect.getfullargspec # pyright: ignore -from invoke.tasks import task from invoke.context import Context +from invoke.tasks import task __author__ = "Colour Developers" __copyright__ = "Copyright 2013 Colour Developers" @@ -37,6 +37,7 @@ "PYPI_PACKAGE_NAME", "PYPI_ARCHIVE_NAME", "BIBLIOGRAPHY_NAME", + "literalise", "clean", "formatting", "quality", @@ -66,6 +67,24 @@ BIBLIOGRAPHY_NAME: str = "BIBLIOGRAPHY.bib" +@task +def literalise(ctx: Context): + """ + Write various literals in the `colour.hints` module. + + Parameters + ---------- + ctx + Context. + """ + + message_box("Literalising...") + with ctx.cd("utilities"): + ctx.run("./literalise.py") + + ctx.run("pre-commit run --files colour/hints/__init__.py", warn=True) + + @task def clean( ctx: Context, @@ -334,7 +353,7 @@ def requirements(ctx: Context): ctx.run( "poetry export -f requirements.txt " "--without-hashes " - "--with dev,optional,graphviz,meshing,docs " + "--with dev,docs,graphviz,meshing,optional " "--output requirements.txt" ) @@ -342,12 +361,12 @@ def requirements(ctx: Context): ctx.run( "poetry export -f requirements.txt " "--without-hashes " - "--with optional,graphviz,meshing,docs " + "--with docs,graphviz,meshing,optional " "--output docs/requirements.txt" ) -@task(clean, preflight, docs, todo, requirements) +@task(literalise, clean, preflight, docs, todo, requirements) def build(ctx: Context): """ Build the project and runs dependency tasks, i.e. *docs*, *todo*, and @@ -372,6 +391,13 @@ def build(ctx: Context): readme_content = readme_file.read() with open("README.rst", "w") as readme_file: + # Adding the *Colour* logo as the first content line because the *raw* + # directive to support light and dark theme is later trimmed. + readme_content = ( + ".. image:: https://raw.githubusercontent.com/colour-science/" + "colour-branding/master/images/Colour_Logo_001.png\n" + + readme_content + ) readme_file.write( re.sub( ( @@ -437,7 +463,7 @@ def tag(ctx: Context): message_box("Tagging...") result = ctx.run("git rev-parse --abbrev-ref HEAD", hide="both") - if result.stdout.strip() == "develop": # pyright: ignore + if result.stdout.strip() != "develop": # pyright: ignore raise RuntimeError("Are you still on a feature or master branch?") with open(os.path.join(PYTHON_PACKAGE_NAME, "__init__.py")) as file_handle: diff --git a/utilities/generate_plots.py b/utilities/generate_plots.py index 020c073b52..13ae747ca9 100755 --- a/utilities/generate_plots.py +++ b/utilities/generate_plots.py @@ -10,19 +10,20 @@ mpl.use("AGG") +import os # noqa: E402 + import matplotlib.pyplot as plt # noqa: E402 import numpy as np # noqa: E402 -import os # noqa: E402 import trimesh # noqa: E402 import colour # noqa: E402 from colour.characterisation import SDS_COLOURCHECKERS # noqa: E402 from colour.colorimetry import ( # noqa: E402 + MSDS_CMFS_STANDARD_OBSERVER, SDS_ILLUMINANTS, - SDS_LIGHT_SOURCES, SDS_LEFS_PHOTOPIC, SDS_LEFS_SCOTOPIC, - MSDS_CMFS_STANDARD_OBSERVER, + SDS_LIGHT_SOURCES, SpectralDistribution, SpectralShape, sd_blackbody, @@ -30,17 +31,18 @@ sd_to_XYZ, ) from colour.geometry import primitive_cube # noqa: E402 +from colour.hints import cast # noqa: E402 from colour.io import read_image # noqa: E402 from colour.models import ( # noqa: E402 RGB_COLOURSPACE_sRGB, RGB_to_XYZ, - sRGB_to_XYZ, XYZ_to_sRGB, XYZ_to_xy, + sRGB_to_XYZ, ) from colour.plotting import ( # noqa: E402 - colour_style, ColourSwatch, + colour_style, plot_automatic_colour_conversion_graph, plot_blackbody_colours, plot_blackbody_spectral_radiance, @@ -63,9 +65,9 @@ plot_multi_lightness_functions, plot_multi_luminance_functions, plot_multi_munsell_value_functions, + plot_multi_sds, plot_multi_sds_colour_quality_scales_bars, plot_multi_sds_colour_rendering_indexes_bars, - plot_multi_sds, plot_planckian_locus_in_chromaticity_diagram_CIE1931, plot_planckian_locus_in_chromaticity_diagram_CIE1960UCS, plot_planckian_locus_in_chromaticity_diagram_CIE1976UCS, @@ -91,26 +93,26 @@ plot_single_lightness_function, plot_single_luminance_function, plot_single_munsell_value_function, + plot_single_sd, plot_single_sd_colour_quality_scale_bars, plot_single_sd_colour_rendering_index_bars, plot_single_sd_colour_rendition_report, plot_single_sd_rayleigh_scattering, - plot_single_sd, plot_the_blue_sky, plot_visible_spectrum, plot_visible_spectrum_section, render, ) from colour.plotting.diagrams import ( # noqa: E402 - plot_spectral_locus, - plot_chromaticity_diagram_colours, plot_chromaticity_diagram, + plot_chromaticity_diagram_colours, plot_sds_in_chromaticity_diagram, + plot_spectral_locus, ) from colour.plotting.models import ( # noqa: E402 - plot_RGB_colourspaces_in_chromaticity_diagram, - plot_RGB_chromaticities_in_chromaticity_diagram, plot_ellipses_MacAdam1942_in_chromaticity_diagram, + plot_RGB_chromaticities_in_chromaticity_diagram, + plot_RGB_colourspaces_in_chromaticity_diagram, ) from colour.plotting.quality import plot_colour_quality_bars # noqa: E402 from colour.plotting.section import ( # noqa: E402 @@ -123,10 +125,10 @@ plot_planckian_locus_in_chromaticity_diagram, ) from colour.quality import colour_quality_scale # noqa: E402 -from colour.utilities import ( # noqa: E402 +from colour.utilities import ( # noqa: E402; noqa: RUF100 domain_range_scale, filter_warnings, -) # noqa: RUF100 +) __copyright__ = "Copyright 2013 Colour Developers" __license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" @@ -1222,10 +1224,9 @@ def generate_documentation_plots(output_directory: str): arguments["filename"] = os.path.join( output_directory, "Tutorial_CIE_1931_Chromaticity_Diagram.png" ) - xy = XYZ_to_xy(XYZ) + xy = cast(tuple[float, float], XYZ_to_xy(XYZ)) plot_chromaticity_diagram_CIE1931(standalone=False) - x, y = xy - plt.plot(x, y, "o-", color="white") + plt.plot(xy[0], xy[1], "o-", color="white") # Annotating the plot. plt.annotate( patch_sd.name.title(), diff --git a/utilities/literalise.py b/utilities/literalise.py new file mode 100755 index 0000000000..b071099e84 --- /dev/null +++ b/utilities/literalise.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python +""" +Literalise +========== +""" + +from __future__ import annotations + +import os +import re +import sys +from textwrap import dedent + +import matplotlib.font_manager + +sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))) + +import colour # noqa: E402 + +__copyright__ = "Copyright 2013 Colour Developers" +__license__ = "BSD-3-Clause - https://opensource.org/licenses/BSD-3-Clause" +__maintainer__ = "Colour Developers" +__email__ = "colour-developers@colour-science.org" +__status__ = "Production" + +__all__ = [ + "PATH_MODULE_HINTS", + "literalise", +] + +PATH_MODULE_HINTS = os.path.join( + os.path.dirname(__file__), "..", "colour", "hints", "__init__.py" +) + + +def literalise(path_module_hints: str = PATH_MODULE_HINTS): + """ + Write various literals in the `colour.hints` module. + + Parameters + ---------- + path_module_hints + Path to the hints module. + """ + + with open(path_module_hints) as file_module_hints: + content = file_module_hints.read() + + font_scalings = [ + scaling + for scaling in matplotlib.font_manager.font_scalings + if scaling is not None + ] + + content = re.sub( + "# LITERALISE::BEGIN.*?# LITERALISE::END", + dedent( + f""" + # LITERALISE::BEGIN + LiteralChromaticAdaptationTransform = \ + Literal{sorted(colour.CHROMATIC_ADAPTATION_TRANSFORMS)} + LiteralColourspaceModel = Literal{sorted(colour.COLOURSPACE_MODELS)} + LiteralRGBColourspace = Literal{sorted(colour.RGB_COLOURSPACES.keys())} + LiteralLogEncoding = Literal{sorted(colour.LOG_ENCODINGS)} + LiteralLogDecoding = Literal{sorted(colour.LOG_DECODINGS)} + LiteralOETF = Literal{sorted(colour.OETFS)} + LiteralOETFInverse = Literal{sorted(colour.OETF_INVERSES)} + LiteralEOTF = Literal{sorted(colour.EOTFS)} + LiteralEOTFInverse = Literal{sorted(colour.EOTF_INVERSES)} + LiteralCCTFEncoding = Literal{sorted(colour.CCTF_ENCODINGS)} + LiteralCCTFDecoding = Literal{sorted(colour.CCTF_DECODINGS)} + LiteralOOTF = Literal{sorted(colour.OOTFS)} + LiteralOOTFInverse = Literal{sorted(colour.OOTF_INVERSES)} + LiteralLUTReadMethod = Literal{sorted(colour.io.LUT_READ_METHODS)} + LiteralLUTWriteMethod = Literal{sorted(colour.io.LUT_WRITE_METHODS)} + LiteralFontScaling = Literal{font_scalings} + # LITERALISE::END + """ + ).strip(), + content, + flags=re.DOTALL, + ) + + with open(path_module_hints, "w") as file_module_hints: + file_module_hints.write(content) + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + + literalise() diff --git a/utilities/mock_for_colour.py b/utilities/mock_for_colour.py index 346906c746..ccdffe27f7 100644 --- a/utilities/mock_for_colour.py +++ b/utilities/mock_for_colour.py @@ -4,17 +4,9 @@ Defines various mock objects to use with `Colour `__. - -References ----------- -- :cite:`SphinxTeam` : Sphinx Team. (n.d.). sphinx.ext.autodoc.mock. - Retrieved May 2, 2019, from https://github.com/sphinx-doc/sphinx/blob/\ -master/sphinx/ext/autodoc/mock.py """ -import os - -from types import FunctionType, MethodType, ModuleType +from unittest.mock import MagicMock __author__ = "Sphinx Team, Colour Developers" __copyright__ = "Copyright 2007-2019 - Sphinx Team" @@ -26,206 +18,10 @@ __status__ = "Production" __all__ = [ - "MockObject", - "MockModule", "mock_scipy_for_colour", ] -class MockObject: - """ - Mock an object to handle *Colour* requirements such as *Scipy*. - - Other Parameters - ---------------- - args - Arguments. - kwargs - Keywords arguments. - - References - ---------- - :cite:`SphinxTeam` - """ - - __display_name__ = "MockObject" - - def __new__(cls, *args, **kwargs): # noqa: ARG003 - """ - Return a new instance of the :class:`MockObject` class. - - Other Parameters - ---------------- - args - Arguments. - kwargs - Keywords arguments. - """ - - if len(args) == 3 and isinstance(args[1], tuple): - superclass = args[1][-1].__class__ - if superclass is cls: - return _make_subclass( - args[0], - superclass.__display_name__, - superclass=superclass, - attributes=args[2], - ) - - return super().__new__(cls) - - def __init__(self, *args, **kwargs): - pass - - def __len__(self): - """Return the length of the :class:`MockObject` class instance, i.e. 0.""" - - return 0 - - def __contains__(self, key): - """ - Return whether the :class:`MockObject` class instance contains given - key. - - Parameters - ---------- - key - Key to check whether is contained in the :class:`MockObject` - class instance. - """ - - return False - - def __iter__(self): - """Iterate over the :class:`MockObject` class instance.""" - - return iter([]) - - def __mro_entries__(self, bases): - """ - If an object that is not a class object appears in the tuple of bases - of a class definition, then method __mro_entries__ is searched on it. - """ - - return (self.__class__,) - - def __getitem__(self, key): - """ - Return the value at given key from the :class:`MockObject` class - instance. - - Parameters - ---------- - key - Key to return the value at. - """ - - return _make_subclass(key, self.__display_name__, self.__class__)() - - def __getattr__(self, key): - """ - Return the attribute at given key from the :class:`MockObject` class - instance. - - Parameters - ---------- - key - Key to return the attribute at. - """ - - return _make_subclass(key, self.__display_name__, self.__class__)() - - def __call__(self, *args, **kwargs): # noqa: ARG002 - """ - Call the :class:`MockObject` class instance. - - Other Parameters - ---------------- - args - Arguments. - kwargs - Keywords arguments. - """ - - if args and type(args[0]) in [FunctionType, MethodType]: - return args[0] - - return self - - def __repr__(self): - """ - Return an evaluable string representation of the :class:`MockObject` - class instance. - """ - - return self.__display_name__ - - -def _make_subclass(name, module, superclass=MockObject, attributes=None): - """ - Produce sub-classes of given super-class type. - - Parameters - ---------- - name - Name of the sub-class. - module - Name of the sub-class module. - superclass - Super-class type. - attributes - Attributes to set the sub-class with. - """ # noqa: D405, D407, D410, D411 - - attrs = {"__module__": module, "__display_name__": module + "." + name} - attrs.update(attributes or {}) - - return type(name, (superclass,), attrs) - - -class MockModule(ModuleType): - """ - A mock object used to mock modules. - - Parameters - ---------- - name - Name of the mocked module. - - References - ---------- - :cite:`SphinxTeam` - """ - - __file__ = os.devnull - - def __init__(self, name): - super().__init__(name) - self.__all__ = [] - self.__path__ = [] - - def __getattr__(self, name): - """ - Return the attribute at given name from the :class:`MockModule` class - instance. - - Parameters - ---------- - name - Name to return the attribute at. - """ - - return _make_subclass(name, self.__name__)() - - def __repr__(self): - """ - Return an evaluable string representation of the :class:`MockModule` - class instance. - """ - - return self.__name__ - - def mock_scipy_for_colour(): """Mock *Scipy* for *Colour*.""" @@ -236,26 +32,15 @@ def mock_scipy_for_colour(): "scipy.interpolate", "scipy.linalg", "scipy.ndimage", + "scipy.optimize", "scipy.spatial", "scipy.spatial.distance", - "scipy.optimize", ): - sys.modules[str(module)] = MockModule(str(module)) + sys.modules[module] = MagicMock() if __name__ == "__main__": - import sys - - for module in ( - "scipy", - "scipy.interpolate", - "scipy.linalg", - "scipy.ndimage", - "scipy.spatial", - "scipy.spatial.distance", - "scipy.optimize", - ): - sys.modules[str(module)] = MockModule(str(module)) + mock_scipy_for_colour() import colour