Skip to content

Commit

Permalink
fix ignoring sessions that have no data (#1035)
Browse files Browse the repository at this point in the history
  • Loading branch information
drammock authored Jan 24, 2025
1 parent dd1f025 commit 284a905
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
command: |
pip install --upgrade --progress-bar off pip
# TODO: Restore https://api.github.com/repos/mne-tools/mne-bids/zipball/main pending https://github.com/mne-tools/mne-bids/pull/1349/files#r1885104885
pip install --upgrade --progress-bar off "autoreject @ https://api.github.com/repos/autoreject/autoreject/zipball/master" "mne[hdf5] @ git+https://github.com/mne-tools/mne-python@main" "mne-bids[full]" numba
pip install --upgrade --progress-bar off "autoreject @ https://api.github.com/repos/autoreject/autoreject/zipball/master" "mne[hdf5] @ git+https://github.com/mne-tools/mne-python@main" "mne-bids[full] @ git+https://github.com/mne-tools/mne-bids@main" numba
pip install -ve .[tests]
pip install "PyQt6!=6.6.1" "PyQt6-Qt6!=6.6.1,!=6.6.2,!=6.6.3,!=6.7.0"
- run:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
with:
python-version: "3.12"
- run: pip install --upgrade pip
- run: pip install -ve .[tests] codespell tomli --only-binary="numpy,scipy,pandas,matplotlib,pyarrow,numexpr"
- run: pip install -ve .[tests] "mne-bids[full] @ git+https://github.com/mne-tools/mne-bids@main" codespell tomli --only-binary="numpy,scipy,pandas,matplotlib,pyarrow,numexpr"
- run: make codespell-error
- run: pytest mne_bids_pipeline -m "not dataset_test"
- uses: codecov/codecov-action@v5
Expand Down
12 changes: 12 additions & 0 deletions mne_bids_pipeline/_config_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import pathlib
from dataclasses import field
from functools import partial
from inspect import signature
from types import SimpleNamespace
from typing import Any

import matplotlib
import mne
import numpy as np
from mne_bids import get_entity_vals
from pydantic import BaseModel, ConfigDict, ValidationError

from ._logging import gen_log_kwargs, logger
Expand Down Expand Up @@ -324,6 +326,16 @@ def _check_config(config: SimpleNamespace, config_path: PathLike | None) -> None
"Please set process_empty_room = True"
)

if (
config.allow_missing_sessions
and "ignore_suffixes" not in signature(get_entity_vals).parameters
):
raise ConfigError(
"You've requested to `allow_missing_sessions`, but this functionality "
"requires a newer version of `mne_bids` than you have available. Please "
"update MNE-BIDS (or if on the latest version, install the dev version)."
)

bl = config.baseline
if bl is not None:
if (bl[0] is not None and bl[0] < config.epochs_tmin) or (
Expand Down
49 changes: 38 additions & 11 deletions mne_bids_pipeline/_config_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import functools
import pathlib
from collections.abc import Iterable, Sized
from inspect import signature
from types import ModuleType, SimpleNamespace
from typing import Any, Literal, TypeVar

Expand Down Expand Up @@ -142,26 +143,52 @@ def _get_sessions(config: SimpleNamespace) -> tuple[str, ...]:
return tuple(str(x) for x in sessions)


def get_subjects_sessions(config: SimpleNamespace) -> dict[str, list[str] | list[None]]:
subj_sessions: dict[str, list[str] | list[None]] = dict()
def get_subjects_sessions(
config: SimpleNamespace,
) -> dict[str, tuple[None] | tuple[str, ...]]:
subjects = get_subjects(config)
cfg_sessions = _get_sessions(config)
for subject in get_subjects(config):
# Only traverse through the current subject's directory
# easy case first: datasets that don't have (named) sessions
if not cfg_sessions:
return {subj: (None,) for subj in subjects}

# find which tasks to ignore when deciding if a subj has data for a session
ignore_datatypes = _get_ignore_datatypes(config)
if config.task == "":
ignore_tasks = None
else:
all_tasks = _get_entity_vals_cached(
root=config.bids_root,
entity_key="task",
ignore_datatypes=ignore_datatypes,
)
ignore_tasks = tuple(set(all_tasks) - set([config.task]))

# loop over subjs and check for available sessions
subj_sessions: dict[str, tuple[None] | tuple[str, ...]] = dict()
kwargs = (
dict(ignore_suffixes=("scans", "coordsystem"))
if "ignore_suffixes" in signature(mne_bids.get_entity_vals).parameters
else dict()
)
for subject in subjects:
valid_sessions_subj = _get_entity_vals_cached(
config.bids_root / f"sub-{subject}",
entity_key="session",
ignore_datatypes=_get_ignore_datatypes(config),
ignore_tasks=ignore_tasks,
ignore_acquisitions=("calibration", "crosstalk"),
ignore_datatypes=ignore_datatypes,
**kwargs,
)
missing_sessions = set(cfg_sessions) - set(valid_sessions_subj)
missing_sessions = sorted(set(cfg_sessions) - set(valid_sessions_subj))
if missing_sessions and not config.allow_missing_sessions:
raise RuntimeError(
f"Subject {subject} is missing session{_pl(missing_sessions)} "
f"{tuple(sorted(missing_sessions))}, and "
"`config.allow_missing_sessions` is False"
f"{missing_sessions}, and `config.allow_missing_sessions` is False"
)
subj_sessions[subject] = sorted(set(cfg_sessions) & set(valid_sessions_subj))
if subj_sessions[subject] == []:
subj_sessions[subject] = [None]
keep_sessions = tuple(sorted(set(cfg_sessions) & set(valid_sessions_subj)))
if len(keep_sessions):
subj_sessions[subject] = keep_sessions
return subj_sessions


Expand Down
2 changes: 1 addition & 1 deletion mne_bids_pipeline/tests/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def test_missing_sessions(
context = (
nullcontext()
if allow_missing_sessions
else pytest.raises(RuntimeError, match=r"Subject 1 is missing session \('b',\)")
else pytest.raises(RuntimeError, match=r"Subject 1 is missing session \['b'\]")
)
# run
command = [
Expand Down

0 comments on commit 284a905

Please sign in to comment.