From 8a76518845ccee507b2d74225bba07cff0b4c444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20H=C3=B6chenberger?= Date: Thu, 18 Apr 2024 12:02:20 +0200 Subject: [PATCH] Don't perform ICA cleaning on raw data by default when epochs are present Fixes #925 --- docs/source/v1.9.md.inc | 11 +++++++++-- mne_bids_pipeline/_config.py | 7 +++++++ .../steps/preprocessing/_08a_apply_ica.py | 9 ++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/docs/source/v1.9.md.inc b/docs/source/v1.9.md.inc index 39103483c..dbd33e27c 100644 --- a/docs/source/v1.9.md.inc +++ b/docs/source/v1.9.md.inc @@ -2,15 +2,22 @@ ### :new: New features & enhancements -- Added number of subject to `sub-average` report (#902, #910 by @SophieHerbst) +- Added number of subjects to `sub-average` report (#902, #910 by @SophieHerbst) - The type annotations in the default configuration file are now easier to read: We replaced `Union[X, Y]` with `X | Y` and `Optional[X]` with `X | None`. (#908, #911 by @hoechenberger) +- Added a new configuration option [`spatial_filter_raw`][mne_bids_pipeline._config.spatial_filter_raw] + to control whether to create cleaned raw data via ICA or SSP. Previously, we'd only clean epochs. + (#840, #926 by @larsoner and @hoechenberger) ### :warning: Behavior changes - All ICA HTML reports have been consolidated in the standard subject `*_report.html` file instead of producing separate files (#899 by @larsoner). -- Changed default for `source_info_path_update` to `None`. In `_04_make_forward.py` +- When using ICA or SSP with resting-state data, we now automatically produce cleaned raw data files. This + behavior can be controlled via the new [`spatial_filter_raw`][mne_bids_pipeline._config.spatial_filter_raw] + configuration option. (#840, #926 by @larsoner and @hoechenberger) +- Changed default for [`source_info_path_update`][mne_bids_pipeline._config.source_info_path_update] + to `None`. In `_04_make_forward.py` and `_05_make_inverse.py`, we retrieve the info from the file from which the `noise_cov` is computed (#919 by @SophieHerbst) - The [`depth`][mne_bids_pipeline._config.depth] parameter doesn't accept `None` diff --git a/mne_bids_pipeline/_config.py b/mne_bids_pipeline/_config.py index 912d257f0..adb460c31 100644 --- a/mne_bids_pipeline/_config.py +++ b/mne_bids_pipeline/_config.py @@ -1138,6 +1138,13 @@ ICA fitting – this file will need to be updated! """ +spatial_filter_raw: bool | None = None +""" +Whether to clean the raw data with the spatial filter. If `True`, creates cleaned data +from both, epochs and raw. If `False`, only creates cleaned epochs. If `None`, creates +cleaned epochs and raw for resting-state data, and only cleaned epochs otherwise. +""" + min_ecg_epochs: Annotated[int, Ge(1)] = 5 """ Minimal number of ECG epochs needed to compute SSP projectors. diff --git a/mne_bids_pipeline/steps/preprocessing/_08a_apply_ica.py b/mne_bids_pipeline/steps/preprocessing/_08a_apply_ica.py index 5b097c106..b23b2314c 100644 --- a/mne_bids_pipeline/steps/preprocessing/_08a_apply_ica.py +++ b/mne_bids_pipeline/steps/preprocessing/_08a_apply_ica.py @@ -196,7 +196,12 @@ def apply_ica_raw( run: str, task: str | None, in_files: dict, -) -> dict: +) -> dict | None: + if cfg.spatial_filter_raw is None and not (cfg.task == "rest" or cfg.task_is_rest): + return + elif cfg.spatial_filter_raw is False: + return + ica = _read_ica_and_exclude(in_files) in_key = list(in_files)[0] assert in_key.startswith("raw"), in_key @@ -240,6 +245,8 @@ def get_config( cfg = SimpleNamespace( baseline=config.baseline, ica_reject=config.ica_reject, + spatial_filter_raw=config.spatial_filter_raw, + task_is_rest=config.task_is_rest, processing="filt" if config.regress_artifact is None else "regress", _epochs_split_size=config._epochs_split_size, **_import_data_kwargs(config=config, subject=subject),