示例#1
0
def get_features_dict(x):
    [ts, fts, rpeaks, tts, thb, hrts,
     hr] = ecg.ecg(signal=x, sampling_rate=loader.FREQUENCY, show=False)
    """
    Returns:	

    ts (array) – Signal time axis reference (seconds).
    filtered (array) – Filtered ECG signal.
    rpeaks (array) – R-peak location indices.
    templates_ts (array) – Templates time axis reference (seconds).
    templates (array) – Extracted heartbeat templates.
    heart_rate_ts (array) – Heart rate time axis reference (seconds).
    heart_rate (array) – Instantaneous heart rate (bpm).
    """

    fx = dict()
    fx.update(heart_rate_features(hr))
    fx.update(frequency_powers(x, n_power_features=60))
    fx.update(add_suffix(frequency_powers(fts), "fil"))
    fx.update(frequency_powers_summary(fts))
    fx.update(heart_beats_features2(thb))
    fx.update(fft_features(heartbeats.median_heartbeat(thb)))
    # fx.update(heart_beats_features3(thb))
    fx.update(r_features(fts, rpeaks))

    fx['PRbyST'] = fx['PR_interval'] * fx['ST_interval']
    fx['P_form'] = fx['P_kurt'] * fx['P_skew']
    fx['T_form'] = fx['T_kurt'] * fx['T_skew']

    for key, value in fx.items():
        if np.math.isnan(value):
            value = 0
        fx[key] = value

    return fx
def get_features_dict_ex(signals, filename):
    """
       ts : array
        Signal time axis reference (seconds).
    filtered : array
        Filtered ECG signal.
    rpeaks : array
        R-peak location indices.
    templates_ts : array
        Templates time axis reference (seconds).
    templates : array
        Extracted heartbeat templates.
    heart_rate_ts : array
        Heart rate time axis reference (seconds).
    heart_rate : array
        Instantaneous heart rate (bpm).
    :param x:
    :return:
    """
    out, rpeaks = ecg.ecgex(signals=signals,
                            sampling_rate=loader.FREQUENCY,
                            show=False,
                            filename=filename)

    result = []
    for i in range(len(out)):
        x = signals.iloc[:, [i]].values.reshape(-1)
        [ts, fts, new_rpeaks, tts, thb, hrts, hr] = out[i]
        import neurokit as nk
        rsa = nk.respiratory_sinus_arrhythmia(rpeaks, rsp_cycles, rsp_signal)
        fx = dict()
        fx.update(add_suffix(frequency_powers(fts), "fil"))
        fx.update(frequency_powers_summary(fts))
        fx.update(heart_beats_features(thb, np.median(np.diff(new_rpeaks))))
        fx.update(fft_features(heartbeats.median_heartbeat(thb)))
        # fx.update(heart_beats_features3(thb))
        # gloal feature
        fx.update(frequency_powers(x, n_power_features=60))
        fx.update(heart_rate_features(hr))
        fx.update(r_features(fts, new_rpeaks))

        fx['PRbyST'] = fx['PR_interval'] * fx['ST_interval']
        fx['P_form'] = fx['P_kurt'] * fx['P_skew']
        fx['T_form'] = fx['T_kurt'] * fx['T_skew']

        for key, value in fx.items():
            if np.math.isnan(value):
                value = 0
            fx[key] = value
        from time_domain_feature import psfeatureTime
        result += psfeatureTime(x)
        result += list(
            np.array([fx[key] for key in sorted(list(fx.keys()))],
                     dtype=np.float32))

    rx = r_features(rpeaks)
    result += list(
        np.array([rx[key] for key in sorted(list(rx.keys()))],
                 dtype=np.float32))
    return result
示例#3
0
def get_features_dict_ex(signals, filename):
    """
       ts : array
        Signal time axis reference (seconds).
    filtered : array
        Filtered ECG signal.
    rpeaks : array
        R-peak location indices.
    templates_ts : array
        Templates time axis reference (seconds).
    templates : array
        Extracted heartbeat templates.
    heart_rate_ts : array
        Heart rate time axis reference (seconds).
    heart_rate : array
        Instantaneous heart rate (bpm).
    :param x:
    :return:
    """
    out, rpeaks = ecg.ecgex(signals=signals,
                            sampling_rate=loader.FREQUENCY,
                            show=False,
                            filename=filename)

    result = []
    templates = []
    for i in range(len(out)):
        x = signals.iloc[:, [i]].values.reshape(-1)
        [ts, fts, new_rpeaks, tts, thb, hrts, hr] = out[i]
        fx = dict()
        fx.update(heart_rate_features(hr))
        fx.update(frequency_powers(x, n_power_features=60))
        fx.update(add_suffix(frequency_powers(fts), "fil"))
        fx.update(frequency_powers_summary(fts))
        fx.update(heart_beats_features2(thb, rpeaks))
        #fx.update(fft_features(heartbeats.median_heartbeat(thb)))
        templates.append(heartbeats.median_heartbeat(thb))

        fx['PRbyST'] = fx['PR_interval'] * fx['ST_interval']
        fx['P_form'] = fx['P_kurt'] * fx['P_skew']
        fx['T_form'] = fx['T_kurt'] * fx['T_skew']

        for key, value in fx.items():
            if np.math.isnan(value):
                value = 0
            fx[key] = value
        from time_domain_feature import psfeatureTime
        result += psfeatureTime(x)
        result += list(
            np.array([fx[key] for key in sorted(list(fx.keys()))],
                     dtype=np.float32))
    rx = r_features(rpeaks)
    result += list(
        np.array([rx[key] for key in sorted(list(rx.keys()))],
                 dtype=np.float32))
    import os
    #path = os.path.join('data', filename)
    #pd.DataFrame(np.array(templates).T).to_csv(path,index=None,header=None)
    return result
示例#4
0
def heart_beats_features(thb):
    means = heartbeats.median_heartbeat(thb)
    mins = np.array([col.min() for col in thb.T])
    maxs = np.array([col.max() for col in thb.T])
    # stds = np.array([col.std() for col in thb.T])
    diff = maxs - mins

    features = dict()
    for i, v in enumerate(means):
        features['median' + str(i)] = v

    for i, v in enumerate(diff):
        features['hbdiff' + str(i)] = v

    return features
示例#5
0
def get_features_dict(x):
    """
       ts : array
        Signal time axis reference (seconds).
    filtered : array
        Filtered ECG signal.
    rpeaks : array
        R-peak location indices.
    templates_ts : array
        Templates time axis reference (seconds).
    templates : array
        Extracted heartbeat templates.
    heart_rate_ts : array
        Heart rate time axis reference (seconds).
    heart_rate : array
        Instantaneous heart rate (bpm).
    :param x:
    :return:
    """
    [ts, fts, rpeaks, tts, thb, hrts,
     hr] = ecg.ecg(signal=x, sampling_rate=loader.FREQUENCY, show=False)
    """
    Returns:	

    ts (array) – Signal time axis reference (seconds).
    filtered (array) – Filtered ECG signal.
    rpeaks (array) – R-peak location indices.
    templates_ts (array) – Templates time axis reference (seconds).
    templates (array) – Extracted heartbeat templates.
    heart_rate_ts (array) – Heart rate time axis reference (seconds).
    heart_rate (array) – Instantaneous heart rate (bpm).
    """

    fx = dict()
    fx.update(heart_rate_features(hr))
    fx.update(frequency_powers(x, n_power_features=60))
    fx.update(add_suffix(frequency_powers(fts), "fil"))
    fx.update(frequency_powers_summary(fts))
    fx.update(heart_beats_features2(thb))
    fx.update(fft_features(heartbeats.median_heartbeat(thb)))
    # fx.update(heart_beats_features3(thb))
    fx.update(r_features(fts, rpeaks))

    fx['PRbyST'] = fx['PR_interval'] * fx['ST_interval']
    fx['P_form'] = fx['P_kurt'] * fx['P_skew']
    fx['T_form'] = fx['T_kurt'] * fx['T_skew']
    """
    from features.template_statistics import TemplateStatistics
    # Get features
    template_statistics = TemplateStatistics(
        ts=ts,
        signal_raw=x,
        signal_filtered=fts,
        rpeaks=rpeaks,
        templates_ts=tts,
        templates=np.array(thb).T,
        fs=loader.FREQUENCY,
        template_before=0.25,
        template_after=0.4
    )
    template_statistics.calculate_template_statistics()

    # Update feature dictionary
    fx.update(template_statistics.get_template_statistics())
    """
    for key, value in fx.items():
        if np.math.isnan(value):
            value = 0
        fx[key] = value

    return fx
示例#6
0
def heart_beats_features2(thb, rpeaks):
    if len(thb) == 0:
        thb = np.zeros((1, int(0.6 * loader.FREQUENCY)), dtype=np.int32)

    diff_rpeak = np.median(np.diff(rpeaks))
    means = heartbeats.median_heartbeat(thb)
    r_pos = int(0.2 * loader.FREQUENCY)

    if diff_rpeak < 350:
        tmp1 = 100 - int(diff_rpeak / 3)
        tmp2 = 100 + int(2 * diff_rpeak / 3)
        for i in range(len(means)):
            if i < tmp1:
                means[i] = 0
            elif i > tmp2:
                means[i] = 0
        freq_cof = diff_rpeak / 350 * loader.FREQUENCY
    else:
        freq_cof = loader.FREQUENCY

    a = dict()
    r_list = []
    p_list = []
    q_list = []
    s_list = []
    t_list = []

    for i in range(np.shape(thb)[0]):
        r_pos = int(0.2 * loader.FREQUENCY)
        template = thb[i, :]
        PQ = template[r_pos - int(0.2 * freq_cof):r_pos - int(0.05 * freq_cof)]
        ST = template[r_pos + int(0.05 * freq_cof):r_pos + int(0.4 * freq_cof)]
        QR = template[r_pos - int(0.07 * freq_cof):r_pos]
        RS = template[r_pos:r_pos + int(0.07 * freq_cof)]

        q_list.append(np.min(QR))
        s_list.append(np.min(RS))

        p_list.append(np.max(PQ))
        t_list.append(np.max(ST))
        r_list.append(template[r_pos])

    a['T_P_max'] = np.max(p_list)
    a['T_P_min'] = np.min(p_list)
    a['T_P_std'] = np.std(p_list)
    a['T_Q_max'] = np.max(q_list)
    a['T_Q_min'] = np.min(q_list)
    a['T_Q_std'] = np.std(q_list)
    a['T_R_max'] = np.max(r_list)
    a['T_R_min'] = np.min(r_list)
    a['T_R_std'] = np.std(r_list)
    a['T_S_max'] = np.max(s_list)
    a['T_S_min'] = np.min(s_list)
    a['T_S_std'] = np.std(s_list)
    a['T_T_max'] = np.max(t_list)
    a['T_T_min'] = np.min(t_list)
    a['T_T_std'] = np.std(t_list)

    # PQ = means[:int(0.15 * loader.FREQUENCY)]
    PQ = means[r_pos - int(0.2 * freq_cof):r_pos - int(0.05 * freq_cof)]
    #ST = means[int(0.25 * loader.FREQUENCY):]
    #ST = means[r_pos + int(0.05 * freq_cof):r_pos + int(0.4 * freq_cof)]
    #QR = means[int(0.13 * loader.FREQUENCY):r_pos]
    QR = means[r_pos - int(0.07 * freq_cof):r_pos]
    RS = means[r_pos:r_pos + int(0.07 * freq_cof)]

    #q_pos = int(0.13 * loader.FREQUENCY) + np.argmin(QR)
    q_pos = r_pos - len(QR) + np.argmin(QR)
    s_pos = r_pos + np.argmin(RS)

    ST = means[s_pos + int(0.08 * freq_cof):r_pos + int(0.35 * freq_cof)]
    p_pos = np.argmax(PQ)

    t_pos = np.argmax(ST)
    if t_pos / len(ST) < 0.2 or t_pos / len(ST) > 0.8:
        t_pos = np.argmin(ST)
        if t_pos / len(ST) < 0.2 or t_pos / len(ST) > 0.8:
            t_pos = int(0.12 * freq_cof)
    t_pos = t_pos + s_pos + int(0.08 * freq_cof)
    t_begin = max(s_pos + int(0.08 * freq_cof), t_pos - int(0.12 * freq_cof))
    st_begin = max(s_pos + int(0.035 * freq_cof),
                   t_begin - int(0.06 * freq_cof))
    #t_begin = int(0.035 * freq_cof) + s_pos
    #t_end = int(0.24 * freq_cof) + t_begin
    t_end = min(len(means) - 1, int(t_pos + int(0.12 * freq_cof)))

    #t_wave = ST[max(0, t_pos - int(0.08 * freq_cof)):min(len(ST), t_pos + int(0.08 * freq_cof))]
    t_wave = means[t_begin:t_end]
    p_wave = PQ[max(0, p_pos -
                    int(0.06 * freq_cof)):min(len(PQ), p_pos +
                                              int(0.06 * freq_cof))]
    st_wave = means[st_begin:t_begin]
    p_pos = p_pos + r_pos - int(0.2 * freq_cof)

    QRS = means[q_pos:s_pos]
    #
    a['PR_interval'] = (r_pos - p_pos) / 500
    a['PQ_interval'] = (p_pos - q_pos) / 500
    a['RT_interval'] = (t_pos - r_pos) / 500
    a['PT_interval'] = (t_pos - p_pos) / 500
    a['ST_interval'] = (t_pos - s_pos) / 500
    a['T_slope1'] = (means[t_pos] - means[t_begin]) / len(t_wave)
    a['T_slope2'] = (means[t_pos] - means[t_end]) / len(t_wave)
    a['ST_slope'] = (means[t_begin] - means[st_begin]) / len(st_wave)
    a['RS_interval'] = (r_pos - q_pos) / 500
    a['QR_interval'] = (q_pos - r_pos) / 500
    a['R_time'] = len(p_wave) / 500
    a['T_time'] = len(t_wave) / 500
    a['t_activity'] = calcActivity(t_wave)
    a['t_mobility'] = calcMobility(t_wave)
    a['t_complexity'] = calcComplexity(t_wave)
    a['p_activity'] = calcActivity(p_wave)
    a['p_mobility'] = calcMobility(p_wave)
    a['p_complexity'] = calcComplexity(p_wave)
    #

    a['P_max'] = means[p_pos]
    a['P_min'] = min(p_wave)
    a['P_to_R'] = means[p_pos] / means[r_pos]
    a['P_to_Q'] = means[p_pos] - means[q_pos]

    a['T_am'] = means[t_pos]
    a['T_max'] = max(t_wave)
    a['T_min'] = min(t_wave)
    a['T_to_R'] = means[t_pos] / means[r_pos]
    a['T_to_S'] = means[t_pos] / means[s_pos]
    a['P_to_T'] = means[p_pos] / means[t_pos]
    a['P_skew'] = skew(p_wave)
    a['P_kurt'] = kurtosis(p_wave)
    a['T_skew'] = skew(t_wave)
    a['T_kurt'] = kurtosis(t_wave)
    a['activity'] = calcActivity(means)
    a['mobility'] = calcMobility(means)
    a['complexity'] = calcComplexity(means)

    qrs_min = abs(min(QRS))
    qrs_max = abs(max(QRS))
    qrs_abs = max(qrs_min, qrs_max)
    sign = -1 if qrs_min > qrs_max else 1

    a['QRS_diff'] = sign * abs(qrs_min / qrs_abs)
    a['QS_diff'] = abs(means[s_pos] - means[q_pos])
    a['QRS_kurt'] = kurtosis(QRS)
    a['QRS_skew'] = skew(QRS)
    a['QRS_minmax'] = qrs_max - qrs_min

    a['T_wave_time'] = len(t_wave) / 500
    a['P_wave_time'] = len(p_wave) / 500

    a['Temp_Median_p_5'] = np.percentile(means, 5)
    a['Temp_Median_p_25'] = np.percentile(means, 25)
    a['Temp_Median_p_75'] = np.percentile(means, 75)
    a['Temp_Median_p_95'] = np.percentile(means, 95)

    a['T_Median_p_5'] = np.percentile(t_wave, 5)
    a['T_Median_p_25'] = np.percentile(t_wave, 25)
    a['T_Median_p_75'] = np.percentile(t_wave, 75)
    a['T_Median_p_95'] = np.percentile(t_wave, 95)

    a.update(fft_features(means))
    return a
示例#7
0
def heart_beats_features2(thb):
    means = heartbeats.median_heartbeat(thb)
    stds = np.array([np.std(col) for col in thb.T])

    r_pos = int(0.2 * loader.FREQUENCY)

    PQ = means[:int(0.15 * loader.FREQUENCY)]
    ST = means[int(0.25 * loader.FREQUENCY):]

    QR = means[int(0.13 * loader.FREQUENCY):r_pos]
    RS = means[r_pos:int(0.27 * loader.FREQUENCY)]

    q_pos = int(0.13 * loader.FREQUENCY) + np.argmin(QR)
    s_pos = r_pos + np.argmin(RS)

    p_pos = np.argmax(PQ)
    t_pos = np.argmax(ST)

    t_wave = ST[max(0, t_pos - int(0.08 * loader.FREQUENCY)
                    ):min(len(ST), t_pos + int(0.08 * loader.FREQUENCY))]
    p_wave = PQ[max(0, p_pos - int(0.06 * loader.FREQUENCY)
                    ):min(len(PQ), p_pos + int(0.06 * loader.FREQUENCY))]

    r_plus = sum(1 if b[r_pos] > 0 else 0 for b in thb)
    r_minus = len(thb) - r_plus

    QRS = means[q_pos:s_pos]

    a = dict()
    a['PR_interval'] = r_pos - p_pos
    a['P_max'] = PQ[p_pos]
    a['P_to_R'] = PQ[p_pos] / means[r_pos]
    a['P_to_Q'] = PQ[p_pos] - means[q_pos]
    a['ST_interval'] = t_pos
    a['T_max'] = ST[t_pos]
    a['R_plus'] = r_plus / max(1, len(thb))
    a['R_minus'] = r_minus / max(1, len(thb))
    a['T_to_R'] = ST[t_pos] / means[r_pos]
    a['T_to_S'] = ST[t_pos] - means[s_pos]
    a['P_to_T'] = PQ[p_pos] / ST[t_pos]
    a['P_skew'] = skew(p_wave)
    a['P_kurt'] = kurtosis(p_wave)
    a['T_skew'] = skew(t_wave)
    a['T_kurt'] = kurtosis(t_wave)
    a['activity'] = calcActivity(means)
    a['mobility'] = calcMobility(means)
    a['complexity'] = calcComplexity(means)
    a['QRS_len'] = s_pos - q_pos

    qrs_min = abs(min(QRS))
    qrs_max = abs(max(QRS))
    qrs_abs = max(qrs_min, qrs_max)
    sign = -1 if qrs_min > qrs_max else 1

    a['QRS_diff'] = sign * abs(qrs_min / qrs_abs)
    a['QS_diff'] = abs(means[s_pos] - means[q_pos])
    a['QRS_kurt'] = kurtosis(QRS)
    a['QRS_skew'] = skew(QRS)
    a['QRS_minmax'] = qrs_max - qrs_min
    a['P_std'] = np.mean(stds[:q_pos])
    a['T_std'] = np.mean(stds[s_pos:])

    return a
示例#8
0
        name = input("Enter an entry name to plot: ")
        name = name.strip()
        if len(name) == 0:
            print("Finishing")
            break

        if not loader.check_has_example(name):
            print("File Not Found")
            continue

        row = loader.load_data_from_file(name)

        print(info[name])
        [ts, fts, rpeaks, tts, thb, hrts,
         hr] = ecg.ecg(signal=row, sampling_rate=loader.FREQUENCY, show=True)
        b = heartbeats.median_heartbeat(thb)
        t = b[int(0.3 * loader.FREQUENCY):int(0.55 * loader.FREQUENCY)]

        a = normalizer.normalize_ecg(t)

        a[a < 0] = 0

        a = np.square(a)

        a -= np.mean(a)

        a[a < 0] = 0

        a, d1 = wavedec(a, 'sym4', level=1)

        # a = normalizer.normalize_ecg(a)
def heart_beats_features3(thb):
    means = heartbeats.median_heartbeat(thb)
    from fastdtw import fastdtw
    dist_list = []
    std_list = []
    mean_list = []
    skew_list = []
    kurtosis_list = []

    for i in range(len(thb)):
        template = thb[i]
        distance = cos_dist(template, means)
        dist_list.append(distance)
        std_list.append(template.std())
        mean_list.append(template.mean())
        skew_list.append(skew(template))
        kurtosis_list.append(kurtosis(template))

    heart_beats_dict = {}
    if len(thb) > 0:
        outlier_index = dist_list.index(min(dist_list))
        max_template = thb[outlier_index]

        dict1 = heart_beats_features(means)
        heart_beats_dict.update(dict1)
        dict2 = add_suffix(heart_beats_features(max_template), "fil")
        heart_beats_dict.update(dict2)

        dist_array = np.array(dist_list)
        dist_array.mean()
        heart_beats_dict['Templates_Dist_Mean'] = dist_array.mean()
        heart_beats_dict['Templates_Dist_Std'] = dist_array.std()
        std_list = np.array(std_list)
        heart_beats_dict['Templates_Std_Mean'] = std_list.mean()
        heart_beats_dict['Templates_Std_Std'] = std_list.std()
        mean_list = np.array(mean_list)
        heart_beats_dict['Templates_Mean_Mean'] = mean_list.mean()
        heart_beats_dict['Templates_Mean_Std'] = mean_list.std()
        skew_list = np.array(skew_list)
        heart_beats_dict['Templates_Skew_Mean'] = skew_list.mean()
        heart_beats_dict['Templates_Skew_Std'] = skew_list.std()
        kurtosis_list = np.array(kurtosis_list)
        heart_beats_dict['Templates_Kurtosis_Mean'] = kurtosis_list.mean()
        heart_beats_dict['Templates_Kurtosis_Std'] = kurtosis_list.std()
    else:
        dict1 = heart_beats_features(means)
        dict2 = add_suffix(heart_beats_features(means), "fil")
        heart_beats_dict.update(dict1)
        heart_beats_dict.update(dict2)

        heart_beats_dict['Templates_Dist_Mean'] = 0
        heart_beats_dict['Templates_Dist_Std'] = 0

        heart_beats_dict['Templates_Std_Mean'] = 0
        heart_beats_dict['Templates_Std_Std'] = 0

        heart_beats_dict['Templates_Mean_Mean'] = 0
        heart_beats_dict['Templates_Mean_Std'] = 0

        heart_beats_dict['Templates_Skew_Mean'] = 0
        heart_beats_dict['Templates_Skew_Std'] = 0

        heart_beats_dict['Templates_Kurtosis_Mean'] = 0
        heart_beats_dict['Templates_Kurtosis_Std'] = 0

    return heart_beats_dict
def heart_beats_features(thb, diff_rpeak):
    means = heartbeats.median_heartbeat(thb)
    r_pos = int(0.2 * loader.FREQUENCY)

    if diff_rpeak < 350:
        tmp1 = 100 - int(diff_rpeak / 3)
        tmp2 = 100 + int(2 * diff_rpeak / 3)
        for i in range(len(means)):
            if i < tmp1:
                means[i] = 0
            elif i > tmp2:
                means[i] = 0
        freq_cof = diff_rpeak / 350 * loader.FREQUENCY
    else:
        freq_cof = loader.FREQUENCY

    # PQ = means[:int(0.15 * loader.FREQUENCY)]
    PQ = means[r_pos - int(0.2 * freq_cof):r_pos - int(0.05 * freq_cof)]
    #ST = means[int(0.25 * loader.FREQUENCY):]
    #ST = means[r_pos + int(0.05 * freq_cof):r_pos + int(0.4 * freq_cof)]
    #QR = means[int(0.13 * loader.FREQUENCY):r_pos]
    QR = means[r_pos - int(0.07 * freq_cof):r_pos]
    RS = means[r_pos:r_pos + int(0.07 * freq_cof)]

    #q_pos = int(0.13 * loader.FREQUENCY) + np.argmin(QR)
    q_pos = r_pos - len(QR) + np.argmin(QR)
    s_pos = r_pos + np.argmin(RS)

    ST = means[s_pos + int(0.08 * freq_cof):r_pos + int(0.35 * freq_cof)]
    p_pos = np.argmax(PQ)

    t_pos = np.argmax(ST)
    if t_pos / len(ST) < 0.2 or t_pos / len(ST) > 0.8:
        t_pos = np.argmin(ST)
        if t_pos / len(ST) < 0.2 or t_pos / len(ST) > 0.8:
            t_pos = 0.12 * freq_cof
    t_pos = t_pos + s_pos + int(0.08 * freq_cof)
    t_begin = max(s_pos + int(0.08 * freq_cof), t_pos - int(0.12 * freq_cof))
    st_begin = max(s_pos + int(0.035 * freq_cof),
                   t_begin - int(0.06 * freq_cof))
    #t_begin = int(0.035 * freq_cof) + s_pos
    #t_end = int(0.24 * freq_cof) + t_begin
    t_end = min(len(means), int(t_pos + int(0.12 * freq_cof)))

    #t_wave = ST[max(0, t_pos - int(0.08 * freq_cof)):min(len(ST), t_pos + int(0.08 * freq_cof))]
    t_wave = means[t_begin:t_end]
    p_wave = PQ[max(0, p_pos -
                    int(0.06 * freq_cof)):min(len(PQ), p_pos +
                                              int(0.06 * freq_cof))]
    st_wave = means[st_begin:t_begin]
    p_pos = p_pos + r_pos - int(0.2 * freq_cof)
    #r_plus = sum(1 if b[r_pos] > 0 else 0 for b in thb)
    #r_minus = len(thb) - r_plus

    QRS = means[q_pos:s_pos]

    import matplotlib.pyplot as plt
    plt.figure()
    plt.plot(means)
    plt.axvline(p_pos, color='red')
    plt.axvline(q_pos, color='green')
    plt.axvline(r_pos, color='blue')
    plt.axvline(s_pos, color='black')
    plt.axvline(t_pos, color='yellow')
    plt.axvline(t_begin, color='orange')
    plt.axvline(t_end, color='purple')
    plt.axvline(st_begin, color='gray')
    #plt.axvline(t_min_pos, color='greenyellow')
    plt.show()

    a = dict()
    a['PR_interval'] = r_pos - p_pos
    a['P_max'] = means[p_pos]
    a['P_to_R'] = means[p_pos] / means[r_pos]
    a['P_to_Q'] = means[p_pos] - means[q_pos]
    a['ST_interval'] = t_pos
    a['T_max'] = means[t_pos]
    #a['R_plus'] = r_plus / max(1, len(thb))
    #a['R_minus'] = r_minus / max(1, len(thb))
    a['T_to_R'] = means[t_pos] / means[r_pos]
    a['T_to_S'] = means[t_pos] - means[s_pos]
    a['P_to_T'] = means[p_pos] / means[t_pos]
    a['P_skew'] = skew(p_wave)
    a['P_kurt'] = kurtosis(p_wave)
    a['T_skew'] = skew(t_wave)
    a['T_kurt'] = kurtosis(t_wave)
    a['activity'] = calcActivity(means)
    a['mobility'] = calcMobility(means)
    a['complexity'] = calcComplexity(means)
    a['QRS_len'] = s_pos - q_pos

    qrs_min = abs(min(QRS))
    qrs_max = abs(max(QRS))
    qrs_abs = max(qrs_min, qrs_max)
    sign = -1 if qrs_min > qrs_max else 1

    a['QRS_diff'] = sign * abs(qrs_min / qrs_abs)
    a['QS_diff'] = abs(means[s_pos] - means[q_pos])
    a['QRS_kurt'] = kurtosis(QRS)
    a['QRS_skew'] = skew(QRS)
    a['QRS_minmax'] = qrs_max - qrs_min
    #a['P_std'] = np.mean(stds[:q_pos])
    #a['T_std'] = np.mean(stds[s_pos:])

    a['Temp_Median_p_5'] = np.percentile(means, 5)
    a['Temp_Median_p_25'] = np.percentile(means, 25)
    a['Temp_Median_p_75'] = np.percentile(means, 75)
    a['Temp_Median_p_95'] = np.percentile(means, 95)

    return a
def heart_beats_features2(thb, rpeaks):
    if len(thb) == 0:
        thb = np.zeros((1, int(0.6 * loader.FREQUENCY)), dtype=np.int32)
    means = heartbeats.median_heartbeat(thb)
    diff_rpeak = np.median(np.diff(rpeaks))
    freq_cof = loader.FREQUENCY
    if diff_rpeak < 280:
        tmp1 = 100 - int(diff_rpeak / 3)
        tmp2 = 100 + int(2 * diff_rpeak / 3)
        for i in range(len(means)):
            if i < tmp1:
                means[i] = 0
            elif i > tmp2:
                means[i] = 0
        freq_cof = diff_rpeak / 300 * loader.FREQUENCY

    a = dict()
    r_list = []
    p_list = []
    q_list = []
    s_list = []
    t_list = []

    for i in range(np.shape(thb)[0]):
        r_pos = int(0.2 * loader.FREQUENCY)
        template = thb[i, :]
        PQ = template[r_pos - int(0.2 * freq_cof):r_pos - int(0.05 * freq_cof)]
        ST = template[r_pos + int(0.05 * freq_cof):r_pos + int(0.4 * freq_cof)]
        QR = template[r_pos - int(0.07 * freq_cof):r_pos]
        RS = template[r_pos:r_pos + int(0.07 * freq_cof)]

        q_list.append(np.min(QR))
        s_list.append(np.min(RS))

        p_list.append(np.max(PQ))
        t_list.append(np.max(ST))
        r_list.append(template[r_pos])

    a['T_P_max'] = np.max(p_list)
    a['T_P_min'] = np.min(p_list)
    a['T_P_std'] = np.std(p_list)
    a['T_Q_max'] = np.max(q_list)
    a['T_Q_min'] = np.min(q_list)
    a['T_Q_std'] = np.std(q_list)
    a['T_R_max'] = np.max(r_list)
    a['T_R_min'] = np.min(r_list)
    a['T_R_std'] = np.std(r_list)
    a['T_S_max'] = np.max(s_list)
    a['T_S_min'] = np.min(s_list)
    a['T_S_std'] = np.std(s_list)
    a['T_T_max'] = np.max(t_list)
    a['T_T_min'] = np.min(t_list)
    a['T_T_std'] = np.std(t_list)

    stds = np.array([np.std(col) for col in thb.T])

    r_pos = int(0.2 * loader.FREQUENCY)

    PQ = means[r_pos - int(0.2 * freq_cof):r_pos - int(0.05 * freq_cof)]
    #ST = means[int(0.25 * loader.FREQUENCY):]
    ST = means[r_pos + int(0.05 * freq_cof):r_pos + int(0.4 * freq_cof)]
    #QR = means[int(0.13 * loader.FREQUENCY):r_pos]
    QR = means[r_pos - int(0.07 * freq_cof):r_pos]
    RS = means[r_pos:r_pos + int(0.07 * freq_cof)]

    #q_pos = int(0.13 * loader.FREQUENCY) + np.argmin(QR)
    q_pos = r_pos - len(QR) + np.argmin(QR)
    s_pos = r_pos + np.argmin(RS)

    p_pos = np.argmax(PQ)
    t_pos = np.argmax(ST)

    t_wave = ST[max(0, t_pos -
                    int(0.08 * freq_cof)):min(len(ST), t_pos +
                                              int(0.08 * freq_cof))]
    p_wave = PQ[max(0, p_pos -
                    int(0.06 * freq_cof)):min(len(PQ), p_pos +
                                              int(0.06 * freq_cof))]

    #r_plus = sum(1 if b[r_pos] > 0 else 0 for b in thb)
    #r_minus = len(thb) - r_plus

    QRS = means[q_pos:s_pos]

    a['PR_interval'] = r_pos - p_pos
    a['P_max'] = PQ[p_pos]
    a['P_min'] = min(PQ)
    a['P_to_R'] = PQ[p_pos] / means[r_pos]
    a['P_to_Q'] = PQ[p_pos] - means[q_pos]
    a['ST_interval'] = t_pos
    a['T_max'] = ST[t_pos]
    a['T_min'] = min(ST)
    a['T_to_R'] = ST[t_pos] / means[r_pos]
    a['T_to_S'] = ST[t_pos] - means[s_pos]
    a['P_to_T'] = PQ[p_pos] / ST[t_pos]
    a['P_skew'] = skew(p_wave)
    a['P_kurt'] = kurtosis(p_wave)
    a['T_skew'] = skew(t_wave)
    a['T_kurt'] = kurtosis(t_wave)
    a['activity'] = calcActivity(means)
    a['mobility'] = calcMobility(means)
    a['complexity'] = calcComplexity(means)
    a['QRS_len'] = s_pos - q_pos

    qrs_min = abs(min(QRS))
    qrs_max = abs(max(QRS))
    qrs_abs = max(qrs_min, qrs_max)
    sign = -1 if qrs_min > qrs_max else 1

    a['QRS_diff'] = sign * abs(qrs_min / qrs_abs)
    a['QS_diff'] = abs(means[s_pos] - means[q_pos])
    a['QRS_kurt'] = kurtosis(QRS)
    a['QRS_skew'] = skew(QRS)
    a['QRS_minmax'] = qrs_max - qrs_min
    a['P_std'] = np.mean(stds[:q_pos])
    a['T_std'] = np.mean(stds[s_pos:])

    a['T_wave_time'] = len(t_wave) / 500
    a['P_wave_time'] = len(p_wave) / 500

    a['Temp_Median_p_5'] = np.percentile(means, 5)
    a['Temp_Median_p_25'] = np.percentile(means, 25)
    a['Temp_Median_p_75'] = np.percentile(means, 75)
    a['Temp_Median_p_95'] = np.percentile(means, 95)

    a.update(fft_features(means))
    return a