Skip to content

Commit ede827c

Browse files
committed
finish first pantompkins code
1 parent 33361db commit ede827c

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

wfdb/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
from .readwrite._signals import estres, wrdatfile
33
from .readwrite.annotations import Annotation, rdann, wrann, showanncodes
44
from .readwrite.downloads import getdblist
5-
from .plot.plots import plotrec, plotann
5+
from .plot.plots import plotrec, plotann
6+
from .processing.ecg.peakdetect import pantompkins

wfdb/processing/ecg/peakdetect.py

Lines changed: 49 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class PanTompkins(object):
1010
Works on static signals. In future update,
1111
will work on streaming ecg signal.
1212
"""
13-
def __init__(self, sig=None, fs=None, streamsig=None, ):
13+
def __init__(self, sig=None, fs=None, streamsig=None):
1414
self.sig = sig
1515
self.fs = fs
1616

@@ -119,7 +119,7 @@ def detect_qrs_static(self):
119119

120120
# Finally can classify as a signal peak
121121
# Update running parameters
122-
self.update_peak_params('s', i)
122+
self.update_peak_params('ss', i)
123123

124124
continue
125125

@@ -132,13 +132,10 @@ def detect_qrs_static(self):
132132
self.update_peak_params('nI', i)
133133

134134

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
142139

143140

144141

@@ -345,7 +342,7 @@ def update_peak_params(self, peaktype, i):
345342
self.qrs_inds.append(i)
346343

347344
# Signal peak, regular threshold criteria
348-
if peaktype == 'sr'
345+
if peaktype == 'sr':
349346
self.sigpeak_I = 0.875*self.sigpeak_I + 0.125*self.sig_I[i]
350347
self.sigpeak_F = 0.875*self.sigpeak_F + 0.125*self.sig_F[i]
351348
else:
@@ -393,6 +390,15 @@ def backsearch(self):
393390

394391
return
395392

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
396402
def istwave(self, i):
397403
"""
398404
Determine whether the coinciding peak index happens
@@ -408,14 +414,42 @@ def istwave(self, i):
408414
# Parameter: Checking width of a qrs complex
409415
# Parameter: Checking width of a t-wave
410416

411-
# Compute 5 point derivative
412417
a_deriv = [1]
413418
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
415438

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()
418451

452+
return detector.qrs_inds
419453

420454

421455
# Determine whether the signal contains a peak at index ind.
@@ -429,6 +463,7 @@ def ispeak_radius(sig, siglen, ind, radius):
429463
# Find all peaks in a signal. Simple algorithm which marks a
430464
# peak if the <radius> samples on its left and right are
431465
# all not bigger than it.
466+
# Faster than calling ispeak_radius for every index.
432467
def findpeaks_radius(sig, radius):
433468

434469
siglen = len(sig)

0 commit comments

Comments
 (0)