vitabel.analysis.ventilation.phases

Detection of respiratory phases (inspiration / expiration) from airflow and airway pressure, see Orlob et al. [OPG+26].

Attributes

Classes

Functions

get_inspiration_starts(→ tuple[numpy.typing.NDArray, ...)

Derives the indices of the start of inspirations from the product of flow and pressure.

get_expiration_starts(→ tuple[numpy.typing.NDArray, ...)

Derives the indices of the start of expirations from the product of flow and slope of pressure.

respiratory_phase_labels(→ list[vitabel.timeseries.Label])

Create the respiratory phase labels.

respiratory_intermediate_channels(...)

Create channels for the intermediate signals of the respiratory phase

detect_respiratory_phases(→ RespiratoryPhaseResult)

Derive the respiratory phases from air flow and airway pressure, as

Module Contents

vitabel.analysis.ventilation.phases.logger
vitabel.analysis.ventilation.phases.get_inspiration_starts(product: vitabel.typing.DataSlice, interpolated_flow: vitabel.typing.DataSlice, interpolated_pressure: vitabel.typing.DataSlice, slope_pressure: vitabel.typing.DataSlice, threshold: float) → tuple[numpy.typing.NDArray, numpy.typing.NDArray, numpy.typing.NDArray]

Derives the indices of the start of inspirations from the product of flow and pressure.

This function identifies segments of the product that are above a certain threshold and finds the last zero crossing before each segment. Preceding segments of less than 20ms of a non-positive product are filtered out to ensure that chest compressions do not fragment the product in the early phase of the inspiration. Potential candidates are further filtered by the duration of the following duration of zeros, which must be greater than 400ms (more than half the duty cycle of CC with 80 BPM) to be considered a valid inspiration. This avoids false positives due to chest compressions fragmenting the product.

Parameters:
product:class:`.DataSlice`

A DataSlice object containing the time index and data of the product of flow and pressure.

interpolated_flow:class:`.DataSlice`

A DataSlice object containing the time index and data of the interpolated flow signal. Must have the same time index as the product.

interpolated_pressure:class:`.DataSlice`

A DataSlice object containing the time index and data of the interpolated pressure signal. Must have the same time index as the product.

slope_pressure:class:`.DataSlice`

A DataSlice object containing the time index and data of the slope of the pressure signal. Must have the same time index as the product.

threshold: float

The threshold value above which the inspiration segments are detected.

Returns:
inspiration_startsnp.ndarray

An array of integer indices for the time index of the given product where the inspirations start (filtered zero crossings). Empty array (dtype int) if no valid inspiration starts are detected.

onsets_above_thresholdnp.ndarray

An array of integer indices where the product first exceeds the threshold for each detected segment. Empty array (dtype int) if no segments are detected.

filtered_onsetsnp.ndarray

An array of integer indices for the onsets above threshold after additional filtering (e.g., slope and pressure criteria). Empty array (dtype int) if no onsets survive filtering.

Notes

All three returned arrays always have dtype int and maintain consistent shapes even when empty, allowing safe tuple unpacking and downstream processing.

vitabel.analysis.ventilation.phases.get_expiration_starts(product: vitabel.typing.DataSlice, threshold: float) → tuple[numpy.typing.NDArray, numpy.typing.NDArray, numpy.typing.NDArray]

Derives the indices of the start of expirations from the product of flow and slope of pressure.

This function identifies segments of the product that are above a certain threshold and finds the preceding zero crossing before each segment as potential expiration start. It returns the first candidate between two inspiration starts as the expiration start.

Parameters:
product:class:`.DataSlice`

A DataSlice object containing the time index and data of the product of flow and slope of pressure.

threshold: float

The threshold value above which the expiration segments are detected.

Returns:
expiration_startsnp.ndarray

An array of integer indices for the time index of the given product where the expirations start (filtered zero crossings). Empty array (dtype int) if no valid expiration starts are detected.

onsets_above_thresholdnp.ndarray

An array of integer indices where the product first exceeds the threshold for each detected segment. Empty array (dtype int) if no segments are detected.

filtered_onsetsnp.ndarray

An array of integer indices for the onsets above threshold after duration filtering. Empty array (dtype int) if no onsets survive filtering.

Notes

All three returned arrays always have dtype int and maintain consistent shapes even when empty, allowing safe tuple unpacking and downstream processing.

vitabel.analysis.ventilation.phases.RESPIRATORY_PHASE_LABEL_NAMES = ['Inspiration Begin', 'Expiration Begin', 'Inspiration', 'Expiration']

Names of the labels created by respiratory_phase_labels().

vitabel.analysis.ventilation.phases.RESPIRATORY_INTERMEDIATE_CHANNEL_NAMES = ['Flow Interpolated', 'Pressure Interpolated', 'Product Flow Pressure', 'Slope Pressure',...

Names of the channels created by respiratory_intermediate_channels().

vitabel.analysis.ventilation.phases.respiratory_phase_labels(insp_begin: pandas.DatetimeIndex, exp_begin: pandas.DatetimeIndex, insp_intervals: list[tuple], exp_intervals: list[tuple]) → list[vitabel.timeseries.Label]

Create the respiratory phase labels.

  • “Inspiration Begin”: point label at each inspiration onset

  • “Expiration Begin”: point label at each expiration onset

  • “Inspiration”: interval label spanning inspiration phases

  • “Expiration”: interval label spanning expiration phases

The interval labels are only created if both inspiration and expiration onsets have been detected.

Parameters:
insp_beginpd.DatetimeIndex

Timestamps of inspiration phase onsets.

exp_beginpd.DatetimeIndex

Timestamps of expiration phase onsets.

insp_intervalslist[tuple]

List of (start, end) tuples for inspiration phases.

exp_intervalslist[tuple]

List of (start, end) tuples for expiration phases.

vitabel.analysis.ventilation.phases.respiratory_intermediate_channels(f_interpolated: vitabel.typing.DataSlice, p_interpolated: vitabel.typing.DataSlice, product_flow_pressure: vitabel.typing.DataSlice, slope_p: vitabel.typing.DataSlice, product_flow_pslope: vitabel.typing.DataSlice) → list[vitabel.timeseries.Channel]

Create channels for the intermediate signals of the respiratory phase detection (useful for debugging and visualization).

Parameters:
f_interpolatedDataSlice

Interpolated flow data resampled to a common time index.

p_interpolatedDataSlice

Interpolated pressure data resampled to a common time index.

product_flow_pressureDataSlice

Product of flow and pressure, used for inspiration detection.

slope_pDataSlice

Time derivative (slope) of the pressure signal.

product_flow_pslopeDataSlice

Product of negative flow and pressure slope, used for expiration detection.

class vitabel.analysis.ventilation.phases.RespiratoryPhaseResult

Result of detect_respiratory_phases().

inspiration_begins: pandas.Index

Timestamps of the inspiration onsets.

expiration_begins: pandas.Index

Timestamps of the expiration onsets.

inspiration_intervals: list[tuple]

(start, end) of the inspiration phases.

expiration_intervals: list[tuple]

(start, end) of the expiration phases.

landmarks: vitabel.typing.RespPhases

All landmarks of the detection (candidates, onsets, thresholds).

flow_interpolated: vitabel.typing.DataSlice
pressure_interpolated: vitabel.typing.DataSlice
product_flow_pressure: vitabel.typing.DataSlice
pressure_slope: vitabel.typing.DataSlice
product_negative_flow_pressure_slope: vitabel.typing.DataSlice
labels() → list[vitabel.timeseries.Label]

The respiratory phase labels, see respiratory_phase_labels().

intermediate_channels() → list[vitabel.timeseries.Channel]

Channels of the intermediate signals, see respiratory_intermediate_channels().

vitabel.analysis.ventilation.phases.detect_respiratory_phases(flow: vitabel.timeseries.Channel, pressure: vitabel.timeseries.Channel, inspiratory_threshold: float = 6.55, expiratory_threshold: float = 0.85) → RespiratoryPhaseResult

Derive the respiratory phases from air flow and airway pressure, as described in Orlob et al. [OPG+26].

Expects flow in L/min and pressure in cmH₂O. The begin of inspiration is derived from the product of flow and pressure (see get_inspiration_starts()), the begin of expiration from the product of (negative) flow and the slope of pressure (see get_expiration_starts()).

See Vitals.compute_respiratory_phases() for details.