diff --git a/doc/changes/dev/13447.newcontrib.rst b/doc/changes/dev/13447.newcontrib.rst new file mode 100644 index 00000000000..c1d81c56626 --- /dev/null +++ b/doc/changes/dev/13447.newcontrib.rst @@ -0,0 +1 @@ +Improve the error message raised by :func:`mne.viz.plot_topomap` (via :func:`mne.channels.layout._auto_topomap_coords`) when mixed 10–20 EEG electrode naming conventions are detected, by :newcontrib:`Aasma Gupta`. \ No newline at end of file diff --git a/doc/changes/names.inc b/doc/changes/names.inc index b684d067a1d..33df89820ae 100644 --- a/doc/changes/names.inc +++ b/doc/changes/names.inc @@ -1,4 +1,5 @@ .. _Aaron Earle-Richardson: https://github.com/Aaronearlerichardson +.. _Aasma Gupta: https://github.com/AasmaGupta .. _Abram Hindle: https://softwareprocess.es .. _Adam Li: https://github.com/adam2392 .. _Adeline Fecker: https://github.com/adelinefecker diff --git a/mne/channels/layout.py b/mne/channels/layout.py index 85b7913c1c6..fe7a1026a8e 100644 --- a/mne/channels/layout.py +++ b/mne/channels/layout.py @@ -971,11 +971,36 @@ def _auto_topomap_coords(info, picks, ignore_overlap, to_sphere, sphere): for elec_i in squareform(dist < 1e-10).any(axis=0).nonzero()[0] ] - raise ValueError( - "The following electrodes have overlapping positions," - " which causes problems during visualization:\n" - + ", ".join(problematic_electrodes) - ) + duplicates_1020 = { + "T3": "T7", + "T4": "T8", + "T5": "P7", + "T6": "P8", + } + + names = set(problematic_electrodes) + duplicate_pairs = [ + (old, new) + for old, new in duplicates_1020.items() + if old in names and new in names + ] + + if duplicate_pairs: + raise ValueError( + "Duplicate EEG electrode positions detected due to mixed 10-20 " + "naming conventions.\n" + "You appear to have both legacy (T3/T4/T5/T6) and modern " + "(T7/T8/P7/P8) electrode names present. The modern convention " + "(T7/T8/P7/P8) is recommended.\n\n" + "Please drop the legacy channels before plotting, for example:\n" + " inst.drop_channels(['T3', 'T4', 'T5', 'T6'])" + ) + + else: + raise ValueError( + "The following electrodes have overlapping positions, which causes " + "problems during visualization:\n" + ", ".join(problematic_electrodes) + ) if to_sphere: # translate to sphere origin, transform/flatten Z, translate back diff --git a/mne/channels/tests/test_layout.py b/mne/channels/tests/test_layout.py index ad44a6873a4..7a7c0358b31 100644 --- a/mne/channels/tests/test_layout.py +++ b/mne/channels/tests/test_layout.py @@ -15,6 +15,7 @@ assert_equal, ) +import mne from mne import pick_info, pick_types from mne._fiff.constants import FIFF from mne._fiff.meas_info import _empty_info @@ -186,6 +187,24 @@ def test_find_topomap_coords(): _find_topomap_coords(info, picks, **kwargs) +def test_duplicate_1020_electrode_names_error(): + """Ensure mixed 10–20 EEG naming conventions raise a clear error.""" + montage = mne.channels.make_standard_montage("standard_1020") + data = np.random.randn(len(montage.ch_names)) + info = mne.create_info( + ch_names=montage.ch_names, + sfreq=1000, + ch_types="eeg", + ) + info.set_montage(montage) + + with pytest.raises( + ValueError, + match="Duplicate EEG electrode positions detected due to mixed 10-20", + ): + mne.viz.plot_topomap(data, pos=info) + + def test_make_eeg_layout(tmp_path): """Test creation of EEG layout.""" lout_orig = read_layout(fname=lout_path / "test_raw.lout")