Пример #1
0
def calculate_hr(signal_data, timestamps=None):
    sampling_rate = 47.63
    if timestamps is not None:
        sampling_rate = hp.get_samplerate_mstimer(timestamps)
        try:
            wd, m = hp.process(signal_data, sample_rate=sampling_rate)
            hr_bpm = m["bpm"]
        except:
            hr_bpm = 75.0

        if np.isnan(hr_bpm):
            hr_bpm = 75.0
        return hr_bpm

    else:
        # We are working with predicted HR:
        # need to filter and do other stuff.. lets see
        signal_data = hp.filter_signal(signal_data,
                                       cutoff=[0.7, 2.5],
                                       sample_rate=sampling_rate,
                                       order=6,
                                       filtertype='bandpass')
        try:
            wd, m = hp.process(signal_data,
                               sample_rate=sampling_rate,
                               high_precision=True,
                               clean_rr=True)
            hr_bpm = m["bpm"]
        except:
            print(
                "BadSignal received (could not be filtered) using def HR value = 75bpm"
            )
            hr_bpm = 75.0
        return hr_bpm
Пример #2
0
def get_peak_error_features(data_sample,
                            sample_rate=100,
                            rpeak_detector=0,
                            low_rri=300,
                            high_rri=2000):
    rules = ["malik", "karlsson", "kamath", "acar"]
    try:
        wd, m = hp.process(data_sample, sample_rate, calc_freq=True)
    except:
        try:
            wd, m = hp.process(data_sample, sample_rate)
        except:
            error_dict = {rule + "_error": np.nan for rule in rules}
            error_dict["outlier_error"] = np.nan
            return error_dict

    if rpeak_detector in [1, 2, 3, 4]:
        detector = PeakDetector(wave_type='ecg')
        peak_list = detector.ppg_detector(data_sample,
                                          rpeak_detector,
                                          preprocess=False)[0]
        wd["peaklist"] = peak_list
        wd = calc_rr(peak_list, sample_rate, working_data=wd)
        wd = check_peaks(wd['RR_list'],
                         wd['peaklist'],
                         wd['ybeat'],
                         reject_segmentwise=False,
                         working_data=wd)
        wd = clean_rr_intervals(working_data=wd)

    rr_intervals = wd["RR_list"]

    rr_intervals_cleaned = remove_outliers(rr_intervals,
                                           low_rri=low_rri,
                                           high_rri=high_rri)
    number_outliers = len(np.where(np.isnan(rr_intervals_cleaned))[0])
    outlier_ratio = number_outliers / (len(rr_intervals_cleaned) -
                                       number_outliers)

    error_sqi = {}
    error_sqi['outlier_error'] = outlier_ratio

    interpolated_rr_intervals = interpolate_nan_values(rr_intervals_cleaned)

    for rule in rules:
        nn_intervals = remove_ectopic_beats(interpolated_rr_intervals,
                                            method=rule)
        number_ectopics = len(np.where(np.isnan(nn_intervals))[0])
        ectopic_ratio = number_ectopics / (len(nn_intervals) - number_ectopics)
        error_sqi[rule + "_error"] = ectopic_ratio

    return error_sqi
Пример #3
0
def analyzeECG(request, version):
    response_data = {}
    if version == 'v1':
        if request.method == "GET":
            path = getECG(request.GET.get('id'), 0)
            data = hp.get_data(path)
            # print(data)

            working_data, measures = hp.process(data, 100.0)
            clean_dict = {
                k: measures[k]
                for k in measures if not isnan(measures[k])
            }
            # print(measures['bpm'])
            # print(measures['rmssd'])
            # print(measures)
            # hp.plotter(working_data, measures)
            response_data['status'] = "success"
            response_data['data'] = clean_dict
            print(type(clean_dict))
            return JsonResponse(response_data)
        else:
            response_data['status'] = "error"
            response_data['message'] = "invalid request"
            return JsonResponse(response_data)
    else:
        response_data['status'] = 'failure'
        response_data['message'] = 'API version does not exist'
        return JsonResponse(response_data)
Пример #4
0
    def get_heartrate_and_breathing(self, data):
        framerate = self.framerate
        if self.resample != -1:
            data = resample(data,
                            (len(data) // self.framerate) * self.resample)
            framerate = self.resample

        if self.filter:
            data = hp.filter_signal(data, [0.7, 3.5],
                                    sample_rate=framerate,
                                    order=3,
                                    filtertype='bandpass')
            data = hp.scale_data(data)

        wd, m = hp.process(data, framerate, high_precision=True, clean_rr=True)

        self.m = m
        self.wd = wd
        hr = m["bpm"]
        rr = m["breathingrate"]

        if self.show:
            hp.plotter(wd, m)

        if self.save_path != '':
            save_plot(data, x_label="Time", y_label="BVP Signal")

        return hr, rr * 60
Пример #5
0
    def process_ecg(self):
        """Runs heartpy.process on up-sampled data and creates a timestamp for each detected beat"""

        print("\n" + "Detecting peaks using the HeartPy algorithm...")

        # Upsamples data by a factor of 4 to improve peak index resolution
        self.ecg_resampled = resample(
            self.ecg_filtered,
            len(self.ecg_filtered) * self.resample_factor)

        self.ecg_scaled = heartpy.scale_data(
            [float(i) for i in self.ecg_resampled])

        # Processes data using standard heartpy processing
        self.wd, self.summary = heartpy.process(
            hrdata=self.ecg_scaled,
            sample_rate=self.signal_frequency * self.resample_factor)

        # Retrieves peaks that got removed in check process
        for peak in self.wd["peaklist"]:
            if peak not in self.wd["peaklist_cor"]:
                self.corrected_peaks.append(peak)

        # Creates a timestamp for every beat using peak indexes
        for peak in self.wd["peaklist_cor"]:
            self.beat_timestamps.append(self.starttime + timedelta(
                seconds=peak / (self.signal_frequency * self.resample_factor)))

        print("Peak detection complete.")
Пример #6
0
    def clicked1():
        wd, m = hp.process(np.array(d), 150)

        for measure in m.keys():
            #configfile.insert(END, (measure, m[measure]))
            print('%s: %f' % (measure, m[measure]))
        configfile.insert(END, m['bpm'])
Пример #7
0
def EvaluateNEATBiostate(BVP_array, EDA_array, genomeList, currentGenomeID):

    working_data, hb_measure = hb.process(BVP_array, 64.0, report_time=True)

    processed_eda = nk.eda_process(EDA_array, freq=1.9, sampling_rate=4)

    #Do the evaluation stuff
    return 0
Пример #8
0
def get_heartrate(ppg_signal, sample_rate):
    try:
        _, measures = hp.process(ppg_signal, sample_rate)
        hr = measures['bpm']
        return hr

    except Exception as exc:
        return 'HeartPy Exception'
Пример #9
0
def get_heartbeats(ecg, hz=360, constant=90):
    import heartpy
    try:
        if type(ecg) is list:
            w, m = heartpy.process(pd.Series(ecg), hz)
        else:
            w, m = heartpy.process(ecg, hz)
    except BadSignalWarning:
        raise BadFeatureGenerationException()

    peaklist = w["peaklist_cor"]
    heartbeats = []
    for i in range(len(peaklist) - 1):
        if i == 0 and peaklist[i] - constant < 0:
            continue
        ii = peaklist[i] - constant
        jj = ii + 300
        heartbeats.append(ecg[ii:jj])
    return heartbeats, w, m
Пример #10
0
 def analyse_data(self):
     try:
         sample_rate = 250
         data = hp.get_data('najnowszy2.csv')
         filtered = hp.filter_signal(
             data, cutoff=0.05, sample_rate=sample_rate, filtertype='notch')
         working_data, measures = hp.process(filtered, sample_rate)
         return data, working_data, measures
     except hp.exceptions.BadSignalWarning as err:
         print(err)
         return None, None, None
Пример #11
0
def getPPGfeatures(sampleRate, PPG):
    wd, m = hp.process(PPG, sample_rate = sampleRate, calc_freq = True) 

    #Without that comment the lib will plot the pieces of PPG and you can see how is doing
    '''plt.figure(figsize=(12,4))
    #call plotter
    hp.plotter(wd, m)'''
    #display measures computed
    #for measure in m.keys():
    #    print('%s: %f' %(measure, m[measure]))
    
    return m
Пример #12
0
def get_bpm(ecg_signal, sample_rate):
    """
    calculate bpm filtering the signal and upsampling it for better results
    :param ecg_signal: 1 lead from an ecg
    :param sample_rate: the sample rate of the ecg
    :param start_at: this defines the start portion of the ecg that you want to analyse
    :param finish_at: this defines the end portion of the ecg that you want to analyse
    :return: the bpm for the given sequence
    """
    upsampled = scipy.signal.resample(ecg_signal, len(ecg_signal) * 4)
    wd, m = hp.process(hp.scale_data(upsampled), sample_rate * 4)

    for measure in m.keys():
        if measure == 'bpm':
            return m[measure]
Пример #13
0
def wave_slicing(sig_data, pre_num, after_num, fs, slices_num):
    data_length = slices_num *(pre_num + after_num)
    if sig_data.shape[0] < data_length :
      print('data is less than ', data_length )
      return np.array()
    sig_data = denoise(sig_data[0:data_length])
    #print('sig_data shape',sig_data.shape)
    #print(sig_data)
  

    data_scale = hp.scale_data(sig_data)
    record_sliced = []
    try:
      # get the location of R wave
      working_data, measures = hp.process(hrdata= data_scale,
                                            sample_rate = fs,
                                            bpmmin=5, bpmmax= 300)
      # get index of R waves
      peaklists = working_data['peaklist']
      # remove the first one and last one
      peaklists = peaklists[1:-1]
      print("index of R waves:", peaklists , '\n len(peaklists):', len(peaklists))

      # get the wave
      for i in peaklists[0:slices_num]:
        #print(i)
        tem_data = data_scale[i - pre_num: i + after_num]
        #print('sliced data shape', tem_data.shape)
        #print('tem_data type:', type(tem_data))
        record_sliced.append(tem_data)
        #print('append tem_data')

      #plot sample
      #plt.plot(record_sliced[-1])
      #title = str(peaklists[-1])
      #plt.title(title)
      #plt.show()

      record_sliced = np.array(record_sliced).T

      print('record_sliced shape:',record_sliced.shape)
    
    except Exception as e:
      print('error:', e)

    return record_sliced
Пример #14
0
def resamples(data, filtered, sample_rate):
    """
    функция для нормализации сигнала
    :param data: исходные данные
    :param filtered: отфильтрованный сигнал
    :param sample_rate: шаг
    :return: wd -содержит пары пиков и множество других характеристик сигнала, m - статистика по сигналу
    """

    resampled_data = resample(data, len(filtered))
    #scale_data - функция, которая масштабирует передаваемые данные так, чтобы они указали границы
    #в любом другом исполнении не работает
    print(hp.scale_data(resampled_data))
    wd, m = hp.process(hp.scale_data(resampled_data), sample_rate * 2)
    # plt.figure(figsize=(12, 4))
    # hp.plotter(wd, m)

    return wd, m
Пример #15
0
    def get_ppg_info(self, ppg_data, time, id):
        # 5000*4 = 20 seconds
        seconds = 5
        points = seconds / 0.004
        bpm = 0
        if len(self.ppg_list) >= points:
            try:
                working_data, measures = hp.process(np.array(self.ppg_list),
                                                    250.0)
                bpm = measures['bpm']
            except:
                print('bad signal: check connection')
            self.ppg_list.clear()
            ppg = PPG(bpm, time, id)
            self.insert_heart_info(ppg)
            print(ppg.bpm)
            return ppg

        self.ppg_list.append(float(ppg_data))
        return 0
Пример #16
0
    def get_bpm_estimate(self, time_data, cam_data):

        fps = hp.get_samplerate_datetime(time_data, '%S.%f')

        cam_bpm = 0

        filtered_ppg_r = hp.filter_signal(cam_data,
                                          cutoff=[0.8, 1],
                                          filtertype='bandpass',
                                          sample_rate=fps,
                                          order=4,
                                          return_top=False)
        try:
            working_data, measures = hp.process(cam_data, fps)
        except BadSignalWarning:
            print("Bad signal")
        else:
            if (measures['bpm'] > 40 and measures['bpm'] < 180):
                cam_bpm = measures['bpm']

        return filtered_ppg_r, cam_bpm
Пример #17
0
    def run_analysis(self, plot=False):

        # Filter the signal
        filtered = hp.filter_signal(self.data,
                                    cutoff=0.05,
                                    sample_rate=self.sample_rate,
                                    filtertype='notch')

        # Run analysis
        wd, m = hp.process(hp.scale_data(filtered), self.sample_rate)

        if plot:
            # Visualise in plot of custom size
            plt.figure(figsize=(12, 4))
            hp.plotter(wd, m)

        # Display computed measures
        for measure in m.keys():
            print('%s: %f' % (measure, m[measure]))

        return m
Пример #18
0
def check_signal(data,
                 sample_rate=100.0,
                 bpmmin=30,
                 bpmmax=150,
                 window_size=128,
                 thresh_val=0.8,
                 thresh_pct=0.5):
    # nan 을 이전 값으로 채움
    data = pd.DataFrame(data).fillna(method='ffill',
                                     axis=0).fillna(method='bfill',
                                                    axis=0).values.ravel()

    is_valid_signal = True
    # run the analysis
    try:
        wd, m = hp.process(
            data,
            sample_rate=sample_rate,
            bpmmin=bpmmin,
            bpmmax=bpmmax,
        )
    # except hp.exceptions.BadSignalWarning:
    except:
        is_valid_signal = False

    if not is_valid_signal:
        return False

    peaks = np.array(wd["peaklist"])
    if len(peaks) == 0:
        return False

    is_normal = topological_abnorality_check(data,
                                             peaks,
                                             window_size=window_size,
                                             thresh_val=thresh_val,
                                             thresh_pct=thresh_pct)

    return is_valid_signal & is_normal
Пример #19
0
def replace(data, sampleRate):
    working_data, measures = hp.process(data, sampleRate, bpmmax=220)
    peaks = working_data['peaklist']
    
    prev_loc = 0
    hr_list = []
    ibi_list = []
    
    for loc in peaks:
        frame = loc - prev_loc
        
        hr = 60/(frame/sampleRate)
        hr_list.extend([hr]*frame)
        
        ibi = (frame/sampleRate)*1000
        ibi_list.extend([-1.0]*(frame-1)+[ibi])
        
        prev_loc = loc
        
    hr_list.extend([hr]*(len(data) - prev_loc))
    ibi_list.extend([-1.0]*(len(data) - prev_loc))
    
    return hr_list, ibi_list
Пример #20
0
    def get_ppg_info(self, ppg_data, time, id):
        # 5000*4 = 20 seconds
        seconds = 5
        points = seconds / 0.004
        bpm = 0
        measures = {}
        ppg = {}
        if len(self.ppg_list) >= points:
            try:
                working_data, measures = hp.process(np.array(self.ppg_list),
                                                    250.0)
                bpm = measures['bpm']
            except:
                print('bad signal, continue')
            self.ppg_list.clear()
            if bpm > 100 or measures == {}: bpm = 99.99
            ppg = PPG(bpm, time, id, measures)
            self.insert_heart_info(ppg)
            print(ppg.bpm)
            return ppg

        self.ppg_list.append(float(ppg_data))
        return 0
Пример #21
0
def process_ecg(data, show=False, framerate=BASE_FREQUENCY):
    filtered = hp.filter_signal(data, [0.7, 3.5],
                                sample_rate=framerate,
                                order=3,
                                filtertype='bandpass')
    #filtered = hp.remove_baseline_wander(filtered, FREQUENCY)
    wd, m = hp.process(hp.scale_data(filtered), framerate)
    if show:
        print(wd.keys())
        print(m.keys())
        hp.plotter(wd, m)

    save_plot(wd["breathing_signal"],
              str(framerate) + "breathing_signal_hp.png",
              framerate,
              x_label='Time (' + str(framerate) + 'hz)',
              y_label='Breathing Signal')

    hr = m["bpm"]
    rr = m["breathingrate"]
    RR_list = wd["RR_list"]

    return hr, rr, RR_list
Пример #22
0
def findPeaks(filteredValues, fs):
    windowData, measure = hp.process(filteredValues,
                                     sample_rate=fs,
                                     calc_freq=True)
    peaks = windowData['peaklist']

    # remove very close peaks - probably false peak detected
    peakFindingIteration = 3  # TODO: change values if there are VERY CLOSE fake peaks detected
    for q in range(peakFindingIteration):
        peaksToRemove = []
        # TODO: change value if threshold too high or too low
        peakWidthThreshold = np.mean(
            np.diff(peaks)) * 0.60  # 60% of average peak widths
        # print(f"peak finding iteration {q}: threshold: {peakWidthThreshold}, aveWidth: {np.mean(np.diff(peaks))}")

        for i in range(len(peaks) - 1):
            cur, nxt = peaks[i], peaks[i + 1]
            if (abs(nxt - cur) < peakWidthThreshold):
                peaksToRemove.append(
                    cur if filteredValues[cur] < filteredValues[nxt] else nxt)

        peaks = [x for x in peaks if x not in peaksToRemove]

    return peaks
Пример #23
0
    def preprocess_data(self):
        print('DM - preprocess_data')
        # run analysis
        self.heartpy_params['wd'], self.heartpy_params['m'] = hp.process(
            self.raw_data, self.fs)
        print(self.heartpy_params['wd']['peaklist'])
        print(self.heartpy_params['wd']['peaklist'][1])

        print(type(self.heartpy_params['wd']['peaklist']))
        peaklist = self.heartpy_params['wd']['peaklist']
        beats = []

        for count, value in enumerate(peaklist, start=2):
            print(value, count)
            if count < len(peaklist):
                t1 = peaklist[count - 2]
                t2 = peaklist[count - 1]
                beats.append(self.raw_data[t1:t2])

        # display computed measures
        for measure in self.heartpy_params['m'].keys():
            print('%s: %f' % (measure, self.heartpy_params['m'][measure]))

        return beats
Пример #24
0
import heartpy as hp
from scipy.io import wavfile

sample_rate, samples = wavfile.read("heartbeat.wav")
working_data, measures = hp.process(samples, sample_rate, report_time=True)

print(measures['bpm'])  #returns BPM value
print(measures['rmssd'])  # returns RMSSD HRV measure
Пример #25
0
def PPNet_preprocess_Mat(path):
    '''
    :param path: label file path
    :return: delta pulse
    '''

    data = loadmat(path)['p']

    #size = 125
    time = 2
    fs = 125
    interval = time * fs  # 250

    down_sample = 4

    ppg = []
    sbp = []  # Systolic Blood Pressure
    dbp = []  # Diastolic Blood Pressue
    hr = []  # Heart Rate

    for i in range(1000):
        temp_mat = data[0, i]

        max_bp = max(temp_mat[1])
        min_bp = min(temp_mat[1])

        if max_bp > 180 or max_bp < 80:
            continue

        if min_bp > 130 or min_bp < 60:
            continue

        try:
            wd, m = hp.process(temp_mat[0],
                               sample_rate=fs,
                               bpmmax=max_bp,
                               bpmmin=min_bp)
            if m['bpm'] < 40 or m['bpm'] > 220:
                continue
        except hp.exceptions.BadSignalWarning:
            continue

        temp_mat_ppg = temp_mat[0]
        temp_mat_ppg -= np.mean(temp_mat_ppg)
        temp_mat_ppg /= np.std(temp_mat_ppg)

        temp_length = temp_mat.shape[1]

        iteration = (int)((temp_length - 1000) / 250 + 1)

        ppg_tmp = []
        sbp_tmp = []
        dbp_tmp = []
        hr_tmp = []

        for j in range(iteration):
            temp_ppg = temp_mat_ppg[j * interval:j * interval + 1000]
            temp_bp = temp_mat[1, j * interval:j * interval + 1000]
            bpmax = max(temp_bp)
            bpmin = min(temp_bp)
            try:
                wd, m = hp.process(temp_ppg,
                                   sample_rate=fs,
                                   bpmmax=bpmax,
                                   bpmmin=bpmin)
            except hp.exceptions.BadSignalWarning:
                continue

            ppg_tmp.append(temp_ppg.reshape(-1, down_sample).mean(axis=1))
            sbp_tmp.append(max(temp_bp))
            dbp_tmp.append(min(temp_bp))
            hr_tmp.append(np.mean(wd['hr']))

        sbp_tmp -= np.mean(sbp_tmp)
        sbp_tmp /= np.std(sbp_tmp)

        dbp_tmp -= np.mean(dbp_tmp)
        dbp_tmp /= np.std(dbp_tmp)

        hr_tmp -= np.mean(hr_tmp)
        hr_tmp /= np.std(hr_tmp)

        ppg.extend(ppg_tmp)
        sbp.extend(sbp_tmp)
        dbp.extend(dbp_tmp)
        hr.extend(hr_tmp)

    return ppg, sbp, dbp, hr
Пример #26
0
def EvaluateAdaptiveBiostate(BVP_array=None, EDA_array=None):
    global hb_measures
    global m_baseHR
    global m_baseHRV
    global m_previousHR
    global m_previousHRV

    global EDA_measures
    global m_baseTonic
    global m_basePhasic
    global m_previousTonic
    global m_previousPhasic

    global m_prevLevel
    global m_curLevel
    global m_lastAction

    global levelStatesList
    global progressionStateList
    global m_Iteration
    #1: higher arousal
    #0: no notificable change
    #-1: lower arousal

    hr_rate = 0
    hrv_rate = 0
    tonic_rate = 0
    phasic_rate = 0

    if BVP_array is not None:
        working_data, hb_measure = hb.process(BVP_array,
                                              64.0,
                                              report_time=True)
    #TODO: Test the difference between resting and playing against the easiest possible character
    # High heart rate and high HRV = decrease level

    if EDA_array is not None:
        current_EDA = nk.eda_process(EDA_array, freq=1.9, sampling_rate=4)

    current_HR = hb_measure['bpm']
    current_HRV = hb_measure['rmssd']

    current_Tonic = current_EDA['df']['EDA_Tonic']
    current_Phasic = current_EDA['df']['EDA_Phasic']

    current_Tonic_mean = np.mean(current_Tonic)
    current_Phasic_mean = np.mean(current_Phasic)
    # Firstly, is he excited compared to baseline this is for HR and EDA
    # Secondly, is he exicted compared to previous
    # 1:0 : Might need to switch back
    # 0:1 : switch up
    # 0:0 : switch up
    # 1:1 : stay
    #Do the evaluation stuff

    #If there is NO difference significantly between HR & EDA and the arousal was higher before, switch back

    #HR
    hr_state = m_baseHR * percentage_change < current_HR
    if m_previousHR == None:
        hr_rate = 1 if hr_state else 0
    elif hr_state == 1:
        prev_hr_state = m_previousHR * percentage_change
        if prev_hr_state < current_HR:
            hr_rate = 1
        elif current_HR * percentage_change < m_previousHR:
            hr_rate = -1
        else:
            hr_rate = 0
    else:
        hr_rate = 0

    #HRV, use HRV in the end.
    hrv_state = m_baseHRV > current_HRV * percentage_change
    if m_previousHRV == None:
        hrv_rate = 1 if hrv_state else 0  #Compare with previous set
    elif hrv_state == 1:
        prev_hrv_state = m_previousHRV
        if prev_hrv_state > current_HRV * percentage_change:
            hrv_rate = 1
        elif current_HRV > m_previousHRV * percentage_change:
            hrv_rate = -1
        else:
            hrv_rate = 0
    else:
        if current_HRV > m_previousHRV * percentage_change:
            hrv_rate = -1
        elif current_HRV * percentage_change < m_previousHRV:
            hrv_rate = 1
        else:
            hrv_rate = -1 if current_HRV > m_baseHRV * percentage_change else 0

    #EDA Tonic

    tonic_stats = mw(current_Tonic, m_baseTonic, alternative='greater')

    if m_previousTonic is None:
        if tonic_stats.pvalue <= p_value:
            tonic_rate = 1  #Increase or stay
        else:
            tonic_rate = 0  #Increase!
    else:
        if tonic_stats.pvalue > p_value:
            tonic_rate = 1  #must upgrade
        else:
            tonic_greater_stats = mw(current_Tonic,
                                     m_previousTonic,
                                     alternative='greater')
            tonic_less_stats = mw(current_Tonic,
                                  m_previousTonic,
                                  alternative='less')
            if tonic_greater_stats.pvalue <= p_value:
                # This is good. Stay or increase
                tonic_rate = 1
            elif tonic_less_stats.pvalue <= p_value:
                tonic_rate = -1  #Revert back to the previous!
            else:
                tonic_rate = 0

    #EDA Phasic
    phasic_stats = mw(current_Phasic, m_basePhasic, alternative='greater')

    if m_previousPhasic is None:
        if phasic_stats.pvalue <= p_value:
            phasic_rate = 1
        else:
            phasic_rate = 0
    else:
        if phasic_stats.pvalue > p_value:
            phasic_rate = 1
        else:
            phasic_greater_stats = mw(current_Phasic,
                                      m_previousPhasic,
                                      alternative='greater')
            phasic_less_stats = mw(current_Phasic,
                                   m_previousPhasic,
                                   alternative='less')
            if phasic_greater_stats.pvalue <= p_value:
                #stay! Or increae
                phasic_rate = 1
            elif phasic_less_stats.pvalue <= p_value:
                #Revert back
                phasic_rate = -1
            else:
                #increase! depending on the previous action
                phasic_rate = 0

    #Phasic component is the main,as
    result = 0

    #Higher arousal
    if ((phasic_rate + tonic_rate + hr_rate) / 3.0) > 0.5:
        #Check last action
        if m_lastAction == m_DECREASE:
            if m_curLevel == 1:
                result = 0
                m_lastAction = m_STAY
            elif levelStatesList[m_curLevel - 2]['HR_mean'] is None:
                result = -1
                m_lastAction = m_DECREASE
            else:
                lowerAffectiveState = (
                    (1 if levelStatesList[m_curLevel -
                                          2]['HR_mean'] < current_HR else 0) +
                    (1 if levelStatesList[m_curLevel - 2]['HRV'] > current_HRV
                     else 0) +
                    (1 if levelStatesList[m_curLevel - 2]['Tonic_mean'] <
                     current_Tonic_mean else 0) +
                    (1 if levelStatesList[m_curLevel - 2]['Phasic_mean'] <
                     current_Phasic_mean else 0)) / 4
                if levelStatesList[m_curLevel - 2]['HR_mean'] is None:
                    result = -1
                    m_lastAction = m_DECREASE
                elif lowerAffectiveState > 0.5:
                    result = -1
                    m_lastAction = m_DECREASE
                else:
                    result = 0
                    m_lastAction = m_STAY
        elif m_lastAction == m_INCREASE:
            if m_curLevel == 5:
                result = 0
                m_lastAction = m_STAY
            elif levelStatesList[m_curLevel]['HR_mean'] is None:
                result = 1
                m_lastAction = m_INCREASE
            else:
                upperAffectiveState = (
                    (1 if levelStatesList[m_curLevel]['HR_mean'] < current_HR
                     else 0) +
                    (1 if levelStatesList[m_curLevel]['HRV'] > current_HRV else
                     0) + (1 if levelStatesList[m_curLevel]['Tonic_mean'] <
                           current_Tonic_mean else 0) +
                    (1 if levelStatesList[m_curLevel]['Phasic_mean'] <
                     current_Phasic_mean else 0)) / 4
                if upperAffectiveState > 0.5:
                    if hrv_rate == -1:
                        result = -1
                        m_lastAction = m_DECREASE
                    else:
                        result = 1
                        m_lastAction = m_INCREASE
                else:
                    result = 0
                    m_lastAction = m_STAY
        else:
            if hrv_rate == -1:
                result = -1
                m_lastAction = m_DECREASE
            elif hrv_rate == 0:
                result = 0
                m_lastAction = m_STAY
            else:
                result = 1
                m_lastAction = m_INCREASE
    # significant lower arousal -- SHOULD NOT STAY
    elif ((phasic_rate + tonic_rate + hr_rate) / 3.0) < 0.0:
        #REVERT!
        if m_curLevel == 1:
            result = 1
            m_lastAction = m_INCREASE
        elif m_curLevel == 5:
            result = -1
            m_lastAction = m_DECREASE
        elif m_lastAction == m_DECREASE:
            result = 1
            m_lastAction = m_INCREASE
        elif m_lastAction == m_INCREASE:
            result = -1
            m_lastAction = m_DECREASE
        else:
            upperAffectiveState = (
                (1 if levelStatesList[m_curLevel]['HR_mean'] < current_HR else
                 0) +
                (1 if levelStatesList[m_curLevel]['HRV'] > current_HRV else 0)
                + (1 if levelStatesList[m_curLevel]['Tonic_mean'] <
                   current_Tonic_mean else 0) +
                (1 if levelStatesList[m_curLevel]['Phasic_mean'] <
                 current_Phasic_mean else 0)) / 4
            lowerAffectiveState = (
                (1 if levelStatesList[m_curLevel - 2]['HR_mean'] < current_HR
                 else 0) +
                (1 if levelStatesList[m_curLevel - 2]['HRV'] > current_HRV else
                 0) + (1 if levelStatesList[m_curLevel - 2]['Tonic_mean'] <
                       current_Tonic_mean else 0) +
                (1 if levelStatesList[m_curLevel - 2]['Phasic_mean'] <
                 current_Phasic_mean else 0)) / 4
            if upperAffectiveState > 0.5:
                m_lastAction = m_DECREASE
                result = -1
            elif lowerAffectiveState > 0.5:
                m_lastAction = m_INCREASE
                result = 1
            else:
                m_lastAction = m_DECREASE
                result = -1

    #No real change between this and the previous, do the same action again
    else:
        if m_previousPhasic is None:
            result = 1
            m_lastAction = m_INCREASE
        elif m_curLevel == 1:
            result = 1
            m_lastAction = m_INCREASE
        elif m_curLevel == 5:
            result = -1
            m_lastAction = m_DECREASE
        elif m_lastAction == m_DECREASE:
            result = -1
        elif m_lastAction == m_INCREASE:
            result = 1
        else:
            result = 0
            m_lastAction = m_STAY

    #Finish off

    m_prevLevel = m_curLevel
    m_curLevel += result
    if m_curLevel > 5:
        m_curLevel = 5
    elif m_curLevel < 1:
        m_curLevel = 1

    m_previousHR = current_HR
    m_previousHRV = current_HRV

    levelStatesList[m_prevLevel - 1]['HR_mean'] = m_previousHR
    levelStatesList[m_prevLevel - 1]['HRV'] = m_previousHRV

    progressionStateList[m_Iteration]['HR_mean'] = m_previousHR
    progressionStateList[m_Iteration]['HRV'] = m_previousHRV

    m_previousTonic = current_Tonic
    m_previousPhasic = current_Phasic

    levelStatesList[m_prevLevel - 1]['Tonic_mean'] = current_Tonic_mean
    levelStatesList[m_prevLevel - 1]['Phasic_mean'] = current_Phasic_mean

    progressionStateList[m_Iteration]['Tonic_mean'] = current_Tonic_mean
    progressionStateList[m_Iteration]['Phasic_mean'] = current_Phasic_mean

    progressionStateList[m_Iteration]['Level'] = m_prevLevel

    m_Iteration += 1
    print("Baseline HR: {0}    HRV: {1}".format(m_baseHR, m_baseHRV))
    print(
        "Phasic:{0}, tonic: {1}, hr: {2}(BPM){3:.3f}, hrv: {4}(RMSSD){5:.3f}".
        format(phasic_rate, tonic_rate, hr_rate, current_HR, hrv_rate,
               current_HRV))
    print("Done with result: {0}".format(result))
    return result
Пример #27
0
def ectopic_sqi(
    data_sample,
    rule_index=0,
    sample_rate=100,
    rpeak_detector=0,
    wave_type='ppg',
    low_rri=300,
    high_rri=2000,
):
    """
    Evaluate the invalid peaks (which exceeds normal range)
    base on HRV rules: Malik, Karlsson, Kamath, Acar
    Output the ratio of invalid
    Parameters
    ----------
    data_sample :

    rule_index:
        0: Default Outlier Peak
        1: Malik
        2: Karlsson
        3: Kamath
        4: Acar
        (Default rule is Malik)

    sample_rate :
        (Default value = 100)
    rpeak_detector :
        (Default value = 0)
        To explain other detector options
    low_rri :
        (Default value = 300)
    high_rri :
        (Default value = 2000)

    Returns
    -------

    
    """
    rules = ["malik", "karlsson", "kamath", "acar"]
    try:
        wd, m = hp.process(data_sample, sample_rate, calc_freq=True)
    except:
        try:
            wd, m = hp.process(data_sample, sample_rate)
        except:
            error_dict = {rule + "_error": np.nan for rule in rules}
            error_dict["outlier_error"] = np.nan
            return error_dict

    # if rpeak_detector in [1, 2, 3, 4]:
    if wave_type == 'ecg':
        detector = PeakDetector(wave_type='ecg')
        peak_list = detector.ecg_detector(data_sample, rpeak_detector)[0]
    else:
        detector = PeakDetector(wave_type='ppg')
        peak_list = detector.ppg_detector(data_sample,
                                          rpeak_detector,
                                          preprocess=False)[0]
    wd["peaklist"] = peak_list
    wd = calc_rr(peak_list, sample_rate, working_data=wd)
    wd = check_peaks(wd['RR_list'],
                     wd['peaklist'],
                     wd['ybeat'],
                     reject_segmentwise=False,
                     working_data=wd)
    wd = clean_rr_intervals(working_data=wd)

    rr_intervals = wd["RR_list"]

    rr_intervals_cleaned = remove_outliers(rr_intervals,
                                           low_rri=low_rri,
                                           high_rri=high_rri)
    number_outliers = len(np.where(np.isnan(rr_intervals_cleaned))[0])
    outlier_ratio = number_outliers / (len(rr_intervals_cleaned) -
                                       number_outliers)
    if rule_index == 0:
        return outlier_ratio

    # error_sqi = {}
    # error_sqi['outlier_error'] = outlier_ratio

    interpolated_rr_intervals = interpolate_nan_values(rr_intervals_cleaned)

    rule = rules[rule_index]
    nn_intervals = remove_ectopic_beats(interpolated_rr_intervals, method=rule)
    number_ectopics = len(np.where(np.isnan(nn_intervals))[0])
    ectopic_ratio = number_ectopics / (len(nn_intervals) - number_ectopics)

    return ectopic_ratio
Пример #28
0
def get_all_features_heartpy(data_sample, sample_rate=100, rpeak_detector=0):
    """

    Parameters
    ----------
    data_sample :
        Raw signal

    sample_rate :
        (Default value = 100)
    rpeak_detector :
        (Default value = 0)

    Returns
    -------


    """
    # time domain features
    td_features = [
        "bpm", "ibi", "sdnn", "sdsd", "rmssd", "pnn20", "pnn50", "hr_mad",
        "sd1", "sd2", "s", "sd1/sd2", "breathingrate"
    ]
    # frequency domain features
    fd_features = ["lf", "hf", "lf/hf"]
    try:
        wd, m = hp.process(data_sample, sample_rate, calc_freq=True)
    except Exception as e:
        try:
            wd, m = hp.process(data_sample, sample_rate)
        except:
            time_domain_features = {k: np.nan for k in td_features}
            frequency_domain_features = {k: np.nan for k in fd_features}
            return time_domain_features, frequency_domain_features
    if rpeak_detector in [1, 2, 3, 4]:
        detector = PeakDetector(wave_type='ecg')
        peak_list = \
        detector.ppg_detector(data_sample, rpeak_detector, preprocess=False)[0]
        wd["peaklist"] = peak_list
        wd = calc_rr(peak_list, sample_rate, working_data=wd)
        wd = check_peaks(wd['RR_list'],
                         wd['peaklist'],
                         wd['ybeat'],
                         reject_segmentwise=False,
                         working_data=wd)
        wd = clean_rr_intervals(working_data=wd)
        rr_diff = wd['RR_list']
        rr_sqdiff = np.power(rr_diff, 2)
        wd, m = calc_ts_measures(wd['RR_list'],
                                 rr_diff,
                                 rr_sqdiff,
                                 working_data=wd)
        m = calc_poincare(wd['RR_list'],
                          wd['RR_masklist'],
                          measures=m,
                          working_data=wd)
        try:
            measures, working_data = calc_breathing(wd['RR_list_cor'],
                                                    data_sample,
                                                    sample_rate,
                                                    measures=m,
                                                    working_data=wd)
        except:
            measures['breathingrate'] = np.nan

        wd, m = calc_fd_measures(measures=measures, working_data=working_data)

    time_domain_features = {k: m[k] for k in td_features}

    frequency_domain_features = {}
    for k in fd_features:
        if k in m.keys():
            frequency_domain_features[k] = m[k]
        else:
            frequency_domain_features[k] = np.nan
    # frequency_domain_features = {k:m[k] for k in fd_features if k in m.keys}
    # frequency_domain_features = {k:np.na for k in fd_features if k not in m.keys}

    return time_domain_features, frequency_domain_features
Пример #29
0
label_records[0].p_signal

#!pip install heartpy

#!pip install heartpy
import heartpy as hp
import pandas as pd
import matplotlib.pyplot as plt

data = hp.scale_data(label_records[0].p_signal.T[0])
data0 = label_records[0].p_signal.T[0]
data0.shape

# get the location of R wave
working_data, measures = hp.process(data, 1000.0)
hp.plotter(working_data, measures)

# get index of R waves
peaklists = working_data['peaklist']
# remove the first one and last one
peaklists = peaklists[1:-1]
print("index of R waves:", peaklists)

# get the wave

records_sliced = []
for i in peaklists: 
  tem_data = data0[i - 400:i + 600] 
  records_sliced.append(tem_data)
import heartpy as hp
import numpy
import csv

# convert txt file to csv
#txt_file_address = 'E:\\Lithic\\data\\heart\\heart-bill.txt'
txt_file_address = 'HR_2019-09-22T14-19-17.txt'
csv_file_address = txt_file_address.replace('txt','csv')
in_txt = csv.reader(open(txt_file_address, "r"), delimiter = ',')
out_csv = csv.writer(open(csv_file_address, 'w'))

out_csv.writerows(in_txt)
print(csv_file_address)

hrdata = hp.get_data(csv_file_address, column_name='Analog1_chB')
timerdata = hp.get_data(csv_file_address, column_name='Timestamp')

working_data, measures = hp.process(hrdata, hp.get_samplerate_mstimer(timerdata))
hp.plotter(working_data, measures, title='good plot')