From 01c1a09eb6594b251158aa098960507774b088fe Mon Sep 17 00:00:00 2001 From: Aasma Gupta Date: Fri, 30 Jan 2026 03:10:04 +0530 Subject: [PATCH 1/9] =?UTF-8?q?ENH:=20clearer=20error=20for=20mixed=2010?= =?UTF-8?q?=E2=80=9320=20EEG=20electrode=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mne/channels/layout.py | 36 ++++++++++++++++++++++++++----- mne/channels/tests/test_layout.py | 18 ++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/mne/channels/layout.py b/mne/channels/layout.py index 85b7913c1c6..d4e136b6ede 100644 --- a/mne/channels/layout.py +++ b/mne/channels/layout.py @@ -971,11 +971,37 @@ 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 old (T3/T4/T5/T6) and new (T7/T8/P7/P8) " + "electrode names present.\n\n" + "Please drop one set before plotting, for example:\n" + " inst.drop_channels(['T3', 'T4', 'T5', 'T6'])\n" + "or\n" + " inst.drop_channels(['T7', 'T8', 'P7', 'P8'])" + ) + 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..99c654b68c4 100644 --- a/mne/channels/tests/test_layout.py +++ b/mne/channels/tests/test_layout.py @@ -4,6 +4,7 @@ import copy from pathlib import Path +import mne import matplotlib.pyplot as plt import numpy as np @@ -185,6 +186,23 @@ def test_find_topomap_coords(): with pytest.raises(RuntimeError, match="No digitization points found"): _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="10.?20", + ): + mne.viz.plot_topomap(data, pos=info) + def test_make_eeg_layout(tmp_path): """Test creation of EEG layout.""" From e2786b7e4c98ba575bd1c5a30c9c45b14dc9e33c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 29 Jan 2026 21:49:35 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- mne/channels/layout.py | 11 +++++------ mne/channels/tests/test_layout.py | 3 ++- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/mne/channels/layout.py b/mne/channels/layout.py index d4e136b6ede..02995a281c1 100644 --- a/mne/channels/layout.py +++ b/mne/channels/layout.py @@ -972,10 +972,10 @@ def _auto_topomap_coords(info, picks, ignore_overlap, to_sphere, sphere): ] duplicates_1020 = { - "T3": "T7", - "T4": "T8", - "T5": "P7", - "T6": "P8", + "T3": "T7", + "T4": "T8", + "T5": "P7", + "T6": "P8", } names = set(problematic_electrodes) @@ -999,8 +999,7 @@ def _auto_topomap_coords(info, picks, ignore_overlap, to_sphere, sphere): else: raise ValueError( "The following electrodes have overlapping positions, which causes " - "problems during visualization:\n" - + ", ".join(problematic_electrodes) + "problems during visualization:\n" + ", ".join(problematic_electrodes) ) if to_sphere: diff --git a/mne/channels/tests/test_layout.py b/mne/channels/tests/test_layout.py index 99c654b68c4..8a1b32fdfed 100644 --- a/mne/channels/tests/test_layout.py +++ b/mne/channels/tests/test_layout.py @@ -4,7 +4,6 @@ import copy from pathlib import Path -import mne import matplotlib.pyplot as plt import numpy as np @@ -16,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 +186,7 @@ def test_find_topomap_coords(): with pytest.raises(RuntimeError, match="No digitization points found"): _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") From 44c708d1b010b53f40b06cea114fa991d5349061 Mon Sep 17 00:00:00 2001 From: Aasma Gupta Date: Fri, 30 Jan 2026 03:23:22 +0530 Subject: [PATCH 3/9] =?UTF-8?q?ENH:=20add=20towncrier=20entry=20for=20mixe?= =?UTF-8?q?d=2010=E2=80=9320=20EEG=20naming=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/changes/dev/13447.enhance.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 doc/changes/dev/13447.enhance.rst diff --git a/doc/changes/dev/13447.enhance.rst b/doc/changes/dev/13447.enhance.rst new file mode 100644 index 00000000000..4c97f24e39f --- /dev/null +++ b/doc/changes/dev/13447.enhance.rst @@ -0,0 +1,3 @@ +Improve the error message raised when mixed 10–20 EEG electrode naming +conventions (T3/T4/T5/T6 vs T7/T8/P7/P8) lead to overlapping sensor positions +during topomap plotting. From 3c3dd7816ffa3a9a83c56a1944cb50cbdaf15b78 Mon Sep 17 00:00:00 2001 From: Aasma Gupta Date: Sat, 31 Jan 2026 00:42:28 +0530 Subject: [PATCH 4/9] DOC: fix towncrier entry and test regex --- doc/changes/dev/13447.newcontrib.rst | 5 +++++ doc/changes/names.inc | 1 + mne/channels/tests/test_layout.py | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 doc/changes/dev/13447.newcontrib.rst diff --git a/doc/changes/dev/13447.newcontrib.rst b/doc/changes/dev/13447.newcontrib.rst new file mode 100644 index 00000000000..79617d906a5 --- /dev/null +++ b/doc/changes/dev/13447.newcontrib.rst @@ -0,0 +1,5 @@ +:newcontrib: + +Improve the error message raised when mixed 10–20 EEG electrode naming +conventions (T3/T4/T5/T6 vs T7/T8/P7/P8) lead to overlapping sensor positions +during topomap plotting. diff --git a/doc/changes/names.inc b/doc/changes/names.inc index b684d067a1d..b395337a3e9 100644 --- a/doc/changes/names.inc +++ b/doc/changes/names.inc @@ -359,3 +359,4 @@ .. _Zhi Zhang: https://github.com/tczhangzhi/ .. _Ziyi ZENG: https://github.com/ZiyiTsang .. _Zvi Baratz: https://github.com/ZviBaratz +.. _Aasma Gupta: https://github.com/AasmaGupta diff --git a/mne/channels/tests/test_layout.py b/mne/channels/tests/test_layout.py index 8a1b32fdfed..0dccb049c56 100644 --- a/mne/channels/tests/test_layout.py +++ b/mne/channels/tests/test_layout.py @@ -200,7 +200,7 @@ def test_duplicate_1020_electrode_names_error(): with pytest.raises( ValueError, - match="10.?20", + match="mixed 10-20", ): mne.viz.plot_topomap(data, pos=info) From 7a422b827268acf3b0c5956ee655710138c8b892 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 30 Jan 2026 19:15:42 +0000 Subject: [PATCH 5/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- doc/changes/names.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/changes/names.inc b/doc/changes/names.inc index b395337a3e9..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 @@ -359,4 +360,3 @@ .. _Zhi Zhang: https://github.com/tczhangzhi/ .. _Ziyi ZENG: https://github.com/ZiyiTsang .. _Zvi Baratz: https://github.com/ZviBaratz -.. _Aasma Gupta: https://github.com/AasmaGupta From ccb952752f55d54547da4f6e862ee6aecd8214b3 Mon Sep 17 00:00:00 2001 From: Aasma Gupta Date: Sat, 31 Jan 2026 00:53:31 +0530 Subject: [PATCH 6/9] =?UTF-8?q?DOC:=20fix=20towncrier=20entry=20type=20for?= =?UTF-8?q?=20mixed=2010=E2=80=9320=20EEG=20naming?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/changes/dev/13447.enhance.rst | 3 --- doc/changes/dev/13447.newcontrib.rst | 6 +----- 2 files changed, 1 insertion(+), 8 deletions(-) delete mode 100644 doc/changes/dev/13447.enhance.rst diff --git a/doc/changes/dev/13447.enhance.rst b/doc/changes/dev/13447.enhance.rst deleted file mode 100644 index 4c97f24e39f..00000000000 --- a/doc/changes/dev/13447.enhance.rst +++ /dev/null @@ -1,3 +0,0 @@ -Improve the error message raised when mixed 10–20 EEG electrode naming -conventions (T3/T4/T5/T6 vs T7/T8/P7/P8) lead to overlapping sensor positions -during topomap plotting. diff --git a/doc/changes/dev/13447.newcontrib.rst b/doc/changes/dev/13447.newcontrib.rst index 79617d906a5..c1d81c56626 100644 --- a/doc/changes/dev/13447.newcontrib.rst +++ b/doc/changes/dev/13447.newcontrib.rst @@ -1,5 +1 @@ -:newcontrib: - -Improve the error message raised when mixed 10–20 EEG electrode naming -conventions (T3/T4/T5/T6 vs T7/T8/P7/P8) lead to overlapping sensor positions -during topomap plotting. +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 From 6466c339daf285bfb2d2336ff6087e5bf76acad4 Mon Sep 17 00:00:00 2001 From: Aasma Gupta Date: Sat, 31 Jan 2026 01:03:24 +0530 Subject: [PATCH 7/9] TEST: simplify for mixed 10-20 naming --- mne/channels/tests/test_layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/channels/tests/test_layout.py b/mne/channels/tests/test_layout.py index 0dccb049c56..be5be9bfd67 100644 --- a/mne/channels/tests/test_layout.py +++ b/mne/channels/tests/test_layout.py @@ -200,7 +200,7 @@ def test_duplicate_1020_electrode_names_error(): with pytest.raises( ValueError, - match="mixed 10-20", + match="mixed 10-20 naming conventions", ): mne.viz.plot_topomap(data, pos=info) From 57091310cbb11ba1b836b5ba249088b335e3bfce Mon Sep 17 00:00:00 2001 From: Aasma Gupta Date: Wed, 11 Feb 2026 00:30:41 +0530 Subject: [PATCH 8/9] =?UTF-8?q?ENH:=20recommend=20modern=2010=E2=80=9310?= =?UTF-8?q?=20electrode=20names=20and=20update=20test=20regex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mne/channels/layout.py | 14 +++++++------- mne/channels/tests/test_layout.py | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mne/channels/layout.py b/mne/channels/layout.py index 02995a281c1..fe7a1026a8e 100644 --- a/mne/channels/layout.py +++ b/mne/channels/layout.py @@ -987,15 +987,15 @@ def _auto_topomap_coords(info, picks, ignore_overlap, to_sphere, sphere): if duplicate_pairs: raise ValueError( - "Duplicate EEG electrode positions detected due to mixed 10–20 " + "Duplicate EEG electrode positions detected due to mixed 10-20 " "naming conventions.\n" - "You appear to have both old (T3/T4/T5/T6) and new (T7/T8/P7/P8) " - "electrode names present.\n\n" - "Please drop one set before plotting, for example:\n" - " inst.drop_channels(['T3', 'T4', 'T5', 'T6'])\n" - "or\n" - " inst.drop_channels(['T7', 'T8', 'P7', 'P8'])" + "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 " diff --git a/mne/channels/tests/test_layout.py b/mne/channels/tests/test_layout.py index be5be9bfd67..377091cf513 100644 --- a/mne/channels/tests/test_layout.py +++ b/mne/channels/tests/test_layout.py @@ -200,7 +200,7 @@ def test_duplicate_1020_electrode_names_error(): with pytest.raises( ValueError, - match="mixed 10-20 naming conventions", + match=r"mixed 10.?20 naming conventions", ): mne.viz.plot_topomap(data, pos=info) From 99f130d504229bc9c4b11026e8ed42630b5f7b2a Mon Sep 17 00:00:00 2001 From: Aasma Gupta Date: Wed, 11 Feb 2026 00:49:20 +0530 Subject: [PATCH 9/9] TEST: simplify regex match for duplicate 10-20 electrode error --- mne/channels/tests/test_layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/channels/tests/test_layout.py b/mne/channels/tests/test_layout.py index 377091cf513..7a7c0358b31 100644 --- a/mne/channels/tests/test_layout.py +++ b/mne/channels/tests/test_layout.py @@ -200,7 +200,7 @@ def test_duplicate_1020_electrode_names_error(): with pytest.raises( ValueError, - match=r"mixed 10.?20 naming conventions", + match="Duplicate EEG electrode positions detected due to mixed 10-20", ): mne.viz.plot_topomap(data, pos=info)