def heart_rate_variability(sample, lead, rpeak_method = 'string'): curdir = 'DATA\TrainData_FeatureExtraction' [all_data, header_data, BAD_LABELS] = data_read.data_files_load(curdir) data = all_data[sample][lead] """INITIALIZE DETECTOR CLASS WITH THE SAMPLING RATE:""" detectors = Detectors(500) """FIND RPEAK USING ONE OF THE METHODS BELOW--------------------""" if rpeak_method == 'hamilton' or rpeak_method == 'string': #Hamilton. r_peaks = detectors.hamilton_detector(data) elif rpeak_method == 'christov': #Christov r_peaks = detectors.christov_detector(data) elif rpeak_method == 'engelse': #Engelse and Zeelenberg r_peaks = detectors.engzee_detector(data) elif rpeak_method == 'pan': #Pan and Tompkins r_peaks = detectors.pan_tompkins_detector(data) elif rpeak_method == 'stationary_wavelet': #Stationary Wavelet Transform r_peaks = detectors.swt_detector(data) elif rpeak_method == 'two_moving_average': #Two Moving Average r_peaks = detectors.two_average_detector(data) #elif rpeak_method == 'matched_filter': #Matched Filter #go to pyhrv documentation to find the template file #r_peaks = detectors.matched_filter_detector(data,template_file) """COMPUTE NNI SERIES-------------------------------------------""" nn = nn_intervals(r_peaks) #nni seems to be off by a factor of 3 print("\n\n", nn, "\n\n") """PLOT ECG/TACHOGRAM-------------------------------------------""" #plot_ecg(data, sampling_rate = 500) #tachogram(nn, sampling_rate = 500) """COMPUTE HRV--------------------------------------------------""" results = hrv(nn, None, None, 500) """COMPUTE HR PARAMETERS--(SOMETHING IS WRONG HERE BPM TOO HIGH)""" hr = heart_rate(nn) """COMPUTE FREQUENCY ANALYSIS-----------------------------------""" freq_results = results['fft_bands'] return results, hr, freq_results
def detect_r_peaks(SampleRate, data): """ R peaks detection and RR intervals calculation """ detectors = Detectors(SampleRate) # use library for peak detection to get array of r peak positions r_peaks = detectors.engzee_detector(data) r_peaks = np.array(r_peaks) # convert list to array return r_peaks
def engelze_zeelenberg_single(fields, record, save_path, sig, save=True): detectors = Detectors(fields['fs']) try: r_peaks = detectors.engzee_detector(sig[:, 0]) except Exception: r_peaks = [0] if save: save_prediction(r_peaks, record, save_path) else: return r_peaks
def find_peaks(ecg_df): unfiltered_ecg = ecg_df['ecg'].values fs = 500 # sampling freq. in Hz detectors = Detectors(fs) # r_peaks = detectors.two_average_detector(unfiltered_ecg) # r_peaks = detectors.matched_filter_detector(unfiltered_ecg,"templates/template_250hz.csv") # r_peaks = detectors.swt_detector(unfiltered_ecg) r_peaks = detectors.engzee_detector(unfiltered_ecg) # r_peaks = detectors.christov_detector(unfiltered_ecg) # r_peaks = detectors.hamilton_detector(unfiltered_ecg) # r_peaks = detectors.pan_tompkins_detector(unfiltered_ecg) r_peaks = ecg_df['timestamp'][r_peaks].values return r_peaks
time = math.floor(len(ecg) / fs) points = time * 256 print("freq", fs) print("ecg initial len", len(ecg)) print("ecg time", time) print("ecg new points", points) #downsampling resampled_signal = scipy.signal.resample(ecg, points) print("ecg resampled len", len(resampled_signal)) #r peak detector detectors = Detectors(256) r_peaks = detectors.engzee_detector(resampled_signal[0:34304]) rr = np.diff(r_peaks) ''' #r peak plot print(r_peaks) plt.figure() plt.plot(ecg[0:2560]) plt.plot(r_peaks, ecg[r_peaks], 'ro') plt.title('Detected R-peaks') plt.savefig('new_downsampled_rpeaks.png', dpi=300) #plot for 5 seconds (2500 points) ''' #HRV time domain parameters time_domain_features = get_time_domain_features(r_peaks) print(time_domain_features)
def ECGfeatures(self, df, sampling_rate=500): drivers = df['Driver'].value_counts() df.reset_index(inplace=True) # Filtering ECG to remove noise for dr in drivers.index: after = ecg.ecg(signal=df.loc[df['Driver'] == dr, 'ECG'], sampling_rate=sampling_rate, show=False) df.loc[df['Driver'] == dr, 'ECG'] = after[1] #Calculating R-R Peaks detectors = Detectors(sampling_rate) r_peaks = detectors.engzee_detector(df['ECG']) # Calculating R-R Interval df['RMSSD'] = [0 for _ in range(len(df))] rp = pd.Series(r_peaks) hrv_obj = HRV(sampling_rate) for dr in drivers.index: start = df.loc[df['Driver'] == dr].index[0] end = df.loc[df['Driver'] == dr].index[-1] RMSSD = hrv_obj.RMSSD(rp[(rp > start) & (rp < end)], normalise=False) df.loc[df['Driver'] == dr, 'RMSSD'] = RMSSD print('Finished extracting RMSSD successfully') drivers = df['Driver'].value_counts().keys() # Calculating other ECG features df['meanNN'] = [0 for _ in range(len(df))] df['sdNN'] = [0 for _ in range(len(df))] df['cvNN'] = [0 for _ in range(len(df))] df['CVSD'] = [0 for _ in range(len(df))] df['medianNN'] = [0 for _ in range(len(df))] df['madNN'] = [0 for _ in range(len(df))] df['mcvNN'] = [0 for _ in range(len(df))] df['pNN20'] = [0 for _ in range(len(df))] df['pNN50'] = [0 for _ in range(len(df))] for dr in drivers: start = df.loc[df['Driver'] == dr, :].index[0] end = df.loc[df['Driver'] == dr, :].index[-1] crop = rp[(rp > start) & (rp < end)].diff() rmssd = df.loc[start, 'RMSSD'] meanNN = crop.mean() df.loc[df['Driver'] == dr, 'meanNN'] = meanNN std = crop.std() df.loc[df['Driver'] == dr, 'sdNN'] = std cvNN = std / meanNN df.loc[df['Driver'] == dr, 'cvNN'] = cvNN cvsd = rmssd / meanNN df.loc[df['Driver'] == dr, 'CVSD'] = cvsd medianNN = crop.median() df.loc[df['Driver'] == dr, 'medianNN'] = medianNN madNN = crop.mad() df.loc[df['Driver'] == dr, 'madNN'] = madNN mcvNN = madNN / medianNN df.loc[df['Driver'] == dr, 'mcvNN'] = mcvNN pNN20 = hrv_obj.pNN20(crop) df.loc[df['Driver'] == dr, 'pNN20'] = pNN20 pNN50 = hrv_obj.pNN50(crop) df.loc[df['Driver'] == dr, 'pNN50'] = pNN50 print( 'Finished extracting meanNN, sdNN, cvNN, CVSD, medianNN, madNN, mcvNN, pNN20, pNN50 successfully' ) self.df = df return df
from ecgdetectors import Detectors from hrvanalysis import remove_outliers, remove_ectopic_beats, interpolate_nan_values from hrvanalysis import get_time_domain_features from hrvanalysis import plot_psd from hrvanalysis import plot_distrib, plot_timeseries from hrvanalysis import plot_timeseries #load dataset for humans dreamer_data = loadmat('DREAMER.mat') #take one signal signal1 = pd.DataFrame(dreamer_data['DREAMER'].item( 0, 0)[0].item(2).item(0)[3]['stimuli'].item(0)[5][0], columns=["c1", "c2"]) #take one channel c11 = signal1['c1'] #r peak detector detectors = Detectors(256) r_peaks = detectors.engzee_detector(c11[0:34304]) rr = np.diff(r_peaks) #HRV time domain parameters time_domain_features = get_time_domain_features(r_peaks) print(time_domain_features) #HRV frequency domain parameters plot_psd(rr, method="welch") plt.show()
def detect_r_peaks(ecg_record, fs): detector = Detectors(fs) unfiltered_ecg = ecg_record[0][:, 1] r_peaks = detector.engzee_detector(unfiltered_ecg) return r_peaks
ax_rc=filters.add_subplot(5,1,4) ax_rc.title.set_text("RC Filtered") plt.plot(xrc,color='red') plt.plot(peaks_rc, xrc[peaks_rc], "kx") ax_butter=filters.add_subplot(5,1,5) ax_butter.title.set_text("Butter Filtered") plt.plot(xbutter,color='green') plt.plot(peaks_butter, xbutter[peaks_butter], "kx") plt.savefig('Plots/Peaks Analog & Digital.png') plt.show() #r peak detection with engzee r_peaks_butter = detectors.engzee_detector(xbutter) r_peaks_rc = detectors.engzee_detector(xrc) r_peaks_wavelet = detectors.engzee_detector(xwavelet) r_peaks_clean = detectors.engzee_detector(xclean) r_peaks_noisy=detectors.engzee_detector(xnoisy) rpeaks=plt.figure(figsize=(20,10)) plt.grid(False) plt.xlabel('Time (Sec)') plt.ylabel('mV') plt.title('Engzee Analog & Digital',y=1.08) ax_clean=rpeaks.add_subplot(5,1,1) ax_clean.title.set_text("Clean Peaks") plt.plot(xclean)
# attempt to use R-peak detection library on PPG data import numpy as np import matplotlib.pyplot as plt import pathlib from ecgdetectors import Detectors current_dir = pathlib.Path(__file__).resolve() example_dir = current_dir.parent/'Raw'/'test2jan21' unfiltered_ecg_dat = np.loadtxt(example_dir) unfiltered_ecg = unfiltered_ecg_dat[:, 0] fs = 250 detectors = Detectors(fs) # r_peaks = detectors.two_average_detector(unfiltered_ecg) #r_peaks = detectors.matched_filter_detector(unfiltered_ecg,"templates/template_250hz.csv") # r_peaks = detectors.swt_detector(unfiltered_ecg) r_peaks = detectors.engzee_detector(unfiltered_ecg) # r_peaks = detectors.christov_detector(unfiltered_ecg) # r_peaks = detectors.hamilton_detector(unfiltered_ecg) # r_peaks = detectors.pan_tompkins_detector(unfiltered_ecg) plt.figure() plt.plot(unfiltered_ecg) plt.plot(r_peaks, unfiltered_ecg[r_peaks], 'ro') plt.title('Detected R-peaks') plt.show()
def Rpeak_detect(x): fs = 500 detectors = Detectors(fs) x_rpeaks = detectors.engzee_detector(x) return x_rpeaks
def ecg_peaks(x, sfreq=1000, new_sfreq=1000, method='pan-tompkins', find_local=True, win_size=100): """A simple wrapper for many popular R peaks detectors algorithms. This function calls methods from the py-ecg-detectors [#]_ module. Parameters ---------- x : list or 1d array-like The oxi signal. sfreq : int The sampling frequency. Default is set to 75 Hz. method : str The method used. Can be one of the following: 'hamilton', 'christov', 'engelse-zeelenberg', 'pan-tompkins', 'wavelet-transform', 'moving-average'. find_local : bool If *True*, will use peaks indexs to search for local peaks given the window size (win_size). win_size : int Size of the time window used by :py:func:`systole.utils.to_neighbour()` Returns ------- peaks : 1d array-like Numpy array containing peaks index. resampled_signal : 1d array-like Signal resampled to the `new_sfreq` frequency. Notes ----- This function will call the py-ecg-detectors package to perform R wave detection. .. warning :: This function will resample the signal to 1000 Hz. Examples -------- >>> from systole import import_dataset >>> from systole.detection import ecg_peaks >>> signal_df = import_dataset()[:20*2000] >>> signal, peaks = ecg_peaks(signal_df.ecg.to_numpy(), method='hamilton', >>> sfreq=2000, find_local=True) >>> print(f'{sum(peaks)} peaks detected.') 24 peaks detected. References ---------- .. [#] Howell, L., Porr, B. Popular ECG R peak detectors written in python. DOI: 10.5281/zenodo.3353396 """ if isinstance(x, list): x = np.asarray(x) # Interpolate f = interp1d(np.arange(0, len(x)/sfreq, 1/sfreq), x, fill_value="extrapolate") time = np.arange(0, len(x)/sfreq, 1/new_sfreq) x = f(time) # Copy resampled signal for output resampled_signal = np.copy(x) detectors = Detectors(new_sfreq) if method == 'hamilton': peaks_idx = detectors.hamilton_detector(resampled_signal) elif method == 'christov': peaks_idx = detectors.christov_detector(resampled_signal) elif method == 'engelse-zeelenberg': peaks_idx = detectors.engzee_detector(resampled_signal) elif method == 'pan-tompkins': peaks_idx = detectors.pan_tompkins_detector(resampled_signal) elif method == 'wavelet-transform': peaks_idx = detectors.swt_detector(resampled_signal) elif method == 'moving-average': peaks_idx = detectors.two_average_detector(resampled_signal) else: raise ValueError( 'Invalid method provided, should be: hamilton,', 'christov, engelse-zeelenberg, pan-tompkins, wavelet-transform,', 'moving-average') peaks = np.zeros(len(resampled_signal), dtype=bool) peaks[peaks_idx] = True if find_local is True: peaks = to_neighbour(resampled_signal, peaks, size=win_size) return resampled_signal, peaks
ecg_channel_maths = maths_class.einthoven_II elif "v" in sys.argv[1]: ecg_channel_sitting = sitting_class.cs_V2_V1 ecg_channel_maths = maths_class.cs_V2_V1 else: print( "Bad argument. Specify 'e' for Einthoven or 'v' for the Chest strap." ) exit(1) r_peaks = detectors.swt_detector(ecg_channel_sitting) sitting_rr_sd.append(hrv_class.RMSSD(r_peaks, True)) r_peaks = detectors.swt_detector(ecg_channel_maths) maths_rr_sd.append(hrv_class.RMSSD(r_peaks, True)) sitting_error_rr = detectors.engzee_detector(ecg_channel_sitting) sitting_error_rr_sd.append(hrv_class.RMSSD(sitting_error_rr, True)) maths_error_rr = detectors.engzee_detector(ecg_channel_maths) maths_error_rr_sd.append(hrv_class.RMSSD(maths_error_rr, True)) maths_true_rr = maths_class.anno_cs maths_true_sd.append(hrv_class.RMSSD(maths_true_rr, True)) sitting_true_rr = sitting_class.anno_cs sitting_true_sd.append(hrv_class.RMSSD(sitting_true_rr, True)) subject = np.array(subject) width = 0.4 fig, ax = plt.subplots()
def run_algo(algorithm: str, sig: numpy.ndarray, freq_sampling: int) -> List[int]: """ run a qrs detector on a signal :param algorithm: name of the qrs detector to use :type algorithm: str :param sig: values of the sampled signal to study :type sig: ndarray :param freq_sampling: value of sampling frequency of the signal :type freq_sampling: int :return: localisations of qrs detections :rtype: list(int) """ detectors = Detectors(freq_sampling) if algorithm == 'Pan-Tompkins-ecg-detector': qrs_detections = detectors.pan_tompkins_detector(sig) elif algorithm == 'Hamilton-ecg-detector': qrs_detections = detectors.hamilton_detector(sig) elif algorithm == 'Christov-ecg-detector': qrs_detections = detectors.christov_detector(sig) elif algorithm == 'Engelse-Zeelenberg-ecg-detector': qrs_detections = detectors.engzee_detector(sig) elif algorithm == 'SWT-ecg-detector': qrs_detections = detectors.swt_detector(sig) elif algorithm == 'Matched-filter-ecg-detector' and freq_sampling == 360: qrs_detections = detectors.matched_filter_detector( sig, 'templates/template_360hz.csv') elif algorithm == 'Matched-filter-ecg-detector' and freq_sampling == 250: qrs_detections = detectors.matched_filter_detector( sig, 'templates/template_250hz.csv') elif algorithm == 'Two-average-ecg-detector': qrs_detections = detectors.two_average_detector(sig) elif algorithm == 'Hamilton-biosppy': qrs_detections = bsp_ecg.ecg(signal=sig, sampling_rate=freq_sampling, show=False)[2] elif algorithm == 'Christov-biosppy': order = int(0.3 * freq_sampling) filtered, _, _ = bsp_tools.filter_signal(signal=sig, ftype='FIR', band='bandpass', order=order, frequency=[3, 45], sampling_rate=freq_sampling) rpeaks, = bsp_ecg.christov_segmenter(signal=filtered, sampling_rate=freq_sampling) rpeaks, = bsp_ecg.correct_rpeaks(signal=filtered, rpeaks=rpeaks, sampling_rate=freq_sampling, tol=0.05) _, qrs_detections = bsp_ecg.extract_heartbeats( signal=filtered, rpeaks=rpeaks, sampling_rate=freq_sampling, before=0.2, after=0.4) elif algorithm == 'Engelse-Zeelenberg-biosppy': order = int(0.3 * freq_sampling) filtered, _, _ = bsp_tools.filter_signal(signal=sig, ftype='FIR', band='bandpass', order=order, frequency=[3, 45], sampling_rate=freq_sampling) rpeaks, = bsp_ecg.engzee_segmenter(signal=filtered, sampling_rate=freq_sampling) rpeaks, = bsp_ecg.correct_rpeaks(signal=filtered, rpeaks=rpeaks, sampling_rate=freq_sampling, tol=0.05) _, qrs_detections = bsp_ecg.extract_heartbeats( signal=filtered, rpeaks=rpeaks, sampling_rate=freq_sampling, before=0.2, after=0.4) elif algorithm == 'Gamboa-biosppy': order = int(0.3 * freq_sampling) filtered, _, _ = bsp_tools.filter_signal(signal=sig, ftype='FIR', band='bandpass', order=order, frequency=[3, 45], sampling_rate=freq_sampling) rpeaks, = bsp_ecg.gamboa_segmenter(signal=filtered, sampling_rate=freq_sampling) rpeaks, = bsp_ecg.correct_rpeaks(signal=filtered, rpeaks=rpeaks, sampling_rate=freq_sampling, tol=0.05) _, qrs_detections = bsp_ecg.extract_heartbeats( signal=filtered, rpeaks=rpeaks, sampling_rate=freq_sampling, before=0.2, after=0.4) elif algorithm == 'mne-ecg': qrs_detections = mne_ecg.qrs_detector(freq_sampling, sig) elif algorithm == 'heartpy': rol_mean = rolling_mean(sig, windowsize=0.75, sample_rate=100.0) qrs_detections = hp_pkdetection.detect_peaks( sig, rol_mean, ma_perc=20, sample_rate=100.0)['peaklist'] elif algorithm == 'gqrs-wfdb': qrs_detections = processing.qrs.gqrs_detect(sig=sig, fs=freq_sampling) elif algorithm == 'xqrs-wfdb': qrs_detections = processing.xqrs_detect(sig=sig, fs=freq_sampling) else: raise ValueError( f'Sorry... unknown algorithm. Please check the list {algorithms_list}' ) cast_qrs_detections = [int(element) for element in qrs_detections] return cast_qrs_detections
plt.plot(x1) plt.plot(peaks4, x4[peaks4] + 3, "kx") plt.plot(peaks3, x3[peaks3] + 2, "kx") plt.plot(peaks2, x2[peaks2] + 1, "kx") plt.plot(peaks1, x1[peaks1], "kx") plt.grid(False) plt.legend([ 'True ECG', 'Wavelet Filtered ECG', 'Butter Filtered ECG', 'RC Filtered ECG' ]) plt.xlabel('Time (Sec)') plt.title('Peaks Analog & Digital') plt.savefig('Plots/Peaks Analog & Digital.png') plt.show() r_peaks1 = detectors.engzee_detector(x1) r_peaks2 = detectors.engzee_detector(x2) r_peaks3 = detectors.engzee_detector(x3) r_peaks4 = detectors.engzee_detector(x4) plt.plot(x4 + 3) plt.plot(x3 + 2) plt.plot(x2 + 1) plt.plot(x1) plt.plot(r_peaks4, x4[r_peaks4] + 3, "kx") plt.plot(r_peaks3, x3[r_peaks3] + 2, "kx") plt.plot(r_peaks2, x2[r_peaks2] + 1, "kx") plt.plot(r_peaks1, x1[r_peaks1], "kx") plt.grid(False) plt.legend(['True ECG', 'Butter Filtered ECG', 'RC Filtered ECG']) plt.xlabel('Time (Sec)')
def ecg_detector(self, s, detector_type="pan_tompkins"): """ Expose ECG peak detector from the github https://github.com/berndporr/py-ecg-detectors Parameters ---------- s : Input signal fs: The signal frequency. Default is '256 Hz' detector_type: 'hamilton': Open Source ECG Analysis Software Documentation, E.P.Limited, 2002. 'christov':Real time electrocardiogram QRS detection using combined adaptive threshold 'engzee': A single scan algorithm for QRS detection and feature extraction 'swt': Real-time QRS detector using Stationary Wavelet Transform for Automated ECG Analysis. Uses the Pan and Tompkins thresolding. 'mva': Frequency Bands Effects on QRS Detection. 'mtemp': 'pan_tompkins': A Real-Time QRS Detection Algorithm Default = 'pan_tompkins' Returns ------- type an array of 1-D numpy array represent the peak list """ if self.wave_type == 'ppg': warnings.warn("A ECG detectors is using on PPG waveform. " "Output may produce incorrect result") detector = Detectors(self.fs) if detector_type == 'hamilton': res = detector.hamilton_detector(s) elif detector_type == 'christov': res = detector.christov_detector(s) elif detector_type == 'engzee': res = detector.engzee_detector(s) elif detector_type == 'swt': res = detector.swt_detector(s) elif detector_type == 'mva': res = detector.two_average_detector(s) elif detector_type == 'mtemp': res = self.matched_filter_detector(s) else: res = detector.pan_tompkins_detector(s) return np.array(res)
print('how many values with nan are present now ? - ' + str(nan_count)) #detecting the R peaks from the ECG signal to detect heart rate #use a library called ecgdetectors from Glasgov university from ecgdetectors import Detectors path = '/scratch/lnw8px/ECG_radar/clinical/GDN0001/GDN0001_1_Resting.mat' x = loadmat(path) fs_ecg = x['fs_ecg'][0, 0] detectors = Detectors(fs_ecg) ecg2 = x['tfm_ecg2'].squeeze() #select a part of the signal for easy visualization sig = ecg2[8000:16000] #detect R peaks with engzee_detector #see https://github.com/berndporr/py-ecg-detectors for details r_peaks = detectors.engzee_detector(sig) plt.figure() plt.plot(sig) plt.plot(r_peaks, sig[r_peaks], 'ro') plt.title('Detected R-peaks') #get the time difference between r_peaks to calculate the time between two heart beats sig = ecg2 r_peaks = detectors.engzee_detector(sig) diffs = np.diff(r_peaks) #convert this into time heart_periods = diffs / fs_ecg plt.hist(heart_periods, bins=500)
label = str(filename[0]) np_label = np.array(label) record = wfdb.rdrecord(directory + label) record.__dict__['sig_name'] # print(record.__dict__['sig_name']) signal_name = record.__dict__['sig_name'] for i, c in enumerate(signal_name): if c == 'MLII': ECG_data = record.__dict__['p_signal'][ 0:50000, record.__dict__['sig_name'].index("MLII")] ECG_filt_data = butter_bandpass_filter(ECG_data, lowcut, highcut, fs, order=1) detectors = Detectors(fs) r_peaks = detectors.engzee_detector(ECG_filt_data) Sequence_ECG = [] for i, c in enumerate(r_peaks[1:-1]): temp = np.append(ECG_filt_data[c - 60:c + 100], np_label) Sequence_ECG.append(temp) # test = pd.DataFrame(Sequence_ECG) test1 = test1.append(pd.DataFrame(Sequence_ECG), ignore_index=True) # print(test1[test1.columns[22:25]].head()) # print(test1[test1.columns[22:25]].tail()) test1.to_csv('data.csv')