v2.0.0
Loading...
Searching...
No Matches
fiff_info_base.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "fiff_info_base.h"
42
43#include <iostream>
44
45#include <QFile>
46#include <QTextStream>
47#include <QDebug>
48
49//=============================================================================================================
50// USED NAMESPACES
51//=============================================================================================================
52
53using namespace FIFFLIB;
54using namespace Eigen;
55
56//=============================================================================================================
57// DEFINE MEMBER METHODS
58//=============================================================================================================
59
61: filename("")
62, nchan(-1)
63{
64}
65
66//=============================================================================================================
67
69: filename(p_FiffInfoBase.filename)
70, bads(p_FiffInfoBase.bads)
71, meas_id(FiffId(p_FiffInfoBase.meas_id))
72, nchan(p_FiffInfoBase.nchan)
73, chs(p_FiffInfoBase.chs)
74, ch_names(p_FiffInfoBase.ch_names)
75, dev_head_t(p_FiffInfoBase.dev_head_t)
76, ctf_head_t(p_FiffInfoBase.ctf_head_t)
77{
78}
79
80//=============================================================================================================
81
85
86//=============================================================================================================
87
88QString FiffInfoBase::channel_type(qint32 idx) const
89{
90 qint32 kind = this->chs[idx].kind;
91 if(kind == FIFFV_MEG_CH)
92 {
93 if(this->chs[idx].unit == FIFF_UNIT_T_M)
94 return "grad";
95 else if(this->chs[idx].unit == FIFF_UNIT_T)
96 return "mag";
97 }
98 else if(kind == FIFFV_REF_MEG_CH)
99 return "ref_meg";
100 else if(kind == FIFFV_EEG_CH)
101 return "eeg";
102 else if(kind == FIFFV_STIM_CH)
103 return "stim";
104 else if(kind == FIFFV_EOG_CH)
105 return "eog";
106 else if(kind == FIFFV_EMG_CH)
107 return "emg";
108 else if(kind == FIFFV_ECG_CH)
109 return "ecg";
110 else if(kind == FIFFV_MISC_CH)
111 return "misc";
112 else if (kind == FIFFV_QUAT_0 || kind == FIFFV_QUAT_1 || kind == FIFFV_QUAT_2
113 || kind == FIFFV_QUAT_3 || kind == FIFFV_QUAT_4 || kind == FIFFV_QUAT_5
114 || kind == FIFFV_QUAT_6 || kind == FIFFV_HPI_G || kind == FIFFV_HPI_ERR || kind == FIFFV_HPI_MOV)
115 return "chpi"; // channels relative to head position monitoring
116 qWarning("Unknown channel type\n"); //ToDo Throw
117 return "";
118}
119
120//=============================================================================================================
121
123{
124 filename = "";
125 meas_id.clear();
126 nchan = -1;
127 chs.clear();
128 ch_names.clear();
129 dev_head_t.clear();
130 ctf_head_t.clear();
131 bads.clear();
132}
133
134//=============================================================================================================
135
136RowVectorXi FiffInfoBase::pick_types(const QString meg, bool eeg, bool stim, const QStringList& include, const QStringList& exclude) const
137{
138 RowVectorXi pick = RowVectorXi::Zero(this->nchan);
139
140 fiff_int_t kind;
141 qint32 k;
142 for(k = 0; k < this->nchan; ++k)
143 {
144 kind = this->chs[k].kind;
145
146 if ((kind == FIFFV_MEG_CH || kind == FIFFV_REF_MEG_CH))
147 {
148 if(meg.compare("all") == 0) {
149 pick(k) = 1;
150 } else if(meg.compare("grad") == 0 && this->chs[k].unit == FIFF_UNIT_T_M) {
151 pick(k) = 1;
152 } else if(meg.compare("mag") == 0 && this->chs[k].unit == FIFF_UNIT_T) {
153 pick(k) = 1;
154 }
155 }
156 else if (kind == FIFFV_EEG_CH && eeg)
157 pick(k) = 1;
158 else if (kind == FIFFV_STIM_CH && stim)
159 pick(k) = 1;
160 }
161
162 // restrict channels to selection if provided
163 qint32 p = 0;
164 QStringList myinclude;
165 for(k = 0; k < this->nchan; ++k)
166 {
167 if (pick(0, k))
168 {
169 myinclude << this->ch_names[k];
170 ++p;
171 }
172 }
173
174 if (include.size() > 0)
175 {
176 for (k = 0; k < include.size(); ++k)
177 {
178 myinclude << include[k];
179 ++p;
180 }
181 }
182
183 RowVectorXi sel;
184 if (p != 0)
185 sel = FiffInfoBase::pick_channels(this->ch_names, myinclude, exclude);
186
187 return sel;
188}
189
190//=============================================================================================================
191
192RowVectorXi FiffInfoBase::pick_types(bool meg, bool eeg, bool stim, const QStringList& include, const QStringList& exclude) const
193{
194 if(meg)
195 return this->pick_types(QString("all"), eeg, stim, include, exclude);
196 else
197 return this->pick_types(QString(""), eeg, stim, include, exclude);
198}
199
200//=============================================================================================================
201
202RowVectorXi FiffInfoBase::pick_channels(const QStringList& ch_names, const QStringList& include, const QStringList& exclude)
203{
204 RowVectorXi sel = RowVectorXi::Zero(ch_names.size());
205
206 QStringList t_includedSelection;
207
208 qint32 count = 0;
209 for(qint32 k = 0; k < ch_names.size(); ++k)
210 {
211 if( (include.size() == 0 || include.contains(ch_names[k])) && !exclude.contains(ch_names[k]))
212 {
213 //make sure channel is unique
214 if(!t_includedSelection.contains(ch_names[k]))
215 {
216 sel[count] = k;
217 ++count;
218 t_includedSelection << ch_names[k];
219 }
220 }
221 }
222 sel.conservativeResize(count);
223 return sel;
224}
225
226//=============================================================================================================
227
228FiffInfoBase FiffInfoBase::pick_info(const RowVectorXi* sel) const
229{
230 FiffInfoBase res = *this;//new FiffInfo(this);
231 if (sel == nullptr)
232 return res;
233
234 //ToDo when pointer List do deletion
235 res.chs.clear();
236 res.ch_names.clear();
237
238 qint32 idx;
239 for(qint32 i = 0; i < sel->size(); ++i)
240 {
241 idx = (*sel)(0,i);
242 res.chs.append(this->chs[idx]);
243 res.ch_names.append(this->ch_names[idx]);
244 }
245 res.nchan = sel->size();
246
247 return res;
248}
249//=============================================================================================================
250
252 int& nmegp,
253 QList<FiffChInfo>& meg_compp,
254 int& nmeg_compp,
255 QList<FiffChInfo>& eegp,
256 int& neegp,
257 FiffCoordTrans& meg_head_t,
258 FiffId& idp) const
259{
260 for (int k = 0; k < nchan; k++) {
261 if (chs[k].kind == FIFFV_MEG_CH) {
262 megp.append(chs[k]);
263 nmegp++;
264 } else if (chs[k].kind == FIFFV_REF_MEG_CH) {
265 meg_compp.append(chs[k]);
266 nmeg_compp++;
267 } else if (chs[k].kind == FIFFV_EEG_CH) {
268 eegp.append(chs[k]);
269 neegp++;
270 }
271 }
272 meg_head_t = dev_head_t;
273 idp = meas_id;
274}
275
276//=============================================================================================================
277
279{
280 QStringList lChannelTypes;
281
282 for(int i = 0; i < chs.size(); ++i)
283 {
284 switch(chs.at(i).kind) {
285 case FIFFV_MEG_CH: {
286 if( chs.at(i).unit == FIFF_UNIT_T_M ) { //Gradiometers
287 if(!lChannelTypes.contains("grad")) {
288 lChannelTypes << "grad";
289 }
290 } else if( chs.at(i).unit == FIFF_UNIT_T ) { //Magnetometers
291 if(!lChannelTypes.contains("mag")) {
292 lChannelTypes << "mag";
293 }
294 }
295 break;
296 }
297
298 case FIFFV_REF_MEG_CH: {
299 if(!lChannelTypes.contains("ref_meg")) {
300 lChannelTypes << "ref_meg";
301 }
302 break;
303 }
304
305 case FIFFV_EEG_CH: { //EEG Channels
306 if(!lChannelTypes.contains("eeg")) {
307 lChannelTypes << "eeg";
308 }
309 break;
310 }
311
312 case FIFFV_ECG_CH: { //ECG Channels
313 if(!lChannelTypes.contains("ecg")) {
314 lChannelTypes << "ecg";
315 }
316 break;
317 }
318 case FIFFV_EMG_CH: { //EMG Channels
319 if(!lChannelTypes.contains("emg")) {
320 lChannelTypes << "emg";
321 }
322 break;
323 }
324 case FIFFV_EOG_CH: { //EOG Channels
325 if(!lChannelTypes.contains("eog")) {
326 lChannelTypes << "eog";
327 }
328 break;
329 }
330
331 case FIFFV_STIM_CH: { //STIM Channels
332 if(!lChannelTypes.contains("stim")) {
333 lChannelTypes << "stim";
334 }
335 break;
336 }
337
338 case FIFFV_MISC_CH: { //MISC Channels
339 if(!lChannelTypes.contains("misc")) {
340 lChannelTypes << "misc";
341 }
342 break;
343 }
344 }
345 }
346
347 return lChannelTypes;
348}
349
350//=============================================================================================================
351
352bool FiffInfoBase::readBadChannelsFromFile(const QString& name, QStringList& listOut)
353{
354 if (name.isEmpty()) {
355 listOut.clear();
356 return true;
357 }
358
359 QFile file(name);
360 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
361 qCritical() << "Cannot open bad channel file:" << name;
362 return false;
363 }
364
365 QStringList list;
366 QTextStream in(&file);
367 while (!in.atEnd()) {
368 QString line = in.readLine().trimmed();
369 if (line.isEmpty() || line.startsWith('#'))
370 continue;
371 list.append(line);
372 }
373
374 if (file.error() != QFileDevice::NoError) {
375 qCritical() << "Error reading bad channel file:" << name;
376 return false;
377 }
378
379 listOut = list;
380 return true;
381}
#define FIFFV_EOG_CH
#define FIFFV_QUAT_0
#define FIFFV_EEG_CH
#define FIFFV_QUAT_1
#define FIFFV_QUAT_2
#define FIFFV_HPI_ERR
#define FIFFV_QUAT_5
#define FIFFV_REF_MEG_CH
#define FIFFV_MISC_CH
#define FIFFV_MEG_CH
#define FIFFV_HPI_G
#define FIFFV_QUAT_3
#define FIFFV_STIM_CH
#define FIFF_UNIT_T
#define FIFFV_QUAT_6
#define FIFFV_HPI_MOV
#define FIFFV_EMG_CH
#define FIFFV_ECG_CH
#define FIFF_UNIT_T_M
#define FIFFV_QUAT_4
FiffInfoBase class declaration.
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
qint32 fiff_int_t
Definition fiff_types.h:89
Coordinate transformation description.
Universally unique identifier.
Definition fiff_id.h:68
static Eigen::RowVectorXi pick_channels(const QStringList &ch_names, const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList)
QString channel_type(qint32 idx) const
QList< FiffChInfo > chs
FiffInfoBase pick_info(const Eigen::RowVectorXi *sel=nullptr) const
FiffCoordTrans ctf_head_t
QStringList get_channel_types()
Eigen::RowVectorXi pick_types(const QString meg, bool eeg=false, bool stim=false, const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList) const
void mne_read_meg_comp_eeg_ch_info(QList< FiffChInfo > &megp, int &nmegp, QList< FiffChInfo > &meg_compp, int &nmeg_compp, QList< FiffChInfo > &eegp, int &neegp, FiffCoordTrans &meg_head_t, FiffId &idp) const
static bool readBadChannelsFromFile(const QString &name, QStringList &listOut)
FiffCoordTrans dev_head_t