Skip to content

Commit

Permalink
Fix participant tsv values when Info contains weight and height inf…
Browse files Browse the repository at this point in the history
…ormation as numpy arrays (#1310)

* add failing test

* add participant data sanitizing

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* update whats_new

* add tests for untested lines

* remove unneccesary check

* added suggestion by eric larson

* tried to evade mne type checking

* add match statement

* FIX: Disable

* Apply suggestions from code review

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Eric Larson <[email protected]>
Co-authored-by: Stefan Appelhoff <[email protected]>
  • Loading branch information
4 people authored Oct 3, 2024
1 parent f94c24e commit 65da1ae
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 0 deletions.
1 change: 1 addition & 0 deletions doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ Detailed list of changes

- When anonymizing the date of a recording, MNE-BIDS will no longer error during `~mne_bids.write_raw_bids` if passing a `~mne.io.Raw` instance to ``empty_room``, by `Daniel McCloy`_ (:gh:`1270`)
- 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`)

⚕️ Code health
^^^^^^^^^^^^^^
Expand Down
45 changes: 45 additions & 0 deletions mne_bids/tests/test_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -4187,3 +4187,48 @@ def test_write_evt_metadata(_bids_validate, tmp_path):
for cur_col in event_metadata.columns:
assert cur_col in events_tsv
assert cur_col in events_json


# XXX: Remove once MNE-Python <1.9 is no longer supported
@testing.requires_testing_data
def test_write_bids_with_age_weight_info(tmp_path, monkeypatch):
"""Test writing participant.tsv when using np.arrays for weight and height."""
bids_root = tmp_path / "bids"
raw_fname = data_path / "MEG" / "sample" / "sample_audvis_trunc_raw.fif"
raw = _read_raw_fif(raw_fname)
# disable MNE-Python 1.9+ validation for the duration of this test
if "subject_info" in getattr(mne.Info, "_attributes", {}):
monkeypatch.setitem(
mne.Info._attributes,
"subject_info",
lambda val, **kwargs: val,
)
raw.info["subject_info"] = {
"weight": np.array([75.0]),
"height": np.array([180.0]),
}

bids_path = _bids_path.copy().update(root=bids_root, datatype="meg", run=1)
write_raw_bids(raw, bids_path=bids_path)
bids_path = _bids_path.copy().update(root=bids_root, datatype="meg", run=2)
write_raw_bids(raw, bids_path=bids_path)

# Test that we get a value error when we have more than one item
raw.info["subject_info"] = {
"weight": np.array([75.0, 10.2]),
"height": np.array([180.0]),
}

bids_path = _bids_path.copy().update(root=bids_root, datatype="meg", run=3)
assert_array_equal(raw.info["subject_info"]["weight"], [75.0, 10.2])
with pytest.raises(ValueError, match="more than one element"):
write_raw_bids(raw, bids_path=bids_path)

# Test that scalar data is handled correctly
raw.info["subject_info"] = {
"weight": 75.0,
"height": np.array([180.0]),
}

bids_path = _bids_path.copy().update(root=bids_root, datatype="meg", run=3)
write_raw_bids(raw, bids_path=bids_path)
23 changes: 23 additions & 0 deletions mne_bids/write.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,29 @@ def _participants_tsv(raw, subject_id, fname, overwrite=False):
}
)

# XXX: Remove once MNE-Python <1.9 is no longer supported
# Make sure that all entries to data are lists that
# contain scalars (i.e. not further lists). Fix if possible
for key in data.keys():
cur_value = data[key]

# Check if all values are scalars
new_value = []
for cur_item in cur_value:
if isinstance(cur_item, list | tuple | np.ndarray):
if len(cur_item) == 1:
new_value.append(cur_item[0])
else:
raise ValueError(
f"Value for key {key} is a list with more "
f"than one element. This is not supported. "
f"Got: {cur_value}."
)
else:
new_value.append(cur_item)

data[key] = new_value

if os.path.exists(fname):
orig_data = _from_tsv(fname)
# whether the new data exists identically in the previous data
Expand Down

0 comments on commit 65da1ae

Please sign in to comment.