예제 #1
0
def get_data_for_patient(patient):
    signal, fields = wfdb.rdsamp(f'{DATA_DIR}/data/{patient}')
    fs = fields['fs']
    r_peaks_ix = processing.gqrs_detect(signal[:, 0], fs=fs, threshold=1.0)

    features = feature_selection(signal, fs, r_peaks_ix)
    return features
예제 #2
0
def get_rr_peaks_indices(record, max_bpm=230):
    """
    :param record_name:
    :param database:
    :param max_bpm:
    :return: list of timestamps for
    """

    qrs_inds = processing.gqrs_detect(sig=record.p_signal[:, 0],
                                      fs=record.fs)
    search_radius = int(record.fs * 60 / max_bpm)
    corrected_peak_inds = processing.correct_peaks(
        record.p_signal[:, 0], peak_inds=qrs_inds,
        search_radius=search_radius, smooth_window_size=150)

    result = []
    discarded_count = 0
    prev_pi = -1
    for pi in corrected_peak_inds:
        if pi != prev_pi:
            result.append(pi)
        else:
            discarded_count += 1
        prev_pi = pi
    # returns r-r peaks timestamps
    result = np.array(result) / record.fs

    return result, discarded_count
예제 #3
0
 def test_pure_prediction(self):
     record_name = self.mitdb + "100"
     sig, fields = wfdb.rdsamp(record_name, channels=[0])
     res = processing.gqrs_detect(sig, fs=fields['fs'])
     wfdb.wrann("100",
                'atr',
                res,
                write_dir="data",
                symbol=(['N'] * len(res)))
     print(res)
     self.assertIsNotNone(res)
def getQRSLocations(file_path):
    '''
    get numpy list of QRS Locations

    Returns:
                    qrs_locs (numpy list): list of QRS locations in the signal

    '''
    record = wfdb.rdrecord(file_path, channels=[0])
    qrs_locs = processing.gqrs_detect(record.p_signal[:, 0], fs=record.fs)
    return qrs_locs
예제 #5
0
def filter_ecg(ecg, fs, get_heart_rate=False, cutoff_frequencies=[0.5, 100.0]):
    nyq_f = fs / 2
    w_low = cutoff_frequencies[0] / (math.pi * nyq_f)
    w_high = cutoff_frequencies[1] / (math.pi * nyq_f)
    filt_order = 4
    b, a = scipy.signal.butter(filt_order, [w_low, w_high], btype='bandpass')
    processed_ecg = scipy.signal.filtfilt(b, a, ecg)
    if get_heart_rate:
        qrs_inds = processing.gqrs_detect(sig=ecg, fs=fs)
        hr = processing.compute_hr(sig_len=len(ecg), qrs_inds=qrs_inds, fs=fs)
        return (processed_ecg, hr)
    else:
        return (processed_ecg)
예제 #6
0
def get_data(age_start, age_stop, limit=1):
    """
    Получение данных пациентов в промежутке возраста от age_start до age_stop (limit по количеству пациентов)
    :return: dict
    """
    data_for_age_range = df.loc[(age_start < df['Age']) & (df['Age'] < age_stop)]

    result = {'data': []}

    for i in range(0, limit):
        try:
            pdf = data_for_age_range.iloc[i]
            fid = pdf['ID']

            signal, fields = wfdb.rdsamp(f'{DATA_DIR}/data/{fid}')
            qrs_locs = processing.gqrs_detect(signal[:, 0], fs=fields['fs'])
            # result['data'].append({'ecg_data': signal.tolist(), 'qrs_ix': qrs_locs.tolist(), 'fields': fields})

            patient_data = {
                    'avatar': f'require("~/assets/images/users/avatar-{randint(1, 4)}.jpg")',
                    'name': choice(["Смирнов", "Кузнецов", "Попов", "Васильев", "Петров", "Соколов", "Михайлов",
                                    "Фролов", "Журавлёв", "Николаев", "Крылов", "Максимов", "Сидоров", "Осипов", "Белоусов",
                                    "Федотов", "Дорофеев", "Егоров", "Матвеев", "Бобров", "Дмитриев","Калинин", 'Петров', "Васильев", "Тылык", "Иванов", "Пушкин", "Лермонтов", "Данилин", "Ванилин", "Герц", "Тесла", "Улец", "Кершин", "Ким"])+' '+choice(['И.', "А.", "В.", "Д.", "К."])+choice(['И.', "А.", "В.", "Д."]),
                    'age': str(pdf['Age']),
                    'id': str(pdf['ID']),
                    'diagnose': pdf['Rhythms'],
                    'state': 'Отклонение от нормы' if pdf['Rhythms'] != 'Sinus rhythm' else 'В норме',
                    'last_visit': f"{randint(1, 31)}/{randint(1, 12)}/2020",
                    'last_data_update': f"{randint(1, 31)}/{randint(1, 12)}/2021",
                    'tmt_online': choice(['Online', 'Offline']),
                    'link': '/dashboard/diagnosis/index2' if pdf['Rhythms'] != 'Sinus rhythm' else '/dashboard/diagnosis',
                  },
            print('{', end='')
            for key, value in patient_data[0].items():

                if key == 'avatar':
                    print(f"{key}: {value}", end=', ')

                else:
                    print(f"{key}: '{value}'", end=', ')
            print('},')
            result['data'].append(patient_data)

        except Exception as e:
            print('Error (getting ecg data): {}'.format(e))
    print(result)
    result = json.dumps(result)
    return result
예제 #7
0
    def test_gqrs(self):

        record = wfdb.rdrecord('sample-data/100', channels=[0],
                                  sampfrom=9998, sampto=19998, physical=False)

        expected_peaks = [271, 580, 884, 1181, 1469, 1770, 2055, 2339, 2634,
                          2939, 3255, 3551, 3831, 4120, 4412, 4700, 5000, 5299,
                          5596, 5889, 6172, 6454, 6744, 7047, 7347, 7646, 7936,
                          8216, 8503, 8785, 9070, 9377, 9682]

        peaks = processing.gqrs_detect(d_sig=record.d_signal[:,0],
                                       fs=record.fs,
                                       adc_gain=record.adc_gain[0],
                                       adc_zero=record.adc_zero[0],
                                       threshold=1.0)

        assert np.array_equal(peaks, expected_peaks)
예제 #8
0
    def test_gqrs(self):

        record = wfdb.rdrecord('sample-data/100', channels=[0],
                                  sampfrom=9998, sampto=19998, physical=False)

        expected_peaks = [271, 580, 884, 1181, 1469, 1770, 2055, 2339, 2634,
                          2939, 3255, 3551, 3831, 4120, 4412, 4700, 5000, 5299,
                          5596, 5889, 6172, 6454, 6744, 7047, 7347, 7646, 7936,
                          8216, 8503, 8785, 9070, 9377, 9682]

        peaks = processing.gqrs_detect(d_sig=record.d_signal[:,0],
                                       fs=record.fs,
                                       adc_gain=record.adc_gain[0],
                                       adc_zero=record.adc_zero[0],
                                       threshold=1.0)

        assert np.array_equal(peaks, expected_peaks)
예제 #9
0
def gqrs_algorithm(filename,
                   sampfrom=None,
                   sampto=None,
                   channel=0,
                   r_peak_inds=None,
                   fig=None,
                   pic_index=1,
                   pic_size=1,
                   skip_flag=False):
    sig, fields = wfdb.rdsamp(filename,
                              channels=[channel],
                              sampfrom=sampfrom,
                              sampto=sampto)
    qrs_inds = processing.gqrs_detect(sig=sig[:, 0], fs=fields['fs'])
    # 标记位置减去采样点开始位置得到相对位置
    r_peak_inds -= sampfrom
    if len(qrs_inds) < 1:
        qrs_inds = np.array([-100])
    if skip_flag:
        return draw_graph(r_peak_inds,
                          sig,
                          fields,
                          'GQRS',
                          qrs_inds,
                          fig=fig,
                          pic_index=pic_index,
                          pic_size=pic_size,
                          skip_flag=skip_flag)
    summary, fig = draw_graph(r_peak_inds,
                              sig,
                              fields,
                              'GQRS',
                              qrs_inds,
                              fig=fig,
                              pic_index=pic_index,
                              pic_size=pic_size)

    return summary, fig
예제 #10
0
def rpeak_gqrs(ecg, fs):
    rr_min = 0.25
    rr_max = 1.5
    res = processing.gqrs_detect(sig=ecg, fs=fs, RRmin=rr_min, RRmax=rr_max)
    return res
예제 #11
0
def ExtractFeatures(dataset, size, minThreshold):
    # Features
    qAmplitudes = []
    rAmplitudes = []
    qrsDurations = []
    rrIntervals = []
    heartRatesDuringHeartBeat = []
    minSize = sys.maxsize

    signals = dataset['signal']
    labels = dataset['label']

    for i, sig in enumerate(signals[:size]):

        print(str(i) + "/" + str(len(signals)) + " ...")
        qrsInds = processing.gqrs_detect(sig=sig.astype('float64'), fs=300)

        heartRates = processing.compute_hr(sig_len=sig.shape[0],
                                           fs=300,
                                           qrs_inds=sorted(qrsInds))

        rPoints, sPoints, qPoints = QRS_util.ECG_QRS_detect(
            sig, 300, True, False)

        lenHb = sys.maxsize
        lenSigQrs = sys.maxsize
        lenHr = sys.maxsize
        lenQ = sys.maxsize
        lenR = sys.maxsize

        if (len(heartRates) > 0 and len(rPoints) > 0):
            # Adding features for each signal.
            heartRatesDuringHeartBeat.append(np.array(heartRates[rPoints]))
            lenHr = len(heartRates[rPoints])

        if (len(qPoints) > 0):
            qAmplitudes.append(np.array(sig[qPoints]))
            lenQ = len(sig[qPoints])

        if (len(rPoints) > 0):
            rAmplitudes.append(np.array(sig[rPoints]))
            lenR = len(sig[rPoints])

        if (len(qPoints) > 0 and len(rPoints) > 0):
            sigQrsDuration = [
                sPoints[i] - qPoints[i] for i in range(len(qPoints) - 1)
            ]
            qrsDurations.append(np.array(sigQrsDuration))
            lenSigQrs = len(sigQrsDuration)

            hbIntervals = [
                rPoints[i + 1] - rPoints[i] for i in range(len(rPoints) - 1)
            ]
            rrIntervals.append(np.array(hbIntervals))
            lenHb = len(hbIntervals)

        minIter = min(lenHb, lenQ, lenR, lenSigQrs, lenHr)

        if minIter < minThreshold:
            # Rollback
            del heartRatesDuringHeartBeat[-1]
            del qAmplitudes[-1]
            del rAmplitudes[-1]
            del qrsDurations[-1]
            del rrIntervals[-1]

        elif minIter < minSize:
            minSize = minIter

    qAmplitudes = np.array(
        [np.array(x[:minSize], dtype='int64') for x in qAmplitudes])
    rAmplitudes = np.array(
        [np.array(x[:minSize], dtype='int64') for x in rAmplitudes])
    rrIntervals = np.array(
        [np.array(x[:minSize], dtype='int64') for x in rrIntervals])
    qrsDurations = np.array(
        [np.array(x[:minSize], dtype='int64') for x in qrsDurations])
    heartRatesDuringHeartBeat = np.array([
        np.array(x[:minSize], dtype='int64') for x in heartRatesDuringHeartBeat
    ])

    qAmplitudes = np.stack(qAmplitudes, axis=0)
    rAmplitudes = np.stack(rAmplitudes, axis=0)
    heartRatesDuringHeartBeat = np.stack(heartRatesDuringHeartBeat, axis=0)
    rrIntervals = np.stack(rrIntervals, axis=0)
    qrsDurations = np.stack(qrsDurations, axis=0)

    return qAmplitudes, rAmplitudes, heartRatesDuringHeartBeat, rrIntervals, qrsDurations, labels[:
                                                                                                  size], minSize
예제 #12
0
from imutils.video import VideoStream
from imutils import face_utils
from threading import Thread
import numpy as np
import pyglet
import argparse
import imutils
import time
import dlib
import cv2

# 1. Read signal
record = wfdb.rdrecord('mit-bih-arrhythmia-database-1.0.0/108', channels=[0])

# 2. Detect QRS locations
qrs_locs = processing.gqrs_detect(record.p_signal[:, 0], fs=record.fs)

# 5. Length of signal
len = record.sig_len

# 6. Compute heart rate
heart_rate = processing.compute_hr(len, qrs_locs, fs=record.fs)

# 7. Remove Nan values from array
heart_rate = heart_rate[~np.isnan(heart_rate)]

# 8. Calculate RR from heart rate
#  RR-interval is shorter and wider for awake subject than drowsy subject.
RR = 60 / heart_rate

# From hrv analysis get frequency features
예제 #13
0
def gqrs_single(fields, record, save_path, sig, save=True):
    r_peaks = processing.gqrs_detect(sig[:, 0], fs=fields['fs'])
    if save:
        save_prediction(r_peaks, record, save_path)
    else:
        return r_peaks
예제 #14
0
import wfdb
from wfdb import processing
import numpy as np

DATA_PATH = "/data/"
SAVE_PATH = "/pred/"

with open(DATA_PATH + "RECORDS", 'r') as f:
    records = f.readlines()
    records = list(map(lambda r: r.strip("\n"), records))

for record in records:
    sig, fields = wfdb.rdsamp(DATA_PATH + record, channels=[0])
    res = processing.gqrs_detect(sig[:, 0], fs=fields['fs'])
    if len(res) > 0:
        wfdb.wrann(record,
                   'atr',
                   res,
                   write_dir=SAVE_PATH,
                   symbol=(['N'] * len(res)))
예제 #15
0
 def detect(self, records):
     return [
         processing.gqrs_detect(sig=record.p_signal.T[0], fs=record.fs)
         for record in records
     ]
예제 #16
0
    ax_left.set_title(title)

    ax_left.set_xlabel('Time (ms)')
    ax_left.set_ylabel('ECG (mV)', color='#3979f0')
    ax_right.set_ylabel('Heart rate (bpm)', color='m')
    #设置颜色使得和线条颜色一致
    ax_left.tick_params('y', colors='#3979f0')
    ax_right.tick_params('y', colors='m')
    if saveto is not None:
        plt.savefig(saveto, dpi=600)
    plt.show()
#加载ECG信号
record=wfdb.rdrecord('./2')  #.hea .dat文件名称
#help(wfdb.rdrecord)
#使用gqrs算法定位qrs波位置
qrs_inds=processing.gqrs_detect(sig=record.p_signal[:, 0], fs=record.fs)  #未矫正位置
#画出结果
#peaks_hr(sig=record.p_signal, peak_inds=qrs_inds, fs=record.fs, title='GQRS peak detection on record 100')
#修正峰值,将其设置为局部最大值
min_bpm=20
max_bpm=230
#使用可能最大的bpm作为搜索半径
search_radius=int(record.fs*60/max_bpm)
corrected_peak_inds=processing.correct_peaks(record.p_signal[:, 0], peak_inds=qrs_inds, search_radius=search_radius, smooth_window_size=150)
#输出矫正后的QRS波峰位置
print('Corrected gqrs detected peak indices:', sorted(corrected_peak_inds))




# Feature 1: 计算R波波峰
예제 #17
0
def dataGeneration(data_path, csv_path, record_path):

    # initialize dataset
    dataset = pd.DataFrame(columns=['label', 'record'])

    if record_path == None:

        # a loop for each patient
        detail_path = data_path + '/'
        record_files = [
            i.split('.')[0] for i in os.listdir(detail_path)
            if (not i.startswith('.') and i.endswith('.hea'))
        ]

        Bar.check_tty = False
        bar = Bar('Processing',
                  max=len(record_files),
                  fill='#',
                  suffix='%(percent)d%%')

        # a loop for each record
        for record_name in record_files:

            # load record
            signal, info = wfdb.rdsamp(detail_path + record_name)

            fs = 200

            signal = processing.resample_sig(signal[:, 0], info['fs'], fs)[0]

            # set some parameters
            window_size_half = int(fs * 0.125 / 2)
            max_bpm = 230

            # detect QRS peaks
            qrs_inds = processing.gqrs_detect(signal, fs=fs)
            search_radius = int(fs * 60 / max_bpm)
            corrected_qrs_inds = processing.correct_peaks(
                signal,
                peak_inds=qrs_inds,
                search_radius=search_radius,
                smooth_window_size=150)

            average_qrs = 0
            count = 0
            for i in range(1, len(corrected_qrs_inds) - 1):
                start_ind = corrected_qrs_inds[i] - window_size_half
                end_ind = corrected_qrs_inds[i] + window_size_half + 1
                if start_ind < corrected_qrs_inds[
                        i - 1] or end_ind > corrected_qrs_inds[i + 1]:
                    continue
                average_qrs = average_qrs + signal[start_ind:end_ind]
                count = count + 1

            # remove outliers
            if count < 8:
                print('\noutlier detected, discard ' + record_name)
                continue

            average_qrs = average_qrs / count

            corrcoefs = []
            for i in range(1, len(corrected_qrs_inds) - 1):
                start_ind = corrected_qrs_inds[i] - window_size_half
                end_ind = corrected_qrs_inds[i] + window_size_half + 1
                if start_ind < corrected_qrs_inds[
                        i - 1] or end_ind > corrected_qrs_inds[i + 1]:
                    corrcoefs.append(-100)
                    continue
                corrcoef = pearsonr(signal[start_ind:end_ind], average_qrs)[0]
                corrcoefs.append(corrcoef)

            max_corr = list(map(corrcoefs.index, heapq.nlargest(8, corrcoefs)))

            index_corr = random.sample(
                list(itertools.permutations(max_corr, 8)), 100)

            for index in index_corr:
                # a temp dataframe to store one record
                record_temp = pd.DataFrame()

                signal_temp = []

                for i in index:
                    start_ind = corrected_qrs_inds[i + 1] - window_size_half
                    end_ind = corrected_qrs_inds[i + 1] + window_size_half + 1
                    sig = processing.normalize_bound(signal[start_ind:end_ind],
                                                     -1, 1)
                    signal_temp = np.concatenate((signal_temp, sig))

                record_temp = record_temp.append(pd.DataFrame(
                    signal_temp.reshape(-1, signal_temp.shape[0])),
                                                 ignore_index=True,
                                                 sort=False)
                record_temp['label'] = record_name
                record_temp['record'] = record_name

                # add it to final dataset
                dataset = dataset.append(record_temp,
                                         ignore_index=True,
                                         sort=False)

            bar.next()
        bar.finish()
    else:
        patient_folders = [
            i for i in os.listdir(data_path)
            if (not i.startswith('.') and i.startswith(record_path))
        ]

        Bar.check_tty = False
        bar = Bar('Processing',
                  max=len(patient_folders),
                  fill='#',
                  suffix='%(percent)d%%')
        # a loop for each patient
        for patient_name in patient_folders:
            detail_path = data_path + patient_name + '/'
            record_files = [
                i.split('.')[0] for i in os.listdir(detail_path)
                if i.endswith('.hea')
            ]

            # a loop for each record
            for record_name in record_files:

                # load record
                signal, info = wfdb.rdsamp(detail_path + record_name)

                fs = 200

                signal = processing.resample_sig(signal[:, 0], info['fs'],
                                                 fs)[0]

                # set some parameters
                window_size_half = int(fs * 0.125 / 2)
                max_bpm = 230

                # detect QRS peaks
                qrs_inds = processing.gqrs_detect(signal, fs=fs)
                search_radius = int(fs * 60 / max_bpm)
                corrected_qrs_inds = processing.correct_peaks(
                    signal,
                    peak_inds=qrs_inds,
                    search_radius=search_radius,
                    smooth_window_size=150)

                average_qrs = 0
                count = 0
                for i in range(1, len(corrected_qrs_inds) - 1):
                    start_ind = corrected_qrs_inds[i] - window_size_half
                    end_ind = corrected_qrs_inds[i] + window_size_half + 1
                    if start_ind < corrected_qrs_inds[
                            i - 1] or end_ind > corrected_qrs_inds[i + 1]:
                        continue
                    average_qrs = average_qrs + signal[start_ind:end_ind]
                    count = count + 1

                # remove outliers
                if count < 8:
                    print('\noutlier detected, discard ' + record_name +
                          ' of ' + patient_name)
                    continue

                average_qrs = average_qrs / count

                corrcoefs = []
                for i in range(1, len(corrected_qrs_inds) - 1):
                    start_ind = corrected_qrs_inds[i] - window_size_half
                    end_ind = corrected_qrs_inds[i] + window_size_half + 1
                    if start_ind < corrected_qrs_inds[
                            i - 1] or end_ind > corrected_qrs_inds[i + 1]:
                        corrcoefs.append(-100)
                        continue
                    corrcoef = pearsonr(signal[start_ind:end_ind],
                                        average_qrs)[0]
                    corrcoefs.append(corrcoef)

                max_corr = list(
                    map(corrcoefs.index, heapq.nlargest(8, corrcoefs)))

                index_corr = random.sample(
                    list(itertools.permutations(max_corr, 8)), 100)

                for index in index_corr:
                    # a temp dataframe to store one record
                    record_temp = pd.DataFrame()

                    signal_temp = []

                    for i in index:
                        start_ind = corrected_qrs_inds[i +
                                                       1] - window_size_half
                        end_ind = corrected_qrs_inds[i +
                                                     1] + window_size_half + 1
                        sig = processing.normalize_bound(
                            signal[start_ind:end_ind], -1, 1)
                        signal_temp = np.concatenate((signal_temp, sig))

                    record_temp = record_temp.append(pd.DataFrame(
                        signal_temp.reshape(-1, signal_temp.shape[0])),
                                                     ignore_index=True,
                                                     sort=False)
                    record_temp['label'] = patient_name
                    record_temp['record'] = record_name

                    # add it to final dataset
                    dataset = dataset.append(record_temp,
                                             ignore_index=True,
                                             sort=False)

            bar.next()
        bar.finish()

    # save for further use
    dataset.to_csv(csv_path, index=False)

    print('processing completed')