Coverage for io/xrite.py: 62%

1"""

2 X-Rite Data Input

3=================

4

5 Define input functionality for X-Rite spectral data files.

6

7- :func:`colour.read_sds_from_xrite_file`

8"""

9

10 from __future__ import annotations

11

12 import codecs

13 import re

14 import typing

15

16 from colour.colorimetry import SpectralDistribution

17

18 if typing.TYPE_CHECKING:

19 from colour.hints import Dict, PathLike

20

21 __author__ = "Colour Developers"

22 __copyright__ = "Copyright 2013 Colour Developers"

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

24 __maintainer__ = "Colour Developers"

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

26 __status__ = "Production"

27

28 __all__ = [

29 "XRITE_FILE_ENCODING",

30 "read_sds_from_xrite_file",

31]

32

33 XRITE_FILE_ENCODING: str = "utf-8"

34

35

36 def read_sds_from_xrite_file(

37 path: str | PathLike,

38) -> Dict[str, SpectralDistribution]:

39 """

40 Read spectral data from the specified *X-Rite* file and convert it to a

41 *dict* of :class:`colour.SpectralDistribution` class instances.

42

43 Parameters

44 ----------

45 path

46 Absolute *X-Rite* file path.

47

48 Returns

49 -------

50 :class:`dict`

51 *dict* of :class:`colour.SpectralDistribution` class instances.

52

53 Raises

54 ------

55 IOError

56 If the file cannot be read.

57

58 Notes

59 -----

60 - This parser is minimalistic and absolutely not bullet-proof.

61

62 Examples

63 --------

64 >>> import os

65 >>> from pprint import pprint

66 >>> xrite_file = os.path.join(

67 ... os.path.dirname(__file__),

68 ... "tests",

69 ... "resources",

70 ... "X-Rite_Digital_Colour_Checker.txt",

71 ... )

72 >>> sds_data = read_sds_from_xrite_file(xrite_file)

73 >>> pprint(list(sds_data.keys())) # doctest: +SKIP

74 ['X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X9', 'X10']

75 """

76

77 path = str(path)

78

79 with codecs.open(path, encoding=XRITE_FILE_ENCODING) as xrite_file:

80 lines = xrite_file.read().strip().split("\n")

81

82 index = 0

83 xrite_sds = {}

84 is_spectral_data_format, is_spectral_data = False, False

85 for line in lines:

86 line = line.strip() # noqa: PLW2901

87

88 if line == "END_DATA_FORMAT":

89 is_spectral_data_format = False

90

91 if line == "END_DATA":

92 is_spectral_data = False

93

94 if is_spectral_data_format:

95 wavelengths = list(re.findall("nm(\\d+)", line))

96 index = len(wavelengths)

97

98 if is_spectral_data:

99 tokens = line.split()

100 xrite_sds[tokens[1]] = SpectralDistribution(

101 tokens[-index:], wavelengths, name=tokens[1]

102 )

103

104 if line == "BEGIN_DATA_FORMAT":

105 is_spectral_data_format = True

106

107 if line == "BEGIN_DATA":

108 is_spectral_data = True

109

110 return xrite_sds