Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ Detailed list of changes
- Dealing with alphanumeric ``sub`` entity labels is now fixed for :func:`~mne_bids.write_raw_bids`, by `Aaron Earle-Richardson`_ (:gh:`1291`)
- When processing subject_info data that MNE Python imports as numpy arrays with only one item, MNE-BIDS now unpacks these, resulting in a correct participants.tsv, by `Thomas Hartmann`_ (:gh:`1310`)
- Fixed broken links in examples 7 and 8, by `William Turner`_ (:gh:`1316`)
- All valid extensions for ``README`` files are now accepted. This prevents an extra ``README`` file being created, when one with a ``.txt``, ``.md``, or ``.rst`` extension is already present. By `Thomas Hartmann`_ (:gh:`1318`)

⚕️ Code health
^^^^^^^^^^^^^^
Expand Down
59 changes: 57 additions & 2 deletions mne_bids/tests/test_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import json
import os.path as op
import shutil
from pathlib import Path

import mne
Expand Down Expand Up @@ -38,7 +39,7 @@
)


@pytest.fixture(scope="session")
@pytest.fixture(scope="function")
def _get_bids_test_dir(tmp_path_factory):
"""Return path to a written test BIDS dir."""
bids_root = str(tmp_path_factory.mktemp("mnebids_utils_test_bids_ds"))
Expand Down Expand Up @@ -76,7 +77,7 @@ def _get_bids_test_dir(tmp_path_factory):
return bids_root


@pytest.fixture(scope="session")
@pytest.fixture(scope="function")
def _get_sidecar_json_update_file(_get_bids_test_dir):
"""Return path to a sidecar JSON updating file."""
bids_root = _get_bids_test_dir
Expand Down Expand Up @@ -292,3 +293,57 @@ def test_update_anat_landmarks(tmp_path):
assert np.allclose(
mri_json["AnatomicalLandmarkCoordinates"][landmark], expected_coords
)


@testing.requires_testing_data
@pytest.mark.parametrize("extension", [None, ".txt", ".rst", ".md"])
def test_readme_conflicts(extension, _get_bids_test_dir):
"""Test that exisiting README files are respected with any extension."""
bids_root = _get_bids_test_dir
assert Path(bids_root, "README").exists()
all_readmes = Path(bids_root).rglob("README*")
assert len(list(all_readmes)) == 1
if extension is not None:
shutil.move(Path(bids_root, "README"), Path(bids_root, f"README{extension}"))

bids_path = BIDSPath(
subject="02",
session=session_id,
run=1,
acquisition=acq,
task=task,
suffix="meg",
root=_get_bids_test_dir,
)

raw_fname = op.join(data_path, "MEG", "sample", "sample_audvis_trunc_raw.fif")
raw = mne.io.read_raw_fif(raw_fname)

write_raw_bids(raw, bids_path, overwrite=False)
all_readmes = Path(bids_root).rglob("README*")
assert len(list(all_readmes)) == 1
shutil.rmtree(bids_root)


@testing.requires_testing_data
def test_multiple_readmes_invalid(_get_bids_test_dir):
"""Test that multiple README files are not allowed."""
bids_root = _get_bids_test_dir
assert Path(bids_root, "README").exists()
shutil.copy(Path(bids_root, "README"), Path(bids_root, "README.md"))
bids_path = BIDSPath(
subject="02",
session=session_id,
run=1,
acquisition=acq,
task=task,
suffix="meg",
root=_get_bids_test_dir,
)

raw_fname = op.join(data_path, "MEG", "sample", "sample_audvis_trunc_raw.fif")
raw = mne.io.read_raw_fif(raw_fname)

with pytest.raises(RuntimeError, match="Multiple README files found"):
write_raw_bids(raw, bids_path, overwrite=False)
shutil.rmtree(bids_root)
13 changes: 12 additions & 1 deletion mne_bids/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,18 @@ def write_raw_bids(
)

# For the remaining files, we can use BIDSPath to alter.
readme_fname = op.join(bids_path.root, "README")
readme_suffixes = ("", ".md", ".rst", ".txt")
found_readmes = sorted(
filter(lambda x: x.suffix in readme_suffixes, bids_path.root.glob("README*"))
)
if len(found_readmes) > 1:
raise RuntimeError(
"Multiple README files found in the BIDS root folder. "
"This violates the BIDS specifications. "
"Please ensure there is only one README file."
)
readme_fname = str((found_readmes or [bids_path.root / "README"])[0])

participants_tsv_fname = op.join(bids_path.root, "participants.tsv")
participants_json_fname = participants_tsv_fname.replace(".tsv", ".json")

Expand Down