Exemple #1
0
def get_indices_of_R_peaks(ecg_signal):
    rp_ind = ecg.engzee_segmenter(signal=ecg_signal,
                                  sampling_rate=300.0,
                                  threshold=0.48)
    rp_peaks = []
    for i in list(rp_ind[0]):
        rp_peaks.append(ecg_signal[i])
    return list(rp_ind[0]), rp_peaks
Exemple #2
0
def engzee_detect(sig:np.ndarray, fs:Real, **kwargs) -> np.ndarray:
    """

    References:
    -----------
    [1] W. Engelse and C. Zeelenberg, "A single scan algorithm for QRS detection and feature extraction", IEEE Comp. in Cardiology, vol. 6, pp. 37-42, 1979
    [2] A. Lourenco, H. Silva, P. Leite, R. Lourenco and A. Fred, "Real Time Electrocardiogram Segmentation for Finger Based ECG Biometrics", BIOSIGNALS 2012, pp. 49-54, 2012
    """
    rpeaks, = BSE.engzee_segmenter(
        signal=sig, sampling_rate=fs,
        threshold=kwargs.get("threshold", 0.48),
    )
    # correct R-peak locations
    rpeaks, = BSE.correct_rpeaks(
        signal=sig,
        rpeaks=rpeaks,
        sampling_rate=fs,
        tol=kwargs.get("correct_tol", 0.05),
    )
    return rpeaks
Exemple #3
0
 def seek(self):
     """Locate R peaks and segment ECG cycles."""
     self.r_coords = bioecg.engzee_segmenter(
         np.ravel(self.record), sampling_rate=self.fs)['rpeaks']
     cycles, rpeaks_relative, median_rr = self.segment_cycles(self.r_coords)
     return self.r_coords.copy(), median_rr, cycles, rpeaks_relative
Exemple #4
0
        target = feautres_right
    else:
        target = feautres_left

    # low pass filter
    filtered = butter_lowpass_filter(signal, cutoff, sampling_rate, order)

    # detrend with a low-pass
    order = 20
    filtered -= filtfilt(
        [1] * order, [order],
        filtered)  # this is a very simple moving average filter

    # Rpeaks
    Rpeaks = engzee_segmenter(signal=filtered,
                              sampling_rate=sampling_rate,
                              threshold=0)['rpeaks']
    Rpeaks = correct_rpeaks(signal=filtered,
                            rpeaks=Rpeaks,
                            sampling_rate=sampling_rate,
                            tol=rpeak_tol)['rpeaks']

    # peak to peak intervals
    IBI = []
    for i in range(1, len(Rpeaks)):
        IBI.append(Rpeaks[i] - Rpeaks[i - 1])
    IBI = np.array(IBI) / sampling_rate
    IBI = correct(IBI, 3)

    # feautres for IBI
    target.append(RMS(IBI))
Exemple #5
0
    def transform(self, X, y=None):
        X = check_array(X)
        T = 1.0 / self.sample_rate
        bio_feature = np.empty(1)
        for i in range(X.shape[0]):
            Xi = X[i, :]
            rpeaks = ecg.engzee_segmenter(Xi,
                                          sampling_rate=300,
                                          threshold=self.threshold)
            rpeaks = rpeaks[0]
            # 1. compute the mean of DFT for one QRS wave
            QR_int = self.segstart  # Q-R interval
            RS_int = self.segend  # R-S interval
            m_idx = X.shape[1] - RS_int
            idx = np.where((rpeaks > QR_int) & (rpeaks < m_idx))
            idx = idx[0]
            new_rpeaks = rpeaks[idx]
            _fft = np.zeros(QR_int + RS_int)
            for j in range(len(new_rpeaks)):
                # extract segment around rpeaks
                QRS = Xi[new_rpeaks[j] - QR_int:new_rpeaks[j] + RS_int]
                # compute the mean of DFT
                fft = np.fft.fft(QRS)
                fft_amp = np.absolute(fft)
                if j == 0:
                    _fft = fft_amp
                else:
                    _fft = np.vstack((_fft, fft_amp))
            fft_mean = np.mean(_fft, axis=0)
            if len(new_rpeaks) == 0 or len(new_rpeaks) == 1:
                fft_mean = _fft

            # 2. compute the statistics of heart beat
            out = ecg.ecg(signal=Xi, sampling_rate=300, show=False)
            [ts, sig, rpeaks, temp_ts, temp, hr_ts, heart_rate] = out
            heart_stats = [0, 0, 0, 0]
            if len(heart_rate) != 0:
                heart_stats[0] = np.mean(heart_rate)
                heart_stats[1] = np.var(heart_rate)
                heart_stats[2] = np.amin(heart_rate)
                heart_stats[3] = np.amax(heart_rate)
            heart_stats = np.asarray(heart_stats)

            # 3. compute the statistics of R-R interval
            RR_int = []
            for k in range(1, len(rpeaks)):
                RR_int.append(T * (rpeaks[k] - rpeaks[k - 1]))
            RR_int = np.asarray(RR_int)
            RR_stats = [0, 0, 0, 0]
            if len(RR_int) != 0:
                RR_stats[0] = np.mean(RR_int)
                RR_stats[1] = np.var(RR_int)
                RR_stats[2] = np.amin(RR_int)
                RR_stats[3] = np.amax(RR_int)
            RR_stats = np.asarray(RR_stats)

            feature = np.hstack((fft_mean, heart_stats))
            feature = np.hstack((feature, RR_stats))
            if i == 0:
                bio_feature = feature
            else:
                bio_feature = np.vstack((bio_feature, feature))
        return bio_feature
import numpy as np
import matplotlib as plt
import biosppy.signals.ecg as bio

samplrate = 3428 / 10
data = np.loadtxt('FilteredData/filtereddata3.txt')

rpeaks1 = bio.christov_segmenter(data, 342)
bio.ecg(data, 342, True)
rpeaks2 = bio.engzee_segmenter(data, 342)
rpeaks3 = bio.gamboa_segmenter(data, 342)
rpeaks4 = bio.hamilton_segmenter(data, 342)
rpeaks5 = bio.ssf_segmenter(data, 342)

np.savetxt('FilteredData/peaksdata13.txt', rpeaks1, header=str(len(rpeaks1)))
np.savetxt('FilteredData/peaksdata23.txt', rpeaks2, header=str(len(rpeaks2)))
np.savetxt('FilteredData/peaksdata33.txt', rpeaks3, header=str(len(rpeaks3)))
np.savetxt('FilteredData/peaksdata43.txt', rpeaks4, header=str(len(rpeaks4)))
np.savetxt('FilteredData/peaksdata53.txt', rpeaks5, header=str(len(rpeaks5)))
#np.savetxt('FilteredData/roundeddata3.txt', introunddata)
@author: Milan
"""
import pandas as pd 
import biosppy.signals.ecg as bse
import numpy as np

#%% Train


data_train = pd.read_csv('Dropbox/MK/ETH MSc Statistics/Machine Learning/Advanced Machine Learning/exercises/project/task3/X_train.csv')
del data_train['id']

rpeaks_init = []
for i in range(0,data_train.shape[0]):
    rpeaks_init.append(bse.engzee_segmenter(signal=data_train.iloc[i,:].values, sampling_rate=300))
    
rpeaks_corrected = []
for i in range(0,data_train.shape[0]):
    rpeaks_corrected.append(bse.correct_rpeaks(signal=data_train.iloc[i,:].values, rpeaks=rpeaks_init[i][0], sampling_rate=300, tol=0.05))

heartbeats = []
for i in range(0,data_train.shape[0]):
    heartbeats.append(bse.extract_heartbeats(signal=data_train.iloc[i,:].values, rpeaks=rpeaks_corrected[i][0], sampling_rate=300, before=0.2, after=0.4)
)
    
R_peaks = []
for i in range(0,data_train.shape[0]):
    R = []
    for j in range(0,len(heartbeats[i][1])):
        R.append(heartbeats[i][1][j]) 
Exemple #8
0
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
Exemple #9
0
 def rinfo_engzee(self, threshold=0.48):
     """Get ECG R peaks by engzee algorithm.
     """
     return ecg.engzee_segmenter(self.__ecg, self.__signal_rate, threshold)
def calculateECGFeatures(dataFrame, smooth=True, normalize=True):
    '''
Inputs:     dataFrame   pandas.dataFrame containing clip of raw ECG data, should have two columns of
                        Timestamps (ms) and Sample (V)
                        
            smooth      optional Boolean, default value is True, flag for whether to smooth input raw
                        ECG data or not
            
            normalize   option Boolean, default value is True, flag for whether to normalize input raw
                        ECG data or not

Outputs:    features    pandas.dataFrame for input clip of data, each column corresponds to a different
                        feature, included features are as follows:
                        - mean                      - ultra low frequency power
                        - median                    - very low frequency power
                        - max                       - low frequency power
                        - variance                  - high frequency power
                        - standard deviation        - LF/HF ratio
                        - absolute deviation        - total power
                        - kurtois                   - R-R interval
                        - skew
'''

    # ----------------------------------------------------------------------------------------------------
    # Data Preprocessing ---------------------------------------------------------------------------------
    # ----------------------------------------------------------------------------------------------------

    time = dataFrame['Timestamp (ms)'].values
    data = dataFrame['Sample (V)'].values

    ## Smooth raw ECG data
    if smooth:
        smooth_signal = tools.smoother(
            data, kernel='median', size=5)  # Convolutional 5x5 kernel window
        data = smooth_signal['signal']

    ## Normalize raw ECG data
    if normalize:
        norm_signal = tools.normalize(data)
        data = norm_signal['signal']

    # ----------------------------------------------------------------------------------------------------
    # Begin Features Extraction Code ---------------------------------------------------------------------
    # ----------------------------------------------------------------------------------------------------
    ## Calculate basic statistic features
    s_mean, s_med, s_max, s_var, s_std_dev, s_abs_dev, s_kurtois, s_skew = tools.signal_stats(
        data)

    ## Obtain Power Spectra
    power_freqs, power_spectrum = tools.power_spectrum(data,
                                                       sampling_rate=2.0,
                                                       decibel=False)

    ## Calculate Ultra Low-Frequency Power (ULF Band: <= 0.003 Hz)
    #    power_ulf = tools.band_power(freqs=power_freqs, power=power_spectrum, frequency=[0, 0.003])
    #    power_ulf = np.absolute(power_ulf['avg_power'])

    # Calculate Very Low-Frequency Power (VLF Band: 0.0033 - 0.04 Hz)
    power_vlf = tools.band_power(freqs=power_freqs,
                                 power=power_spectrum,
                                 frequency=[0.0033, 0.04])
    power_vlf = np.absolute(power_vlf['avg_power'])

    # Calculate Low-Frequency Power (LF Band: 0.04 - 0.15 Hz Hz)
    power_lf = tools.band_power(freqs=power_freqs,
                                power=power_spectrum,
                                frequency=[0.04, 0.15])
    power_lf = np.absolute(power_lf['avg_power'])

    ## Calculate High-Frequency Power (HF Band: 0.15 - 0.40 Hz)
    power_hf = tools.band_power(freqs=power_freqs,
                                power=power_spectrum,
                                frequency=[0.15, 0.40])
    power_hf = np.absolute(power_hf['avg_power'])

    ## Calculate LF/HF Ratio
    lf_hf_ratio = power_lf / power_hf

    ## Calculate Total Power (VLF + LF + HF power)
    power_total = power_vlf + power_lf + power_hf

    # Calculate R peak indices
    r_peaks = ecg.engzee_segmenter(data, sampling_rate=500.0)
    if np.size(r_peaks) != 1:
        rr_indices = time[r_peaks]
        rr_intervals = np.mean(np.diff(rr_indices))
    else:
        rr_intervals = np.nan  # NaN indicates not enough R peaks within window to calculate R-R interval

    # ----------------------------------------------------------------------------------------------------
    # Collect Features and convert into dataFrame --------------------------------------------------------
    # ----------------------------------------------------------------------------------------------------

    signal_features = {
        'mean': s_mean,
        'median': s_med,
        'max': s_max,
        'variance': s_var,
        'std_dev': s_std_dev,
        'abs_dev': s_abs_dev,
        'kurtois': s_kurtois,
        'skew': s_skew,
        #                       'ulf_power': power_ulf,
        'vlf_power': power_vlf,
        'lf_power': power_lf,
        'hf_power': power_hf,
        'lf_hf_ratio': lf_hf_ratio,
        'rr_interval': rr_intervals,
    }

    features = pd.Series(signal_features)

    a = [
        s_mean,
        s_med,
        s_max,
        s_var,
        s_std_dev,
        s_abs_dev,
        s_kurtois,
        s_skew,
        #         power_ulf,
        power_vlf,
        power_lf,
        power_hf,
        lf_hf_ratio,
        rr_intervals
        #      rr_indices
    ]
    return a