API

respiration

physio.respiration.compute_respiration(raw_resp, srate, parameter_preset='human_airflow', parameters=None)
Function for respiration that:
  • preprocess the signal

  • detect cycle

  • clean cycles

  • compute metrics cycle by cycle

Parameters:
raw_resp: np.array

Raw traces of respiratory signal

srate: float

Sampling rate

parameter_preset: str or None

Name of parameters set ‘human_airflow’ This use the automatic parameters you can also have with get_respiration_parameters(‘human’)

parametersdict or None

When not None this overwrite the parameter set.

Returns:
resp: np.array

A preprocess traces

cycles: pd.Dataframe

Table that contain all cycle information : inspiration/expiration indexes, amplitudes, volumes, durations, …

physio.respiration.detect_respiration_cycles(resp, srate, method='crossing_baseline', **method_kwargs)
Detect respiration with several methods:
  • “crossing_baseline”: internally use detect_respiration_cycles_crossing_baseline()

  • “co2” : internally use detect_respiration_cycles_co2()

Parameters:
resp: np.array

Preprocess traces of respiratory signal.

srate: float

Sampling rate

method: ‘crossing_baseline’ / ‘co2’

Which method for respiration.

**method_kwargs:

All other option 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, low_limit_log_ratio=3)

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

Returns:
cleaned_cycles:

Clean version of cycles.

physio.respiration.compute_respiration_cycle_features(resp, srate, cycles, baseline=None, compute_volume=True, compute_amplitude=True)

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 substracted to resp to compute amplitudes and volumes.

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

Parameters:
raw_ecg: np.array

Raw traces of ECG signal

srate: float

Sampling rate

parameter_preset: str or None

Name of parameters set like ‘human_ecg’ This use the automatic parameters you can also have with get_ecg_parameters(‘human_ecg’)

parametersdict or None

When not None this overwrite the parameter set.

Returns:
clean_ecg: np.array

preprocess and normalized ecg traces

ecg_peaks: pd.DataFrame

dataframe with indices of R peaks, times of R peaks.

physio.ecg.clean_ecg_peak(ecg, srate, raw_peak_inds, min_interval_ms=400.0, max_clean_loop=4)

Clean peak with ultra 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 (dfault 400ms)

Minimum interval for cleaning

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 on ecg peaks: HRV_Mean, HRV_SD, HRV_Median, …

This metrics are a bit more robust that neurokit2 ones because strange interval are skiped from the analysis.

Parameters:
ecg_peaks: pr.DataFrame

Datfarame 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 contaning metrics

physio.ecg.compute_instantaneous_rate(ecg_peaks, new_times, limits=None, units='bpm', interpolation_kind='linear')
Parameters:
ecg_peaks: pr.DataFrame

Datfarame containing ecg R peaks.

new_timesnp.array

Time vector for interpolating the instanteneous rate.

limitslist or None

Limits for removing outliers.

units‘bpm’ / ‘Hz’ / ‘ms’ / ‘s’

Units of the rate. can be interval or rate.

interpolation_kind‘linear’/ ‘cubic’
physio.ecg.compute_hrv_psd(ecg_peaks, sample_rate=100.0, limits=None, units='bpm', freqency_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:
  1. 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.

  2. 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.

  3. 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

  4. 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.

  5. 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: pr.DataFrame

Datfarame containing ecg R peaks.

sample_rate=100.
limits=None
units=’bpm’
interpolation_kind

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 time axis must always be 0

times:

real timestamps associated to data

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: ‘stacked’ / ‘unstacked’ / ‘unstacked_full’
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

RSA

physio.rsa.compute_rsa(resp_cycles, ecg_peaks, srate=100.0, units='bpm', limits=None, two_segment=True, points_per_cycle=50)

RSA = Respiratory Sinus Arrhythmia

Compute the RSA with the cyclic way
  • compute instanteneous heart rate

  • on resp cycle basis compute peak-to-trough

Also compute the cyclic deformation of the instantaneous heart rate

Parameters:
resp_cycles
ecg_peaks
srate
100 is safe for both animal and human for human 10 is also OK.
units
limits
two_segment
points_per_cycle
Returns:
rsa_cycles
cyclic_cardiac_rate

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=True)

Apply simple filter using scipy

For ECG bessel 5-50Hz and order 5 is maybe a good choice.

By default 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: cool (default True)

Aplly 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 multi segment deformation then vertical line are also ploted

two_cycles: bool (dafult True)

Plot 2 consecutive cycles.

ax: None or matplotlib axes

Optional an external ax

Returns
——-

tools

physio.tools.compute_median_mad(data, axis=0)

Compute median and mad

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, exclude_sweep_ms=4.0)

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_threholds = med + thresh * 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.

Returns
——-
inds: np.array

Indices on the peaks

physio.tools.get_empirical_mode(traces, nbins=200)

Get the emprical mode of a distribution. This is a really lazy implementation that make an histogram of the traces inside quantile [0.25, 0.75] and make an histogram of 200 bins and take 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.

physio.parameters.get_ecg_parameters(parameter_preset)

Get parameters nested dict for a given predefined parameter preset.