Skip to content

Commit b2b0380

Browse files
larsonerautofix-ci[bot]drammock
authored
Add fsaverage_1005 (#13936)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Daniel McCloy <dan@mccloy.info>
1 parent 177faf3 commit b2b0380

10 files changed

Lines changed: 583 additions & 23 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added ``'fsaverage_1005'`` montage, which is a slightly improved version of the existing ``'colin27_1005'`` montage (known in 1.12 and older as ``'standard_1005'``). The electrodes have already been mapped to the ``fsaverage`` head surface. Changes by `Eric Larson`_.

mne/channels/_standard_montage_utils.py

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os.path as op
77
from collections import OrderedDict
88
from functools import partial
9+
from pathlib import Path
910

1011
import numpy as np
1112

@@ -114,9 +115,11 @@ def _mgh_or_standard(basename, head_size, coord_frame="unknown"):
114115
)
115116

116117

117-
def _read_spherical_tsv(fname, head_size):
118+
def _read_eeg_positions_tsv(*, basename, head_size):
119+
# Read TSV files like those produced by eeg_positions
118120
ch_names = []
119121
pos = []
122+
fname = Path(MONTAGE_PATH) / basename
120123
with open(fname) as f:
121124
f.readline() # skip header
122125
for row in csv.reader(f, delimiter="\t"):
@@ -129,6 +132,9 @@ def _read_spherical_tsv(fname, head_size):
129132
nasion = ch_pos.pop("NAS")
130133
lpa = ch_pos.pop("LPA")
131134
rpa = ch_pos.pop("RPA")
135+
# two extras generated by FieldTrip when creating fsaverage montages
136+
ch_pos.pop("INI", None)
137+
ch_pos.pop("Nz", None)
132138

133139
if head_size is not None:
134140
scale = head_size / np.median(
@@ -165,6 +171,19 @@ def _read_spherical_tsv(fname, head_size):
165171
"biosemi64": partial(_biosemi, basename="biosemi64.txt"),
166172
"mgh60": partial(_mgh_or_standard, basename="mgh60.elc", coord_frame="mri"),
167173
"mgh70": partial(_mgh_or_standard, basename="mgh70.elc", coord_frame="mri"),
174+
# fsaverage via https://gist.github.com/larsoner/5af20934521278927c8a3056df2bcb69
175+
"fsaverage_1005": partial(
176+
_read_eeg_positions_tsv,
177+
basename="fsaverage_1005.tsv",
178+
),
179+
"fsaverage_1010": partial(
180+
_read_eeg_positions_tsv,
181+
basename="fsaverage_1010.tsv",
182+
),
183+
"fsaverage_1020": partial(
184+
_read_eeg_positions_tsv,
185+
basename="fsaverage_1020.tsv",
186+
),
168187
"colin27_1005": partial(
169188
_mgh_or_standard, basename="colin27_1005.elc", coord_frame="mri"
170189
),
@@ -193,13 +212,16 @@ def _read_spherical_tsv(fname, head_size):
193212
_easycap, basename="brainproducts-RNP-BA-128.txt"
194213
),
195214
"spherical_1005": partial(
196-
_read_spherical_tsv, op.join(MONTAGE_PATH, "spherical_1005.tsv")
215+
_read_eeg_positions_tsv,
216+
basename="spherical_1005.tsv",
197217
),
198218
"spherical_1010": partial(
199-
_read_spherical_tsv, op.join(MONTAGE_PATH, "spherical_1010.tsv")
219+
_read_eeg_positions_tsv,
220+
basename="spherical_1010.tsv",
200221
),
201222
"spherical_1020": partial(
202-
_read_spherical_tsv, op.join(MONTAGE_PATH, "spherical_1020.tsv")
223+
_read_eeg_positions_tsv,
224+
basename="spherical_1020.tsv",
203225
),
204226
}
205227

mne/channels/data/montages/fsaverage_1005.tsv

Lines changed: 341 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
label x y z
2+
LPA -0.0820787224767085 -0.0293041925438933 -0.0411245510037724
3+
RPA 0.0834811119150642 -0.0285034070849422 -0.0407909563372145
4+
NAS 0.0015257470752712 0.0857120972834004 -0.0352920505030129
5+
Fp1 -0.0292811604883705 0.0839923366306848 0.0027166993525041
6+
Fpz 0.0010145384588165 0.0887770581271724 0.0044033463354227
7+
Fp2 0.0306257951597534 0.084018322869127 0.0028308106557744
8+
AF7 -0.0540586961883833 0.0659147316247142 0.0010325910836783
9+
AFz 0.0006286110426344 0.0794624169674513 0.0432403876366741
10+
AF8 0.0549319494049847 0.0664728785564758 0.0012599017645204
11+
F9 -0.0719200695538433 0.0400491675165332 -0.0391067566489234
12+
F7 -0.0708204691934873 0.040153234495631 -0.0003977665209734
13+
F5 -0.0635347785079349 0.0451339380999023 0.0266026156542629
14+
F3 -0.0493847283836248 0.0496591047450529 0.0507788153953548
15+
F1 -0.0269388955839328 0.0529253984969059 0.0676531756687883
16+
Fz 0.000479208202084 0.0544294712466611 0.0746189130473796
17+
F2 0.0279172601069479 0.0534824837150213 0.0681276379382506
18+
F4 0.0504019360413014 0.0506007427788517 0.0512480803906933
19+
F6 0.0644736445350185 0.0463010922923489 0.0269806173420169
20+
F8 0.0716427067493973 0.0414322274794438 -8.66406980105438e-05
21+
F10 0.0743359276156109 0.040777428726348 -0.0388843048593927
22+
FT9 -0.0815214730494951 0.0119587109063013 -0.0401407891589863
23+
FT7 -0.0813914363732593 0.0112158044712079 -0.0015728091034477
24+
FC5 -0.0757689007593723 0.0138682267434461 0.0326430889583354
25+
FC3 -0.0599106607148846 0.0163770481472205 0.0633745088463384
26+
FC1 -0.0332086553084157 0.0183562582728159 0.0854211142220363
27+
FCz 0.0005614944497306 0.0194409806887125 0.0945409069900452
28+
FC2 0.0335457021732133 0.019140263752495 0.0854556696248649
29+
FC4 0.0603616019789147 0.0178027844463694 0.063611148831316
30+
FC6 0.0769526443868325 0.0156948931341934 0.0331587753832555
31+
FT8 0.0820648415174289 0.0131583553037296 -0.0011863742116163
32+
FT10 0.0839538264893574 0.0131874383393136 -0.0398675774667275
33+
T9 -0.0827097135870027 -0.0181370355479935 -0.0408934549397819
34+
T7 -0.0835937487603662 -0.019525372193334 -0.0023491726668447
35+
C5 -0.0820810897923946 -0.020811626682403 0.0361562971843083
36+
C3 -0.0670234260195356 -0.0218716728586043 0.0711910468514749
37+
C1 -0.037157513370015 -0.0224066656081856 0.0953422064172467
38+
Cz -0.0001033324215976 -0.0223617287453268 0.104808602517519
39+
C2 0.0371028031660319 -0.0216680617340279 0.0955559121279765
40+
C4 0.0669887397285408 -0.020536116614284 0.071500007411479
41+
C6 0.0817776675180596 -0.0191693679406355 0.0362664326209568
42+
T8 0.0852272127651827 -0.0168727641993645 -0.0019606188397811
43+
T10 0.0834211630255213 -0.0164828305635504 -0.040522563293326
44+
TP7 -0.0819319302716329 -0.050313186491959 -0.0029245392782304
45+
CP5 -0.0801502647931555 -0.0539831573075331 0.0338723249083209
46+
CP3 -0.0639472450913855 -0.0569376975651329 0.066480946742409
47+
CP1 -0.0352056064002067 -0.0586818060521841 0.0896062472267399
48+
CPz 0.0012568996337269 -0.0586791291296895 0.096949368711512
49+
CP2 0.0368463412800938 -0.0573147874254576 0.0905969427762103
50+
CP4 0.0655177125650338 -0.0544239207542547 0.0676903800472753
51+
CP6 0.0802932403073166 -0.0507521780589653 0.034222417226468
52+
TP8 0.0834651635390172 -0.0469897325574605 -0.0024913627317454
53+
P9 -0.0706491974210579 -0.0763231460551085 -0.0417881445305015
54+
P7 -0.0733143023678992 -0.0798926050129789 -0.0031102937996744
55+
P5 -0.0680123253098727 -0.0846413251564195 0.0258718110345045
56+
P3 -0.0518992809676258 -0.0883889456105598 0.0505829878628514
57+
P1 -0.0277057195937326 -0.0906551722681681 0.0677536650486635
58+
Pz 0.001849368905695 -0.0907160940487649 0.0726711555824476
59+
P2 0.0310141487174543 -0.0893794100234815 0.0692392467671665
60+
P4 0.054916710261992 -0.0858427154288949 0.0519478134424029
61+
P6 0.0689832928886881 -0.0811130856342705 0.0260647580759801
62+
P8 0.0753775077369245 -0.0760993039735263 -0.0026863672658036
63+
P10 0.0739449104331882 -0.0739393717663847 -0.0414784715750218
64+
PO9 -0.05197937541018 -0.0997754012896665 -0.0416096989787222
65+
PO7 -0.0541676472693924 -0.10379581413119 -0.0026235420783083
66+
POz 0.0024614151754572 -0.112273025947628 0.0387895039497594
67+
PO8 0.0575904612306775 -0.100325332614626 -0.0022979957151223
68+
PO10 0.0576528842499382 -0.0982396349876328 -0.0414282155249872
69+
O1 -0.0274739525289969 -0.118933752950687 -0.001553724537091
70+
Oz 0.0030278390474609 -0.122432470113388 -3.44789193595093e-05
71+
O2 0.0325761868875559 -0.116985044736657 -0.0013942802904455
72+
I1 -0.026558525226297 -0.115993543151642 -0.0409979435751963
73+
Iz 0.0034659675018193 -0.117416783675416 -0.0398592714008632
74+
I2 0.0327644623068528 -0.114257852074429 -0.0408715430664998
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
label x y z
2+
LPA -0.0820787224767085 -0.0293041925438933 -0.0411245510037724
3+
RPA 0.0834811119150642 -0.0285034070849422 -0.0407909563372145
4+
NAS 0.0015257470752712 0.0857120972834004 -0.0352920505030129
5+
Fp1 -0.0292811604883705 0.0839923366306848 0.0027166993525041
6+
Fpz 0.0010145384588165 0.0887770581271724 0.0044033463354227
7+
Fp2 0.0306257951597534 0.084018322869127 0.0028308106557744
8+
F7 -0.0708204691934873 0.040153234495631 -0.0003977665209734
9+
F3 -0.0493847283836248 0.0496591047450529 0.0507788153953548
10+
Fz 0.000479208202084 0.0544294712466611 0.0746189130473796
11+
F4 0.0504019360413014 0.0506007427788517 0.0512480803906933
12+
F8 0.0716427067493973 0.0414322274794438 -8.66406980105438e-05
13+
T7 -0.0835937487603662 -0.019525372193334 -0.0023491726668447
14+
C3 -0.0670234260195356 -0.0218716728586043 0.0711910468514749
15+
Cz -0.0001033324215976 -0.0223617287453268 0.104808602517519
16+
C4 0.0669887397285408 -0.020536116614284 0.071500007411479
17+
T8 0.0852272127651827 -0.0168727641993645 -0.0019606188397811
18+
P7 -0.0733143023678992 -0.0798926050129789 -0.0031102937996744
19+
P3 -0.0518992809676258 -0.0883889456105598 0.0505829878628514
20+
Pz 0.001849368905695 -0.0907160940487649 0.0726711555824476
21+
P4 0.054916710261992 -0.0858427154288949 0.0519478134424029
22+
P8 0.0753775077369245 -0.0760993039735263 -0.0026863672658036
23+
O1 -0.0274739525289969 -0.118933752950687 -0.001553724537091
24+
Oz 0.0030278390474609 -0.122432470113388 -3.44789193595093e-05
25+
O2 0.0325761868875559 -0.116985044736657 -0.0013942802904455

mne/channels/montage.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,21 @@ class _BuiltinStandardMontage:
7171

7272

7373
_BUILTIN_STANDARD_MONTAGES = [
74+
_BuiltinStandardMontage(
75+
name="fsaverage_1005",
76+
description="Electrodes are named according to the international 10-05 system "
77+
"and positioned on the fsaverage head model (335+3 locations)",
78+
),
79+
_BuiltinStandardMontage(
80+
name="fsaverage_1010",
81+
description="Electrodes are named according to the international 10-10 system "
82+
"and positioned on the fsaverage head model (70+3 locations)",
83+
),
84+
_BuiltinStandardMontage(
85+
name="fsaverage_1020",
86+
description="Electrodes are named according to the international 10-20 system "
87+
"and positioned on the fsaverage head model (21+3 locations)",
88+
),
7489
_BuiltinStandardMontage(
7590
name="colin27_1005",
7691
description="Electrodes are named according to the international 10-05 system "
@@ -90,7 +105,7 @@ class _BuiltinStandardMontage:
90105
name="colin27_postfixed",
91106
description="Electrodes are named according to the international extended 10-20"
92107
" system using postfixes for intermediate positions and positioned on the "
93-
"Colin27 head model(100+3 locations)",
108+
"Colin27 head model (100+3 locations)",
94109
),
95110
_BuiltinStandardMontage(
96111
name="colin27_prefixed",
@@ -130,19 +145,19 @@ class _BuiltinStandardMontage:
130145
),
131146
_BuiltinStandardMontage(
132147
name="easycap-M1",
133-
description="EasyCap with 10-05 electrode names (74 locations)",
148+
description="EasyCap with 10-05 electrode names (74+3 locations)",
134149
),
135150
_BuiltinStandardMontage(
136151
name="easycap-M10",
137-
description="EasyCap with numbered electrodes (61 locations)",
152+
description="EasyCap with numbered electrodes (61+3 locations)",
138153
),
139154
_BuiltinStandardMontage(
140155
name="easycap-M43",
141-
description="EasyCap with numbered electrodes (64 locations)",
156+
description="EasyCap with numbered electrodes (64+3 locations)",
142157
),
143158
_BuiltinStandardMontage(
144159
name="EGI_256",
145-
description="Geodesic Sensor Net (256 locations)",
160+
description="Geodesic Sensor Net (256+3 locations)",
146161
),
147162
_BuiltinStandardMontage(
148163
name="GSN-HydroCel-32",
@@ -191,19 +206,22 @@ class _BuiltinStandardMontage:
191206
),
192207
_BuiltinStandardMontage(
193208
name="brainproducts-RNP-BA-128",
194-
description="Brain Products with 10-10 electrode names (128 channels)",
209+
description="Brain Products with 10-10 electrode names (130+3 locations)",
195210
),
196211
_BuiltinStandardMontage(
197212
name="spherical_1005",
198-
description="10–05 electrode names and locations using a spherical head model",
213+
description="10–05 electrode names and locations using a spherical head model"
214+
" (344+3 locations)",
199215
),
200216
_BuiltinStandardMontage(
201217
name="spherical_1010",
202-
description="10–10 electrode names and locations using a spherical head model",
218+
description="10–10 electrode names and locations using a spherical head model"
219+
" (70+3 locations)",
203220
),
204221
_BuiltinStandardMontage(
205222
name="spherical_1020",
206-
description="10–20 electrode names and locations using a spherical head model",
223+
description="10–20 electrode names and locations using a spherical head model"
224+
" (21+3 locations)",
207225
),
208226
]
209227

@@ -2008,9 +2026,9 @@ def make_standard_montage(kind, head_size="auto"):
20082026
head_size : float | None | str
20092027
The head size (radius, in meters) to use for spherical montages.
20102028
Can be None to not scale the read sizes. ``'auto'`` (default) will
2011-
use 95mm for all montages except the ``'colin27*'``, ``'mgh*'``, and
2012-
``'artinis*'``, which are already in fsaverage's MRI coordinates
2013-
(same as MNI).
2029+
use 95mm for all montages except the ``'fsaverage*'``,
2030+
``'colin27*'``, ``'mgh*'``, and ``'artinis*'``, which are already in
2031+
fsaverage's MRI coordinates (same as MNI).
20142032
20152033
Returns
20162034
-------
@@ -2051,7 +2069,7 @@ def make_standard_montage(kind, head_size="auto"):
20512069
_validate_type(head_size, ("numeric", str, None), "head_size")
20522070
if isinstance(head_size, str):
20532071
_check_option("head_size", head_size, ("auto",), extra="when str")
2054-
if kind.startswith(("colin27", "mgh", "artinis")):
2072+
if kind.startswith(("fsaverage", "colin27", "mgh", "artinis")):
20552073
head_size = None
20562074
else:
20572075
head_size = HEAD_SIZE_DEFAULT

mne/channels/tests/test_interpolation.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ def test_method_str():
502502

503503

504504
@pytest.mark.parametrize(
505-
"montage_name", ["biosemi16", "spherical_1005", "colin27_1020"]
505+
"montage_name", ["biosemi16", "spherical_1005", "colin27_1020", "fsaverage_1005"]
506506
)
507507
@pytest.mark.parametrize("method", ["spline", "MNE"])
508508
@pytest.mark.parametrize("data_type", ["raw", "epochs", "evoked"])

0 commit comments

Comments
 (0)