From e1d1807ca3b8afacbca094bdd777e61f4f026420 Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Sun, 28 Jul 2024 08:12:33 +0200 Subject: [PATCH 1/2] suppress channel unit change warnings --- mne_bids/read.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mne_bids/read.py b/mne_bids/read.py index 66d19cc49..e31fc8067 100644 --- a/mne_bids/read.py +++ b/mne_bids/read.py @@ -683,7 +683,9 @@ def _handle_channels_reading(channels_fname, raw): f"Cannot set channel type for the following channels, as they " f'are missing in the raw data: {", ".join(sorted(ch_diff))}' ) - raw.set_channel_types(channel_type_bids_mne_map_available_channels) + raw.set_channel_types( + channel_type_bids_mne_map_available_channels, on_unit_change="ignore" + ) # Set bad channels based on _channels.tsv sidecar if "status" in channels_dict: From c9cb5b42b4972545c937462112eae903396d1c44 Mon Sep 17 00:00:00 2001 From: Stefan Appelhoff Date: Sun, 28 Jul 2024 09:02:18 +0200 Subject: [PATCH 2/2] fix some tests, add whatsnew --- doc/whats_new.rst | 2 +- mne_bids/tests/test_read.py | 28 ++++++---------------------- mne_bids/tests/test_write.py | 18 +++++------------- 3 files changed, 12 insertions(+), 36 deletions(-) diff --git a/doc/whats_new.rst b/doc/whats_new.rst index 978d35460..502182fa9 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -36,7 +36,7 @@ Detailed list of changes 🧐 API and behavior changes ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- nothing yet +- :func:`mne_bids.read_raw_bids` no longer warns about unit changes in channels upon reading, as that information is taken from ``channels.tsv`` and judged authorative, by `Stefan Appelhoff`_ (:gh:`1282`) 🛠 Requirements ^^^^^^^^^^^^^^^ diff --git a/mne_bids/tests/test_read.py b/mne_bids/tests/test_read.py index 09a61af4e..ac58858c9 100644 --- a/mne_bids/tests/test_read.py +++ b/mne_bids/tests/test_read.py @@ -794,7 +794,6 @@ def test_handle_info_reading(tmp_path): assert raw.info["line_freq"] == 55 -@pytest.mark.filterwarnings(warning_str["channel_unit_changed"]) @pytest.mark.filterwarnings(warning_str["maxshield"]) @testing.requires_testing_data def test_handle_chpi_reading(tmp_path): @@ -827,7 +826,6 @@ def test_handle_chpi_reading(tmp_path): with ( pytest.warns(RuntimeWarning, match="Defaulting to .* mne.Raw object"), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): raw_read = read_raw_bids(bids_path, extra_params=dict(allow_maxshield="yes")) @@ -842,7 +840,6 @@ def test_handle_chpi_reading(tmp_path): @pytest.mark.filterwarnings(warning_str["nasion_not_found"]) -@pytest.mark.filterwarnings(warning_str["channel_unit_changed"]) @testing.requires_testing_data def test_handle_eeg_coords_reading(tmp_path): """Test reading iEEG coordinates from BIDS files.""" @@ -859,7 +856,7 @@ def test_handle_eeg_coords_reading(tmp_path): raw = _read_raw_edf(raw_fname) # ensure we are writing 'eeg' data - raw.set_channel_types({ch: "eeg" for ch in raw.ch_names}) + raw.set_channel_types({ch: "eeg" for ch in raw.ch_names}, on_unit_change="ignore") # set a `random` montage ch_names = raw.ch_names @@ -903,11 +900,8 @@ def test_handle_eeg_coords_reading(tmp_path): bids_path, suffix="coordsystem", extension=".json" ) _update_sidecar(coordsystem_fname, "EEGCoordinateSystem", "besa") - with ( - pytest.warns( - RuntimeWarning, match="is not a BIDS-acceptable coordinate frame for EEG" - ), - pytest.warns(RuntimeWarning, match="The unit for channel"), + with pytest.warns( + RuntimeWarning, match="is not a BIDS-acceptable coordinate frame for EEG" ): raw_test = read_raw_bids(bids_path) assert raw_test.info["dig"] is None @@ -915,7 +909,6 @@ def test_handle_eeg_coords_reading(tmp_path): @pytest.mark.parametrize("bids_path", [_bids_path, _bids_path_minimal]) @pytest.mark.filterwarnings(warning_str["nasion_not_found"]) -@pytest.mark.filterwarnings(warning_str["channel_unit_changed"]) @testing.requires_testing_data def test_handle_ieeg_coords_reading(bids_path, tmp_path): """Test reading iEEG coordinates from BIDS files.""" @@ -926,7 +919,7 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path): raw = _read_raw_edf(raw_fname) # ensure we are writing 'ecog'/'ieeg' data - raw.set_channel_types({ch: "ecog" for ch in raw.ch_names}) + raw.set_channel_types({ch: "ecog" for ch in raw.ch_names}, on_unit_change="ignore") # coordinate frames in mne-python should all map correctly # set a `random` montage @@ -978,11 +971,8 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path): for axis in ["x", "y", "z"]: electrodes_dict[axis] = np.multiply(orig_electrodes_dict[axis], scaling) _to_tsv(electrodes_dict, electrodes_fname) - with ( - pytest.warns( - RuntimeWarning, match="Coordinate unit is not an accepted BIDS unit" - ), - pytest.warns(RuntimeWarning, match="The unit for channel"), + with pytest.warns( + RuntimeWarning, match="Coordinate unit is not an accepted BIDS unit" ): raw_test = read_raw_bids(bids_path=bids_fname, verbose=False) @@ -1012,7 +1002,6 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path): # and make sure all digpoints are MRI coordinate frame with ( pytest.warns(RuntimeWarning, match="not an MNE-Python coordinate frame"), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): raw_test = read_raw_bids(bids_path=bids_fname, verbose=False) assert raw_test.info["dig"] is not None @@ -1031,7 +1020,6 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path): pytest.warns( RuntimeWarning, match="not an MNE-Python coordinate frame" ), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): raw_test = read_raw_bids(bids_path=bids_fname, verbose=False) assert raw_test.info["dig"] is not None @@ -1061,7 +1049,6 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path): # however, a warning will be raised through mne-python with ( pytest.warns(RuntimeWarning, match="DigMontage is only a subset of info"), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): read_raw_bids(bids_path=bids_fname, verbose=False) @@ -1080,7 +1067,6 @@ def test_handle_ieeg_coords_reading(bids_path, tmp_path): nan_chs = [electrodes_dict["name"][i] for i in [0, 3]] with ( pytest.warns(RuntimeWarning, match="There are channels without locations"), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): raw = read_raw_bids(bids_path=bids_fname, verbose=False) for idx, ch in enumerate(raw.info["chs"]): @@ -1188,7 +1174,6 @@ def test_handle_channel_type_casing(tmp_path): read_raw_bids(bids_path) -@pytest.mark.filterwarnings(warning_str["channel_unit_changed"]) @testing.requires_testing_data def test_handle_non_mne_channel_type(tmp_path): """Test that channel types not known to MNE will be read as 'misc'.""" @@ -1212,7 +1197,6 @@ def test_handle_non_mne_channel_type(tmp_path): with ( pytest.warns(RuntimeWarning, match='will be set to "misc"'), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): raw = read_raw_bids(bids_path) diff --git a/mne_bids/tests/test_write.py b/mne_bids/tests/test_write.py index 5d450ff17..2eab55959 100644 --- a/mne_bids/tests/test_write.py +++ b/mne_bids/tests/test_write.py @@ -504,7 +504,6 @@ def test_line_freq(line_freq, _bids_validate, tmp_path): @testing.requires_testing_data -@pytest.mark.filterwarnings(warning_str["channel_unit_changed"]) @pytest.mark.filterwarnings(warning_str["maxshield"]) def test_fif(_bids_validate, tmp_path): """Test functionality of the write_raw_bids conversion for fif.""" @@ -549,7 +548,8 @@ def test_fif(_bids_validate, tmp_path): { raw.ch_names[i]: "misc" for i in mne.pick_types(raw.info, stim=True, meg=False) - } + }, + on_unit_change="ignore", ) bids_root = tmp_path / "bids2" bids_path.update(root=bids_root) @@ -611,7 +611,6 @@ def test_fif(_bids_validate, tmp_path): bids_path.update(root=bids_root, datatype="eeg") with ( pytest.warns(RuntimeWarning, match="Not setting position"), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): raw2 = read_raw_bids(bids_path=bids_path) os.remove(op.join(bids_root, "test-raw.fif")) @@ -1055,8 +1054,7 @@ def test_kit(_bids_validate, tmp_path): _bids_validate(bids_root) assert op.exists(bids_root / "participants.tsv") - with pytest.warns(RuntimeWarning, match=".* changed from V to NA"): - read_raw_bids(bids_path=kit_bids_path) + read_raw_bids(bids_path=kit_bids_path) # ensure the marker file is produced in the right place marker_fname = BIDSPath( @@ -1183,7 +1181,6 @@ def test_ctf(_bids_validate, tmp_path): _bids_validate(tmp_path) with ( pytest.warns(RuntimeWarning, match="Did not find any events"), - pytest.warns(RuntimeWarning, match="The unit for channel"), ): raw = read_raw_bids(bids_path=bids_path, extra_params=dict(clean_names=False)) @@ -1871,11 +1868,7 @@ def test_bdf(_bids_validate, tmp_path): # Now read the raw data back from BIDS, with the tampered TSV, to show # that the channels.tsv truly influences how read_raw_bids sets ch_types # in the raw data object - with ( - pytest.warns(RuntimeWarning, match=r"The unit for channel\(s\) Fp1"), - pytest.warns(RuntimeWarning, match=r"The unit for channel\(s\) Status"), - ): - raw = read_raw_bids(bids_path=bids_path) + raw = read_raw_bids(bids_path=bids_path) assert coil_type(raw.info, test_ch_idx) == "misc" with pytest.raises(TypeError, match="unexpected keyword argument 'foo'"): read_raw_bids(bids_path=bids_path, extra_params=dict(foo="bar")) @@ -4071,8 +4064,7 @@ def test_repeat_write_location(tmpdir): bids_path = write_raw_bids(raw, bids_path, verbose=False) # Read back in - with pytest.warns(RuntimeWarning, match=".* has changed from NA to V"): - raw = read_raw_bids(bids_path, verbose=False) + raw = read_raw_bids(bids_path, verbose=False) # Re-writing with src == dest should error with pytest.raises(FileExistsError, match="Desired output BIDSPath"):