@@ -78,6 +78,12 @@ def ecg(signal=None, sampling_rate=1000., show=True):
7878 # segment
7979 rpeaks , = hamilton_segmenter (signal = filtered , sampling_rate = sampling_rate )
8080
81+ # correct R-peak locations
82+ rpeaks , = correct_rpeaks (signal = filtered ,
83+ rpeaks = rpeaks ,
84+ sampling_rate = sampling_rate ,
85+ tol = 0.05 )
86+
8187 # extract templates
8288 templates , rpeaks = extract_heartbeats (signal = filtered ,
8389 rpeaks = rpeaks ,
@@ -388,6 +394,56 @@ def compare_segmentation(reference=None, test=None, sampling_rate=1000.,
388394 return utils .ReturnTuple (args , names )
389395
390396
397+ def correct_rpeaks (signal = None , rpeaks = None , sampling_rate = 1000. , tol = 0.05 ):
398+ """Correct R-peak locations to the maximum within a tolerance.
399+
400+ Parameters
401+ ----------
402+ signal : array
403+ ECG signal.
404+ rpeaks : array
405+ R-peak location indices.
406+ sampling_rate : int, float, optional
407+ Sampling frequency (Hz).
408+ tol : int, float, optional
409+ Correction tolerance (seconds).
410+
411+ Returns
412+ -------
413+ rpeaks : array
414+ Cerrected R-peak location indices.
415+
416+ Notes
417+ -----
418+ * The tolerance is defined as the time interval :math:`[R-tol, R+tol[`.
419+
420+ """
421+
422+ # check inputs
423+ if signal is None :
424+ raise TypeError ("Please specify an input signal." )
425+
426+ if rpeaks is None :
427+ raise TypeError ("Please specify the input R-peaks." )
428+
429+ tol = int (tol * sampling_rate )
430+ length = len (signal )
431+
432+ newR = []
433+ for r in rpeaks :
434+ a = r - tol
435+ if a < 0 :
436+ continue
437+ b = r + tol
438+ if b > length :
439+ break
440+ newR .append (a + np .argmax (signal [a :b ]))
441+
442+ newR = np .array (newR , dtype = 'int' )
443+
444+ return utils .ReturnTuple ((newR ,), ('rpeaks' ,))
445+
446+
391447def ssf_segmenter (signal = None , sampling_rate = 1000. , threshold = 20 , before = 0.03 ,
392448 after = 0.01 ):
393449 """ECG R-peak segmentation based on the Slope Sum Function (SSF).
0 commit comments