API
respiration
- physio.respiration.compute_respiration(raw_resp, srate, parameter_preset=None, parameters=None)
- Function for respiration that:
preprocess the signal
detect cycles
clean cycles
compute metrics cycle by cycle
This function works with 3 types of possible sensors : airflow, belt and co2. Depending on these parameters, 3 differents algo will be internatlly used. So the parameters dict must contain sensor_type Note that the `resp_cycles`dataframe will contains cycles boundaries and features. Features will depend on sensor type.
See Handling parameters for parameters details.
- Parameters:
- raw_resp: np.array
Raw respiratory signal
- srate: float
Sampling rate of the raw respiratory signal
- parameter_preset: str or None
Possible presets are : ‘human_airflow’ | ‘human_belt’ | ‘human_co2’ | ‘rat_plethysmo’ | ‘rat_etisens_belt’ This string specifies the type of respiratory data, which determines the set of parameters used for processing. This set equivalent of the one you get using physio.get_respiration_parameters(preset) with preset being the same one.
- parametersdict or None
When not None this updates the parameter set.
- Returns:
- resp: np.array
A preprocess respiratory trace
- resp_cycles: pd.Dataframe
resp_cycles is a dataframe containing one row per respiratory cycle and one column per feature (timings, durations, amplitudes, volumnes …).
- physio.respiration.detect_respiration_cycles(resp, srate, method='crossing_baseline', **method_kwargs)
- Detect respiration with several possible methods:
“crossing_baseline”: method used when the respiratory signal is airflow internally uses detect_respiration_cycles_crossing_baseline()
“min_max” : method used when the respiratory signal is volume internally uses detect_respiration_cycles_min_max()
“co2” : method used when the respiratory signal is from co2 sensor internally uses detect_respiration_cycles_co2()
- Parameters:
- resp: np.array
Preprocessed respiratory signal.
- srate: float
Sampling rate
- method: ‘crossing_baseline’ | ‘co2’ | ‘min_max’
Which method is used for respiratory cycle detection respiration.
- **method_kwargs:
All other options are routed to the sub-function.
- Returns:
- cycles: np.array
Indices of inspiration and expiration. shape=(num_cycle, 3) with [index_inspi, index_expi, index_next_inspi]
- physio.respiration.clean_respiration_cycles(resp, srate, resp_cycles, baseline=None, variable_names=None, low_limit_log_ratio=3.0, sensor_type=None)
Remove outlier cycles.
- This is done
on cycle duration
on resp/insp amplitudes
- This can be done with:
hard threshold
median + K * mad
- Parameters:
- resp: np.array
Preprocess traces of respiratory signal.
- srate: float
Sampling rate
- resp_cycles: pd.Dataframe
Features of all cycles given by compute_respiration_cycle_features before clean.
- baseline:
The baseline used to recompute resp_cycles, this is needed when sensor_type=”airflow”
- variable_names: list of str
Which columns used to search for small deviant
- low_limit_log_ratio: float
Used to compute low limit with “limit = med - mad * low_limit_log_ratio”
- sensor_type: ‘airflow’ | ‘belt’ | ‘co2’
sensor type
- Returns:
- cleaned_cycles:
Clean version of cycles.
- physio.respiration.compute_respiration_cycle_features(resp, srate, cycles, baseline=None, sensor_type='airflow')
Compute respiration features cycle by cycle
- Parameters:
- resp: np.array
Preprocess traces of respiratory signal.
- srate: float
Sampling rate
- cycles: np.array
Indices of inspiration and expiration. shape=(num_cycle + 1, 2)
- baseline: float or None
If not None then the baseline is subtracted to resp to compute amplitudes and volumes.
- sensor_type: str
The sensor type. Can be one of : ‘airflow’ | ‘belt’ | ‘co2’
- Returns:
- resp_cycles: pd.Dataframe
Features of all cycles.
ECG
- physio.ecg.compute_ecg(raw_ecg, srate, parameter_preset='human_ecg', parameters=None)
- Function for ECG that:
preprocess the ECG
detect R peaks
apply some cleaning to remove too small ECG interval
See Handling parameters for parameters details.
- Parameters:
- raw_ecg: np.array
Raw ECG signal
- srate: float
Sampling rate
- parameter_preset: str or None
Can be : ‘human_ecg’ | ‘rat_ecg’ This recruites parameters automatically through the use of physio.get_ecg_parameters(preset) where preset stands for what you chose.
- parametersdict or None
When not None this overwrites the parameter set.
- Returns:
- clean_ecg: np.array
preprocess and normalized ecg traces
- ecg_peaks: pd.DataFrame
dataframe with indices and timings of detected R peaks.
- physio.ecg.clean_ecg_peak(ecg, srate, raw_peak_inds, min_interval_ms=400.0, max_clean_loop=4)
Clean peaks with simple idea: remove short interval.
- Parameters:
- ecg: np.array
preprocess traces of ECG signal
- srate: float
Sampling rate
- raw_peak_inds: np.array
Array of peaks indices to be cleaned
- min_interval_ms: float (default 400ms)
Minimum interval for cleaning
- max_clean_loop: int
Cleaning is iterated by looping in the range() of this value.
- Returns:
- peak_inds: np.array
Cleaned array of peaks indices
- physio.ecg.compute_ecg_metrics(ecg_peaks, min_interval_ms=500.0, max_interval_ms=2000.0, verbose=False)
Compute metrics from ecg peaks:
HRV_Mean : Mean of RR intervals (Warning: this is not a measure of variability but a measure of central tendency …)
HRV_SD : Standard-Deviation of RR intervals
HRV_Median : Median of RR intervals (Warning: this is not a measure of variability but a measure of central tendency …)
HRV_Mad : Median Absolute Deviation (MAD) of RR intevals. MAD is more robust to outliers than a classic standard-deviation.
HRV_CV : HRV_SD / HRV_Mean = Coefficient of Variation = Normalized SD
HRV_MCV : HRV_Mad / HRV_Median = MAD Coefficient of Variation = Robust version of Coefficient of Variation
HRV_Asymmetry = HRV_Median - HRV_Mean = Difference between Median and Mean that diverges from 0 in case of outliers / non normal distribution of RR intervals.
HRV_RMSSD = Root-Mean Square of Successive Differences ~ like a 2nd derivative of RR intervals. Sensitive to fine variations of RR intervals but also very sensitive to outliers.
These metrics are a bit more robust than others toolboxes because are computed after a cleaning of RR intervals based on min and max intervals as set.
- Parameters:
- ecg_peaks: pd.DataFrame
DataFrame containing ecg R peaks.
- min_interval_ms: float (default 500ms)
Minimum interval inter R peak
- max_interval_ms: float (default 2000ms)
Maximum interval inter R peak
- verbose: bool (default False)
Control verbosity
- Returns:
- metrics: pd.Series
A table containing HRV metrics
- physio.ecg.compute_instantaneous_rate(ecg_peaks, new_times, limits=None, units='bpm', interpolation_kind='linear')
- Parameters:
- ecg_peaks: pd.DataFrame
DataFrame containing ecg R peaks.
- new_timesnp.array
Time vector for interpolating the instantaneous rate.
- limitslist or None
Limits for removing outliers.
- unitsstr
Can be : ‘bpm’ / ‘Hz’ / ‘ms’ / ‘s’. Set the units of the output. Can be interval (ms or s) or rate (Hz or bpm).
- interpolation_kindstr
‘linear’ or ‘cubic’
- Returns:
- instantaneous_ratenp.array
Instaneous rate of the shape of new_times because reinterpolated according ti this time basis
- physio.ecg.compute_hrv_psd(ecg_peaks, sample_rate=100.0, limits=None, units='bpm', frequency_bands={'hf': (0.15, 0.4), 'lf': (0.04, 0.15)}, window_s=250.0, interpolation_kind='cubic')
- Compute hrv power spectrum density and extract some metrics:
lf power
hf power
- Please note:
The duration of the signal and the window are important parameters to estimate low frequencies in a spectrum. Some warnings or errors should popup if they are too short.
Given that the hrv is mainly driven by the respiration the frequency boudaries are often innacurate! For instance a slow respiration at 0.1Hz is moving out from the ‘hf’ band wheras this band should capture the respiratory part of the hrv.
The instataneous rate is computed by interpolating eccg peak interval, the interpolation method ‘linear’ or ‘cubic’ are a real impact of the dynamic and signal smoothness and so the spectrum should differ because of the wieight of the harmonics
The units of the instantaneous hrv (bpm, interval in second, interval in ms) have a high impact on the magnitude of metrics. Many toolboxes (neurokit2, ) differ a lot on this important detail.
Here we choose the classical welch method for spectrum density estimation. Some parameters have also small impact on the results : dentend, windowing, overlap.
- Parameters:
- ecg_peaks: pd.DataFrame
DataFrame containing ecg R peaks.
- sample_rate: float
Sampling rate of the interpolated instantanous heart rate
- limits: None or List
If list, ex [30, 200], RR intervals correspond out of this range (here bpm) are removed before interpolation.
- unitsstr
Can be : ‘bpm’ / ‘Hz’ / ‘ms’ / ‘s’. Set the units of the interpolated instantaneous heart rate.
- frequency_bandsdict
Defines the frequency band of interest
- window_sfloat
Size of the Welch’s window for PSD computation. Should be long enough to contain at least 5 iterations of the slowest frequency of intereset.
- interpolation_kindstr
‘linear’ or ‘cubic’
- Returns:
- psd_freqsnp.array
Frequency vector of the PSD
- psdnp.array
Power Spectral Density vector
- metricspd.Series
Power of the set frequency bands, obtained using trapezoïdal rule.
Cylic tools
- physio.cyclic_deformation.deform_traces_to_cycle_template(data, times, cycle_times, points_per_cycle=40, segment_ratios=None, output_mode='stacked', progress_bar=False)
Deform a signal a 1D signal (or also ND) to a ‘cycle template’. Every cycle chunk in the signal will be interpolated to have the same length. In short it is a times to cycles transformation.
- Parameters:
- data: nd.array
Axis of the time must always be 0, meaning of shape (n_times,…).
- times: np.array
Time vector of the data. Shape = (n_times,)
- cycle_times: np.array
Array with shape(num_cycle, num_segment + 1). Typically for respiration n cycles array with 3 columns (inspi time + expi time + next inspi time) will make deformation with 2 segments. If the cycle_times is 1D then it is converted to shape (size-1, 2). The end of every cycles must match the start of the next cycle.
- points_per_cycle: int (default 40)
number of respi phase per cycle
- segment_ratios: None or float or list of float
If multi segment deformation then a list of segmetn ratio must provived.
- output_mode: str
‘stacked’ / ‘unstacked’ / ‘unstacked_full’ Format of the outputs. Stacked -> 2D matrix : cycles / points per cycle. Unstacked -> 1D matrix : flattened version of the stacked. Unstacked_full returns extra-outputs.
- progress_barbool
To display or not a progress bar
- Returns:
- If mode == ‘stacked’
- deformed_data_stacked:
A 2d array of stacked cycles. Shape = (num_cycles, points_per_cycle)
- If mode == ‘unstacked’
- deformed_data:
A 1d array of deformed cycles. Shape = (num_cycles * points_per_cycle)
- cycle_points:
The cycle vector
- If mode == ‘unstacked’:
- clipped_times:
The clipped time vector
- times_to_cycles:
The vector times to cycle
RespHRV
- physio.resphrv.compute_resphrv(resp_cycles, ecg_peaks, srate=100.0, units='bpm', limits=None, two_segment=True, points_per_cycle=50, return_cyclic_cardiac_rate=True)
RSA = Respiratory Sinus Arrhythmia (or Respiratory Heart Rate Variability / RespHRV)
- Compute the RSA cycle-by-cycle
compute instantaneous heart rate
on resp cycle basis compute peak-to-trough
Also compute the cyclic deformation of the instantaneous heart rate
- Parameters:
- resp_cyclespd.DataFrame
DataFrame of detected respiratory cycles
- ecg_peakspd.DataFrame
DataFrame of detected ecg R peaks
- srateint or float
Sampling rate used for interpolation to get an instantaneous heart rate vector, to compute cyclic_cardiac_rate. 100 is safe for both animal and human. For human 10 also works.
- unitsstr
bpm / Hz
- limitslist or None
Limits for removing outliers. To set according to the units parameter. Ex : [30, 200] to remove heart rates (in bpm) out of this range.
- two_segmentbool
True or False (default = True). Deform instantaneous heart rate by respiratory phase using one segment (inspi_time to next_inspi_time) or two segments (inspi_time to expi_time and expi_time to next_inspi_time), to compute cyclic_cardiac_rate.
- points_per_cycleint
Number of respiratory phase points per cycle, used in deform_traces_to_cycle_template() to build cyclic_cardiac_rate matrix
- return_cyclic_cardiac_ratebool
If True, returns both outputs (resphrv_cycles and cyclic_cardiac_rate), else computes and returns only resphrv_cycles and not cyclic_cardiac_rate
- Returns:
- resphrv_cyclespd.DataFrame
Cycle-by-cycle features of Heart Rate dynamics. Ex : decay_amplitude gives the by-cycle peak-to-trough amplitude.
- cyclic_cardiac_ratend.array
2D Matrix (respiratory cycle * respiratory phase) with instantaneous heart rate at each resp cycle and phase point.
reader
- physio.reader.read_one_channel(filename, format, channel_name, scaled=True)
Simple function on top of neo that read one channel from file in supported format.
>>> ecg, srate = physio.read_one_channel('/path/to/micromed_file.TRC', 'micromed', 'p7+', scaled=True)
- Parameters:
- filename: str or Path
The file
- format: str
The foormat of the file ‘micromed’ or ‘brainvision’
- channel_name: str
The channel names.
- scaled: bool (default True)
Return traces scaled to unit or unscaled (int16)
- Returns:
- trace: np.array
The trace of the channel as a numpy 1d array.
- srate: float
The sampling rate.
preproces
- physio.preprocess.preprocess(traces, srate, band=[5.0, 45.0], btype='bandpass', ftype='bessel', order=5, normalize=False)
Apply simple filter using scipy
For ECG bessel 5-50Hz and order 5 is maybe a good choice.
Optionally also normalize the signal using median and mad.
- Parameters:
- traces: np.array
Input signal.
- srate: float
Sampling rate
- band: list of float or float
Tha band in Hz or scalar if high/low pass.
- btype: ‘bandpass’, ‘highpass’, ‘lowpass’
The band pass type
- ftype: str (dfault ‘bessel’)
The filter type used to generate coefficient using scipy.signal.iirfilter
- order: int (default 5)
The order
- normalize: bool (default False)
Apply or not normalization
- Returns:
- traces_clean: np.array
The preprocess traces
- physio.preprocess.smooth_signal(trace, srate, win_shape='gaussian', sigma_ms=5.0)
A simple signal smoother using gaussian/rect kernel.
- Parameters:
- traces: np.array
Input signal.
- srate: float
Sampling rate
- win_shape: ‘gaussian’ / ‘rect’
The shape of the kernel
- sigma_ms: float (default 5ms)
The length of the kernel. Sigma for the gaussian case.
- Returns:
- trace_smooth: np.array
The smoothed traces
plotting
- physio.plotting.plot_cyclic_deformation(data, segment_ratios=None, two_cycles=True, ax=None)
- Parameters:
- data: np.array
A 2d cyclic deformed array
- segment_ratios: None or list
Multi-segment deformation (then vertical line are also plotted at this ratio)
- two_cycles: bool (dafult True)
Plot 2 consecutive cycles.
- ax: None or matplotlib axes
Use it to plot on an external ax
- Returns:
- None
tools
- physio.tools.compute_median_mad(data, axis=0)
Compute median and mad (median absolute deviation)
- Parameters:
- data: np.array
An array
- axis: int (default 0)
The axis
- Returns:
- med:
The median
- mad:
The mad
- physio.tools.detect_peak(traces, srate, thresh=5, abs_threshold=None, exclude_sweep_ms=4.0, thresh_artifact=None, abs_thresh_artifact=None)
Simple positive peak detector.
- Parameters:
- traces: np.array
An array
- srate: float
Sampling rate of the traces
- thresh: float (default 5)
The threhold as mad factor abs_threshold = med + thresh * mad
- abs_thresholdNone or float
This replace thresh (which is relative to mad)
- exclude_sweep_ms: float
Zone to exclude multiple peak detection when noisy. If several peaks or detected in the same sweep the best is the winner.
- thresh_artifact: float, default None
Ceil threshold that peaks must not exceed, this aims to remove big artifact This is relative to mad : abs_threshold = med + thresh_artifact * mad
- abs_thresh_artifact: float, None
Same as thresh_artifact but absolute
- Returns:
- inds: np.array
Indices on the peaks
- physio.tools.get_empirical_mode(traces, nbins=200)
Get the empirical mode of a distribution. This is a really lazy implementation that makes an histogram of the traces inside quantile [0.25, 0.75] and makes an histogram of 200 bins and takes the max.
- Parameters:
- traces: np.array
The traces
- nbins: int (default 200)
Number of bins for the histogram
- Returns:
- mode: float
The empirical mode.
parameters
Some predefined parameters preset for computing respiration and ecg without pain.
- physio.parameters.get_respiration_parameters(parameter_preset)
Get parameters nested dict for a given predefined parameter preset.
- Parameters:
- parameter_presetstr
Possible presets are : ‘human_airflow’ | ‘human_belt’ | ‘human_co2’ | ‘rat_etisens_belt’ | ‘rat_plethysmo’
- Returns:
- presetdict
Dictionary of predefined parameters
- physio.parameters.get_ecg_parameters(parameter_preset)
Get parameters nested dict for a given predefined parameter preset.
- Parameters:
- parameter_presetstr
Possible presets are : ‘human_ecg’ | ‘rat_ecg’
- Returns:
- presetdict
Dictionary of predefined parameters