From dc0d318ae9f023cb63540288eccfcddfa13500dc Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Thu, 2 Jan 2025 10:49:37 -0600 Subject: [PATCH 1/5] add new param --- mne_bids/path.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mne_bids/path.py b/mne_bids/path.py index 83c5ebe53..d6dc30c51 100644 --- a/mne_bids/path.py +++ b/mne_bids/path.py @@ -1897,6 +1897,7 @@ def get_entity_vals( ignore_modalities=None, ignore_datatypes=None, ignore_dirs=("derivatives", "sourcedata"), + ignore_suffixes=None, with_key=False, verbose=None, ): @@ -1958,6 +1959,11 @@ def get_entity_vals( include all directories in the search. .. versionadded:: 0.9 + ignore_suffixes : str | array-like of str | None + Suffixes to ignore. If ``None``, include all suffixes. This can be helpful for + ignoring non-data sidecars such as `*_scans.tsv` or `*_coordsystem.json`. + + .. versionadded:: 0.17 with_key : bool If ``True``, returns the full entity with the key and the value. This will for example look like ``['sub-001', 'sub-002']``. @@ -2043,7 +2049,7 @@ def get_entity_vals( ignore_splits = _ensure_tuple(ignore_splits) ignore_descriptions = _ensure_tuple(ignore_descriptions) ignore_modalities = _ensure_tuple(ignore_modalities) - + ignore_suffixes = _ensure_tuple(ignore_suffixes) ignore_dirs = _ensure_tuple(ignore_dirs) existing_ignore_dirs = [ root / d for d in ignore_dirs if (root / d).exists() and (root / d).is_dir() @@ -2061,6 +2067,10 @@ def get_entity_vals( ): continue + if ignore_suffixes and any( + [filename.stem.endswith(s) for s in ignore_suffixes] + ): + continue if ignore_datatypes and filename.parent.name in ignore_datatypes: continue if ignore_subjects and any( From 659ca1b82e22d98d5e7288a3e9b9c97c3737ec3a Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Thu, 2 Jan 2025 10:50:10 -0600 Subject: [PATCH 2/5] unrelated typo fix --- mne_bids/path.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne_bids/path.py b/mne_bids/path.py index d6dc30c51..331bc9292 100644 --- a/mne_bids/path.py +++ b/mne_bids/path.py @@ -1950,7 +1950,7 @@ def get_entity_vals( .. versionadded:: 0.11 ignore_modalities : str | array-like of str | None - Modalities(s) to ignore. If ``None``, include all modalities. + Modalities to ignore. If ``None``, include all modalities. ignore_datatypes : str | array-like of str | None Datatype(s) to ignore. If ``None``, include all datatypes (i.e. ``anat``, ``ieeg``, ``eeg``, ``meg``, ``func``, etc.) From b39a6a0b30564a8dfefe79c652da7468dc0e960e Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Thu, 2 Jan 2025 12:05:29 -0600 Subject: [PATCH 3/5] add test case --- mne_bids/tests/test_path.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/mne_bids/tests/test_path.py b/mne_bids/tests/test_path.py index 605050f96..0eecdf49a 100644 --- a/mne_bids/tests/test_path.py +++ b/mne_bids/tests/test_path.py @@ -100,6 +100,15 @@ def test_get_keys(return_bids_test_dir): ("bogus", None, None), ("subject", [subject_id], None), ("session", [session_id], None), + ( + "session", + [], + dict( + ignore_tasks="testing", + ignore_acquisitions=("calibration", "crosstalk"), + ignore_suffixes=("scans", "coordsystem"), + ), + ), ("run", [run, "02"], None), ("acquisition", ["calibration", "crosstalk"], None), ("task", [task], None), @@ -153,7 +162,6 @@ def test_get_entity_vals(entity, expected_vals, kwargs, return_bids_test_dir): ) if entity not in ("acquisition", "run"): assert "deriv" in entities - # Clean up shutil.rmtree(deriv_path) From d9002bb8f0f14cb314f1b7c58964f3e7937e59f6 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Thu, 2 Jan 2025 12:05:47 -0600 Subject: [PATCH 4/5] add debug logging --- mne_bids/path.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mne_bids/path.py b/mne_bids/path.py index 331bc9292..d0471a0a8 100644 --- a/mne_bids/path.py +++ b/mne_bids/path.py @@ -4,6 +4,7 @@ # SPDX-License-Identifier: BSD-3-Clause import glob +import inspect import json import os import re @@ -1996,6 +1997,7 @@ def get_entity_vals( .. [1] https://bids-specification.rtfd.io/en/latest/common-principles.html#entities """ + params = inspect.signature(get_entity_vals).parameters # for debug messages root = _check_fname( fname=root, overwrite="read", @@ -2120,6 +2122,15 @@ def get_entity_vals( value = f"{entity_long_abbr_map[entity_key]}-{value}" if value not in values: values.append(value) + # display all non-default params passed into the function + param_string = ", ".join( + f"{k}={v!r}" + for k, v in inspect.currentframe().f_back.f_locals.items() + if k in params and v != params[k].default + ) + logger.debug( + "%s matched by get_entity_vals(%s)", filename.name, param_string + ) return sorted(values) From 6fb4708ae9cf786a09023cc3c218ec821d564b35 Mon Sep 17 00:00:00 2001 From: Daniel McCloy Date: Thu, 2 Jan 2025 12:07:38 -0600 Subject: [PATCH 5/5] changelog --- doc/whats_new.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/whats_new.rst b/doc/whats_new.rst index 5bf145c15..17039eeb0 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -32,6 +32,7 @@ Detailed list of changes ^^^^^^^^^^^^^^^ - :func:`mne_bids.write_raw_bids()` can now handle mne `Raw` objects with `eyegaze` and `pupil` channels, by `Christian O'Reilly`_ (:gh:`1344`) +- :func:`mne_bids.get_entity_vals()` has a new parameter ``ignore_suffixes`` to easily ignore sidecar files, by `Daniel McCloy`_ (:gh:`1362`) 🧐 API and behavior changes