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