MNE-CPP  0.1.9
A Framework for Electrophysiology
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 
65 using namespace Eigen;
66 using namespace FIFFLIB;
67 using namespace MNELIB;
68 
69 //=============================================================================================================
70 // DEFINE MEMBER METHODS
71 //=============================================================================================================
72 
73 MneRawInfo::MneRawInfo()
74 {
75 }
76 
77 //=============================================================================================================
78 
79 MneRawInfo::~MneRawInfo()
80 {
81  this->filename.clear();
82  FREE_33(this->trans);
83 // FREE_33(this->rawDir);
84  FREE_33(this->id);
85 }
86 
87 //=============================================================================================================
88 
89 FiffDirNode::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 
107 FiffDirNode::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 
129 FiffDirNode::SPtr MneRawInfo::find_raw(const FiffDirNode::SPtr &node)
130 /*
131  * Find the raw data
132  */
133 {
134  FiffDirNode::SPtr raw;
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 
149 FiffDirNode::SPtr MneRawInfo::find_maxshield(const FiffDirNode::SPtr &node)
150 
151 {
152  FiffDirNode::SPtr raw;
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 
162 int 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;
187  FiffDirNode::SPtr meas;
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 
372 bad : {
373  // FREE_33(tag.data);
374  return (-1);
375  }
376 }
377 
378 //=============================================================================================================
379 
380 int 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 */
400  FiffDirNode::SPtr raw;
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;
460  info->maxshield_data = maxshield_data;
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 
509 out : {
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 }
Information about raw data in fiff file.
Definition: mne_raw_info.h:80
FIFFLIB::FiffCoordTransOld * trans
Definition: mne_raw_info.h:134
Channel info descriptor.
Definition: fiff_ch_info.h:74
ToDo Old implementation use new fiff_id.h instead.
Definition: fiff_types.h:218
QList< FIFFLIB::FiffDirEntry::SPtr > rawDir
Definition: mne_raw_info.h:146
QSharedPointer< FiffDirNode > SPtr
Definition: fiff_dir_node.h:77
MneRawInfo class declaration.
#define FIFF_CH_INFO
Definition: fiff_file.h:456
#define FIFF_NCHAN
Definition: fiff_file.h:453
QSharedPointer< FiffTag > SPtr
Definition: fiff_tag.h:152
#define FIFF_HIGHPASS
Definition: fiff_file.h:476
FIFF File I/O routines.
Definition: fiff_stream.h:104
Coordinate transformation descriptor.
#define FIFF_SFREQ
Definition: fiff_file.h:454
#define FIFF_MEAS_DATE
Definition: fiff_file.h:457
#define FIFF_COORD_TRANS
Definition: fiff_file.h:475
#define FIFF_DATA_BUFFER
Definition: fiff_file.h:558
FIFFLIB::fiffId id
Definition: mne_raw_info.h:128
QSharedPointer< FiffStream > SPtr
Definition: fiff_stream.h:107
FiffTag class declaration, which provides fiff tag I/O and processing methods.
#define FIFFB_SMSH_RAW_DATA
Definition: fiff_file.h:382
#define FIFF_LOWPASS
Definition: fiff_file.h:472
QList< FIFFLIB::FiffChInfo > chInfo
Definition: mne_raw_info.h:130
FIFFLIB::fiffTimeRec start_time
Definition: mne_raw_info.h:140