MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
mne_raw_info.cpp
Go to the documentation of this file.
1//=============================================================================================================
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "mne_raw_info.h"
42
43#include <fiff/fiff_tag.h>
44
45#include <Eigen/Core>
46
47#include <QFile>
48
49#ifndef TRUE
50#define TRUE 1
51#endif
52
53#ifndef FALSE
54#define FALSE 0
55#endif
56
57#define FREE_33(x) if ((char *)(x) != NULL) free((char *)(x))
58
59#define MALLOC_33(x,t) (t *)malloc((x)*sizeof(t))
60
61//=============================================================================================================
62// USED NAMESPACES
63//=============================================================================================================
64
65using namespace Eigen;
66using namespace FIFFLIB;
67using namespace MNELIB;
68
69//=============================================================================================================
70// DEFINE MEMBER METHODS
71//=============================================================================================================
72
76
77//=============================================================================================================
78
80{
81 this->filename.clear();
82 FREE_33(this->trans);
83// FREE_33(this->rawDir);
84 FREE_33(this->id);
85}
86
87//=============================================================================================================
88
89FiffDirNode::SPtr MneRawInfo::find_meas(const FiffDirNode::SPtr &node)
90/*
91 * Find corresponding meas node
92 */
93{
94 FiffDirNode::SPtr empty_node;
95 FiffDirNode::SPtr tmp_node = node;
96
97 while (tmp_node->type != FIFFB_MEAS) {
98 if (tmp_node->parent == NULL)
99 return empty_node;//(NULL);
100 tmp_node = tmp_node->parent;
101 }
102 return (tmp_node);
103}
104
105//=============================================================================================================
106
107FiffDirNode::SPtr MneRawInfo::find_meas_info(const FiffDirNode::SPtr &node)
108/*
109 * Find corresponding meas info node
110 */
111{
112 int k;
113 FiffDirNode::SPtr empty_node;
114 FiffDirNode::SPtr tmp_node = node;
115
116 while (tmp_node->type != FIFFB_MEAS) {
117 if (tmp_node->parent == NULL)
118 return empty_node;
119 tmp_node = tmp_node->parent;
120 }
121 for (k = 0; k < tmp_node->nchild(); k++)
122 if (tmp_node->children[k]->type == FIFFB_MEAS_INFO)
123 return (tmp_node->children[k]);
124 return empty_node;
125}
126
127//=============================================================================================================
128
129FiffDirNode::SPtr MneRawInfo::find_raw(const FiffDirNode::SPtr &node)
130/*
131 * Find the raw data
132 */
133{
135 QList<FiffDirNode::SPtr> temp;
136 temp = node->dir_tree_find(FIFFB_RAW_DATA);
137 if (temp.size() == 0) {
138 temp = node->dir_tree_find(FIFFB_CONTINUOUS_DATA);
139 if (temp.size() > 0)
140 raw = temp[0];
141 }
142 else
143 raw = temp[0];
144 return raw;
145}
146
147//=============================================================================================================
148
149FiffDirNode::SPtr MneRawInfo::find_maxshield(const FiffDirNode::SPtr &node)
150
151{
153 QList<FiffDirNode::SPtr> temp;
154 temp = node->dir_tree_find(FIFFB_SMSH_RAW_DATA);
155 if (temp.size() > 0)
156 raw = temp[0];
157 return (raw);
158}
159
160//=============================================================================================================
161
162int MneRawInfo::get_meas_info(FiffStream::SPtr &stream,
163 FiffDirNode::SPtr &node,
164 fiffId *id,
165 int *nchan,
166 float *sfreq,
167 float *highpass,
168 float *lowpass,
169 QList<FiffChInfo>& chp,
170 FiffCoordTransOld **trans,
171 fiffTime *start_time) /* Measurement date (starting time) */
172/*
173 * Find channel information from
174 * nearest FIFFB_MEAS_INFO parent of
175 * node.
176 */
177{
178 FiffTag::SPtr t_pTag;
179 // fiffTagRec tag;
180 // fiffDirEntry this_ent;
181 QList<FiffChInfo> ch;
182 FiffChInfo this_ch;
183 FiffCoordTransOld* t = nullptr;
184 int j,k;
185 int to_find = 4;
186 QList<FiffDirNode::SPtr> hpi;
188 fiff_int_t kind, pos;
189
190 // tag.data = NULL;
191 *trans = NULL;
192 *id = NULL;
193 *start_time = NULL;
194 /*
195 * Find desired parents
196 */
197 // meas = node->dir_tree_find(FIFFB_MEAS);
198 if (!(meas = find_meas(node))) {
199 // if (meas.size() == 0) {
200 printf ("Meas. block not found!");
201 goto bad;
202 }
203
204 // meas_info = node->dir_tree_find(FIFFB_MEAS_INFO);
205 if (!(node = find_meas_info(node))) {
206 // if (meas_info.count() == 0) {
207 printf ("Meas. info not found!");
208 goto bad;
209 }
210 /*
211 * Is there a block id is in the FIFFB_MEAS node?
212 */
213 // if (meas->id != NULL) {
214 if (!meas->id.isEmpty()) {
215 *id = MALLOC_33(1,fiffIdRec);
216 // memcpy (*id,meas[0]->id,sizeof(fiffIdRec));
217 (*id)->version = meas->id.version;
218 (*id)->machid[0] = meas->id.machid[0];
219 (*id)->machid[1] = meas->id.machid[1];
220 (*id)->time = meas->id.time;
221 }
222 /*
223 * Others from FIFFB_MEAS_INFO
224 */
225 *lowpass = -1;
226 *highpass = -1;
227 for (k = 0; k < node->nent(); k++) {
228 kind = node->dir[k]->kind;
229 pos = node->dir[k]->pos;
230 switch (kind) {
231
232 case FIFF_NCHAN :
233 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
234 // goto bad;
235 // *nchan = *(int *)(tag.data);
236 if (!stream->read_tag(t_pTag,pos))
237 goto bad;
238 *nchan = *t_pTag->toInt();
239
240 for (j = 0; j < *nchan; j++) {
241 ch.append(FiffChInfo());
242 ch[j].scanNo = -1;
243 }
244 to_find = to_find + *nchan - 1;
245 break;
246
247 case FIFF_SFREQ :
248 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
249 // goto bad;
250 // *sfreq = *(float *)(tag.data);
251 if (!stream->read_tag(t_pTag,pos))
252 goto bad;
253 *sfreq = *t_pTag->toFloat();
254 to_find--;
255 break;
256
257 case FIFF_LOWPASS :
258 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
259 // goto bad;
260 // *lowpass = *(float *)(tag.data);
261 if (!stream->read_tag(t_pTag,pos))
262 goto bad;
263 *lowpass = *t_pTag->toFloat();
264 to_find--;
265 break;
266
267 case FIFF_HIGHPASS :
268 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
269 // goto bad;
270 // *highpass = *(float *)(tag.data);
271 if (!stream->read_tag(t_pTag,pos))
272 goto bad;
273 *highpass = *t_pTag->toFloat();
274 to_find--;
275 break;
276
277 case FIFF_CH_INFO : /* Information about one channel */
278 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
279 // goto bad;
280 // this_ch = (fiffChInfo)(tag.data);
281 if (!stream->read_tag(t_pTag,pos))
282 goto bad;
283
284 this_ch = t_pTag->toChInfo();
285 if (this_ch.scanNo <= 0 || this_ch.scanNo > *nchan) {
286 qCritical ("FIFF_CH_INFO : scan # out of range!");
287 goto bad;
288 }
289 else
290 ch[this_ch.scanNo-1] = this_ch;
291 to_find--;
292 break;
293
294 case FIFF_MEAS_DATE :
295 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
296 // goto bad;
297 if (!stream->read_tag(t_pTag,pos))
298 goto bad;
299 if (*start_time)
300 FREE_33(*start_time);
301 // *start_time = (fiffTime)tag.data;
302 *start_time = (fiffTime)t_pTag->data();
303 // tag.data = NULL;
304 break;
305
306 case FIFF_COORD_TRANS :
307 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
308 // goto bad;
309 // t = (fiffCoordTrans)tag.data;
310 if (!stream->read_tag(t_pTag,pos))
311 goto bad;
312 if(t)
313 delete t;
314 t = FiffCoordTransOld::read_helper( t_pTag );
315 /*
316 * Require this particular transform!
317 */
318 if (t->from == FIFFV_COORD_DEVICE && t->to == FIFFV_COORD_HEAD) {
319 *trans = t;
320 // tag.data = NULL;
321 break;
322 }
323 }
324 }
325 /*
326 * Search for the coordinate transformation from
327 * HPI_RESULT block if it was not previously found
328 */
329 // hpi = fiff_dir_tree_find(node,FIFFB_HPI_RESULT);
330 // node = hpi[0];
331
332 hpi = node->dir_tree_find(FIFFB_HPI_RESULT);
333 node = hpi[0];
334
335 // FREE_33(hpi);
336 if (hpi.size() > 0 && *trans == NULL)
337 for (k = 0; k < hpi[0]->nent(); k++)
338 if (hpi[0]->dir[k]->kind == FIFF_COORD_TRANS) {
339 // if (fiff_read_this_tag (file->fd,this_ent->pos,&tag) == -1)
340 // goto bad;
341 // t = (fiffCoordTrans)tag.data;
342 if (!stream->read_tag(t_pTag,hpi[0]->dir[k]->pos))
343 goto bad;
344 t = FiffCoordTransOld::read_helper( t_pTag );
345 /*
346 * Require this particular transform!
347 */
348 if (t->from == FIFFV_COORD_DEVICE && t->to == FIFFV_COORD_HEAD) {
349 *trans = t;
350 // tag.data = NULL;
351 break;
352 }
353 }
354 if (to_find < 3) {
355 if (*lowpass < 0) {
356 *lowpass = *sfreq/2.0;
357 to_find--;
358 }
359 if (*highpass < 0) {
360 *highpass = 0.0;
361 to_find--;
362 }
363 }
364 if (to_find != 0) {
365 printf ("Not all essential tags were found!");
366 goto bad;
367 }
368 // FREE_33(tag.data);
369 chp = ch;
370 return (0);
371
372bad : {
373 // FREE_33(tag.data);
374 return (-1);
375 }
376}
377
378//=============================================================================================================
379
380int MneRawInfo::mne_load_raw_info(const QString& name, int allow_maxshield, MneRawInfo **infop)
381/*
382 * Load raw data information from a fiff file
383 */
384{
385 QFile file(name);
386 FiffStream::SPtr stream(new FiffStream(&file));
387
388 // fiffFile in = NULL;
389
390 int res = FIFF_FAIL;
391 QList<FiffChInfo> chs; /* Channel info */
392 FiffCoordTransOld* trans = NULL; /* The coordinate transformation */
393 fiffId id = NULL; /* Measurement id */
394 QList<FiffDirEntry::SPtr> rawDir; /* Directory of raw data tags */
395 MneRawInfo* info = NULL;
396 int nchan = 0; /* Number of channels */
397 float sfreq = 0.0; /* Sampling frequency */
398 float highpass; /* Highpass filter frequency */
399 float lowpass; /* Lowpass filter frequency */
401 // FiffDirEntry one;
402 fiffTime start_time = NULL;
403 int k;
404 int maxshield_data = FALSE;
405 /*
406 * Open file
407 */
408 // if ((in = fiff_open(name)) == NULL)
409 // goto out;
410 if(!stream->open())
411 goto out;
412 raw = find_raw(stream->dirtree());
413 if (raw->isEmpty()) {
414 if (allow_maxshield) {
415 raw = find_maxshield(stream->dirtree());
416 if (raw->isEmpty()) {
417 printf("No raw data in this file.");
418 goto out;
419 }
420 maxshield_data = TRUE;
421 }
422 else {
423 printf("No raw data in this file.");
424 goto out;
425 }
426 }
427 /*
428 * Get the essential measurement information
429 */
430 if (get_meas_info (stream,
431 raw,
432 &id,
433 &nchan,
434 &sfreq,
435 &highpass,
436 &lowpass,
437 chs,
438 &trans,
439 &start_time) < 0)
440 goto out;
441 /*
442 * Get the raw directory
443 */
444 // rawDir = MALLOC_33(raw->nent,fiffDirEntryRec);
445 // memcpy(rawDir,raw->dir,raw->nent*sizeof(fiffDirEntryRec));
446 rawDir = raw->dir;
447 /*
448 * Ready to put everything together
449 */
450 info = new MneRawInfo();
451 info->filename = name;
452 info->nchan = nchan;
453 info->chInfo = chs;
454 info->coord_frame = FIFFV_COORD_DEVICE;
455 info->trans = trans;
456 info->sfreq = sfreq;
457 info->lowpass = lowpass;
458 info->highpass = highpass;
459 // info->rawDir = NULL;
461 if (id) {
462 info->id = MALLOC_33(1,fiffIdRec);
463 *info->id = *id;
464 }
465 else
466 info->id = NULL;
467 /*
468 * Getting starting time from measurement ID is not too accurate...
469 */
470 if (start_time)
471 info->start_time = *start_time;
472 else {
473 if (id)
474 info->start_time = id->time;
475 else {
476 info->start_time.secs = 0;
477 info->start_time.usecs = 0;
478 }
479 }
480 info->buf_size = 0;
481 // for (k = 0, one = raw->dir; k < raw->nent; k++, one++) {
482 for (k = 0; k < raw->nent(); k++) {
483 // raw->dir[k]->kind
484 // raw->dir[k]->type
485 // raw->dir[k].size
486 if (raw->dir[k]->kind == FIFF_DATA_BUFFER) {
487 if (raw->dir[k]->type == FIFFT_DAU_PACK16 || raw->dir[k]->type == FIFFT_SHORT)
488 info->buf_size = raw->dir[k]->size/(nchan*sizeof(fiff_short_t));
489 else if (raw->dir[k]->type == FIFFT_FLOAT)
490 info->buf_size = raw->dir[k]->size/(nchan*sizeof(fiff_float_t));
491 else if (raw->dir[k]->type == FIFFT_INT)
492 info->buf_size = raw->dir[k]->size/(nchan*sizeof(fiff_int_t));
493 else {
494 printf("We are not prepared to handle raw data type: %d",raw->dir[k]->type);
495 goto out;
496 }
497 break;
498 }
499 }
500 if (info->buf_size <= 0) {
501 printf("No raw data buffers available.");
502 goto out;
503 }
504 info->rawDir = rawDir;
505 info->ndir = raw->nent();
506 *infop = info;
507 res = FIFF_OK;
508
509out : {
510 if (res != FIFF_OK) {
511 FREE_33(trans);
512 // FREE_33(rawDir);
513 FREE_33(info);
514 }
515 FREE_33(id);
516 // fiff_close(in);
517 stream->close();
518 return (res);
519 }
520}
FiffTag class declaration, which provides fiff tag I/O and processing methods.
int k
Definition fiff_tag.cpp:324
#define FIFF_DATA_BUFFER
Definition fiff_file.h:556
#define FIFF_NCHAN
Definition fiff_file.h:453
#define FIFF_HIGHPASS
Definition fiff_file.h:476
#define FIFFB_SMSH_RAW_DATA
Definition fiff_file.h:382
#define FIFF_COORD_TRANS
Definition fiff_file.h:475
#define FIFF_MEAS_DATE
Definition fiff_file.h:457
#define FIFF_CH_INFO
Definition fiff_file.h:456
#define FIFF_LOWPASS
Definition fiff_file.h:472
#define FIFF_SFREQ
Definition fiff_file.h:454
MneRawInfo class declaration.
Coordinate transformation descriptor.
ToDo Old implementation use new fiff_id.h instead.
Channel info descriptor.
QSharedPointer< FiffDirNode > SPtr
FIFF File I/O routines.
QSharedPointer< FiffStream > SPtr
QSharedPointer< FiffTag > SPtr
Definition fiff_tag.h:152
Information about raw data in fiff file.
FIFFLIB::fiffId id
QList< FIFFLIB::FiffChInfo > chInfo
FIFFLIB::FiffCoordTransOld * trans
QList< FIFFLIB::FiffDirEntry::SPtr > rawDir
FIFFLIB::fiffTimeRec start_time