Skip to content

Commit

Permalink
Ensure that spectral distribution not starting or ending on a tenth w…
Browse files Browse the repository at this point in the history
…avelength and having an interval of 10 or 20 can be integrated using practise "ASTM E308-15".
  • Loading branch information
KelSolaar committed Jun 29, 2023
1 parent b7ec8aa commit 1dbda61
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 5 deletions.
5 changes: 5 additions & 0 deletions colour/colorimetry/spectrum.py
Original file line number Diff line number Diff line change
Expand Up @@ -1590,6 +1590,11 @@ def trim(self, shape: SpectralShape) -> Self:
self.wavelengths = wavelengths
self.values = values

if self.shape.boundaries != shape.boundaries:
runtime_warning(
f'"{shape}" shape could not be honoured, using "{self.shape}"!'
)

return self

def normalise(self, factor: Real = 1) -> Self:
Expand Down
21 changes: 21 additions & 0 deletions colour/colorimetry/tests/test_tristimulus_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,17 @@ def test_sd_to_XYZ_ASTME308_mi_10nm(self):
decimal=7,
)

np.testing.assert_array_almost_equal(
sd_to_XYZ_ASTME308(
reshape_sd(self._sd, SpectralShape(401, 701, 10)),
self._cmfs,
self._A,
k=1,
),
np.array([15.6713226093, 11.7392254489, 2.2117708792]),
decimal=7,
)

def test_sd_to_XYZ_ASTME308_mi_20nm(self):
"""
Test :func:`colour.colorimetry.tristimulus_values.sd_to_XYZ_ASTME308`
Expand Down Expand Up @@ -1310,6 +1321,16 @@ def test_sd_to_XYZ_ASTME308_mi_20nm(self):
decimal=7,
)

np.testing.assert_array_almost_equal(
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,
)

def test_raise_exception_sd_to_XYZ_ASTME308(self):
"""
Test :func:`colour.colorimetry.tristimulus_values.sd_to_XYZ_ASTME308`
Expand Down
32 changes: 27 additions & 5 deletions colour/colorimetry/tristimulus_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ def sd_to_XYZ_tristimulus_weighting_factors_ASTME308(

if sd.shape.boundaries != cmfs.shape.boundaries:
runtime_warning(
f'Trimming "{illuminant.name}" spectral distribution shape to '
f'Trimming "{sd.name}" spectral distribution boundaries using '
f'"{cmfs.name}" colour matching functions shape.'
)
sd = reshape_sd(sd, cmfs.shape, "Trim", copy=False)
Expand All @@ -875,6 +875,7 @@ def sd_to_XYZ_tristimulus_weighting_factors_ASTME308(
W = adjust_tristimulus_weighting_factors_ASTME308(
W, SpectralShape(start_w, end_w, sd.shape.interval), sd.shape
)

R = sd.values

XYZ = np.sum(W * R[..., None], axis=0)
Expand Down Expand Up @@ -1010,6 +1011,18 @@ def sd_to_XYZ_ASTME308(
"with measurement interval of 1, 5, 10 or 20nm!"
)

if sd.shape.interval in (10, 20) and (
sd.shape.start % 10 != 0 or sd.shape.end % 10 != 0
):
runtime_warning(
f'"{sd.name}" spectral distribution shape does not start at a '
f'tenth and will be aligned to "{cmfs.name}" colour matching '
'functions shape! Note that practise "ASTM E308-15" does not '
"define a behaviour in this case."
)

sd = reshape_sd(sd, cmfs.shape, copy=False)

if use_practice_range:
# pylint: disable=E1102
cmfs = reshape_msds(cmfs, SPECTRAL_SHAPE_ASTME308, "Trim", copy=False)
Expand All @@ -1031,13 +1044,17 @@ def sd_to_XYZ_ASTME308(
sd = sd.copy()
if sd.shape.boundaries != cmfs.shape.boundaries:
runtime_warning(
f'Trimming "{illuminant.name}" spectral distribution shape to '
f'Trimming "{sd.name}" spectral distribution shape to '
f'"{cmfs.name}" colour matching functions shape.'
)
sd.trim(cmfs.shape)
sd = reshape_sd(sd, cmfs.shape, "Trim", copy=False)

# Extrapolation of additional 20nm padding intervals.
sd.align(SpectralShape(sd.shape.start - 20, sd.shape.end + 20, 10))
sd = reshape_sd(
sd,
SpectralShape(sd.shape.start - 20, sd.shape.end + 20, 10),
copy=False,
)
for i in range(2):
sd[sd.wavelengths[i]] = (
3 * sd.values[i + 2] - 3 * sd.values[i + 4] + sd.values[i + 6]
Expand All @@ -1060,7 +1077,12 @@ def sd_to_XYZ_ASTME308(
)

# Discarding the additional 20nm padding intervals.
sd.trim(SpectralShape(sd.shape.start + 20, sd.shape.end - 20, 10))
sd = reshape_sd(
sd,
SpectralShape(sd.shape.start + 20, sd.shape.end - 20, 10),
"Trim",
copy=False,
)

XYZ = method(sd, cmfs, illuminant, k=k)

Expand Down

0 comments on commit 1dbda61

Please sign in to comment.