Skip to content

Parsers (layer 1)

loader

High-level parser routing entry points.

Use load_data() as single public entry point:

  1. auto-detect extension/vendor/format for supported vendor and extension.
  2. build parser from registry
  3. validate+parse via parse_safe
  4. attach detection metadata to output

For multiple files use load_many() or load_folder().

default_parser_registry

default_parser_registry() -> dict[tuple[str, str], ParserFactory]

Return default (vendor, extension) -> parser factory mapping.

Keys use canonical lowercase vendor and suffix with dot.

build_parser_from_detection

build_parser_from_detection(detection: FileDetection, *, registry: dict[tuple[str, str], ParserFactory] | None = None) -> BaseParser

Instantiate parser for an auto-detection payload.

Vendor string is normalised before lookup so that spelling variants ("drager", "Dräger", "DRAEGER") all resolve correctly.

Raises:

Type Description
NotImplementedError

when no parser is registered for detected key.

load_data

load_data(path: Path, *, registry: dict[tuple[str, str], ParserFactory] | None = None) -> BaseData

Single entry point: detect format/vendor then parse with matching parser.

load_many

load_many(paths: Iterable[Path | str], *, registry: dict[tuple[str, str], ParserFactory] | None = None) -> list[BaseData]

Parse multiple files and return a list of data containers.

Each file is parsed independently with load_data(). Files are returned in the same order as paths.

Parameters:

Name Type Description Default
paths Iterable[Path | str]

Iterable of file paths (strings or Path objects).

required
registry dict[tuple[str, str], ParserFactory] | None

Optional custom parser registry; forwarded to load_data().

None

Returns:

Type Description
list[BaseData]

List of BaseData subclass instances, one per input file.

Example::

from fasteit.parsers.loader import load_many

recordings = load_many(["patient01.bin", "patient02.bin"])
for rec in recordings:
    print(rec.filename, rec.n_frames, rec.fs)

load_folder

load_folder(folder: Path | str, pattern: str = '*', *, registry: dict[tuple[str, str], ParserFactory] | None = None) -> list[BaseData]

Parse all matching files in a folder and return a list of data containers.

Files are sorted by name before parsing. Use pattern to filter by extension or naming convention (standard glob syntax).

Parameters:

Name Type Description Default
folder Path | str

Directory to scan.

required
pattern str

Glob pattern relative to folder. Default "*" matches every file directly inside the folder (non-recursive). Use "**/*.bin" for recursive search.

'*'
registry dict[tuple[str, str], ParserFactory] | None

Optional custom parser registry; forwarded to load_data().

None

Returns:

Type Description
list[BaseData]

List of BaseData subclass instances for all matched files that

list[BaseData]

could be parsed. Files that raise an error are skipped with a warning

list[BaseData]

printed to stderr.

Example::

from fasteit.parsers.loader import load_folder

# All .bin files in a folder
recordings = load_folder("/data/patient01/", pattern="*.bin")

# Mixed folder - all supported formats
recordings = load_folder("/data/patient01/")

bin_parser

Drager .bin parser.

DragerBinParser

Bases: BaseParser

Parser for Dräger PulmoVista 500 .bin files.

Supports two frame layouts identified automatically by file size: - BASE (4358 bytes/frame): 32×32 pixels + 52 Medibus channels - EXT (4382 bytes/frame): 32×32 pixels + 58 Medibus channels (PressurePod variant with esophageal/transpulmonary pressure fields)

New frame sizes can be added by registering a FormatSpec in parsers/bin_formats.py without modifying this parser.

Format sources: - Reverse-engineered from PulmoVista 500 binary output - Cross-referenced with eitprocessing (Apache-2.0): https://github.com/EIT-ALIVE/eitprocessing

validate

validate(path: Path) -> bool

Return True if file exists, is non-empty, and has a known frame size.

parse

parse(path: Path, first_frame: int = 0, max_frames: int | None = None) -> ReconstructedFrameData

Parse .bin file into ReconstructedFrameData.

Parameters:

Name Type Description Default
path Path

Path to the .bin file.

required
first_frame int

Zero-indexed frame to start from. Default 0.

0
max_frames int | None

Maximum number of frames to load. If None, load all frames from first_frame to end of file.

None

Returns:

Type Description
ReconstructedFrameData

ReconstructedFrameData with frames, timestamps, pixels,

ReconstructedFrameData

aux_signals (Medibus dict), fs, and metadata.

Raises:

Type Description
UnsupportedFrameSizeError

If file size is not a multiple of a known frame size.

AmbiguousFormatError

If file size is a multiple of >1 frame sizes (rare).

InvalidSliceError

If first_frame/max_frames are invalid.

eit_parser

Dräger .eit parser.

Format summary (reverse-engineered from PulmoVista 500 output, cross-referenced with EIDORS read_draeger_header/read_draeger_file):

Byte 0..11            : preamble - 3 × int32 LE
                        [0:4]  format_version (always 51)
                        [4:8]  sep_offset      (variable, file-specific)
                        [8:12] unknown_int
Byte 12..sep_offset-1 : ASCII header (latin-1, "key: value\r\n" lines)
Byte sep_offset..+7   : separator b'**\r\n\r\n\r\n' (8 bytes)
Byte sep_offset+8..   : binary frames, each 5495 bytes

DragerEitParser

Bases: BaseParser

Parser for Dräger PulmoVista 500 .eit files.

Produces a RawImpedanceData container with the raw transimpedance measurements (208 values per frame) extracted from the binary section of the file. These are the inputs to pyEIT image reconstruction.

Format sources: - Reverse-engineered from PulmoVista 500 .eit output - Cross-referenced with EIDORS read_draeger_header / read_draeger_file (GPL, understanding only - no code copied)

validate

validate(path: Path) -> bool

Return True if file contains a recognised .eit vendor magic string.

parse

parse(path: Path) -> RawImpedanceData

Parse .eit file into RawImpedanceData.

Parameters:

Name Type Description Default
path Path

Path to the .eit file.

required

Returns:

Type Description
RawImpedanceData

RawImpedanceData with transimpedance measurements,

RawImpedanceData

sampling frequency, and header metadata.

Raises:

Type Description
ValueError

If the file is not a valid Dräger .eit file.

asc_parser

Drager .asc parser for PulmoVista tabular exports.

DragerAscParser

Bases: BaseParser

Parser for Dräger PulmoVista 500 .asc tabular exports.

The .asc file contains several sections: - ASCII header - recording metadata (file, length, filter settings) - Dynamic Image - 32×32 pixel table, one row per frame (skipped) - Tidal Image - 32×32 pixel table, breath-averaged (skipped) - Tidal Variations - breath-averaged summary (~11 columns, skipped) - Continuous waveforms - frame-by-frame signal table (~68 columns, parsed)

This parser targets the continuous waveforms section, identified by its header row starting with Image and containing more than 20 tab-separated columns. The other sections have ≤11 columns and are deliberately skipped.

Header metadata is preserved in ContinuousSignalData.metadata.

Format source: reverse-engineered from PulmoVista 500 exports. See docs/reverse_eng/draeger_bin_format.ipynb for field-level findings.

timpel_parser

Timpel tabular EIT file parser.

Parses Timpel comma-separated export files (.csv / .txt) into ReconstructedFrameData.

File format (1030 columns per row, no header, comma-delimited): cols 0-1023 32×32 reconstructed pixel impedance (row-major, arbitrary units) col 1024 airway pressure (cmH₂O) col 1025 flow (L/s) col 1026 volume (L) col 1027 min_flag 1 = expiration trough detected, 0 = none col 1028 max_flag 1 = inspiration peak detected, 0 = none col 1029 qrs_flag 1 = QRS complex detected, 0 = none

Sentinel: −1000.0 → NaN (electrode disconnection or N/A channel). Sampling frequency: 50 Hz (fixed by device firmware; no timestamps in file).

Format reference: eitprocessing timpel.py loader (Apache-2.0) https://github.com/EIT-ALIVE/eitprocessing Somhorst P et al., "eitprocessing", JOSS 2026;11(117):8179 DOI: 10.21105/joss.08179

TimpelTabularParser

Bases: BaseParser

Parser for Timpel EIT tabular export files (.csv / .txt).

Detects Timpel files by the characteristic 1030-column schema (no header). Supports partial loading via first_frame / max_frames.

Format reference: eitprocessing timpel.py loader (Apache-2.0). https://github.com/EIT-ALIVE/eitprocessing

validate

validate(path: Path) -> bool

Return True if the file looks like a Timpel tabular export.

parse

parse(path: Path, first_frame: int = 0, max_frames: int | None = None) -> ReconstructedFrameData

Parse Timpel CSV into ReconstructedFrameData.

Parameters:

Name Type Description Default
path Path

Path to the Timpel .csv / .txt file.

required
first_frame int

Zero-indexed frame to start from. Default 0.

0
max_frames int | None

Maximum frames to load. None = all from first_frame.

None

Returns:

Type Description
ReconstructedFrameData

ReconstructedFrameData with:

ReconstructedFrameData
  • frames: structured array with "ts" (seconds) and "pixels" (32×32)
ReconstructedFrameData
  • aux_signals: dict with airway_pressure, flow, volume, min_flag, max_flag, qrs_flag - each shape (N,)
ReconstructedFrameData
  • fs: TIMPEL_DEFAULT_SAMPLE_FREQUENCY (50 Hz)

Raises:

Type Description
ValueError

Wrong column count or empty slice.

InvalidSliceError

first_frame out of bounds or max_frames <= 0.

OSError

File cannot be read as text (encoding error).