33
44import numpy as np
55from scipy import signal
6- from sklearn .preprocessing import normalize
76
8- from wfdb .processing .basic import get_filter_gain
7+ from wfdb .processing .basic import get_filter_gain , normalize
98from wfdb .processing .peaks import find_local_peaks
109from wfdb .io .record import Record
1110
1211
1312class XQRS (object ):
1413 """
15- The QRS detector class for the XQRS algorithm. The `XQRS.Conf`
16- class is the configuration class that stores initial parameters
14+ The QRS detector class for the XQRS algorithm. The `XQRS.Conf`
15+ class is the configuration class that stores initial parameters
1716 for the detection. The `XQRS.detect` method runs the detection algorithm.
1817
1918 The process works as follows:
@@ -85,7 +84,7 @@ class Conf(object):
8584 ----------
8685 hr_init : int, float, optional
8786 Initial heart rate in beats per minute. Used for calculating
88- recent R-R intervals.
87+ recent R-R intervals.
8988 hr_max : int, float, optional
9089 Hard maximum heart rate between two beats, in beats per
9190 minute. Used for refractory period.
@@ -104,13 +103,13 @@ class Conf(object):
104103 ref_period : int, float, optional
105104 The QRS refractory period.
106105 t_inspect_period : int, float, optional
107- The period below which a potential QRS complex is
108- inspected to see if it is a T-wave.
106+ The period below which a potential QRS complex is inspected to
107+ see if it is a T-wave. Leave as 0 for no T-wave inspection .
109108
110109 """
111110 def __init__ (self , hr_init = 75 , hr_max = 200 , hr_min = 25 , qrs_width = 0.1 ,
112111 qrs_thr_init = 0.13 , qrs_thr_min = 0 , ref_period = 0.2 ,
113- t_inspect_period = 0.36 ):
112+ t_inspect_period = 0 ):
114113 if hr_min < 0 :
115114 raise ValueError ("'hr_min' must be >= 0" )
116115
@@ -134,7 +133,7 @@ def __init__(self, hr_init=75, hr_max=200, hr_min=25, qrs_width=0.1,
134133 def _set_conf (self ):
135134 """
136135 Set configuration parameters from the Conf object into the detector
137- object. Time values are converted to samples, and amplitude values
136+ object. Time values are converted to samples, and amplitude values
138137 are in mV.
139138
140139 Parameters
@@ -288,10 +287,10 @@ def _learn_init_params(self, n_calib_beats=8):
288287
289288 # Question: should the signal be squared? Case for inverse QRS
290289 # complexes
291- sig_segment = normalize (( self .sig_f [i - self .qrs_radius :
292- i + self .qrs_radius ]). reshape ( - 1 , 1 ), axis = 0 )
290+ sig_segment = normalize (self .sig_f [i - self .qrs_radius :
291+ i + self .qrs_radius ])
293292
294- xcorr = np .correlate (sig_segment [:, 0 ] , ricker_wavelet [:,0 ])
293+ xcorr = np .correlate (sig_segment , ricker_wavelet [:,0 ])
295294
296295 # Classify as QRS if xcorr is large enough
297296 if xcorr > 0.6 and i - last_qrs_ind > self .rr_min :
@@ -470,15 +469,15 @@ def _update_qrs(self, peak_num, backsearch=False):
470469 The peak number of the MWI signal where the QRS is detected.
471470 backsearch: bool, optional
472471 Whether the QRS was found via backsearch.
473-
472+
474473 Returns
475474 -------
476475 N/A
477476
478477 """
479478 i = self .peak_inds_i [peak_num ]
480479
481- # Update recent R-R interval if the beat is consecutive (do this
480+ # Update recent R-R interval if the beat is consecutive (do this
482481 # before updating self.last_qrs_ind)
483482 rr_new = i - self .last_qrs_ind
484483 if rr_new < self .rr_max :
@@ -514,7 +513,7 @@ def _is_twave(self, peak_num):
514513 ----------
515514 peak_num : int
516515 The peak number of the MWI signal where the QRS is detected.
517-
516+
518517 Returns
519518 -------
520519 bool
@@ -530,8 +529,7 @@ def _is_twave(self, peak_num):
530529
531530 # Get half the QRS width of the signal to the left.
532531 # Should this be squared?
533- sig_segment = normalize ((self .sig_f [i - self .qrs_radius :i ]
534- ).reshape (- 1 , 1 ), axis = 0 )
532+ sig_segment = normalize (self .sig_f [i - self .qrs_radius :i ])
535533 last_qrs_segment = self .sig_f [self .last_qrs_ind - self .qrs_radius :
536534 self .last_qrs_ind ]
537535
@@ -901,7 +899,7 @@ def __init__(self, fs, adc_gain, hr=75,
901899 class Peak (object ):
902900 """
903901 Holds all of the peak information for the QRS object.
904-
902+
905903 Attributes
906904 ----------
907905 peak_time : int, float
@@ -923,7 +921,7 @@ def __init__(self, peak_time, peak_amp, peak_type):
923921 class Annotation (object ):
924922 """
925923 Holds all of the annotation information for the QRS object.
926-
924+
927925 Attributes
928926 ----------
929927 ann_time : int, float
@@ -1160,8 +1158,8 @@ def qfv_put(self, t, v):
11601158
11611159 def sm (self , at_t ):
11621160 """
1163- Implements a trapezoidal low pass (smoothing) filter (with a gain
1164- of 4*smdt) applied to input signal sig before the QRS matched
1161+ Implements a trapezoidal low pass (smoothing) filter (with a gain
1162+ of 4*smdt) applied to input signal sig before the QRS matched
11651163 filter qf(). Before attempting to 'rewind' by more than BUFLN-smdt
11661164 samples, reset smt and smt0.
11671165
@@ -1220,7 +1218,7 @@ def qf(self):
12201218 N/A
12211219
12221220 """
1223- # Do this first, to ensure that all of the other smoothed values
1221+ # Do this first, to ensure that all of the other smoothed values
12241222 # needed below are in the buffer
12251223 dv2 = self .sm (self .t + self .c .dt4 )
12261224 dv2 -= self .smv_at (self .t - self .c .dt4 )
@@ -1302,17 +1300,17 @@ def add_peak(peak_time, peak_amp, peak_type):
13021300
13031301 def peaktype (p ):
13041302 """
1305- The neighborhood consists of all other peaks within rrmin.
1306- Normally, "most prominent" is equivalent to "largest in
1307- amplitude", but this is not always true. For example, consider
1308- three consecutive peaks a, b, c such that a and b share a
1309- neighborhood, b and c share a neighborhood, but a and c do not;
1310- and suppose that amp(a) > amp(b) > amp(c). In this case, if
1303+ The neighborhood consists of all other peaks within rrmin.
1304+ Normally, "most prominent" is equivalent to "largest in
1305+ amplitude", but this is not always true. For example, consider
1306+ three consecutive peaks a, b, c such that a and b share a
1307+ neighborhood, b and c share a neighborhood, but a and c do not;
1308+ and suppose that amp(a) > amp(b) > amp(c). In this case, if
13111309 there are no other peaks, a is the most prominent peak in the (a, b)
1312- neighborhood. Since b is thus identified as a non-prominent peak,
1313- c becomes the most prominent peak in the (b, c) neighborhood.
1314- This is necessary to permit detection of low-amplitude beats that
1315- closely precede or follow beats with large secondary peaks (as,
1310+ neighborhood. Since b is thus identified as a non-prominent peak,
1311+ c becomes the most prominent peak in the (b, c) neighborhood.
1312+ This is necessary to permit detection of low-amplitude beats that
1313+ closely precede or follow beats with large secondary peaks (as,
13161314 for example, in R-on-T PVCs).
13171315
13181316 Parameters
@@ -1323,7 +1321,7 @@ def peaktype(p):
13231321 Returns
13241322 -------
13251323 int
1326- Whether the input peak is the most prominent peak in its
1324+ Whether the input peak is the most prominent peak in its
13271325 neighborhood (1) or not (2).
13281326
13291327 """
@@ -1534,8 +1532,8 @@ def gqrs_detect(sig=None, fs=None, d_sig=None, adc_gain=None, adc_zero=None,
15341532 """
15351533 Detect QRS locations in a single channel ecg. Functionally, a direct port
15361534 of the GQRS algorithm from the original WFDB package. Accepts either a
1537- physical signal, or a digital signal with known adc_gain and adc_zero. See
1538- the notes below for a summary of the program. This algorithm is not being
1535+ physical signal, or a digital signal with known adc_gain and adc_zero. See
1536+ the notes below for a summary of the program. This algorithm is not being
15391537 developed/supported.
15401538
15411539 Parameters
0 commit comments