Ejemplo n.º 1
0
def split_segment(s, split_type=0, duration=30.0,
                      overlaping=1,sampling_rate=100,
                   peak_detector=7, wave_type='ppg'):
    """
    Save segment waveform and plot (optional) to csv and image file.
    Input is a segment with timestamps.

    Parameters
    ----------
    s :
        array-like represent the signal.
    split_type :
        0: split by time
        1: split by beat
    duration :
        the duration of each segment if split by time in seconds, default = 30 (second)
        the number of complex/beat in each segement if split by beat, default = 30(beat/segment)

    sampling_rate :
        device sampling rate

    peak_detector :
        The type of peak detection if split the segment by beat.

    wave_type:
        Type of signal. Either 'ppg' or 'ecg'

    Returns
    -------
    >>>from vital_sqi.common.utils import generate_timestamp
    >>>s = np.arange(100000)
    >>>timestamps = generate_timestamp(None,100,len(s))
    >>>df = pd.DataFrame(np.hstack((np.array(timestamps).reshape(-1,1),
                                 np.array(s).reshape(-1,1))))
    >>>split_segment(df,overlaping=3)
    """
    assert check_signal_format(s) is True
    if split_type is 0:
        chunk_size = int(duration * sampling_rate)
        chunk_step = int(overlaping * sampling_rate)
        chunk_indices = [
                [int(i), int(i + chunk_size)] for i in
                range(0, len(s), chunk_size - chunk_step)
            ]
    else:
        if wave_type == 'ppg':
            detector = PeakDetector(wave_type='ppg')
            peak_list, trough_list = detector.ppg_detector(s,detector_type=peak_detector)
        else:
            detector = PeakDetector(wave_type='ecg')
            peak_list, trough_list = detector.ecg_detector(s, detector_type=peak_detector)
        chunk_indices = [
                [peak_list[i], peak_list[i+duration]] for i in range(0,
                                                                     len(peak_list),int(duration-overlaping))
        ]
        chunk_indices[0] = 0
    milestones = pd.DataFrame(chunk_indices)
    segments = cut_segment(s, milestones)
    return segments, milestones
Ejemplo n.º 2
0
def msq_sqi(s, peak_detector_1=7, peak_detector_2=6, wave_type='ppg'):
    """
    MSQ SQI as defined in Elgendi et al
    "Optimal Signal Quality Index for Photoplethysmogram Signals"
    with modification of the second algorithm used.
    Instead of Bing's, a SciPy built-in implementation is used.
    The SQI tracks the agreement between two peak detectors
    to evaluate quality of the signal.

    Parameters
    ----------
    s : sequence
        A signal with peaks.

    peak_detector_1 : array of int
        Type of the primary peak detection algorithm, default = Billauer

    peak_detect2 : int
        Type of the second peak detection algorithm, default = Scipy

    Returns
    -------
    msq_sqi : number
        MSQ SQI value for the given signal

    """
    if wave_type == 'ppg':
        detector = PeakDetector(wave_type='ppg')
        peaks_1, trough_list = detector.ppg_detector(
            s, detector_type=peak_detector_1)
        peaks_2 = detector.ppg_detector(s,
                                        detector_type=peak_detector_2,
                                        preprocess=False)
    else:
        detector = PeakDetector(wave_type='ecg')
        peaks_1, trough_list = detector.ecg_detector(
            s, detector_type=peak_detector_1)
        peaks_2 = detector.ecg_detector(s,
                                        detector_type=peak_detector_2,
                                        preprocess=False)
    if len(peaks_1) == 0 or len(peaks_2) == 0:
        return 0.0
    peak1_dom = len(np.intersect1d(peaks_1, peaks_2)) / len(peaks_1)
    peak2_dom = len(np.intersect1d(peaks_2, peaks_1)) / len(peaks_2)
    return min(peak1_dom, peak2_dom)
Ejemplo n.º 3
0
def get_all_features_hrva(s, sample_rate=100, rpeak_method=0,wave_type='ecg'):
    """

    Parameters
    ----------
    data_sample :
        Raw signal
    rpeak_method :
        return: (Default value = 0)
    sample_rate :
        (Default value = 100)

    Returns
    -------


    """

    # if rpeak_method in [1, 2, 3, 4]:
    #     detector = PeakDetector()
    #     peak_list = detector.ppg_detector(data_sample, rpeak_method)[0]
    # else:
    #     rol_mean = rolling_mean(data_sample, windowsize=0.75, sample_rate=100.0)
    #     peaks_wd = detect_peaks(data_sample, rol_mean, ma_perc=20,
    #                             sample_rate=100.0)
    #     peak_list = peaks_wd["peaklist"]
    if wave_type=='ppg':
        detector = PeakDetector(wave_type='ppg')
        peak_list, trough_list = detector.ppg_detector(s, detector_type=rpeak_method)
    else:
        detector = PeakDetector(wave_type='ecg')
        peak_list, trough_list = detector.ecg_detector(s, detector_type=rpeak_method)

    rr_list = np.diff(peak_list) * (1000 / sample_rate)  # 1000 milisecond

    nn_list = get_nn_intervals(rr_list)
    nn_list_non_na = np.copy(nn_list)
    nn_list_non_na[np.where(np.isnan(nn_list_non_na))[0]] = -1

    time_domain_features = get_time_domain_features(rr_list)
    frequency_domain_features = get_frequency_domain_features(rr_list)
    geometrical_features = get_geometrical_features(rr_list)
    csi_cvi_features = get_csi_cvi_features(rr_list)

    return time_domain_features, frequency_domain_features, geometrical_features, csi_cvi_features
Ejemplo n.º 4
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