Skip to content

Commit db7a15e

Browse files
authored
Merge pull request #115 from Remi-Gau/group
[ENH] add group level QA plot and table
2 parents d828a56 + e637344 commit db7a15e

15 files changed

Lines changed: 336 additions & 55 deletions

bidsmreye/bids_utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,10 @@ def list_subjects(cfg: Config, layout: BIDSLayout) -> list[str]:
218218
:return: _description_
219219
:rtype: list
220220
"""
221-
subjects = layout.get(return_type="id", target="subject", subject=cfg.participant)
221+
subjects = layout.get(return_type="id", target="subject", subject=cfg.subjects)
222222

223223
if subjects == [] or subjects is None:
224-
raise RuntimeError("No subject found")
224+
raise RuntimeError(f"No subject found in layout:\n\t{layout.root}")
225225

226226
if cfg.debug:
227227
subjects = [subjects[0]]

bidsmreye/bidsmreye.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
from . import _version
1515
from bidsmreye.configuration import Config
16+
from bidsmreye.defaults import allowed_actions
1617
from bidsmreye.defaults import available_models
1718
from bidsmreye.defaults import default_log_level
1819
from bidsmreye.defaults import default_model
@@ -22,6 +23,7 @@
2223
from bidsmreye.logging import bidsmreye_log
2324
from bidsmreye.prepare_data import prepare_data
2425
from bidsmreye.quality_control import quality_control_input
26+
from bidsmreye.visualize import group_report
2527

2628
__version__ = _version.get_versions()["version"]
2729

@@ -92,7 +94,7 @@ def bidsmreye(
9294
cfg = Config(
9395
bids_dir,
9496
output_dir,
95-
participant=participant_label or None,
97+
subjects=participant_label or None,
9698
space=space or None,
9799
task=task or None,
98100
run=run or None,
@@ -121,23 +123,29 @@ def bidsmreye(
121123
if action in {"all", "generalize"} and isinstance(cfg.model_weights_file, str):
122124
cfg.model_weights_file = download(cfg.model_weights_file)
123125

124-
if analysis_level == "participant":
126+
dispatch(analysis_level=analysis_level, action=action, cfg=cfg)
125127

128+
129+
def dispatch(analysis_level: str, action: str, cfg: Config) -> None:
130+
if analysis_level == "group":
131+
if action == "qc":
132+
group_report(cfg=cfg)
133+
else:
134+
log.error("Unknown group level action")
135+
sys.exit(1)
136+
137+
elif analysis_level == "participant":
126138
if action == "all":
127139
prepare_data(cfg)
128140
generalize(cfg)
129-
130141
elif action == "prepare":
131142
prepare_data(cfg)
132-
133143
elif action == "generalize":
134144
generalize(cfg)
135-
136145
elif action == "qc":
137146
quality_control_input(cfg)
138-
139147
else:
140-
log.error("Unknown action")
148+
log.error("Unknown participant level action")
141149
sys.exit(1)
142150

143151

@@ -175,15 +183,15 @@ def common_parser() -> MuhParser:
175183
Multiple participant level analyses can be run independently (in parallel)
176184
using the same output_dir.
177185
""",
178-
choices=["participant"],
186+
choices=["participant", "group"],
179187
default="participant",
180188
)
181189
parser.add_argument(
182190
"--action",
183191
help="""
184192
What action to perform.
185193
""",
186-
choices=["all", "prepare", "generalize", "qc"],
194+
choices=allowed_actions(),
187195
default="all",
188196
)
189197
parser.add_argument(

bidsmreye/config/default_filter_file.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@
1616
"eyetrack": {
1717
"suffix": "^eyetrack$$",
1818
"extension": "tsv"
19+
},
20+
"eyetrack_qc": {
21+
"suffix": "^eyetrack$$",
22+
"extension": "json"
1923
}
2024
}

bidsmreye/configuration.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def _check_input_dir(self, attribute: str, value: Path) -> None:
4646

4747
output_dir: Path = field(default=None, converter=Path)
4848

49-
participant: Any | None = field(kw_only=True, default=None)
49+
subjects: Any | None = field(kw_only=True, default=None)
5050

5151
space: Any | None = field(kw_only=True, default=None)
5252
task: Any | None = field(kw_only=True, default=None)
@@ -101,7 +101,7 @@ def __attrs_post_init__(self) -> None:
101101
if not database_path.is_dir():
102102
layout_in.save(database_path)
103103

104-
self.check_argument(attribute="participant", layout_in=layout_in)
104+
self.check_argument(attribute="subjects", layout_in=layout_in)
105105
self.check_argument(attribute="task", layout_in=layout_in)
106106
self.check_argument(attribute="run", layout_in=layout_in)
107107
self.check_argument(attribute="space", layout_in=layout_in)
@@ -120,7 +120,7 @@ def check_argument(self, attribute: str, layout_in: BIDSLayout) -> Config:
120120
:return:
121121
:rtype: Config
122122
"""
123-
if attribute == "participant":
123+
if attribute == "subjects":
124124
value = layout_in.get_subjects()
125125
elif attribute == "task":
126126
value = layout_in.get_tasks()

bidsmreye/defaults.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
from __future__ import annotations
33

44

5+
def allowed_actions() -> list[str]:
6+
"""Return a list of allowed actions."""
7+
return ["all", "prepare", "generalize", "qc"]
8+
9+
510
def default_log_level() -> str:
611
"""Return default log level."""
712
return "WARNING"

bidsmreye/generalize.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from bidsmreye.logging import bidsmreye_log
2525
from bidsmreye.quality_control import quality_control_output
2626
from bidsmreye.utils import add_sidecar_in_root
27+
from bidsmreye.utils import check_if_file_found
2728
from bidsmreye.utils import create_dir_for_file
2829
from bidsmreye.utils import move_file
2930
from bidsmreye.utils import set_this_filter
@@ -160,11 +161,7 @@ def process_subject(cfg: Config, layout_out: BIDSLayout, subject_label: str) ->
160161
**this_filter,
161162
)
162163

163-
if len(bf) == 0:
164-
log.warning(f"No file found for subject {subject_label}")
165-
else:
166-
to_print = [str(Path(x).relative_to(layout_out.root)) for x in bf]
167-
log.debug(f"Found files\n{to_print}")
164+
check_if_file_found(bf, this_filter, layout_out)
168165

169166
for file in bf:
170167

bidsmreye/prepare_data.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from bidsmreye.bids_utils import list_subjects
1919
from bidsmreye.configuration import Config
2020
from bidsmreye.logging import bidsmreye_log
21+
from bidsmreye.utils import check_if_file_found
2122
from bidsmreye.utils import get_deepmreye_filename
2223
from bidsmreye.utils import move_file
2324
from bidsmreye.utils import set_this_filter
@@ -133,11 +134,7 @@ def process_subject(
133134
**this_filter,
134135
)
135136

136-
if len(bf) == 0:
137-
log.warning(f"No file found for subject {subject_label}")
138-
else:
139-
to_print = [str(Path(x).relative_to(layout_in.root)) for x in bf]
140-
log.debug(f"Found files\n{to_print}")
137+
check_if_file_found(bf, this_filter, layout_in)
141138

142139
for img in bf:
143140

bidsmreye/quality_control.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from bidsmreye.bids_utils import list_subjects
1919
from bidsmreye.configuration import Config
2020
from bidsmreye.logging import bidsmreye_log
21+
from bidsmreye.utils import check_if_file_found
2122
from bidsmreye.utils import create_dir_for_file
2223
from bidsmreye.utils import set_this_filter
2324
from bidsmreye.visualize import visualize_eye_gaze_data
@@ -204,11 +205,7 @@ def qc_subject(
204205
**this_filter,
205206
)
206207

207-
if len(bf) == 0:
208-
log.warning(f"No file found for subject {subject_label}")
209-
else:
210-
to_print = [str(Path(x).relative_to(layout_in.root)) for x in bf]
211-
log.debug(f"Found files\n{to_print}")
208+
check_if_file_found(bf, this_filter, layout_in)
212209

213210
for file in bf:
214211

bidsmreye/utils.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,22 @@ def add_sidecar_in_root(layout_out: BIDSLayout) -> None:
4545
json.dump(content, open(sidecar_name, "w"), indent=4)
4646

4747

48-
def set_this_filter(cfg: Config, subject_label: str, filter_type: str) -> dict[str, Any]:
48+
def check_if_file_found(bf: Any, this_filter: dict[str, Any], layout: BIDSLayout) -> None:
49+
if len(bf) == 0:
50+
log.warning(f"No file found for filter {this_filter}")
51+
else:
52+
to_print = [str(Path(x).relative_to(layout.root)) for x in bf]
53+
log.debug(f"Found files\n{to_print}")
54+
55+
56+
def set_this_filter(
57+
cfg: Config, subject_label: str | list[str], filter_type: str
58+
) -> dict[str, Any]:
4959

5060
this_filter = cfg.bids_filter[filter_type]
5161
this_filter["suffix"] = return_regex(this_filter["suffix"])
5262
this_filter["task"] = return_regex(cfg.task)
53-
if filter_type not in ("eyetrack"):
63+
if filter_type not in ("eyetrack", "eyetrack_qc"):
5464
this_filter["space"] = return_regex(cfg.space)
5565
this_filter["subject"] = subject_label
5666
if cfg.run:

0 commit comments

Comments
 (0)