66import os
77import math
88
9+ def loaddata (recordname , annot ):
10+ with open (recordname + '.' + annot , 'rb' ) as f :
11+ filebytes = np .fromfile (f , '<u1' ).reshape ([- 1 , 2 ])
12+ return filebytes
13+
914def get_sample_freq (filebytes ,bpi ):
1015 """Check the beginning of the annotation file to see if it is storing the
1116 'time resolution' field.
@@ -122,6 +127,25 @@ def format_anntype(anndisp,anntype):
122127 anntype = [anncodes [code ] for code in anntype ]
123128 return anntype
124129
130+ def init_arrays (filebytes ):
131+ samplelength = filebytes .shape [0 ]
132+ annsamp = np .zeros (samplelength )
133+ anntype = np .zeros (samplelength )
134+ subtype = np .zeros (samplelength )
135+ chan = np .zeros (samplelength )
136+ num = np .zeros (samplelength )
137+ aux = ['' ] * samplelength
138+ return samplelength , annsamp , anntype , subtype , chan , num , aux
139+
140+ def snip_arrays (annsamp ,anntype ,num ,subtype ,chan ,aux ,ai ):
141+ annsamp = annsamp [0 :ai ].astype (int )
142+ anntype = anntype [0 :ai ].astype (int )
143+ num = num [0 :ai ].astype (int )
144+ subtype = subtype [0 :ai ].astype (int )
145+ chan = chan [0 :ai ].astype (int )
146+ aux = aux [0 :ai ]
147+ return annsamp ,anntype ,num ,subtype ,chan ,aux
148+
125149def rdann (recordname , annot , sampfrom = 0 , sampto = [], anndisp = 1 ):
126150 """ Read a WFDB annotation file recordname.annot and return the fields as lists or arrays
127151
@@ -161,32 +185,19 @@ def rdann(recordname, annot, sampfrom=0, sampto=[], anndisp=1):
161185 # fields=readheader(recordname)
162186 dirname , baserecordname = os .path .split (recordname )
163187
164- # Read the file's byte pairs.
165- with open (recordname + '.' + annot , 'rb' ) as f :
166- filebytes = np .fromfile (f , '<u1' ).reshape ([- 1 , 2 ])
167-
168- # Allocate for the maximum possible number of annotations contained in the
169- # file.
170- samplelength = filebytes .shape [0 ]
171- annsamp = np .zeros (samplelength )
172- anntype = np .zeros (samplelength )
173- subtype = np .zeros (samplelength )
174- chan = np .zeros (samplelength )
175- num = np .zeros (samplelength )
176- aux = ['' ] * samplelength
188+ # Read the file's byte pairs
189+ filebytes = loaddata (recordname , annot )
177190
178- # Check the beginning of the annotation file to see if it is storing the
179- # 'time resolution' field.
180- bpi = 0 # Byte pair index, for searching through bytes of the annotation file.
181- annfs ,bpi = get_sample_freq (filebytes ,bpi )
191+ # Initialise arrays to the total number of annotations in the file
192+ samplelength , annsamp , anntype , subtype , chan , num , aux = init_arrays (filebytes )
182193
183- # Total number of samples of current annotation from beginning of record.
184- # Annotation bytes only store dt.
185- ts = 0
194+ # Initialise variables
195+ bpi = 0 # Byte pair index for searching the annotation file
196+ ts = 0 # Total number of samples from beginning of record. Annotation bytes only store dt.
197+ ai = 0 # Annotation index, the number of annotations processed.
186198
187- # Annotation index, the number of annotations processed. Not to be
188- # confused with the 'num' field of an annotation.
189- ai = 0
199+ # Check the beginning of the annotation file for optional 'time resolution'
200+ annfs ,bpi = get_sample_freq (filebytes ,bpi )
190201
191202 # Processing annotations. Iterate across length of sequence
192203 # Sequence for one ann is: SKIP pair (if any) ->
@@ -200,8 +211,7 @@ def rdann(recordname, annot, sampfrom=0, sampto=[], anndisp=1):
200211
201212 # flags that specify whether to copy the previous channel/num value for
202213 # the current annotation.
203- cpychan = 1
204- cpynum = 1
214+ cpychan , cpynum = 1 , 1
205215 ts ,annsamp ,anntype ,bpi = copy_prev (AT ,ts ,filebytes ,bpi ,annsamp ,anntype ,ai )
206216
207217 AT = filebytes [bpi , 1 ] >> 2
@@ -224,13 +234,8 @@ def rdann(recordname, annot, sampfrom=0, sampto=[], anndisp=1):
224234 # Finished processing current annotation. Move onto next.
225235 ai = ai + 1
226236
227- # Get rid of the unallocated parts of the arrays
228- annsamp = annsamp [0 :ai ].astype (int )
229- anntype = anntype [0 :ai ].astype (int )
230- num = num [0 :ai ].astype (int )
231- subtype = subtype [0 :ai ].astype (int )
232- chan = chan [0 :ai ].astype (int )
233- aux = aux [0 :ai ]
237+ # Snip the unallocated end of the arrays
238+ annsamp ,anntype ,num ,subtype ,chan ,aux = snip_arrays (annsamp ,anntype ,num ,subtype ,chan ,aux ,ai )
234239
235240 # Apply annotation range (from X to Y)
236241 annsamp ,anntype ,num ,subtype ,chan ,aux = apply_annotation_range (annsamp ,
0 commit comments