Source code for colour_datasets.loaders.ebner1998

"""
Constant Perceived-Hue Data - Ebner and Fairchild (1998)
========================================================

Defines the objects implementing support for *Ebner and Fairchild (1998)*
*Constant Perceived-Hue Data* dataset loading:

-   :class:`colour_datasets.loaders.DatasetLoader_Ebner1998`
-   :func:`colour_datasets.loaders.build_Ebner1998`

References
----------
-   :cite:`Ebner1998` : Ebner, F., & Fairchild, M. D. (1998). Finding constant
    hue surfaces in color space. In G. B. Beretta & R. Eschbach (Eds.), Proc.
    SPIE 3300, Color Imaging: Device-Independent Color, Color Hardcopy, and
    Graphic Arts III, (2 January 1998) (pp. 107-117). doi:10.1117/12.298269
"""

from __future__ import annotations

import codecs
import os
from collections import namedtuple

import numpy as np
from colour.hints import Dict, NDArrayFloat
from colour.utilities import as_float_array

from colour_datasets.loaders import AbstractDatasetLoader
from colour_datasets.records import datasets

__author__ = "Colour Developers"
__copyright__ = "Copyright 2019 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__ = [
    "ConstantPerceivedHueColourMatches_Ebner1998",
    "DatasetLoader_Ebner1998",
    "build_Ebner1998",
]


class ConstantPerceivedHueColourMatches_Ebner1998(
    namedtuple(
        "ConstantPerceivedHueColourMatches_Ebner1998",
        ("name", "XYZ_r", "XYZ_cr", "XYZ_ct", "metadata"),
    )
):
    """
    Define *Ebner and Fairchild (1998)* *Constant Perceived-Hue Data*
    colour matches data for a given hue angle.

    Parameters
    ----------
    name
        *Ebner and Fairchild (1998)* *Constant Perceived-Hue Data* hue angle or
        name.
    XYZ_r
        *CIE XYZ* tristimulus values of the reference illuminant.
    XYZ_cr
        *CIE XYZ* tristimulus values of the reference colour under the
        reference illuminant.
    XYZ_ct
        *CIE XYZ* tristimulus values of the colour matches under the reference
        illuminant.
    metadata
        Dataset metadata.
    """


[docs] class DatasetLoader_Ebner1998(AbstractDatasetLoader): """ Define the *Ebner and Fairchild (1998)* *Constant Perceived-Hue Data* dataset loader. Attributes ---------- - :attr:`colour_datasets.loaders.DatasetLoader_Ebner1998.ID` Methods ------- - :meth:`colour_datasets.loaders.DatasetLoader_Ebner1998.__init__` - :meth:`colour_datasets.loaders.DatasetLoader_Ebner1998.load` References ---------- :cite:`Ebner1998` """ ID: str = "3362536" """Dataset record id, i.e. the *Zenodo* record number.""" def __init__(self) -> None: super().__init__(datasets()[DatasetLoader_Ebner1998.ID])
[docs] def load( self, ) -> Dict[str, Dict[int, ConstantPerceivedHueColourMatches_Ebner1998]]: """ Sync, parse, convert and return the *Ebner and Fairchild (1998)* *Constant Perceived-Hue Data* dataset content. Returns ------- :class:`dict` *Ebner and Fairchild (1998)* Constant Perceived-Hue Data* dataset content. Examples -------- >>> from colour_datasets.utilities import suppress_stdout >>> dataset = DatasetLoader_Ebner1998() >>> with suppress_stdout(): ... dataset.load() >>> len(dataset.content.keys()) 1 """ super().sync() self._content = {"Constant Perceived-Hue Data": {}} datafile_path = os.path.join( self.record.repository, "dataset", "Ebner_Constant_Hue_Data.txt" ) def _parse_float_values(data: str) -> NDArrayFloat: """Parse float values from given data.""" values = np.reshape( as_float_array([float(x) / 100 for x in data.split("\t") if x]), (-1, 3), ) return np.squeeze(values) with codecs.open(datafile_path, encoding="utf-8") as database_file: lines = filter(None, (line.strip() for line in database_file.readlines())) for line in lines: if line.startswith("White Point"): XYZ_r = _parse_float_values(line.split(":")[-1]) elif line.startswith("reference hue"): line = line.replace("reference hue ", "") # noqa: PLW2901 attribute, value = line.split("\t", 1) hue, data = int(attribute), _parse_float_values(value) self._content["Constant Perceived-Hue Data"][ hue ] = ConstantPerceivedHueColourMatches_Ebner1998( f"Reference Hue Angle - {hue}", XYZ_r, data[0], data[1:], {"h": hue}, ) return self._content
_DATASET_LOADER_EBNER1998: DatasetLoader_Ebner1998 | None = None """ Singleton instance of the *Ebner and Fairchild (1998)* *Constant Perceived-Hue Data* dataset loader. """
[docs] def build_Ebner1998(load: bool = True) -> DatasetLoader_Ebner1998: """ Singleton factory that builds the *Ebner and Fairchild (1998)* *Constant Perceived-Hue Data* dataset loader. Parameters ---------- load Whether to load the dataset upon instantiation. Returns ------- :class:`colour_datasets.loaders.DatasetLoader_Ebner1998` Singleton instance of the *Ebner and Fairchild (1998)* *Constant Perceived-Hue Data* dataset loader. References ---------- :cite:`Ebner1998` """ global _DATASET_LOADER_EBNER1998 # noqa: PLW0603 if _DATASET_LOADER_EBNER1998 is None: _DATASET_LOADER_EBNER1998 = DatasetLoader_Ebner1998() if load: _DATASET_LOADER_EBNER1998.load() return _DATASET_LOADER_EBNER1998