Skip to content

Commit b5961d7

Browse files
committed
Ensure that jagged pulses generated by "colour.volume.generate_pulse_waves" definition can be easily filtered.
1 parent 2c27d42 commit b5961d7

File tree

2 files changed

+75
-4
lines changed

2 files changed

+75
-4
lines changed

colour/volume/spectrum.py

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
_CACHE_OUTER_SURFACE_XYZ_POINTS = {}
5353

5454

55-
def generate_pulse_waves(bins, pulse_order='Bins'):
55+
def generate_pulse_waves(bins, pulse_order='Bins', filter_jagged_pulses=False):
5656
"""
5757
Generates the pulse waves of given number of bins necessary to totally
5858
stimulate the colour matching functions and produce the *Rösch-MacAdam*
@@ -94,6 +94,23 @@ def generate_pulse_waves(bins, pulse_order='Bins'):
9494
*Pulse Wave Width* ordering, instead of iterating over the pulse wave
9595
widths first, iteration occurs over the bins, producing blocks of pulse
9696
waves with increasing width.
97+
filter_jagged_pulses : bool, optional
98+
Whether to filter jagged pulses. When ``pulse_order`` is set to
99+
*Pulse Wave Width*, the pulses are ordered by increasing width. Because
100+
of the discrete nature of the underlying signal, the resulting pulses
101+
will be jagged. For example assuming 5 bins, the center block with
102+
the two extreme values added would be as follows::
103+
104+
0 0 0 0 0
105+
0 0 1 0 0
106+
0 0 1 1 0 <--
107+
0 1 1 1 0
108+
0 1 1 1 1 <--
109+
1 1 1 1 1
110+
111+
Setting the ``filter_jagged_pulses`` parameter to `True` will result
112+
in the removal of the two marked pulses above which avoid jagged lines
113+
when plotting and having to resort to excessive ``bins`` values.
97114
98115
Returns
99116
-------
@@ -152,6 +169,19 @@ def generate_pulse_waves(bins, pulse_order='Bins'):
152169
[ 1., 0., 0., 1., 1.],
153170
[ 1., 1., 0., 1., 1.],
154171
[ 1., 1., 1., 1., 1.]])
172+
>>> generate_pulse_waves(5, 'Pulse Wave Width', True)
173+
array([[ 0., 0., 0., 0., 0.],
174+
[ 1., 0., 0., 0., 0.],
175+
[ 1., 1., 0., 0., 1.],
176+
[ 0., 1., 0., 0., 0.],
177+
[ 1., 1., 1., 0., 0.],
178+
[ 0., 0., 1., 0., 0.],
179+
[ 0., 1., 1., 1., 0.],
180+
[ 0., 0., 0., 1., 0.],
181+
[ 0., 0., 1., 1., 1.],
182+
[ 0., 0., 0., 0., 1.],
183+
[ 1., 0., 0., 1., 1.],
184+
[ 1., 1., 1., 1., 1.]])
155185
"""
156186

157187
square_waves = []
@@ -167,6 +197,9 @@ def generate_pulse_waves(bins, pulse_order='Bins'):
167197
for j, square_wave_basis in enumerate(square_waves_basis):
168198
square_waves.append(np.roll(square_wave_basis, i - j // 2))
169199

200+
if filter_jagged_pulses:
201+
square_waves = square_waves[::2]
202+
170203
return np.vstack([
171204
zeros(bins),
172205
np.vstack(square_waves),
@@ -178,6 +211,7 @@ def XYZ_outer_surface(cmfs=MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
178211
.copy().align(SPECTRAL_SHAPE_OUTER_SURFACE_XYZ),
179212
illuminant=sd_ones(SPECTRAL_SHAPE_OUTER_SURFACE_XYZ),
180213
point_order='Bins',
214+
filter_jagged_points=False,
181215
**kwargs):
182216
"""
183217
Generates the *Rösch-MacAdam* colour solid, i.e. *CIE XYZ* colourspace
@@ -192,10 +226,28 @@ def XYZ_outer_surface(cmfs=MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
192226
Illuminant spectral distribution.
193227
point_order : unicode, optional
194228
**{'Bins', 'Pulse Wave Width'}**,
195-
Method for ordering the pulse waves. *Bins* is the default order, with
229+
Method for ordering the underlying pulse waves used to generate the
230+
*Rösch-MacAdam* colour solid. *Bins* is the default order, with
196231
*Pulse Wave Width* ordering, instead of iterating over the pulse wave
197232
widths first, iteration occurs over the bins, producing blocks of pulse
198233
waves with increasing width.
234+
filter_jagged_points : bool, optional
235+
Whether to filter the underlying jagged pulses. When ``point_order`` is
236+
set to *Pulse Wave Width*, the pulses are ordered by increasing width.
237+
Because of the discrete nature of the underlying signal, the resulting
238+
pulses will be jagged. For example assuming 5 bins, the center block
239+
with the two extreme values added would be as follows::
240+
241+
0 0 0 0 0
242+
0 0 1 0 0
243+
0 0 1 1 0 <--
244+
0 1 1 1 0
245+
0 1 1 1 1 <--
246+
1 1 1 1 1
247+
248+
Setting the ``filter_jagged_points`` parameter to `True` will result
249+
in the removal of the two marked pulses above which avoid jagged lines
250+
when plotting and having to resort to excessive ``bins`` values.
199251
200252
Other Parameters
201253
----------------
@@ -257,11 +309,13 @@ def XYZ_outer_surface(cmfs=MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
257309
settings = {'method': 'Integration', 'shape': cmfs.shape}
258310
settings.update(kwargs)
259311

260-
key = (hash(cmfs), hash(illuminant), point_order, str(settings))
312+
key = (hash(cmfs), hash(illuminant), point_order, filter_jagged_points,
313+
str(settings))
261314
XYZ = _CACHE_OUTER_SURFACE_XYZ.get(key)
262315

263316
if XYZ is None:
264-
pulse_waves = generate_pulse_waves(len(cmfs.wavelengths), point_order)
317+
pulse_waves = generate_pulse_waves(
318+
len(cmfs.wavelengths), point_order, filter_jagged_points)
265319
XYZ = msds_to_XYZ(pulse_waves, cmfs, illuminant, **settings) / 100
266320

267321
_CACHE_OUTER_SURFACE_XYZ[key] = XYZ

colour/volume/tests/test_spectrum.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,23 @@ def test_generate_pulse_waves(self):
9696
np.sort(generate_pulse_waves(5), axis=0),
9797
np.sort(generate_pulse_waves(5, 'Pulse Wave Width'), axis=0))
9898

99+
np.testing.assert_array_equal(
100+
generate_pulse_waves(5, 'Pulse Wave Width', True),
101+
np.array([
102+
[0.0, 0.0, 0.0, 0.0, 0.0],
103+
[1.0, 0.0, 0.0, 0.0, 0.0],
104+
[1.0, 1.0, 0.0, 0.0, 1.0],
105+
[0.0, 1.0, 0.0, 0.0, 0.0],
106+
[1.0, 1.0, 1.0, 0.0, 0.0],
107+
[0.0, 0.0, 1.0, 0.0, 0.0],
108+
[0.0, 1.0, 1.0, 1.0, 0.0],
109+
[0.0, 0.0, 0.0, 1.0, 0.0],
110+
[0.0, 0.0, 1.0, 1.0, 1.0],
111+
[0.0, 0.0, 0.0, 0.0, 1.0],
112+
[1.0, 0.0, 0.0, 1.0, 1.0],
113+
[1.0, 1.0, 1.0, 1.0, 1.0],
114+
]))
115+
99116

100117
class TestXYZOuterSurface(unittest.TestCase):
101118
"""

0 commit comments

Comments
 (0)