Skip to content
Open
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/changes/dev/13700.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix bug where :func:`mne.channels.DigMontage.set_montage` raised an :exc:`IndexError` on MEG+EEG recordings when EEG reference positions were set to the placeholder value ``[1, 0, 0]`` (i.e., digitization was not performed), by :newcontrib:`Famous077`.
2 changes: 1 addition & 1 deletion doc/changes/names.inc
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@
.. _Ezequiel Mikulan: https://github.com/ezemikulan
.. _Ezequiel Mikulan: https://github.com/ezemikulan
.. _Fahimeh Mamashli: https://github.com/fmamashli
.. _Famous Raj Bhat: https://github.com/Famous077
.. _Famous077: https://github.com/Famous077
.. _Farzin Negahbani: https://github.com/Farzin-Negahbani
.. _Federico Raimondo: https://github.com/fraimondo
.. _Federico Zamberlan: https://github.com/fzamberlan
Expand Down
7 changes: 6 additions & 1 deletion mne/channels/montage.py
Original file line number Diff line number Diff line change
Expand Up @@ -1256,7 +1256,12 @@ def _backcompat_value(pos, ref_pos):
# keep reference location from EEG-like channels if they
# already exist and are all the same.
# Note: ref position is an empty list for fieldtrip data
if len(ref_pos) and ref_pos[0].any() and (ref_pos[0] == ref_pos).all():
if (
len(ref_pos)
and ref_pos[0].any()
and (ref_pos[0] == ref_pos).all()
and not np.array_equal(ref_pos[0], [1.0, 0.0, 0.0])
):
eeg_ref_pos = ref_pos[0]
# since we have an EEG reference position, we have
# to add it into the info['dig'] as EEG000
Expand Down
32 changes: 29 additions & 3 deletions mne/channels/tests/test_montage.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@

import mne.channels.montage
from mne import (
__file__ as _mne_file,
)
from mne import (
EpochsArray,
create_info,
pick_types,
read_evokeds,
)
from mne import (
__file__ as _mne_file,
)
from mne._fiff._digitization import (
_count_points_by_type,
_format_dig_points,
Expand Down Expand Up @@ -2145,3 +2146,28 @@ def test_fnirs_montage():
raw.set_channel_types({ch_name: "eeg" for ch_name in raw.ch_names[-2:]})
with pytest.raises(ValueError, match="mix of fNIRS"):
raw.get_montage()


def test_set_montage_meg_eeg_no_digitization():
"""Regression test for GH-12011.

set_montage() must not crash when MEG+EEG info has EEG reference
positions set to the [1, 0, 0] sentinel (digitization was skipped).
"""
ch_names = [f"EEG{i:03d}" for i in range(1, 11)] + ["MEG0111"]
ch_types = ["eeg"] * 10 + ["grad"]
info = create_info(ch_names=ch_names, sfreq=1000.0, ch_types=ch_types)

# Simulate MEG reader behaviour when digitization is skipped:
# EEG ref position (loc[3:6]) is set to the [1, 0, 0] sentinel
with info._unlock():
for ch in info["chs"]:
if ch["ch_name"].startswith("EEG"):
ch["loc"][3:6] = [1.0, 0.0, 0.0]

data = np.zeros((1, len(ch_names), 100))
epochs = EpochsArray(data, info)

# This must not raise IndexError (regression test for GH-12011)
montage = make_standard_montage("standard_1020")
epochs.set_montage(montage, on_missing="ignore")