Skip to content

Models

base_data

BaseData: base dataclass for all fasteit data containers.

BaseData dataclass

BaseData(filename: str = '', file_format: str = '', vendor: str = '', fs: float | None = None, metadata: dict = dict())

Base container for raw data from any parser.

Attributes:

Name Type Description
filename str

Path of the source file.

file_format str

Format identifier - "bin", "eit", "asc", "csv", or "txt".

vendor str

Detected device vendor - "draeger" or "timpel".

fs float | None

Sampling rate in Hz, estimated by parser from timestamps.

metadata dict

Parsed header information (framerate, date, firmware, etc.).

n_frames int

Number of frames - set by subclass post_init.

duration float

Recording duration in seconds - set by subclass post_init.

reconstructed_data

ReconstructedFrameData: container for frame-wise reconstructed EIT data.

Produced by: DragerBinParser (.bin), TimpelTabularParser (.txt/.csv).

ReconstructedFrameData dataclass

ReconstructedFrameData(filename: str = '', file_format: str = '', vendor: str = '', fs: float | None = None, metadata: dict = dict(), frames: ndarray | None = None, aux_signals: dict | None = None)

Bases: BaseData

Container for frame-wise reconstructed EIT data with synchronized signals.

Stores vendor-reconstructed 32×32 pixel images and any continuous signals that are frame-synchronised in the source file (e.g. Medibus waveforms in Dräger .bin, device channels in Timpel .txt).

aux_signals is a vendor-agnostic dict of named continuous signals that are frame-aligned with frames. For Dräger .bin this is the Medibus dict; for Timpel tabular exports it holds the 6 device channels.

Attributes:

Name Type Description
frames ndarray | None

Structured numpy array, shape (N,). Required fields: ts (float64, timestamp), pixels (float32, 32×32 image).

aux_signals dict | None

Dict mapping signal name → 1-D array of length N, or None if the source file carries no auxiliary channels.

timestamps property

timestamps: ndarray

Timestamp per frame. Shape (N,).

Convention depends on vendor: - Dräger .bin: wall-clock time as fraction of day (0.0-1.0, float64) - Timpel .csv: seconds from start of recording (e.g. 2.0 s at frame 100 with 50 Hz), generated as (first_frame + i) / fs

pixels property

pixels: ndarray

Reconstructed 32×32 images for all frames. Shape (N, 32, 32).

min_max_flags property

min_max_flags: ndarray

Breath phase marker per frame. Shape (N,). Dräger .bin only.

+1 = inspiration peak, -1 = expiration trough, 0 = neither.

event_markers property

event_markers: ndarray

Event counter per frame. Shape (N,). Dräger .bin only.

event_texts property

event_texts: ndarray

Event text strings per frame. Shape (N,) of bytes. Dräger .bin only.

global_signal property

global_signal: ndarray

Sum of all pixels per frame (no lung mask applied). Shape (N,).

roi_signals property

roi_signals: ndarray

4 ventro-dorsal strip signals (equal horizontal strips). Shape (N, 4).

Each strip sums 8 rows of the 32×32 image: strip 0 = rows 0- 7 (ventral) strip 1 = rows 8-15 (mid-ventral) strip 2 = rows 16-23 (mid-dorsal) strip 3 = rows 24-31 (dorsal)

These are the four horizontal layers of the PulmoVista display (its ROI 1-4 are strips 0-3 here), on the whole image. Regions of interest as layers or quadrants: TREND consensus, Frerichs et al., Thorax 2017; doi:10.1136/thoraxjnl-2016-208357. The regions of the lung (halves, layers on the lung extent, quadrants) are computed in layer 2 (EITRecording.roi_masks).

roi_signal

roi_signal(roi: int) -> np.ndarray

Signal for a single ROI (0 = ventral … 3 = dorsal). Shape (N,).

Parameters:

Name Type Description Default
roi int

ROI index in range 0-3.

required

continuous_data

ContinuousSignalData: container for signal-table EIT exports (no pixel matrices).

Produced by: DragerAscParser (.asc), and future vendors with signal-only exports.

ContinuousSignalData dataclass

ContinuousSignalData(filename: str = '', file_format: str = '', vendor: str = '', fs: float | None = None, metadata: dict = dict(), table: DataFrame | None = None)

Bases: BaseData

Container for time-aligned continuous signal tables.

For files whose primary artifact is a table of sampled signals over time, with no pixel matrices.

Dräger .asc is the canonical source. Future vendors producing signal-only exports (no pixel matrices) should map here too.

Attributes:

Name Type Description
table DataFrame | None

Parsed tabular data as a pandas DataFrame.

raw_impedance_data

RawImpedanceData: container for raw transimpedance measurements.

Produced by: DragerEitParser (.eit). Primary use case: pyEIT interface for image reconstruction.

RawImpedanceData dataclass

RawImpedanceData(filename: str = '', file_format: str = '', vendor: str = '', fs: float | None = None, metadata: dict = dict(), measurements: ndarray | None = None, aux_signals: dict[str, ndarray] | None = None)

Bases: BaseData

Container for raw EIT transimpedance measurements.

Stores the 208 transimpedance values per frame as-is from the file, before any image reconstruction. The intended consumer is pyEIT.

Attributes:

Name Type Description
measurements ndarray | None

Calibrated transimpedance array, shape (N_frames, 208). Values are gain-corrected (e.g. vv = FT_A*trans_A - FT_B*trans_B for Dräger), not raw ADC counts and not yet image-reconstructed. 208 = 16 electrodes × 13 measurement pairs (adjacent drive, standard Dräger pattern).

aux_signals dict[str, ndarray] | None

Optional dict of auxiliary waveforms keyed by signal name, e.g. {"timestamp": ..., "frame_counter": ..., "medibus_Paw": ...}. Each value is a 1-D array of length N_frames.

eit_recording

Containers for a preprocessed recording (layer 2).

  • Segment - a time interval of a recording (exclusion, PEEP step, phase)
  • RecordingContext - attributes of the whole recording (patient, label, position, protocol, tidal volume)
  • EITRecording - the recording ready for analysis, output of preprocess()

Segment dataclass

Segment(start: float, end: float, category: str = EXCLUSION, label: str = '', source: str = 'manual', parameters: dict = dict())

A time interval of a recording, in seconds from the start of the recording.

Attributes:

Name Type Description
start float

Start time in seconds.

end float

End time in seconds (must be greater than start).

category str

What the interval is: "exclusion" (layer 2), "peep_step" or "phase" (layer 2b).

label str

Why, e.g. "artifact", "movement", "timing_error".

source str

Who created it: "manual", "device" or "auto".

parameters dict

For automatic segments, how they were found. Not used for hashing, so segments can be put in a set.

Two segments that share an end point, e.g. [0, 10] and [10, 20], touch: a breath ending at 10 s overlaps both.

overlaps

overlaps(start: float, end: float) -> bool

Return True if the interval [start, end] touches this segment.

RecordingContext dataclass

RecordingContext(patient_id: str = '', label: str = '', position: str | None = None, protocol: str = 'tidal', interface: str | None = None, tidal_volume_ml: float | None = None, notes: str = '')

Attributes of the whole recording, given by the user.

Attributes:

Name Type Description
patient_id str

Anonymised patient identifier.

label str

Name of the recording for this patient, e.g. a time point ("T0") or a position; with patient_id it identifies the rows of the exported tables (layer 4), where it can also be changed.

position str | None

Patient position during the recording, e.g. "supine", "prone".

protocol str

"tidal" or "peep_trial"; recorded in the settings table of the export (layer 4), it does not change what is computed.

interface str | None

Ventilation interface, e.g. "helmet", "face_mask".

tidal_volume_ml float | None

Tidal volume of the whole recording typed by the user (mL), e.g. the one set in volume control or the mean on the case report form; None if not typed. It wins over the tidal volume measured on the ventilator curves of each breath.

notes str

Free text.

EITRecording dataclass

EITRecording(raw: ReconstructedFrameData, config: PreprocessingConfig, context: RecordingContext, exclusions: tuple[Segment, ...], time: ndarray, rates: dict[str, float | None], cardiac_filter: str, pixels: ndarray, image_mask: ndarray, detection_signal: ndarray, global_signal: ndarray, breaths: DataFrame, lung_mask: ndarray, tiv_map: ndarray, roi_masks: dict[str, ndarray], roi_signals: DataFrame, aux: DataFrame, aux_units: dict[str, str | None], pressure_channel: str | None, tidal_volume_channel: str | None, log: tuple[str, ...])

A recording ready for breath-by-breath analysis (output of preprocess()).

To change a parameter or an exclusion, call preprocess() again. The fields cannot be reassigned, the config is frozen, the arrays are read-only and the parsed data in raw is never modified. The DataFrames and dicts can still be changed in place by Python: do not modify them, make a copy.

All signals are in arbitrary impedance units (EELI is relative, not comparable between recordings). Breath frames (start_idx, peak_idx, end_idx) are extrema of detection_signal, the signal they were found on.

Attributes:

Name Type Description
raw ReconstructedFrameData

Data from the parser, untouched.

config PreprocessingConfig

Parameters used.

context RecordingContext

Attributes of the recording given by the user.

exclusions tuple[Segment, ...]

Excluded parts (manual and device), widened by the margin and merged.

time ndarray

(N,) seconds from the start of the recording.

rates dict[str, float | None]

respiratory_rate_hz from the spectrum (None if it could not be estimated) and heart_rate_hz as entered by the user (None if not given).

cardiac_filter str

Filter actually applied: "mdn" (cardiac component removed) or "moving_average" (not removed).

pixels ndarray

(N, rows, cols) float32, after the cardiac step; NaN for pixels without data in the whole recording.

image_mask ndarray

(rows, cols) bool, pixels with a signal (the image inside the belt outline); wider than the lung, e.g. for silent spaces.

detection_signal ndarray

(N,) sum of all pixels after the cardiac step, used for the breath detection and the quality flags.

global_signal ndarray

(N,) sum of the pixels inside the lung mask.

breaths DataFrame

One row per breath: times and frames of start, peak and end, quality flags, excluded, exclusion_label, is_valid; peep, plateau and driving_pressure (cmH2O) and the inspiratory tidal_volume (mL), NaN where not available.

lung_mask ndarray

(rows, cols) bool, ventilated lung (not the anatomical lung).

tiv_map ndarray

(rows, cols) mean TIV of the valid breaths (first and last breath excluded), used for the mask.

roi_masks dict[str, ndarray]

Regions of interest, each inside the lung mask.

roi_signals DataFrame

(N, n_regions) sum of the pixels of each region.

aux DataFrame

(N, n_channels) auxiliary signals with data (pressures, flow, volume, device breath markers), "no data" values as NaN, not filtered; rows are frame numbers like the breath indices. Same units for every vendor: pressures in cmH2O, flow in L/s, volumes in mL.

aux_units dict[str, str | None]

Unit of each column of aux ("" for markers and flags, None if unknown).

pressure_channel str | None

Column of aux the pressures of the breaths were read from, or None if there was no pressure.

tidal_volume_channel str | None

Column of aux the tidal volumes of the breaths come from (volume curve, flow curve or ventilator value), or None.

log tuple[str, ...]

What each step did, with fallbacks and warnings.

fs property

fs: float

Sampling frequency in Hz.

valid_breaths property

valid_breaths: DataFrame

The breaths without quality flags and outside the exclusions.

peep_trial

PeepTrial: a preprocessed PEEP trial split into PEEP steps (layer 2b).

PeepTrial dataclass

PeepTrial(recording: EITRecording, config: SegmentationConfig, source: str, phase: Segment | None, steps: DataFrame, breaths: DataFrame, log: tuple[str, ...])

A PEEP trial ready for layer 3: PEEP steps and the breaths analysed in each.

Output of segment_peep_trial(). To change a parameter or a step placed by hand, call it again. Do not modify the DataFrames in place: make a copy.

Attributes:

Name Type Description
recording EITRecording

The preprocessed recording (layer 2).

config SegmentationConfig

Parameters used.

source str

Where the steps come from: "pressure" or "manual".

phase Segment | None

The PEEP trial part of the recording, or None for the whole recording.

steps DataFrame

One row per step: step, peep (level, as measured or as typed, cmH2O), peep_set (the nearest PEEP level of the protocol, SegmentationConfig.peep_levels), start_time, end_time, n_breaths, n_analysed, enough (at least the minimum), plateau and driving_pressure with driving_pressure_source: "breaths" (median of the analysed breaths, continuous pause), "hold" (median of the breaths of the step with an inspiratory hold) or "typed" (step placed by hand); n_driving_pressure and enough_driving_pressure; tidal_volume (mL) with tidal_volume_source: "typed" (for the step), "typed_recording" (RecordingContext.tidal_volume_ml) or "breaths" (median of the analysed breaths, ventilator curves).

breaths DataFrame

The breath table of the recording (with peep, plateau and driving_pressure in cmH2O and tidal_volume in mL, read in layer 2) plus peep_step (-1 outside every step) and analysed.

log tuple[str, ...]

What the segmentation did, with warnings.

analysed_breaths property

analysed_breaths: DataFrame

The breaths analysed in each step.

features

Clinical indices of a recording (layer 3), as tables ready for a database or R.

  • TidalFeatures - indices of each breath of a recording, and their summary
  • PeepTrialFeatures - indices of each breath and of each PEEP step of a PEEP trial

Each object holds everything: its tables, and the objects of the layers before it (features.trial.recording.breaths...). Each value is stored once: the tables of layer 3 have the keys (breath_id, step, peep, region) and what layer 3 computes; what layers 2 and 2b measured (times, quality, pressures, steps) stays in their own tables, joined on the keys. The tables are "long" by region (one row per breath, or step, and region), so that they can be joined with the clinical data (patient, position, side) at the time of the analysis.

TidalFeatures dataclass

TidalFeatures(recording: EITRecording, breaths: DataFrame, regions: DataFrame, summary: DataFrame, log: tuple[str, ...])

Clinical indices of a recording breathing at one setting (output of tidal_features()). Do not modify the DataFrames in place: make a copy.

Attributes:

Name Type Description
recording EITRecording

The preprocessed recording (layer 2).

breaths DataFrame

One row per breath of the recording: breath_id, in_phase, respiratory_rate, eeli, tiv, gi, cov_vd, cov_rl, tidal_volume_used (typed or measured) and its tidal_volume_source, compliance (EIT units per cmH2O), compliance_ml (mL/cmH2O). Times, quality and pressures: recording.breaths.

regions DataFrame

One row per breath and region: breath_id, region, eeli, tiv, share, tiv_ml, compliance, compliance_ml.

summary DataFrame

One row per region ("global" for the whole lung) and index (column feature, with PEEP, plateau and driving pressure): median, q1, q3 over the valid breaths of the phase, and n_breaths with a value.

log tuple[str, ...]

What was computed, with warnings.

PeepTrialFeatures dataclass

PeepTrialFeatures(trial: PeepTrial, config: AnalysisConfig, breaths: DataFrame, regions: DataFrame, steps: DataFrame, step_regions: DataFrame, summary: DataFrame, log: tuple[str, ...])

Clinical indices of a PEEP trial (output of peep_trial_features()). Do not modify the DataFrames in place: make a copy.

Attributes:

Name Type Description
trial PeepTrial

The segmented PEEP trial (layer 2b).

config AnalysisConfig

Parameters used.

breaths DataFrame

One row per breath, as in TidalFeatures (without in_phase). Step and analysed breaths: trial.breaths.

regions DataFrame

One row per breath and region, as in TidalFeatures.

steps DataFrame

One row per PEEP step (step, peep), from its analysed breaths: medians of the breath indices, compliance in EIT units and in mL/cmH2O (and as % of the best step), Costa collapse and overdistension, and the changes vs the previous and the first step. Driving pressure, tidal volume, breaths analysed: trial.steps.

step_regions DataFrame

One row per step and region: eeli, tiv, share, tiv_ml, compliance, compliance_ml.

summary DataFrame

One row per region and feature (region, feature, value): for "global" the crossing PEEP of collapse and overdistension, the PEEP of the best compliance in EIT units and in mL/cmH2O, the two PEEP of the R/I; for every region (global included) the recruitment-to-inflation ratio ri and the recruited_volume_ml.

log tuple[str, ...]

What was computed, with warnings.