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