Source code for colour.io.xrite
"""
X-Rite Data Input
=================
Define the input object for *X-Rite* spectral data files:
- :func:`colour.read_sds_from_xrite_file`
"""
from __future__ import annotations
import codecs
import re
from pathlib import Path
from colour.colorimetry import SpectralDistribution
from colour.hints import Dict
__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__ = [
"XRITE_FILE_ENCODING",
"read_sds_from_xrite_file",
]
XRITE_FILE_ENCODING: str = "utf-8"
[docs]
def read_sds_from_xrite_file(
path: str | Path,
) -> Dict[str, SpectralDistribution]:
"""
Read the spectral data from given *X-Rite* file and returns it as a
*dict* of :class:`colour.SpectralDistribution` class instances.
Parameters
----------
path
Absolute *X-Rite* file path.
Returns
-------
:class:`dict`
*dict* of :class:`colour.SpectralDistribution` class instances.
Notes
-----
- This parser is minimalistic and absolutely not bullet-proof.
Examples
--------
>>> import os
>>> from pprint import pprint
>>> xrite_file = os.path.join(
... os.path.dirname(__file__),
... "tests",
... "resources",
... "X-Rite_Digital_Colour_Checker.txt",
... )
>>> sds_data = read_sds_from_xrite_file(xrite_file)
>>> pprint(list(sds_data.keys())) # doctest: +SKIP
['X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9', 'X10']
"""
path = str(path)
with codecs.open(path, encoding=XRITE_FILE_ENCODING) as xrite_file:
lines = xrite_file.read().strip().split("\n")
index = 0
xrite_sds = {}
is_spectral_data_format, is_spectral_data = False, False
for line in lines:
line = line.strip() # noqa: PLW2901
if line == "END_DATA_FORMAT":
is_spectral_data_format = False
if line == "END_DATA":
is_spectral_data = False
if is_spectral_data_format:
wavelengths = list(re.findall("nm(\\d+)", line))
index = len(wavelengths)
if is_spectral_data:
tokens = line.split()
xrite_sds[tokens[1]] = SpectralDistribution(
tokens[-index:], wavelengths, name=tokens[1]
)
if line == "BEGIN_DATA_FORMAT":
is_spectral_data_format = True
if line == "BEGIN_DATA":
is_spectral_data = True
return xrite_sds