Skip to content

Commit f103afc

Browse files
committed
enable fmt 212 to read odd numbered samples
1 parent c07edf1 commit f103afc

File tree

4 files changed

+40
-307
lines changed

4 files changed

+40
-307
lines changed

devtests.ipynb

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,24 +124,25 @@
124124
},
125125
{
126126
"cell_type": "code",
127-
"execution_count": 19,
127+
"execution_count": 20,
128128
"metadata": {
129129
"collapsed": false
130130
},
131131
"outputs": [
132132
{
133133
"data": {
134134
"text/plain": [
135-
"int"
135+
"[1, 2]"
136136
]
137137
},
138-
"execution_count": 19,
138+
"execution_count": 20,
139139
"metadata": {},
140140
"output_type": "execute_result"
141141
}
142142
],
143143
"source": [
144-
"type(record.siglen)"
144+
"x = [1,2,3]\n",
145+
"x[:-1]"
145146
]
146147
},
147148
{

tests/test_records.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ def test_1(self):
1818
del(fields['comments'][0])
1919

2020
# Test file writing
21-
22-
2321
assert np.array_equal(siground, targetsig)
2422
assert np.array_equal(sig, pbsig) and fields == pbfields
2523

wfdb/_signals.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -365,17 +365,19 @@ def processwfdbbytes(filename, dirname, pbdir, fmt, startbyte, readlen, nsig, sa
365365
# Read the bytes from the file as unsigned integer blocks
366366
sigbytes, bytesloaded = getdatbytes(filename, dirname, pbdir, fmt, nsamp, startbyte)
367367

368-
print('startbyte: ', startbyte)
369-
print('nsamp: ', nsamp)
370-
print('sigbytes: ')
371-
print(sigbytes)
372-
print(len(sigbytes))
373-
print(bytesloaded)
368+
# use this for byte processing
369+
processnsamp = nsamp
374370

371+
# For odd sampled records, imagine an extra sample and add an extra byte
372+
# to simplify the processing step and remove the extra sample at the end.
373+
if processnsamp % 2:
374+
sigbytes = np.append(sigbytes, 0).astype('uint64')
375+
processnsamp+=1
375376

376-
if tsampsperframe == nsig: # No extra samples/frame
377+
# No extra samples/frame
378+
if tsampsperframe == nsig:
377379
# Turn the bytes into actual samples.
378-
sig = np.zeros(nsamp) # 1d array of actual samples
380+
sig = np.zeros(processnsamp) # 1d array of actual samples
379381
# One sample pair is stored in one byte triplet.
380382
sig[0::2] = sigbytes[0::3] + 256 * \
381383
np.bitwise_and(sigbytes[1::3], 0x0f) # Even numbered samples
@@ -385,15 +387,21 @@ def processwfdbbytes(filename, dirname, pbdir, fmt, startbyte, readlen, nsig, sa
385387
sig[1::2] = sigbytes[2::3] + 256*np.bitwise_and(sigbytes[1::3] >> 4, 0x0f)
386388
if floorsamp: # Remove extra sample read
387389
sig = sig[floorsamp:]
390+
391+
# Remove extra sample read if originally odd sampled
392+
if nsamp % 2:
393+
sig = sig[:-1]
394+
388395
# Reshape into final array of samples
389396
sig = sig.reshape(readlen, nsig)
390397
sig = sig.astype(int)
391398
# Loaded values as unsigned. Convert to 2's complement form: values
392399
# > 2^11-1 are negative.
393400
sig[sig > 2047] -= 4096
394-
else: # At least one channel has multiple samples per frame. All extra samples are discarded.
401+
# At least one channel has multiple samples per frame. All extra samples are discarded.
402+
else:
395403
# Turn the bytes into actual samples.
396-
sigall = np.zeros(nsamp) # 1d array of actual samples
404+
sigall = np.zeros(processnsamp) # 1d array of actual samples
397405
sigall[0::2] = sigbytes[0::3] + 256 * \
398406
np.bitwise_and(sigbytes[1::3], 0x0f) # Even numbered samples
399407

@@ -403,6 +411,11 @@ def processwfdbbytes(filename, dirname, pbdir, fmt, startbyte, readlen, nsig, sa
403411
np.bitwise_and(sigbytes[1::3] >> 4, 0x0f)
404412
if floorsamp: # Remove extra sample read
405413
sigall = sigall[floorsamp:]
414+
415+
# Remove extra sample read if originally odd sampled
416+
if nsamp % 2:
417+
sigall = sigall[:-1]
418+
406419
# Convert to int64 to be able to hold -ve values
407420
sigall = sigall.astype('int')
408421
# Loaded values as unsigned. Convert to 2's complement form: values
@@ -592,6 +605,7 @@ def getdatbytes(filename, dirname, pbdir, fmt, nsamp, startbyte):
592605
# count is the number of elements to read using np.fromfile
593606
# bytecount is the number of bytes to read
594607
if fmt == '212':
608+
# fmt 212
595609
bytecount = int(np.ceil((nsamp) * 1.5))
596610
count = bytecount
597611
elif fmt == '310':
@@ -846,13 +860,16 @@ def wrdatfile(filename, fmt, d_signals):
846860
d_signals = d_signals.reshape(-1)
847861

848862
nsamp = len(d_signals)
849-
# Odd numbered number of samples. Fill in extra blank.
850-
if nsamp % 2:
863+
# use this for byte processing
864+
processnsamp = nsamp
865+
866+
# Odd numbered number of samples. Fill in extra blank for following byte calculation.
867+
if processnsamp % 2:
851868
d_signals = np.concatenate([d_signals, np.array([0])])
852-
nsamp +=1
869+
processnsamp +=1
853870

854871
# The individual bytes to write
855-
bwrite = np.zeros([int(1.5*nsamp)], dtype = 'uint8')
872+
bwrite = np.zeros([int(1.5*processnsamp)], dtype = 'uint8')
856873

857874
# Fill in the byte triplets
858875

@@ -863,8 +880,10 @@ def wrdatfile(filename, fmt, d_signals):
863880
# Triplet 3 from lowest 8 bits of sample 2
864881
bwrite[2::3] = d_signals[1::2] & 255
865882

866-
#bwrite = bwrite.astype('uint8')
867-
883+
# If we added an extra sample for byte calculation, remove the last byte (don't write)
884+
if nsamp % 2:
885+
bwrite = bwrite[:-1]
886+
868887
elif fmt == '16':
869888
# convert to 16 bit two's complement
870889
d_signals[d_signals<0] = d_signals[d_signals<0] + 65536

0 commit comments

Comments
 (0)