Skip to content

Commit

Permalink
adc: optimize replacement of NaNs.
Browse files Browse the repository at this point in the history
When converting physical to digital sample arrays, we must replace NaN
values with the appropriate invalid-sample sentinel value.

To do this, we need to call np.isnan and use the result as a mask to
replace entries in the output array.  (Although the function
np.nan_to_num also exists, it's less efficient: it literally does just
this, but also handles infinities.)

What we don't need to do is to call any() to check whether there are
any true entries - that just means we're iterating through the same
array three times rather than once.  Furthermore, np.copyto can
broadcast d_nans across the rows of p_signal, so all the channels can
be handled at once.

Also use copyto in adc_inplace_1d for consistency.
  • Loading branch information
Benjamin Moody committed Apr 18, 2024
1 parent 5a05f7a commit e013d5b
Showing 1 changed file with 2 additions and 5 deletions.
7 changes: 2 additions & 5 deletions wfdb/io/_signal.py
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,7 @@ def adc_inplace_1d(ch_p_signal, adc_gain, baseline, d_nan):
np.multiply(ch_p_signal, adc_gain, ch_p_signal)
np.add(ch_p_signal, baseline, ch_p_signal)
np.round(ch_p_signal, 0, ch_p_signal)
ch_p_signal[ch_nanlocs] = d_nan
np.copyto(ch_p_signal, d_nan, where=ch_nanlocs)
ch_d_signal = ch_p_signal.astype(intdtype, copy=False)
return ch_d_signal

Expand All @@ -550,10 +550,7 @@ def adc_inplace_2d(p_signal):
np.multiply(p_signal, self.adc_gain, p_signal)
np.add(p_signal, self.baseline, p_signal)
np.round(p_signal, 0, p_signal)
if nanlocs.any():
for ch in range(p_signal.shape[1]):
if nanlocs[:, ch].any():
p_signal[nanlocs[:, ch], ch] = d_nans[ch]
np.copyto(p_signal, d_nans, where=nanlocs)
d_signal = p_signal.astype(intdtype, copy=False)
return d_signal

Expand Down

0 comments on commit e013d5b

Please sign in to comment.