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 -------
@@ -130,6 +147,29 @@ def generate_pulse_waves(bins, pulse_order='Bins'):
130147 [ 1., 1., 1., 0., 1.],
131148 [ 1., 1., 1., 1., 1.]])
132149 >>> generate_pulse_waves(5, 'Pulse Wave Width')
150+ array([[ 0., 0., 0., 0., 0.],
151+ [ 1., 0., 0., 0., 0.],
152+ [ 1., 1., 0., 0., 0.],
153+ [ 1., 1., 0., 0., 1.],
154+ [ 1., 1., 1., 0., 1.],
155+ [ 0., 1., 0., 0., 0.],
156+ [ 0., 1., 1., 0., 0.],
157+ [ 1., 1., 1., 0., 0.],
158+ [ 1., 1., 1., 1., 0.],
159+ [ 0., 0., 1., 0., 0.],
160+ [ 0., 0., 1., 1., 0.],
161+ [ 0., 1., 1., 1., 0.],
162+ [ 0., 1., 1., 1., 1.],
163+ [ 0., 0., 0., 1., 0.],
164+ [ 0., 0., 0., 1., 1.],
165+ [ 0., 0., 1., 1., 1.],
166+ [ 1., 0., 1., 1., 1.],
167+ [ 0., 0., 0., 0., 1.],
168+ [ 1., 0., 0., 0., 1.],
169+ [ 1., 0., 0., 1., 1.],
170+ [ 1., 1., 0., 1., 1.],
171+ [ 1., 1., 1., 1., 1.]])
172+ >>> generate_pulse_waves(5, 'Pulse Wave Width', True)
133173 array([[ 0., 0., 0., 0., 0.],
134174 [ 1., 0., 0., 0., 0.],
135175 [ 1., 1., 0., 0., 0.],
@@ -167,6 +207,9 @@ def generate_pulse_waves(bins, pulse_order='Bins'):
167207 for j , square_wave_basis in enumerate (square_waves_basis ):
168208 square_waves .append (np .roll (square_wave_basis , i - j // 2 ))
169209
210+ if filter_jagged_pulses :
211+ square_waves = square_waves [::2 ]
212+
170213 return np .vstack ([
171214 zeros (bins ),
172215 np .vstack (square_waves ),
@@ -178,6 +221,7 @@ def XYZ_outer_surface(cmfs=MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
178221 .copy ().align (SPECTRAL_SHAPE_OUTER_SURFACE_XYZ ),
179222 illuminant = sd_ones (SPECTRAL_SHAPE_OUTER_SURFACE_XYZ ),
180223 point_order = 'Bins' ,
224+ filter_jagged_points = False ,
181225 ** kwargs ):
182226 """
183227 Generates the *Rösch-MacAdam* colour solid, i.e. *CIE XYZ* colourspace
@@ -192,10 +236,28 @@ def XYZ_outer_surface(cmfs=MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
192236 Illuminant spectral distribution.
193237 point_order : unicode, optional
194238 **{'Bins', 'Pulse Wave Width'}**,
195- Method for ordering the pulse waves. *Bins* is the default order, with
239+ Method for ordering the underlying pulse waves used to generate the
240+ *Rösch-MacAdam* colour solid. *Bins* is the default order, with
196241 *Pulse Wave Width* ordering, instead of iterating over the pulse wave
197242 widths first, iteration occurs over the bins, producing blocks of pulse
198243 waves with increasing width.
244+ filter_jagged_points : bool, optional
245+ Whether to filter the underlying jagged pulses. When ``point_order`` is
246+ set to *Pulse Wave Width*, the pulses are ordered by increasing width.
247+ Because of the discrete nature of the underlying signal, the resulting
248+ pulses will be jagged. For example assuming 5 bins, the center block
249+ with the two extreme values added would be as follows::
250+
251+ 0 0 0 0 0
252+ 0 0 1 0 0
253+ 0 0 1 1 0 <--
254+ 0 1 1 1 0
255+ 0 1 1 1 1 <--
256+ 1 1 1 1 1
257+
258+ Setting the ``filter_jagged_points`` parameter to `True` will result
259+ in the removal of the two marked pulses above which avoid jagged lines
260+ when plotting and having to resort to excessive ``bins`` values.
199261
200262 Other Parameters
201263 ----------------
@@ -257,11 +319,13 @@ def XYZ_outer_surface(cmfs=MSDS_CMFS['CIE 1931 2 Degree Standard Observer']
257319 settings = {'method' : 'Integration' , 'shape' : cmfs .shape }
258320 settings .update (kwargs )
259321
260- key = (hash (cmfs ), hash (illuminant ), point_order , str (settings ))
322+ key = (hash (cmfs ), hash (illuminant ), point_order , filter_jagged_points ,
323+ str (settings ))
261324 XYZ = _CACHE_OUTER_SURFACE_XYZ .get (key )
262325
263326 if XYZ is None :
264- pulse_waves = generate_pulse_waves (len (cmfs .wavelengths ), point_order )
327+ pulse_waves = generate_pulse_waves (
328+ len (cmfs .wavelengths ), point_order , filter_jagged_points )
265329 XYZ = msds_to_XYZ (pulse_waves , cmfs , illuminant , ** settings ) / 100
266330
267331 _CACHE_OUTER_SURFACE_XYZ [key ] = XYZ
0 commit comments