Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

suppress channel unit change warnings #1282

Merged
merged 2 commits into from
Jul 28, 2024
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
2 changes: 1 addition & 1 deletion doc/whats_new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^
Expand Down
4 changes: 3 additions & 1 deletion mne_bids/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
28 changes: 6 additions & 22 deletions mne_bids/tests/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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"))

Expand All @@ -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."""
Expand All @@ -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
Expand Down Expand Up @@ -903,19 +900,15 @@ 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


@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."""
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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)

Expand All @@ -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"]):
Expand Down Expand Up @@ -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'."""
Expand All @@ -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)

Expand Down
18 changes: 5 additions & 13 deletions mne_bids/tests/test_write.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."""
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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))

Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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"):
Expand Down