@@ -10,7 +10,7 @@ class PanTompkins(object):
10
10
Works on static signals. In future update,
11
11
will work on streaming ecg signal.
12
12
"""
13
- def __init__ (self , sig = None , fs = None , streamsig = None , ):
13
+ def __init__ (self , sig = None , fs = None , streamsig = None ):
14
14
self .sig = sig
15
15
self .fs = fs
16
16
@@ -119,7 +119,7 @@ def detect_qrs_static(self):
119
119
120
120
# Finally can classify as a signal peak
121
121
# Update running parameters
122
- self .update_peak_params ('s ' , i )
122
+ self .update_peak_params ('ss ' , i )
123
123
124
124
continue
125
125
@@ -132,13 +132,10 @@ def detect_qrs_static(self):
132
132
self .update_peak_params ('nI' , i )
133
133
134
134
135
- # Convert the peak indices back to the original fs if necessary
136
- if fs != 200 :
137
- qrs = qrs * fs / 200
138
- qrs = qrs .astype ('int64' )
139
-
140
-
141
- return
135
+ # Convert the peak indices back to the original fs if necessary
136
+ self .returnresample ()
137
+
138
+ return
142
139
143
140
144
141
@@ -345,7 +342,7 @@ def update_peak_params(self, peaktype, i):
345
342
self .qrs_inds .append (i )
346
343
347
344
# Signal peak, regular threshold criteria
348
- if peaktype == 'sr'
345
+ if peaktype == 'sr' :
349
346
self .sigpeak_I = 0.875 * self .sigpeak_I + 0.125 * self .sig_I [i ]
350
347
self .sigpeak_F = 0.875 * self .sigpeak_F + 0.125 * self .sig_F [i ]
351
348
else :
@@ -393,6 +390,15 @@ def backsearch(self):
393
390
394
391
return
395
392
393
+
394
+ # QRS duration between 0.06s and 0.12s
395
+ # Check left half - 0.06s = 12 samples
396
+ qrscheckwidth = 12
397
+ # ST segment between 0.08 and 0.12s.
398
+ # T-wave duration between 0.1 and 0.25s.
399
+ # We are only analyzing left half for gradient
400
+ # Overall, check 0.12s to the left of the peak.
401
+ #tcheckwidth = 24
396
402
def istwave (self , i ):
397
403
"""
398
404
Determine whether the coinciding peak index happens
@@ -408,14 +414,42 @@ def istwave(self, i):
408
414
# Parameter: Checking width of a qrs complex
409
415
# Parameter: Checking width of a t-wave
410
416
411
- # Compute 5 point derivative
412
417
a_deriv = [1 ]
413
418
b_deriv = [1 / 4 , 1 / 8 , 0 , - 1 / 8 , - 1 / 4 ]
414
- sig_F_deriv = scisig .lfilter (b_deriv , a_deriv , self .sig_F )
419
+
420
+ lastqrsind = self .qrs_inds [:- 1 ]
421
+
422
+ qrs_sig_F_deriv = scisig .lfilter (b_deriv , a_deriv , self .sig_F [lastqrsind - qrscheckwidth :lastqrsind ])
423
+ checksection_sig_F_deriv = scisig .lfilter (b_deriv , a_deriv , self .sig_F [i - qrscheckwidth :i ])
424
+
425
+ # Classified as a t-wave
426
+ if max (checksection_sig_F_deriv ) < 0.5 * max (qrs_sig_F_deriv ):
427
+ return True
428
+ else :
429
+ return False
430
+
431
+ def returnresample (self ):
432
+ # Refactor the qrs indices to match the fs of the original signal
433
+
434
+ self .qrs_inds = np .array (self .qrs_inds )
435
+
436
+ if self .fs != 200 :
437
+ self .qrs_inds = self .qrs_inds * fs / 200
415
438
416
- # Square the derivative
417
- sig_F_deriv = np .square (sig_F_deriv )
439
+ self .qrs_inds = self .qrs_inds .astype ('int64' )
440
+
441
+
442
+
443
+ def pantompkins (sig , fs ):
444
+ """
445
+ Pan Tompkins ECG peak detector
446
+ """
447
+
448
+ detector = PanTompkins (sig = sig , fs = fs )
449
+
450
+ detect_qrs_static ()
418
451
452
+ return detector .qrs_inds
419
453
420
454
421
455
# Determine whether the signal contains a peak at index ind.
@@ -429,6 +463,7 @@ def ispeak_radius(sig, siglen, ind, radius):
429
463
# Find all peaks in a signal. Simple algorithm which marks a
430
464
# peak if the <radius> samples on its left and right are
431
465
# all not bigger than it.
466
+ # Faster than calling ispeak_radius for every index.
432
467
def findpeaks_radius (sig , radius ):
433
468
434
469
siglen = len (sig )
0 commit comments