Skip to content

Commit 6bede91

Browse files
author
Benjamin Moody
committed
_rd_dat_signals: fix conversion of format 8.
In signal format 8, each sample is stored as an 8-bit signed difference from the previous sample. This means that after reading the raw byte values, they must be translated to absolute sample values by calling cumsum() and adding the initial value.
1 parent ce1834d commit 6bede91

File tree

1 file changed

+26
-0
lines changed

1 file changed

+26
-0
lines changed

wfdb/io/_signal.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1182,6 +1182,32 @@ def _rd_dat_signals(file_name, dir_name, pn_dir, fmt, n_sig, sig_len,
11821182
elif fmt == '160':
11831183
sig_data = (sig_data.astype('int32') - 32768).astype('int16')
11841184

1185+
# For format 8, convert sample differences to absolute samples. Note
1186+
# that if sampfrom is not 0, the results will be wrong, since we can't
1187+
# know the starting value without reading the entire record from the
1188+
# beginning - an inherent limitation of the format, and the use of
1189+
# format 8 is discouraged for this reason! However, the following is
1190+
# consistent with the behavior of the WFDB library: the initial value
1191+
# specified by the header file is used as the starting sample value,
1192+
# regardless of where in the record we begin reading. Therefore, the
1193+
# following should give the same results as rdsamp.
1194+
if fmt == '8':
1195+
dif_frames = sig_data.reshape(-1, tsamps_per_frame)
1196+
abs_frames = np.empty(dif_frames.shape, dtype='int32')
1197+
ch_start = 0
1198+
for ch in range(n_sig):
1199+
ch_end = ch_start + samps_per_frame[ch]
1200+
# Extract sample differences as a 2D array
1201+
ch_dif_signal = dif_frames[:, ch_start:ch_end]
1202+
# Convert to a 1D array of absolute samples
1203+
ch_abs_signal = ch_dif_signal.cumsum(dtype=abs_frames.dtype)
1204+
ch_abs_signal += init_value[ch]
1205+
# Transfer to the output array
1206+
ch_abs_signal = ch_abs_signal.reshape(ch_dif_signal.shape)
1207+
abs_frames[:, ch_start:ch_end] = ch_abs_signal
1208+
ch_start = ch_end
1209+
sig_data = abs_frames.reshape(-1)
1210+
11851211
# At this point, dtype of sig_data is the minimum integer format
11861212
# required for storing the final digital samples.
11871213

0 commit comments

Comments
 (0)