Skip to content

Commit 1cd7539

Browse files
committed
Add transform_to_physio auto mode
1 parent 3a08510 commit 1cd7539

File tree

4 files changed

+101
-0
lines changed

4 files changed

+101
-0
lines changed

physutils/tasks.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22
from functools import wraps
33

4+
from bids import BIDSLayout
45
from loguru import logger
56

67
from physutils.io import load_from_bids, load_physio
@@ -33,6 +34,19 @@ def wrapped_func(*args, **kwargs):
3334
return decorator
3435

3536

37+
def is_bids_directory(directory):
38+
try:
39+
# Attempt to create a BIDSLayout object
40+
_ = BIDSLayout(directory)
41+
return True
42+
except Exception as e:
43+
# Catch other exceptions that might indicate the directory isn't BIDS compliant
44+
logger.error(
45+
f"An error occurred while trying to load {directory} as a BIDS Layout object: {e}"
46+
)
47+
return False
48+
49+
3650
@mark_task(pydra_imported=pydra_imported)
3751
def transform_to_physio(
3852
input_file: str, mode="physio", fs=None, bids_parameters=dict(), bids_channel=None
@@ -45,6 +59,15 @@ def transform_to_physio(
4559
if not fs:
4660
fs = None
4761

62+
if mode == "auto":
63+
if input_file.endswith((".phys", ".physio", ".1D", ".txt", ".tsv", ".csv")):
64+
mode = "physio"
65+
elif is_bids_directory(input_file):
66+
mode = "bids"
67+
else:
68+
raise ValueError(
69+
"Could not determine mode automatically, please specify mode"
70+
)
4871
if mode == "physio":
4972
if fs is not None:
5073
physio_obj = load_physio(input_file, fs=fs, allow_pickle=True)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"SamplingFrequency": 10000.0,
3+
"StartTime": -3,
4+
"Columns": [
5+
"time",
6+
"respiratory_chest",
7+
"trigger",
8+
"cardiac",
9+
"respiratory_CO2",
10+
"respiratory_O2"
11+
]
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"SamplingFrequency": 10000.0,
3+
"StartTime": -3,
4+
"Columns": [
5+
"time",
6+
"respiratory_chest",
7+
"trigger",
8+
"cardiac",
9+
"respiratory_CO2",
10+
"respiratory_O2"
11+
]
12+
}

physutils/tests/test_tasks.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,57 @@ def test_transform_to_physio_bids_file():
5151

5252
physio_obj = task.result().output.out
5353
assert isinstance(physio_obj, physio.Physio)
54+
55+
56+
def test_transform_to_physio_auto():
57+
create_random_bids_structure("physutils/tests/data", recording_id="cardiac")
58+
bids_parameters = {
59+
"subject": "01",
60+
"session": "01",
61+
"task": "rest",
62+
"run": "01",
63+
"recording": "cardiac",
64+
}
65+
bids_dir = os.path.abspath("physutils/tests/data/bids-dir")
66+
task = tasks.transform_to_physio(
67+
input_file=bids_dir,
68+
mode="auto",
69+
bids_parameters=bids_parameters,
70+
bids_channel="cardiac",
71+
)
72+
73+
assert task.inputs.input_file == bids_dir
74+
assert task.inputs.mode == "auto"
75+
assert task.inputs.fs is None
76+
assert task.inputs.bids_parameters == bids_parameters
77+
assert task.inputs.bids_channel == "cardiac"
78+
79+
task()
80+
81+
physio_obj = task.result().output.out
82+
assert isinstance(physio_obj, physio.Physio)
83+
84+
85+
def test_transform_to_physio_auto_error(caplog):
86+
bids_dir = os.path.abspath("physutils/tests/data/non-bids-dir")
87+
task = tasks.transform_to_physio(
88+
input_file=bids_dir,
89+
mode="auto",
90+
bids_channel="cardiac",
91+
)
92+
93+
assert task.inputs.input_file == bids_dir
94+
assert task.inputs.mode == "auto"
95+
assert task.inputs.fs is None
96+
assert task.inputs.bids_channel == "cardiac"
97+
98+
try:
99+
task()
100+
except Exception:
101+
assert caplog.text.count("ERROR") == 1
102+
assert (
103+
caplog.text.count(
104+
"dataset_description.json' is missing from project root. Every valid BIDS dataset must have this file."
105+
)
106+
== 1
107+
)

0 commit comments

Comments
 (0)