Skip to content

Commit 2650fa7

Browse files
committed
Merge branch 'restructuremods'
2 parents 80f537a + 4bd932a commit 2650fa7

File tree

7 files changed

+470
-481
lines changed

7 files changed

+470
-481
lines changed

tests/test_readannot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import numpy as np
2-
from wfdb import readannot
2+
from wfdb import rdann
33
import re
44

55
class test_rdann():
@@ -9,7 +9,7 @@ class test_rdann():
99
def test_1(self):
1010

1111
# Read data from WFDB python package
12-
annsamp, anntype, subtype, chan, num, aux, annfs=readannot.rdann('sampledata/100', 'atr')
12+
annsamp, anntype, subtype, chan, num, aux, annfs=rdann('sampledata/100', 'atr')
1313
aux[0]='(N' # This is not the fault of the script. The annotation file specifies a length 3
1414
# aux field with a null written after '(N' which the script correctly picks up. I am just
1515
# getting rid of the null in this unit test to compare with the regexp output below which has
@@ -49,7 +49,7 @@ def test_1(self):
4949
def test_2(self):
5050

5151
# Read data from WFDB python package
52-
annsamp, anntype, subtype, chan, num, aux, annfs=readannot.rdann('sampledata/12726', 'anI')
52+
annsamp, anntype, subtype, chan, num, aux, annfs=rdann('sampledata/12726', 'anI')
5353

5454
# Target data from WFDB software package
5555
lines=tuple(open('tests/targetoutputdata/anntarget2', 'r'))

tests/test_readsignal.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,50 @@
11
import numpy as np
2-
from wfdb import readsignal
2+
from wfdb import rdsamp
33

44
class test_rdsamp():
55

66
# Test 1 - Format 212/Entire signal/Physical
77
# Target file created with: rdsamp -r sampledata/100 -P | cut -f 2- > target1
88
def test_1(self):
9-
sig, fields=readsignal.rdsamp('sampledata/100')
9+
sig, fields=rdsamp('sampledata/100')
1010
sig=np.round(sig, decimals=8)
1111
targetsig=np.genfromtxt('tests/targetoutputdata/target1')
1212
assert np.array_equal(sig, targetsig)
1313

1414
# Test 2 - Format 212/Selected Duration/Selected Channel/Digital.
1515
# Target file created with: rdsamp -r sampledata/100 -f 0.002 -t 30 -s 1 | cut -f 2- > target2
1616
def test_2(self):
17-
sig, fields=readsignal.rdsamp('sampledata/100', sampfrom=1, sampto=10800, channels=[1], physical=0)
17+
sig, fields=rdsamp('sampledata/100', sampfrom=1, sampto=10800, channels=[1], physical=0)
1818
targetsig=np.genfromtxt('tests/targetoutputdata/target2')
1919
targetsig=targetsig.reshape(len(targetsig), 1)
2020
assert np.array_equal(sig, targetsig)
2121

2222
# Test 3 - Format 16/Entire signal/Digital
2323
# Target file created with: rdsamp -r sampledata/test01_00s | cut -f 2- > target3
2424
def test_3(self):
25-
sig, fields=readsignal.rdsamp('sampledata/test01_00s', physical=0)
25+
sig, fields=rdsamp('sampledata/test01_00s', physical=0)
2626
targetsig=np.genfromtxt('tests/targetoutputdata/target3')
2727
assert np.array_equal(sig, targetsig)
2828

2929
# Test 4 - Format 16 with byte offset/Selected Duration/Selected Channels/Physical
3030
# Target file created with: rdsamp -r sampledata/a103l -f 50 -t 160 -s 2 0 -P | cut -f 2- > target4
3131
def test_4(self):
32-
sig, fields=readsignal.rdsamp('sampledata/a103l', sampfrom=12500, sampto=40000, channels=[2, 0])
32+
sig, fields=rdsamp('sampledata/a103l', sampfrom=12500, sampto=40000, channels=[2, 0])
3333
sig=np.round(sig, decimals=8)
3434
targetsig=np.genfromtxt('tests/targetoutputdata/target4')
3535
assert np.array_equal(sig, targetsig)
3636

3737
# Test 5 - Format 16 with byte offset/Selected Duration/Selected Channels/Digital
3838
# Target file created with: rdsamp -r sampledata/a103l -f 80 -s 0 1 | cut -f 2- > target5
3939
def test_5(self):
40-
sig, fields=readsignal.rdsamp('sampledata/a103l', sampfrom=20000, physical=0, channels=[0, 1])
40+
sig, fields=rdsamp('sampledata/a103l', sampfrom=20000, physical=0, channels=[0, 1])
4141
targetsig=np.genfromtxt('tests/targetoutputdata/target5')
4242
assert np.array_equal(sig, targetsig)
4343

4444
# Test 6 - Format 80/Selected Duration/Selected Channels/Physical
4545
# Target file created with: rdsamp -r sampledata/3000003_0003 -f 1 -t 8 -s 1 -P | cut -f 2- > target6
4646
def test_6(self):
47-
sig, fields=readsignal.rdsamp('sampledata/3000003_0003', sampfrom=125, sampto=1000, channels=[1])
47+
sig, fields=rdsamp('sampledata/3000003_0003', sampfrom=125, sampto=1000, channels=[1])
4848
sig=np.round(sig, decimals=8)
4949
targetsig=np.genfromtxt('tests/targetoutputdata/target6')
5050
targetsig=targetsig.reshape(len(targetsig), 1)
@@ -53,22 +53,22 @@ def test_6(self):
5353
# Test 7 - Multi-dat/Entire signal/Digital
5454
# Target file created with: rdsamp -r sampledata/s0010_re | cut -f 2- > target7
5555
def test_7(self):
56-
sig, fields=readsignal.rdsamp('sampledata/s0010_re', physical=0)
56+
sig, fields=rdsamp('sampledata/s0010_re', physical=0)
5757
targetsig=np.genfromtxt('tests/targetoutputdata/target7')
5858
assert np.array_equal(sig, targetsig)
5959

6060
# Test 8 - Multi-dat/Selected Duration/Selected Channels/Physical
6161
# Target file created with: rdsamp -r sampledata/s0010_re -f 5 -t 38 -P -s 13 0 4 8 3 | cut -f 2- > target8
6262
def test_8(self):
63-
sig, fields=readsignal.rdsamp('sampledata/s0010_re', sampfrom=5000, sampto=38000, channels=[13, 0, 4, 8, 3])
63+
sig, fields=rdsamp('sampledata/s0010_re', sampfrom=5000, sampto=38000, channels=[13, 0, 4, 8, 3])
6464
sig=np.round(sig, decimals=8)
6565
targetsig=np.genfromtxt('tests/targetoutputdata/target8')
6666
assert np.array_equal(sig, targetsig)
6767

6868
# Test 9 - Format 12 multi-samples per frame and skew/Entire Signal/Digital
6969
# Target file created with: rdsamp -r sampledata/03700181 | cut -f 2- > target9
7070
def test_9(self):
71-
sig, fields=readsignal.rdsamp('sampledata/03700181', physical=0)
71+
sig, fields=rdsamp('sampledata/03700181', physical=0)
7272
sig=sig[:-4,:] # The WFDB library rdsamp does not return the final N samples for all channels due to the skew.
7373
# The WFDB python rdsamp does return the final N samples, filling in NANs for end of skewed channels only.
7474
targetsig=np.genfromtxt('tests/targetoutputdata/target9')
@@ -77,7 +77,7 @@ def test_9(self):
7777
# Test 10 - Format 12 multi-samples per frame and skew/Selected Duration/Selected Channels/Physical
7878
# Target file created with: rdsamp -r sampledata/03700181 -f 8 -t 128 -s 0 2 -P | cut -f 2- > target10
7979
def test_10(self):
80-
sig, fields=readsignal.rdsamp('sampledata/03700181', channels=[0,2], sampfrom=1000, sampto=16000)
80+
sig, fields=rdsamp('sampledata/03700181', channels=[0,2], sampfrom=1000, sampto=16000)
8181
sig=np.round(sig, decimals=8)
8282
targetsig=np.genfromtxt('tests/targetoutputdata/target10')
8383
assert np.array_equal(sig, targetsig)
@@ -88,15 +88,15 @@ def test_10(self):
8888
# Test 11 - Multi-segment variable layout/Entire signal/Physical
8989
# Target file created with: rdsamp -r sampledata/matched/s25047/s25047-2704-05-04-10-44 -P | cut -f 2- > target11
9090
#def test_11(self):
91-
#sig, fields=readsignal.rdsamp('sampledata/matched/s25047/s25047-2704-05-04-10-44')
91+
#sig, fields=rdsamp('sampledata/matched/s25047/s25047-2704-05-04-10-44')
9292
#sig=np.round(sig, decimals=8)
9393
#targetsig=np.genfromtxt('tests/targetoutputdata/target11')
9494
#assert np.array_equal(sig, targetsig)
9595

9696
# Test 12 - Multi-segment variable layout/Selected duration/Selected Channels/Physical
9797
# Target file created with: rdsamp -r sampledata/matched/s00001/s00001-2896-10-10-00-31 -f 70 -t 4000 -s 3 0 -P | cut -f 2- > target12
9898
#def test_12(self):
99-
#sig, fields=readsignal.rdsamp('sampledata/matched/s00001/s00001-2896-10-10-00-31', sampfrom=8750, sampto=500000, channels=[3, 0])
99+
#sig, fields=rdsamp('sampledata/matched/s00001/s00001-2896-10-10-00-31', sampfrom=8750, sampto=500000, channels=[3, 0])
100100
#sig=np.round(sig, decimals=8)
101101
#targetsig=np.genfromtxt('tests/targetoutputdata/target12')
102102
#assert np.array_equal(sig, targetsig)
@@ -107,15 +107,15 @@ def test_10(self):
107107
# Target file created with: rdsamp -r sampledata/3000003_0003 -f 0 -t 8.21 | cut -f 2- | wrsamp -o 310derive -O 310
108108
# rdsamp -r 310derive -f 0.007 | cut -f 2- > target13
109109
def test_13(self):
110-
sig, fields=readsignal.rdsamp('sampledata/310derive', sampfrom=2, physical=0)
110+
sig, fields=rdsamp('sampledata/310derive', sampfrom=2, physical=0)
111111
targetsig=np.genfromtxt('tests/targetoutputdata/target13')
112112
assert np.array_equal(sig, targetsig)
113113

114114
# Test 14 - Format 311/Selected Duration/Physical
115115
# Target file created with: rdsamp -r sampledata/3000003_0003 -f 0 -t 8.21 -s 1 | cut -f 2- | wrsamp -o 311derive -O 311
116116
# rdsamp -r 311derive -f 0.005 -t 3.91 -P | cut -f 2- > target14
117117
def test_14(self):
118-
sig, fields=readsignal.rdsamp('sampledata/311derive', sampfrom=1, sampto=978)
118+
sig, fields=rdsamp('sampledata/311derive', sampfrom=1, sampto=978)
119119
sig=np.round(sig, decimals=8)
120120
targetsig=np.genfromtxt('tests/targetoutputdata/target14')
121121
targetsig=targetsig.reshape([977,1])

wfdb/__init__.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
1-
import pbdownload
2-
import plotwfdb
3-
import readannot
4-
import readsignal
1+
from ._rdsamp import rdsamp
2+
from ._rdann import rdann

wfdb/readannot.py renamed to wfdb/_rdann.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,29 +31,25 @@ def rdann(recordname, annot, sampfrom=0, sampto=[], anndisp=1):
3131
*NOTE: Every annotation contains the 'annsamp' and 'anntype' field. All other fields default to 0 or empty if not present.
3232
"""
3333

34-
if sampto:
35-
if sampto<sampfrom:
36-
sys.exit("sampto must be greater than sampfrom")
34+
if sampto and sampto<=sampfrom:
35+
raise ValueError("sampto must be greater than sampfrom")
3736

38-
#fields=readheader(recordname) # Get the info from the header file
37+
# Get the info from the header file
38+
#fields=readheader(recordname)
3939
dirname, baserecordname=os.path.split(recordname)
4040

41-
if dirname:
42-
dirname=dirname+"/"
43-
44-
f=open(recordname+'.'+annot, 'rb')
45-
filebytes=np.fromfile(f, '<u1').reshape([-1, 2]) # Read the file's byte pairs.
46-
f.close()
41+
# Read the file's byte pairs.
42+
with open(recordname+'.'+annot, 'rb') as f:
43+
filebytes=np.fromfile(f, '<u1').reshape([-1, 2])
4744

4845
# Allocate for the maximum possible number of annotations contained in the file.
49-
annsamp=np.zeros(filebytes.shape[0])
50-
anntype=np.zeros(filebytes.shape[0])
51-
subtype=np.zeros(filebytes.shape[0])
52-
chan=np.zeros(filebytes.shape[0])
53-
num=np.zeros(filebytes.shape[0])
46+
annsamp=np.empty(filebytes.shape[0])
47+
anntype=np.empty(filebytes.shape[0])
48+
subtype=np.empty(filebytes.shape[0])
49+
chan=np.empty(filebytes.shape[0])
50+
num=np.empty(filebytes.shape[0])
5451
aux=['']*filebytes.shape[0]
55-
56-
annfs=[] # Stores the fs written in the annotation file if it exists.
52+
annfs=[] # Stores the frequencies written in the annotation file if it exists.
5753
ai=0 # Annotation index, the number of annotations processed. Not to be comfused with the 'num' field of an annotation.
5854
bpi=0 # Byte pair index, for searching through bytes of the annotation file.
5955

@@ -169,7 +165,6 @@ def rdann(recordname, annot, sampfrom=0, sampto=[], anndisp=1):
169165
elif anndisp==2:
170166
anntype=[anncodes[code] for code in anntype]
171167

172-
173168
return (annsamp, anntype, subtype, chan, num, aux, annfs)
174169

175170

@@ -275,4 +270,7 @@ def rdann(recordname, annot, sampfrom=0, sampto=[], anndisp=1):
275270
#40: 'JPT', # J point (end of QRS) */
276271
41: 'RONT' # R-on-T premature ventricular contraction */
277272
}
273+
274+
if __name__ == '__main__':
275+
rdann(sys.argv)
278276

0 commit comments

Comments
 (0)