Skip to content

Commit

Permalink
add config for passing extra kwargs to maxwell_filter (#1038)
Browse files Browse the repository at this point in the history
Co-authored-by: Eric Larson <[email protected]>
  • Loading branch information
drammock and larsoner authored Jan 16, 2025
1 parent 8a43ede commit 8408697
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/source/dev.md.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- It is now possible to use separate MRIs for each session within a subject, as in longitudinal studies. This is achieved by creating separate "subject" folders for each subject-session combination, with the naming convention `sub-XXX_ses-YYY`, in the freesurfer `SUBJECTS_DIR`. (#987 by @drammock)
- New config option [`allow_missing_sessions`][mne_bids_pipeline._config.allow_missing_sessions] allows to continue when not all sessions are present for all subjects. (#1000 by @drammock)
- New config option [`mf_extra_kws`][mne_bids_pipeline._config.mf_extra_kws] passes additional keyword arguments to `mne.preprocessing.maxwell_filter`. (#1038 by @drammock)

[//]: # (### :warning: Behavior changes)

Expand Down
8 changes: 7 additions & 1 deletion mne_bids_pipeline/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,13 @@
Use mne.chpi.filter_chpi after Maxwell filtering. Can be None to use
the same value as [`mf_mc`][mne_bids_pipeline._config.mf_mc].
Only used when [`use_maxwell_filter=True`][mne_bids_pipeline._config.use_maxwell_filter]
""" # noqa: E501
"""

mf_extra_kws: dict[str, Any] = {}
"""
A dictionary of extra kwargs to pass to `mne.preprocessing.maxwell_filter`. If kwargs
are passed here that have dedicated config settings already, an error will be raised.
"""

# ## Filtering & resampling

Expand Down
22 changes: 21 additions & 1 deletion mne_bids_pipeline/_config_import.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
from .typing import PathLike


class ConfigError(ValueError):
pass


def _import_config(
*,
config_path: PathLike | None,
Expand Down Expand Up @@ -248,7 +252,23 @@ def _check_config(config: SimpleNamespace, config_path: PathLike | None) -> None
and len(set(config.ch_types).intersection(("meg", "grad", "mag"))) == 0
):
raise ValueError("Cannot use Maxwell filter without MEG channels.")

mf_reserved_kwargs = (
"raw",
"calibration",
"cross_talk",
"st_duration",
"st_correlation",
"origin",
"coord_frame",
"destination",
"head_pos",
"extended_proj",
)
if duplicates := (set(config.mf_extra_kws) & set(mf_reserved_kwargs)):
raise ConfigError(
f"`mf_extra_kws` contains keys {', '.join(sorted(duplicates))} that are "
"handled by dedicated config keys. Please remove them from `mf_extra_kws`."
)
reject = config.reject
ica_reject = config.ica_reject
if config.spatial_filter == "ica":
Expand Down
4 changes: 4 additions & 0 deletions mne_bids_pipeline/steps/preprocessing/_03_maxfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,9 @@ def run_maxwell_filter(
head_pos=head_pos,
extended_proj=extended_proj,
)
# If the mf_kws keys above change, we need to modify our list
# of illegal keys in _config_import.py
mf_kws |= cfg.mf_extra_kws

logger.info(**gen_log_kwargs(message=f"{apply_msg} {recording_type} data"))
if not (run is None and task == "noise"):
Expand Down Expand Up @@ -592,6 +595,7 @@ def get_config_maxwell_filter(
mf_mc_rotation_velocity_limit=config.mf_mc_rotation_velocity_limit,
mf_mc_translation_velocity_limit=config.mf_mc_translation_velocity_limit,
mf_esss=config.mf_esss,
mf_extra_kws=config.mf_extra_kws,
**_import_data_kwargs(config=config, subject=subject),
)
return cfg
Expand Down
1 change: 1 addition & 0 deletions mne_bids_pipeline/tests/configs/config_ds003392.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
find_flat_channels_meg = False
find_noisy_channels_meg = False
use_maxwell_filter = True
mf_extra_kws = {"bad_condition": "warning"}
ch_types = ["meg"]

l_freq = 1.0
Expand Down
7 changes: 6 additions & 1 deletion mne_bids_pipeline/tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import pytest

from mne_bids_pipeline._config_import import _import_config
from mne_bids_pipeline._config_import import ConfigError, _import_config


def test_validation(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
Expand Down Expand Up @@ -48,6 +48,11 @@ def test_validation(tmp_path: Path, capsys: pytest.CaptureFixture[str]) -> None:
_import_config(config_path=config_path)
msg, err = capsys.readouterr()
assert msg == err == "" # no new message
# maxfilter extra kwargs
bad_text = working_text + "mf_extra_kws = {'calibration': 'x', 'head_pos': False}\n"
config_path.write_text(bad_text)
with pytest.raises(ConfigError, match="contains keys calibration, head_pos that"):
_import_config(config_path=config_path)
# old values
bad_text = working_text
bad_text += "debug = True\n"
Expand Down

0 comments on commit 8408697

Please sign in to comment.