v2.0.0
Loading...
Searching...
No Matches
layoutloader.cpp
Go to the documentation of this file.
1//=============================================================================================================
22
23//=============================================================================================================
24// INCLUDES
25//=============================================================================================================
26
27#include "layoutloader.h"
28#include <algorithm>
29#include <fstream>
30
31//=============================================================================================================
32// QT INCLUDES
33//=============================================================================================================
34
35#include <QIODevice>
36#include <QTextStream>
37#include <QFile>
38#include <QDebug>
39#include <QRegularExpression>
40
41//=============================================================================================================
42// USED NAMESPACES
43//=============================================================================================================
44
45using namespace UTILSLIB;
46
47//=============================================================================================================
48// DEFINE MEMBER METHODS
49//=============================================================================================================s
50
51bool LayoutLoader::readAsaElcFile(const QString& path,
52 QStringList &channelNames,
53 QList<QVector<float> > &location3D,
54 QList<QVector<float> > &location2D,
55 QString &unit)
56{
57 //Open .elc file
58 if(!path.contains(".elc"))
59 return false;
60
61 QFile file(path);
62 if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
63 qDebug()<<"Error opening elc file";
64 return false;
65 }
66
67 //Start reading from file
68 double numberElectrodes;
69 QTextStream in(&file);
70 bool read2D = false;
71
72 while(!in.atEnd())
73 {
74 QString line = in.readLine();
75
76 QStringList fields = line.split(QRegularExpression("\\s+"));
77
78 //Delete last element if it is a blank character
79 if(fields.at(fields.size()-1) == "")
80 fields.removeLast();
81
82 if(!line.contains("#")) //Skip commented areas in file
83 {
84 //Read number of electrodes
85 if(line.contains("NumberPositions"))
86 numberElectrodes = fields.at(1).toDouble();
87
88 //Read the unit of the position values
89 if(line.contains("UnitPosition"))
90 unit = fields.at(1);
91
92 //Read actual electrode positions
93 if(line.contains("Positions2D"))
94 read2D = true;
95
96 if(line.contains(":") && !read2D) //Read 3D positions
97 {
98 channelNames.push_back(fields.at(0));
99 QVector<float> posTemp;
100
101 posTemp.push_back(fields.at(fields.size()-3).toDouble()); //x
102 posTemp.push_back(fields.at(fields.size()-2).toDouble()); //y
103 posTemp.push_back(fields.at(fields.size()-1).toDouble()); //z
104
105 location3D.append(posTemp);
106 }
107
108 if(line.contains(":") && read2D) //Read 2D positions
109 {
110 QVector<float> posTemp;
111 posTemp.push_back(fields.at(fields.size()-2).toDouble()); //x
112 posTemp.push_back(fields.at(fields.size()-1).toDouble()); //y
113 location2D.append(posTemp);
114 }
115
116 //Read channel names
117 if(line.contains("Labels"))
118 {
119 line = in.readLine();
120 fields = line.split(QRegularExpression("\\s+"));
121
122 //Delete last element if it is a blank character
123 if(fields.at(fields.size()-1) == "")
124 fields.removeLast();
125
126 channelNames = fields;
127 }
128 }
129 }
130
131 Q_UNUSED(numberElectrodes);
132
133 file.close();
134
135 return true;
136}
137
138//=============================================================================================================
139
140bool LayoutLoader::readAsaElcFile(const std::string &path,
141 std::vector<std::string> &channelNames,
142 std::vector<std::vector<float> > &location3D,
143 std::vector<std::vector<float> > &location2D,
144 std::string &unit)
145{
146
147 if(path.find(".elc") == std::string::npos){
148 return false;
149 }
150
151 std::ifstream inFile(path);
152
153 if(!inFile.is_open()){
154 qDebug()<<"Error opening elc file";
155 return false;
156 }
157
158 //Start reading from file
159 double numberElectrodes;
160 bool read2D = false;
161
162 std::string line;
163
164 while(std::getline(inFile, line)){
165 if(line.find('#') == std::string::npos){
166 std::vector<std::string> elements;
167 std::stringstream stream{line};
168 std::string element;
169
170 stream >> std::ws;
171 while(stream >> element){
172 elements.push_back(std::move(element));
173 stream >> std::ws;
174 }
175
176 //Read number of electrodes
177 if(line.find("NumberPositions") != std::string::npos)
178 numberElectrodes = std::stod(elements.at(1));
179
180 //Read the unit of the position values
181 if(line.find("UnitPosition") != std::string::npos)
182 unit = elements.at(1);
183
184 //Read actual electrode positions
185 if(line.find("Positions2D") != std::string::npos)
186 read2D = true;
187
188 if(line.find(':') != std::string::npos && !read2D) //Read 3D positions
189 {
190 channelNames.push_back(elements.at(0));
191 std::vector<float> posTemp;
192
193 posTemp.push_back(std::stod(elements.at(elements.size()-3))); //x
194 posTemp.push_back(std::stod(elements.at(elements.size()-2))); //y
195 posTemp.push_back(std::stod(elements.at(elements.size()-1))); //z
196
197 location3D.push_back(std::move(posTemp));
198 }
199
200 if(line.find(":") != std::string::npos && read2D) //Read 2D positions
201 {
202 std::vector<float> posTemp;
203 posTemp.push_back(std::stod(elements.at(elements.size()-2))); //x
204 posTemp.push_back(std::stod(elements.at(elements.size()-1))); //y
205 location2D.push_back(std::move(posTemp));
206 }
207
208 //Read channel names
209 if(line.find("Labels") != std::string::npos)
210 {
211 std::getline(inFile, line);
212 std::stringstream channels{line};
213 std::vector<std::string> listOfNames;
214
215 std::string channelName;
216
217 channels >> std::ws;
218 while(channels >> channelName){
219 listOfNames.push_back(std::move(channelName));
220 channels >> std::ws;
221 }
222
223 channelNames = std::move(listOfNames);
224 }
225 }
226 }
227
228 Q_UNUSED(numberElectrodes);
229
230 return true;
231}
232
233//=============================================================================================================
234
235bool LayoutLoader::readMNELoutFile(const QString &path, QMap<QString, QPointF> &channelData)
236{
237 //Open .elc file
238 if(!path.contains(".lout"))
239 return false;
240
241 channelData.clear();
242
243 QFile file(path);
244 if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
245 qDebug()<<"Error opening mne lout file";
246 return false;
247 }
248
249 //Start reading from file
250 QTextStream in(&file);
251
252 //skip first line
253 in.readLine();
254
255 while(!in.atEnd()) {
256 QString line = in.readLine();
257
258 QStringList fields = line.split(QRegularExpression("\\s+"));
259
260 //Delete last element if it is a blank character
261 if(fields.at(fields.size()-1) == "")
262 fields.removeLast();
263
264 QPointF posTemp;
265 posTemp.setX(fields.at(1).toDouble()); //x
266 posTemp.setY(fields.at(2).toDouble()); //y
267
268 //Create channel data map entry
269 QString key = QString("%1 %2").arg(fields.at(fields.size()-2)).arg(fields.at(fields.size()-1));
270 channelData.insert(key, posTemp);
271 }
272
273 file.close();
274
275 return true;
276}
277
278//=============================================================================================================
279
280bool LayoutLoader::readMNELoutFile(const std::string &path, QMap<std::string, QPointF> &channelData)
281{
282
283 if(path.find(".lout") == std::string::npos){
284 return false;
285 }
286
287 channelData.clear();
288 std::ifstream inFile(path);
289
290 if(!inFile.is_open()){
291 qDebug()<<"Error opening mne lout file";
292 return false;
293 }
294
295 std::string line;
296
297 // Skip first line (bounding box)
298 std::getline(inFile, line);
299
300 while(std::getline(inFile, line)){
301 if(line.empty()) continue;
302
303 std::vector<std::string> elements;
304 std::stringstream stream{line};
305 std::string element;
306
307 stream >> std::ws;
308 while(stream >> element){
309 elements.push_back(std::move(element));
310 stream >> std::ws;
311 }
312
313 if(elements.size() < 4) continue;
314
315 QPointF posTemp;
316 posTemp.setX(std::stod(elements.at(1))); //x
317 posTemp.setY(std::stod(elements.at(2))); //y
318
319 //Create channel data map entry
320 std::string key{elements.at(elements.size() - 2) + " " + elements.at(elements.size() - 1)};
321 channelData.insert(key, posTemp);
322 }
323
324 return true;
325}
Reader for ANT .elc electrode files and MNE .lout 2-D channel layouts used by the topographic plottin...
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
static bool readAsaElcFile(const QString &path, QStringList &channelNames, QList< QVector< float > > &location3D, QList< QVector< float > > &location2D, QString &unit)
static bool readMNELoutFile(const QString &path, QMap< QString, QPointF > &channelData)