v2.0.0
Loading...
Searching...
No Matches
standard_montage.cpp
Go to the documentation of this file.
1//=============================================================================================================
20
21//=============================================================================================================
22// INCLUDES
23//=============================================================================================================
24
25#include "standard_montage.h"
26
27//=============================================================================================================
28// USED NAMESPACES
29//=============================================================================================================
30
31using namespace UTILSLIB;
32using namespace Eigen;
33
34//=============================================================================================================
35// STATIC HELPERS
36//=============================================================================================================
37
38namespace
39{
40
41ElectrodePosition makeElectrode(const QString& name, double x, double y, double z)
42{
44 ep.name = name;
45 ep.pos = Vector3d(x, y, z);
46 return ep;
47}
48
49} // anonymous namespace
50
51//=============================================================================================================
52// DEFINE MEMBER METHODS
53//=============================================================================================================
54
55QList<ElectrodePosition> StandardMontage::buildStandard1020()
56{
57 // Standard 10-20 electrode positions in MNI head coordinates (metres)
58 // Reference: Oostenveld & Praamstra, Clin. Neurophysiol. 112(4), 713-719, 2001.
59 QList<ElectrodePosition> montage;
60 montage.reserve(21);
61
62 montage << makeElectrode("Fp1", -0.0309, 0.0832, 0.0330);
63 montage << makeElectrode("Fp2", 0.0309, 0.0832, 0.0330);
64 montage << makeElectrode("F7", -0.0709, 0.0399, 0.0095);
65 montage << makeElectrode("F3", -0.0487, 0.0537, 0.0625);
66 montage << makeElectrode("Fz", 0.0000, 0.0620, 0.0780);
67 montage << makeElectrode("F4", 0.0487, 0.0537, 0.0625);
68 montage << makeElectrode("F8", 0.0709, 0.0399, 0.0095);
69 montage << makeElectrode("T7", -0.0810, 0.0000, -0.0010);
70 montage << makeElectrode("C3", -0.0562, 0.0000, 0.0683);
71 montage << makeElectrode("Cz", 0.0000, 0.0000, 0.0870);
72 montage << makeElectrode("C4", 0.0562, 0.0000, 0.0683);
73 montage << makeElectrode("T8", 0.0810, 0.0000, -0.0010);
74 montage << makeElectrode("P7", -0.0709, -0.0399, 0.0095);
75 montage << makeElectrode("P3", -0.0487, -0.0537, 0.0625);
76 montage << makeElectrode("Pz", 0.0000, -0.0620, 0.0780);
77 montage << makeElectrode("P4", 0.0487, -0.0537, 0.0625);
78 montage << makeElectrode("P8", 0.0709, -0.0399, 0.0095);
79 montage << makeElectrode("O1", -0.0309, -0.0832, 0.0330);
80 montage << makeElectrode("O2", 0.0309, -0.0832, 0.0330);
81 montage << makeElectrode("A1", -0.0830, 0.0000, -0.0370);
82 montage << makeElectrode("A2", 0.0830, 0.0000, -0.0370);
83
84 return montage;
85}
86
87//=============================================================================================================
88
89QList<ElectrodePosition> StandardMontage::buildStandard1010()
90{
91 // Start with 10-20 and add 10-10 intermediate positions
92 QList<ElectrodePosition> montage = buildStandard1020();
93
94 // Additional 10-10 positions (60 more electrodes)
95 // Frontal-central
96 montage << makeElectrode("AF7", -0.0530, 0.0680, 0.0180);
97 montage << makeElectrode("AF3", -0.0350, 0.0740, 0.0530);
98 montage << makeElectrode("AFz", 0.0000, 0.0780, 0.0600);
99 montage << makeElectrode("AF4", 0.0350, 0.0740, 0.0530);
100 montage << makeElectrode("AF8", 0.0530, 0.0680, 0.0180);
101
102 montage << makeElectrode("F5", -0.0610, 0.0470, 0.0370);
103 montage << makeElectrode("F1", -0.0240, 0.0580, 0.0720);
104 montage << makeElectrode("F2", 0.0240, 0.0580, 0.0720);
105 montage << makeElectrode("F6", 0.0610, 0.0470, 0.0370);
106
107 montage << makeElectrode("FT7", -0.0770, 0.0200, -0.0010);
108 montage << makeElectrode("FC5", -0.0660, 0.0270, 0.0340);
109 montage << makeElectrode("FC3", -0.0500, 0.0280, 0.0670);
110 montage << makeElectrode("FC1", -0.0250, 0.0300, 0.0790);
111 montage << makeElectrode("FCz", 0.0000, 0.0310, 0.0840);
112 montage << makeElectrode("FC2", 0.0250, 0.0300, 0.0790);
113 montage << makeElectrode("FC4", 0.0500, 0.0280, 0.0670);
114 montage << makeElectrode("FC6", 0.0660, 0.0270, 0.0340);
115 montage << makeElectrode("FT8", 0.0770, 0.0200, -0.0010);
116
117 // Central-temporal
118 montage << makeElectrode("C5", -0.0700, 0.0000, 0.0340);
119 montage << makeElectrode("C1", -0.0280, 0.0000, 0.0810);
120 montage << makeElectrode("C2", 0.0280, 0.0000, 0.0810);
121 montage << makeElectrode("C6", 0.0700, 0.0000, 0.0340);
122
123 montage << makeElectrode("TP7", -0.0770, -0.0200, -0.0010);
124 montage << makeElectrode("CP5", -0.0660, -0.0270, 0.0340);
125 montage << makeElectrode("CP3", -0.0500, -0.0280, 0.0670);
126 montage << makeElectrode("CP1", -0.0250, -0.0300, 0.0790);
127 montage << makeElectrode("CPz", 0.0000, -0.0310, 0.0840);
128 montage << makeElectrode("CP2", 0.0250, -0.0300, 0.0790);
129 montage << makeElectrode("CP4", 0.0500, -0.0280, 0.0670);
130 montage << makeElectrode("CP6", 0.0660, -0.0270, 0.0340);
131 montage << makeElectrode("TP8", 0.0770, -0.0200, -0.0010);
132
133 // Parietal-occipital
134 montage << makeElectrode("P5", -0.0610, -0.0470, 0.0370);
135 montage << makeElectrode("P1", -0.0240, -0.0580, 0.0720);
136 montage << makeElectrode("P2", 0.0240, -0.0580, 0.0720);
137 montage << makeElectrode("P6", 0.0610, -0.0470, 0.0370);
138
139 montage << makeElectrode("PO7", -0.0530, -0.0680, 0.0180);
140 montage << makeElectrode("PO3", -0.0350, -0.0740, 0.0530);
141 montage << makeElectrode("POz", 0.0000, -0.0780, 0.0600);
142 montage << makeElectrode("PO4", 0.0350, -0.0740, 0.0530);
143 montage << makeElectrode("PO8", 0.0530, -0.0680, 0.0180);
144
145 montage << makeElectrode("Oz", 0.0000, -0.0870, 0.0170);
146
147 // Inferior temporal
148 montage << makeElectrode("FT9", -0.0850, 0.0220, -0.0280);
149 montage << makeElectrode("FT10", 0.0850, 0.0220, -0.0280);
150 montage << makeElectrode("TP9", -0.0850, -0.0220, -0.0280);
151 montage << makeElectrode("TP10", 0.0850, -0.0220, -0.0280);
152
153 // Frontal-polar
154 montage << makeElectrode("Fpz", 0.0000, 0.0870, 0.0170);
155 montage << makeElectrode("Iz", 0.0000, -0.0870, -0.0170);
156 montage << makeElectrode("Nz", 0.0000, 0.0870, -0.0170);
157
158 // Additional central positions
159 montage << makeElectrode("F9", -0.0850, 0.0400, -0.0280);
160 montage << makeElectrode("F10", 0.0850, 0.0400, -0.0280);
161 montage << makeElectrode("P9", -0.0850, -0.0400, -0.0280);
162 montage << makeElectrode("P10", 0.0850, -0.0400, -0.0280);
163
164 return montage;
165}
166
167//=============================================================================================================
168
169QList<ElectrodePosition> StandardMontage::getMontage(System system)
170{
171 switch (system) {
173 return buildStandard1020();
175 return buildStandard1010();
177 // For now, return 10-10 (full 10-05 has 345 electrodes — extensible later)
178 return buildStandard1010();
179 default:
180 return {};
181 }
182}
183
184//=============================================================================================================
185
187{
188 QStringList names;
189 for (const auto& ep : getMontage(system)) {
190 names << ep.name;
191 }
192 return names;
193}
194
195//=============================================================================================================
196
197bool StandardMontage::findElectrode(const QString& name, Vector3d& pos)
198{
199 // Search in 10-10 (which includes 10-20)
200 for (const auto& ep : buildStandard1010()) {
201 if (ep.name.compare(name, Qt::CaseInsensitive) == 0) {
202 pos = ep.pos;
203 return true;
204 }
205 }
206 return false;
207}
208
209//=============================================================================================================
210
212{
213 return getMontage(system).size();
214}
Built-in 10-20 / 10-10 / 10-05 EEG electrode position tables in MNI head coordinates.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Represents an electrode position in a montage.
static QList< ElectrodePosition > getMontage(System system)
Get a standard montage by system name.
System
Supported standard montage systems.
static bool findElectrode(const QString &name, Eigen::Vector3d &pos)
Look up a single electrode position by name.
static int electrodeCount(System system)
Get the number of electrodes in a montage.
static QStringList getElectrodeNames(System system)
Get electrode names for a standard montage.