resurfemg.postprocessing.quality_assessment module

Copyright 2022 Netherlands eScience Center and University of Twente Licensed under the Apache License, version 2.0. See LICENSE for details.

This file contains functions to determine peak and signal quality from preprocessed EMG arrays.

resurfemg.postprocessing.quality_assessment.detect_extreme_time_products(time_products, upper_percentile=95.0, upper_factor=10.0, lower_percentile=5.0, lower_factor=0.1)

Detect extreme (high or low) time product values. See postprocessing. features.time_product ————————————————————————— :param time_products: List of time_productsvalues. :type time_products: ~numpy.ndarray[~float] :param upper_percentile: percentile for detecting high time products :type upper_percentile: ~float :param upper_factor: multiplication factor for upper_percentile :type upper_factor: ~float :param lower_percentile: percentile for detecting low time products :type lower_percentile: ~float :param lower_factor: multiplication factor for lower_percentile :type lower_factor: ~float

Returns valid_etps:

Boolean list of time product values within bounds

Rtype valid_etps:

numpy.ndarray[bool]

resurfemg.postprocessing.quality_assessment.detect_local_high_aub(aubs, threshold_percentile=75.0, threshold_factor=4.0)

Detect local upward deflections in the area under the baseline. param aubs: List of area under the baseline values. See resurfemg.postprocessing.features.area_under_baseline ————————————————————————— :features.area_under_baseline :type aubs: ~numpy.ndarray[~float] :param threshold_percentile: percentile for detecting high baseline :type threshold_percentile: ~float :param threshold_factor: multiplication factor for threshold_percentile :type threshold_factor: ~float

Returns valid_aubs:

Boolean list of aub values under threshold

Rtype valid_aubs:

numpy.ndarray[bool]

resurfemg.postprocessing.quality_assessment.detect_non_consecutive_manoeuvres(ventilator_breath_idxs, manoeuvres_idxs)

Detect manoeuvres (for example Pocc) with no supported breaths in between. Input are the ventilator breaths, to be detected with the function post_processing.event_detecton.detect_supported_breaths If no supported breaths are detected in between two manoeuvres, valid_manoeuvres is ‘True’. Note: fs of both signals should be equal. ————————————————————————— :param ventilator_breath_idxs: list of supported breath indices :type ventilator_breath_idxs: ~list :param manoeuvres_idxs : list of manoeuvres indices :type manoeuvres_idxs: ~list

Returns valid_manoeuvres:

Boolean list of valid manoeuvres

Rtype valid_manoeuvres:

numpy.ndarray[bool]

resurfemg.postprocessing.quality_assessment.evaluate_bell_curve_error(peak_idxs, start_idxs, end_idxs, signal, fs, time_products, bell_window_s=None, bell_threshold=40)

Calculate the bell-curve error of signal peaks, in accordance with Warnaar et al. (2024). ————————————————————————— :param signal: filtered signal :type signal: ~numpy.ndarray :param peak_idxs: list of peak indices :type peak_idxs: ~numpy.ndarray :param start_idxs: list of onsets indices :type start_idxs: ~numpy.ndarray :param end_idxs: list of offsets indices :type end_idxs: ~numpy.ndarray :param fs: sampling rate :type fs: int :param time_products: list of area under the curves per peak :type time_products: ~numpy.ndarray :param bell_window_s: number of samples before and after peak_idxs to look for the nadir :type bell_window_s: ~int :param bell_threshold: maximum bell error percentage for a valid peak :type bell_threshold: ~float

Returns valid_peak:

boolean list of valid peaks

Rtype valid_peak:

numpy.ndarray[bool]

Returns percentage_bell_error:

calculated bell errors in percentage

Return type:

numpy.ndarray[float]

Returns bell_error:

calculated bell errors

Return type:

numpy.ndarray[float]

Returns y_min:

minimum value of the baseline

Return type:

numpy.ndarray[float]

Returns fitted_parameters:

fitted bell curve parameters

Return type:

numpy.ndarray[float]

resurfemg.postprocessing.quality_assessment.evaluate_event_timing(t_events_1, t_events_2, delta_min=0, delta_max=None)

Evaluate whether the timing of the events in t_events_1 preceeds the events in t_events_2 minimally by delta_min and maximally by delta_max. t_events_1 and t_events_2 should be the same length. ————————————————————————— :param t_events_1: Timing of the events that should happen first :type t_events_1: ~numpy.ndarray[float] :param t_events_2: Timing of the events that should happen second :type t_events_2: ~numpy.ndarray[float] :param delta_min: The delta time event 1 should at least preceed event 2. :type delta_min: ~float :param delta_max: The delta time event 1 should maximally preceed event 2. :type delta_max: ~float

Returns correct_timing:

Boolean list of correct timing

Rtype correct_timing:

numpy.ndarray[bool]

Returns delta_time:

List of delta times between the events

Rtype delta_time:

numpy.ndarray[float]

resurfemg.postprocessing.quality_assessment.evaluate_respiratory_rates(emg_breath_idxs, t_emg, rr_vent, min_fraction=0.1)

This function evaluates fraction of detected EMG breaths relative to the ventilatory respiratory rate. ————————————————————————— :param emg_breath_idxs: EMG breath indices :type emg_breath_idxs: ~numpy.ndarray :param t_emg: Recording time in seconds :type t_emg: ~float :param vent_rr: ventilatory respiratory rate (breath/min) :type vent_rr: ~float :param min_fraction: Required minimum detected fraction of EMG breaths :type min_fraction: ~numpy.ndarray

Returns detected_fraction:

Fraction of detected EMG breaths

Rtype detected_fraction:

float

Returns criterium_met:

Boolean if the fraction is above the minimum

Rtype criterium_met:

bool

resurfemg.postprocessing.quality_assessment.interpeak_dist(ecg_peak_idxs, emg_peak_idxs, threshold=1.1)

Calculate the median interpeak distances for ECG and EMG and check if their ratio is above the given threshold, i.e. if cardiac frequency is higher than respiratory frequency (True) ————————————————————————— :param ecg_peak_idxs: Indices of ECG peaks :type ecg_peak_idxs: ~numpy.ndarray :param emg_peak_idxs: Indices of EMG peaks :type emg_peak_idxs: ~numpy.ndarray :param threshold: The threshold value to compare against. Default is 1.1 :type threshold: ~float

Returns valid_interpeak:

Boolean value if the interpeak distance is valid

Rtype valid_interpeak:

bool

resurfemg.postprocessing.quality_assessment.percentage_under_baseline(signal, fs, peak_idxs, start_idxs, end_idxs, baseline, aub_window_s=None, ref_signal=None, aub_threshold=40)

Calculate the percentage area under the baseline, in accordance with Warnaar et al. (2024). ————————————————————————— :param signal: signal in which the peaks are detected :type signal: ~numpy.ndarray :param fs: sampling frequency :type fs: ~int :param peak_idxs: list of individual peak indices :type peak_idxs: ~list :param start_idxs: list of individual peak start indices :type start_idxs: ~list :param end_idxs: list of individual peak end indices :type end_idxs: ~list :param baseline: running baseline of the signal :type baseline: ~numpy.ndarray :param aub_window_s: number of samples before and after peak_idxs to look for the nadir :type aub_window_s: ~int :param ref_signal: signal in which the nadir is searched :type ref_signal: ~numpy.ndarray :param aub_threshold: maximum aub error percentage for a peak :type aub_threshold: ~float

Returns valid_timeproducts:

boolean list of valid time products

Rtype valid_timeproducts:

numpy.ndarray[bool]

Returns percentages_aub:

list of calculated aub percentages

Rtype percentages_aub:

numpy.ndarray[float]

resurfemg.postprocessing.quality_assessment.pocc_quality(p_vent_signal, pocc_peaks, pocc_ends, ptp_occs, dp_up_10_threshold=0.0, dp_up_90_threshold=2.0, dp_up_90_norm_threshold=0.8)

Evaluation of occlusion pressure (Pocc) quality, in accordance with Warnaar et al. (2024). Poccs are labelled invalid if too many negative deflections happen in the upslope (first decile < 0), or if the upslope is to steep (high absolute or relative 9th decile), indicating occlusion release before the patient’s inspiriratory effort has ended. ————————————————————————— :param signal: Airway pressure signal :type signal: ~numpy.ndarray :param pocc_peaks: list of individual peak indices :type pocc_peaks: ~list :param pocc_ends: list of individual peak end indices :type pocc_ends: ~list :param dp_up_10_threshold: Minimum first decile of upslope after the (negative) occlusion pressure peak :type dp_up_10_threshold: ~float :param dp_up_90_threshold: Maximum 9th decile of upslope after the (negative) occlusion pressure peak :type dp_up_90_threshold: ~float :param dp_up_90_norm_threshold: Maximum 9th decile of upslope after the (negative) occlusion pressure peak :type dp_up_90_norm_threshold: ~float

Returns valid_poccs:

boolean list of valid Pocc peaks

Rtype valid_poccs:

numpy.ndarray[bool]

Returns criteria_matrix:

matrix of the calculated criteria

Rtype criteria_matrix:

numpy.ndarray

resurfemg.postprocessing.quality_assessment.snr_pseudo(src_signal, peaks, baseline, fs)

Approximate the signal-to-noise ratio (SNR) of the signal based on the peak height relative to the baseline. ————————————————————————— :param signal: Signal to evaluate :type signal: ~numpy.ndarray[float] :param peaks: list of individual peak indices :type gate_peaks: ~list[int] :param baseline: Baseline signal to evaluate SNR to. :type baseline: ~numpy.ndarray[float] :param fs: sampling rate :type fs: int

Returns snr_peaks:

the SNR per peak

Rtype snr_peaks:

numpy.ndarray[float]