diff --git a/eitprocessing/datahandling/loading/__init__.py b/eitprocessing/datahandling/loading/__init__.py index a8c8b238a..3dad111fa 100644 --- a/eitprocessing/datahandling/loading/__init__.py +++ b/eitprocessing/datahandling/loading/__init__.py @@ -18,6 +18,10 @@ def load_eit_data( ) -> Sequence: """Load EIT data from path(s). + Current limitations: + - Dräger data is assumed to have a limited set of (Medibus) data. Newer additions that add data like pleural + pressure are not yet supported. + Args: path: relative or absolute path(s) to data file. vendor: vendor indicating the device used. @@ -64,6 +68,10 @@ def load_eit_data( Vendor.SENTEC: sentec.load_from_single_path, }[vendor] + if vendor == Vendor.DRAEGER and not sample_frequency: + msg = """Provide a sample frequency when loading Draeger data.""" + raise NotImplementedError(msg) # automatic sample frequency detection is to be implemented per #217 + first_frame = _check_first_frame(first_frame) paths = EITData.ensure_path_list(path) diff --git a/eitprocessing/datahandling/loading/draeger.py b/eitprocessing/datahandling/loading/draeger.py index e55003f9c..3e41abb71 100644 --- a/eitprocessing/datahandling/loading/draeger.py +++ b/eitprocessing/datahandling/loading/draeger.py @@ -23,13 +23,12 @@ from numpy.typing import NDArray _FRAME_SIZE_BYTES = 4358 -DRAEGER_SAMPLE_FREQUENCY = 20 load_draeger_data = partial(load_eit_data, vendor=Vendor.DRAEGER) def load_from_single_path( path: Path, - sample_frequency: float | None = 20, + sample_frequency: float, first_frame: int = 0, max_frames: int | None = None, ) -> dict[str, DataCollection]: @@ -38,7 +37,9 @@ def load_from_single_path( if file_size % _FRAME_SIZE_BYTES: msg = ( f"File size {file_size} of file {path!s} not divisible by {_FRAME_SIZE_BYTES}.\n" - f"Make sure this is a valid and uncorrupted Dräger data file." + "Currently this package does not support loading files containing " + "esophageal pressure or other non-standard data. " + "Make sure this is a valid and uncorrupted Dräger data file." ) raise OSError(msg) total_frames = file_size // _FRAME_SIZE_BYTES @@ -88,7 +89,8 @@ def load_from_single_path( ) if not sample_frequency: - sample_frequency = DRAEGER_SAMPLE_FREQUENCY + msg = "No sample frequency provided. " + raise ValueError(msg) eit_data = EITData( vendor=Vendor.DRAEGER, diff --git a/tests/conftest.py b/tests/conftest.py index 660858610..45bfdd48f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,17 +21,17 @@ @pytest.fixture(scope="session") def draeger1(): - return load_eit_data(draeger_file1, vendor="draeger", label="draeger1") + return load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20, label="draeger1") @pytest.fixture(scope="session") def draeger2(): - return load_eit_data(draeger_file2, vendor="draeger", label="draeger2") + return load_eit_data(draeger_file2, vendor="draeger", sample_frequency=20, label="draeger2") @pytest.fixture(scope="session") def draeger_both(): - return load_eit_data([draeger_file2, draeger_file1], vendor="draeger", label="draeger_both") + return load_eit_data([draeger_file2, draeger_file1], vendor="draeger", sample_frequency=20, label="draeger_both") @pytest.fixture(scope="session") diff --git a/tests/mixins/test_eq.py b/tests/mixins/test_eq.py index 4f6385c82..f4300b635 100644 --- a/tests/mixins/test_eq.py +++ b/tests/mixins/test_eq.py @@ -8,8 +8,8 @@ def test_eq(): - data = load_eit_data(draeger_file1, vendor="draeger") - data2 = load_eit_data(draeger_file1, vendor="draeger") + data = load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20) + data2 = load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20) data.isequivalent(data2) diff --git a/tests/test_labels.py b/tests/test_labels.py index b8edb2d7d..1b3ec2ca8 100644 --- a/tests/test_labels.py +++ b/tests/test_labels.py @@ -6,7 +6,7 @@ def test_default_label(draeger1: Sequence): - draeger_default = load_eit_data(draeger_file1, vendor="draeger") + draeger_default = load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20) assert isinstance(draeger_default.label, str) assert draeger_default.label == f"Sequence_{id(draeger_default)}" @@ -15,7 +15,7 @@ def test_default_label(draeger1: Sequence): assert timpel_default.label == f"Sequence_{id(timpel_default)}" # test that default label changes upon reloading identical data - draeger_reloaded = load_eit_data(draeger_file1, vendor="draeger") + draeger_reloaded = load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20) assert draeger_default == draeger_reloaded assert draeger_default.label != draeger_reloaded.label assert draeger_default.label != draeger1.label diff --git a/tests/test_loading.py b/tests/test_loading.py index 24d20d834..265e07fc8 100644 --- a/tests/test_loading.py +++ b/tests/test_loading.py @@ -2,9 +2,14 @@ from eitprocessing.datahandling.eitdata import EITData, Vendor from eitprocessing.datahandling.loading import load_eit_data -from eitprocessing.datahandling.loading.draeger import DRAEGER_SAMPLE_FREQUENCY from eitprocessing.datahandling.sequence import Sequence -from tests.conftest import draeger_file1, draeger_file2, draeger_file3, dummy_file, timpel_file +from tests.conftest import ( + draeger_file1, + draeger_file2, + draeger_file3, + dummy_file, + timpel_file, +) # ruff: noqa: ERA001 #TODO: remove this line @@ -20,8 +25,8 @@ def test_loading_draeger( assert len(draeger1.eit_data["raw"]) == len(draeger1.eit_data["raw"].time) assert len(draeger2.eit_data["raw"].time) == 20740 - assert draeger1 == load_eit_data(draeger_file1, vendor="draeger", label="draeger1") - assert draeger1 == load_eit_data(draeger_file1, vendor="draeger", label="something_else") + assert draeger1 == load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20, label="draeger1") + assert draeger1 == load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20, label="something_else") assert draeger1 != draeger2 # Load multiple @@ -55,13 +60,17 @@ def test_loading_illegal(): # non existing for vendor in ["draeger", "timpel"]: with pytest.raises(FileNotFoundError): - _ = load_eit_data(dummy_file, vendor=vendor) + _ = load_eit_data(dummy_file, vendor=vendor, sample_frequency=20) # incorrect vendor with pytest.raises(OSError): _ = load_eit_data(draeger_file1, vendor="timpel") with pytest.raises(OSError): - _ = load_eit_data(timpel_file, vendor="draeger") + _ = load_eit_data(timpel_file, vendor="draeger", sample_frequency=20) + + # no sample frequency provided + with pytest.raises(NotImplementedError): + _ = load_eit_data(timpel_file, vendor="draeger", sample_frequency=None) def test_load_partial( @@ -79,8 +88,8 @@ def test_load_partial( # file for this situation. # Timpel - timpel_part1 = load_eit_data(timpel_file, "timpel", max_frames=cutoff, label="timpel_part_1") - timpel_part2 = load_eit_data(timpel_file, "timpel", first_frame=cutoff, label="timpel_part2") + timpel_part1 = load_eit_data(timpel_file, vendor="timpel", max_frames=cutoff, label="timpel_part_1") + timpel_part2 = load_eit_data(timpel_file, vendor="timpel", first_frame=cutoff, label="timpel_part2") assert len(timpel_part1) == cutoff assert len(timpel_part2) == len(timpel1) - cutoff @@ -90,8 +99,20 @@ def test_load_partial( # assert Sequence.concatenate(timpel_part2, timpel_part1) != timpel1 # Draeger - draeger2_part1 = load_eit_data(draeger_file2, "draeger", max_frames=cutoff, label="draeger_part_1") - draeger2_part2 = load_eit_data(draeger_file2, "draeger", first_frame=cutoff, label="draeger_part_2") + draeger2_part1 = load_eit_data( + draeger_file2, + vendor="draeger", + sample_frequency=20, + max_frames=cutoff, + label="draeger_part_1", + ) + draeger2_part2 = load_eit_data( + draeger_file2, + vendor="draeger", + sample_frequency=20, + first_frame=cutoff, + label="draeger_part_2", + ) assert len(draeger2_part1) == cutoff assert len(draeger2_part2) == len(draeger2) - cutoff @@ -108,24 +129,19 @@ def test_load_partial( def test_illegal_first_frame(): for ff in [0.5, -1, "fdw", 1e12]: with pytest.raises((TypeError, ValueError)): - _ = load_eit_data(draeger_file1, "draeger", first_frame=ff) + _ = load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20, first_frame=ff) for ff2 in [0, 0.0, 1.0, None]: - _ = load_eit_data(draeger_file1, "draeger", first_frame=ff2) + _ = load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20, first_frame=ff2) def test_max_frames_too_large(): with pytest.warns(): - _ = load_eit_data(draeger_file1, "draeger", max_frames=1e12) - - -def test_sample_frequency_unset(): - loaded_draeger = load_eit_data(draeger_file1, "draeger", sample_frequency=None) - assert loaded_draeger.eit_data["raw"].sample_frequency == DRAEGER_SAMPLE_FREQUENCY + _ = load_eit_data(draeger_file1, vendor="draeger", sample_frequency=20, max_frames=1e12) def test_event_on_first_frame(draeger2: Sequence): - draeger3 = load_eit_data(draeger_file3, vendor="draeger") + draeger3 = load_eit_data(draeger_file3, vendor="draeger", sample_frequency=20) draeger3_events = draeger3.sparse_data["events_(draeger)"] assert draeger3_events == draeger2.sparse_data["events_(draeger)"] assert draeger3_events.time[0] == draeger3.eit_data["raw"].time[0]