Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 56 additions & 8 deletions mne_bids/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,62 @@
datatype = "meg" # We're only concerned about MEG data here
bids_fname = bids_path.update(suffix=datatype).fpath
_, ext = _parse_ext(bids_fname)
# Create a path for the empty-room directory to be used for matching.
emptyroom_dir = BIDSPath(root=bids_root, subject="emptyroom").directory

if not emptyroom_dir.exists():
# Find matching "task-noise" files in the same directory as the recording.
noisetask_path = bids_path.update(
split=None, run=None, task="noise", datatype=datatype, suffix=datatype
)

allowed_extensions = list(reader.keys())
# `.pdf` is just a "virtual" extension for BTi data (which is stored inside
# a dedicated directory that doesn't have an extension)
del allowed_extensions[allowed_extensions.index(".pdf")]

# Get possible noise task files in the same directory as the recording.
noisetask_tmp = [
candidate
for candidate in noisetask_path.match()
if candidate.extension in allowed_extensions
]
# For some reason a single file can produce multiple hits in the match function.
# Remove dups
noisetask_fns = []
for i in range(len(noisetask_tmp)):
fn = noisetask_tmp.pop()
if len(noisetask_tmp) == 0 or not any(
fn.fpath == f.fpath for f in noisetask_fns
):
noisetask_fns.append(fn)

# If we have more than one noise task file, we need to disambiguate.
# It might be that it's a
# split recording.
if len(noisetask_fns) > 1 and any(path.split is not None for path in noisetask_fns):
noisetask_path.update(spilt="01")
noisetask_fns = [

Check warning on line 93 in mne_bids/path.py

View check run for this annotation

Codecov / codecov/patch

mne_bids/path.py#L92-L93

Added lines #L92 - L93 were not covered by tests
candidate
for candidate in noisetask_path.match()
if candidate.extension in allowed_extensions
]

# If it wasn't a split recording, warn the user that something is wonky,
# then resort to looking for sub-emptyroom recordings and date-matching.
if len(noisetask_fns) > 1:
msg = (
"Found more than one matching noise task file."
" Falling back to looking for sub-emptyroom recordings and date-matching."
)
warn(msg)
noisetask_fns = []
elif len(noisetask_fns) == 1:
return noisetask_fns[0]

if not emptyroom_dir.exists() and not noisetask_fns:
return list()

# Find the empty-room recording sessions.
# Check the 'emptyroom' subject for empty-room recording sessions.
emptyroom_session_dirs = [
x
for x in emptyroom_dir.iterdir()
Expand All @@ -71,12 +121,6 @@
emptyroom_session_dirs = [emptyroom_dir]

# Now try to discover all recordings inside the session directories.

allowed_extensions = list(reader.keys())
# `.pdf` is just a "virtual" extension for BTi data (which is stored inside
# a dedicated directory that doesn't have an extension)
del allowed_extensions[allowed_extensions.index(".pdf")]

candidate_er_fnames = []
for session_dir in emptyroom_session_dirs:
dir_contents = glob.glob(
Expand Down Expand Up @@ -105,6 +149,10 @@
from mne_bids import read_raw_bids # avoid circular import.

candidates = _find_empty_room_candidates(bids_path)
# If a single candidate is returned, then there's a same-session noise
# task recording that takes priority.
if not isinstance(candidates, list):
return candidates

# Walk through recordings, trying to extract the recording date:
# First, from the filename; and if that fails, from `info['meas_date']`.
Expand Down
25 changes: 25 additions & 0 deletions mne_bids/tests/test_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -1146,6 +1146,7 @@ def test_find_empty_room(return_bids_test_dir, tmp_path):
task="audiovisual",
run="01",
root=bids_root,
datatype="meg",
suffix="meg",
)
write_raw_bids(raw, bids_path, overwrite=True, verbose=False)
Expand Down Expand Up @@ -1173,6 +1174,30 @@ def test_find_empty_room(return_bids_test_dir, tmp_path):
recovered_er_bids_path = bids_path.find_empty_room()
assert er_bids_path == recovered_er_bids_path

# Test that when there is a noise task file in the subject directory it will take
# precedence over the emptyroom directory file
os.remove(er_bids_path.fpath)
er_noise_task_path = bids_path.copy().update(
run=None,
task="noise",
)

write_raw_bids(er_raw, er_noise_task_path, overwrite=True, verbose=False)
recovered_er_bids_path = bids_path.find_empty_room()
assert er_noise_task_path == recovered_er_bids_path

# Check that when there are multiple matches that cannot be resolved via assigning
# split=01 that the sub-emptyroom is the fallback
dup_noise_task_path = er_noise_task_path.copy()
dup_noise_task_path.update(run="100", split=None)
write_raw_bids(er_raw, dup_noise_task_path, overwrite=True, verbose=False)
write_raw_bids(er_raw, er_bids_path, overwrite=True, verbose=False)
with pytest.warns(RuntimeWarning):
recovered_er_bids_path = bids_path.find_empty_room()
assert er_bids_path == recovered_er_bids_path
os.remove(er_noise_task_path.fpath)
os.remove(dup_noise_task_path.fpath)

# assert that we get best emptyroom if there are multiple available
sh.rmtree(op.join(bids_root, "sub-emptyroom"))
dates = ["20021204", "20021201", "20021001"]
Expand Down
Loading