v2.0.0
Loading...
Searching...
No Matches
mne_raw_info.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
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#include <QDebug>
49
50//=============================================================================================================
51// USED NAMESPACES
52//=============================================================================================================
53
54using namespace Eigen;
55using namespace FIFFLIB;
56using namespace MNELIB;
57
58//=============================================================================================================
59// DEFINE MEMBER METHODS
60//=============================================================================================================
61
63: nchan(0)
64, coord_frame(0)
65, sfreq(0.0f)
66, lowpass(0.0f)
67, highpass(0.0f)
68, buf_size(0)
70, ndir(0)
71{
72}
73
74//=============================================================================================================
75
79
80//=============================================================================================================
81
83{
84 FiffDirNode::SPtr empty_node;
85 FiffDirNode::SPtr tmp_node = node;
86
87 while (tmp_node->type != FIFFB_MEAS) {
88 if (tmp_node->parent == nullptr)
89 return empty_node;
90 tmp_node = tmp_node->parent;
91 }
92 return tmp_node;
93}
94
95//=============================================================================================================
96
98{
99 int k;
100 FiffDirNode::SPtr empty_node;
101 FiffDirNode::SPtr tmp_node = node;
102
103 while (tmp_node->type != FIFFB_MEAS) {
104 if (tmp_node->parent == nullptr)
105 return empty_node;
106 tmp_node = tmp_node->parent;
107 }
108 for (k = 0; k < tmp_node->nchild(); k++)
109 if (tmp_node->children[k]->type == FIFFB_MEAS_INFO)
110 return (tmp_node->children[k]);
111 return empty_node;
112}
113
114//=============================================================================================================
115
117{
119 QList<FiffDirNode::SPtr> temp;
120 temp = node->dir_tree_find(FIFFB_RAW_DATA);
121 if (temp.size() == 0) {
122 temp = node->dir_tree_find(FIFFB_CONTINUOUS_DATA);
123 if (temp.size() > 0)
124 raw = temp[0];
125 }
126 else
127 raw = temp[0];
128 return raw;
129}
130
131//=============================================================================================================
132
134
135{
137 QList<FiffDirNode::SPtr> temp;
138 temp = node->dir_tree_find(FIFFB_SMSH_RAW_DATA);
139 if (temp.size() > 0)
140 raw = temp[0];
141 return (raw);
142}
143
144//=============================================================================================================
145
147 FiffDirNode::SPtr &node,
148 std::unique_ptr<FiffId>& id,
149 int *nchan,
150 float *sfreq,
151 float *highpass,
152 float *lowpass,
153 QList<FiffChInfo>& chp,
155{
156 FiffTime dummy;
157 return get_meas_info(stream, node, id, nchan, sfreq, highpass, lowpass, chp, trans, dummy);
158}
159
160//=============================================================================================================
161
163 FiffDirNode::SPtr &node,
164 std::unique_ptr<FiffId>& id,
165 int *nchan,
166 float *sfreq,
167 float *highpass,
168 float *lowpass,
169 QList<FiffChInfo>& chp,
172{
173 FiffTag::UPtr t_pTag;
174 QList<FiffChInfo> ch;
175 FiffChInfo this_ch;
177 int j,k;
178 int to_find = 4;
179 QList<FiffDirNode::SPtr> hpi;
181 FiffDirNode::SPtr meas_info;
182 fiff_int_t kind, pos;
183 bool found_meas_date = false;
184
186 id.reset();
188 /*
189 * Find desired parents
190 */
191 if (!(meas = find_meas(node))) {
192 qCritical ("Meas. block not found!");
193 return (-1);
194 }
195
196 if (!(meas_info = find_meas_info(node))) {
197 qCritical ("Meas. info not found!");
198 return (-1);
199 }
200 /*
201 * Is there a block id is in the FIFFB_MEAS node?
202 */
203 if (!meas->id.isEmpty()) {
204 id = std::make_unique<FiffId>();
205 id->version = meas->id.version;
206 id->machid[0] = meas->id.machid[0];
207 id->machid[1] = meas->id.machid[1];
208 id->time = meas->id.time;
209 }
210 /*
211 * Others from FIFFB_MEAS_INFO
212 */
213 *lowpass = -1;
214 *highpass = -1;
215 for (k = 0; k < meas_info->nent(); k++) {
216 kind = meas_info->dir[k]->kind;
217 pos = meas_info->dir[k]->pos;
218 switch (kind) {
219
220 case FIFF_NCHAN :
221 if (!stream->read_tag(t_pTag,pos))
222 return (-1);
223 *nchan = *t_pTag->toInt();
224
225 for (j = 0; j < *nchan; j++) {
226 ch.append(FiffChInfo());
227 ch[j].scanNo = -1;
228 }
229 to_find = to_find + *nchan - 1;
230 break;
231
232 case FIFF_SFREQ :
233 if (!stream->read_tag(t_pTag,pos))
234 return (-1);
235 *sfreq = *t_pTag->toFloat();
236 to_find--;
237 break;
238
239 case FIFF_LOWPASS :
240 if (!stream->read_tag(t_pTag,pos))
241 return (-1);
242 *lowpass = *t_pTag->toFloat();
243 to_find--;
244 break;
245
246 case FIFF_HIGHPASS :
247 if (!stream->read_tag(t_pTag,pos))
248 return (-1);
249 *highpass = *t_pTag->toFloat();
250 to_find--;
251 break;
252
253 case FIFF_CH_INFO :
254 if (!stream->read_tag(t_pTag,pos))
255 return (-1);
256
257 this_ch = t_pTag->toChInfo();
258 if (this_ch.scanNo <= 0 || this_ch.scanNo > *nchan) {
259 qCritical ("FIFF_CH_INFO : scan # out of range!");
260 return (-1);
261 }
262 else
263 ch[this_ch.scanNo-1] = this_ch;
264 to_find--;
265 break;
266
267 case FIFF_MEAS_DATE :
268 if (!stream->read_tag(t_pTag,pos))
269 return (-1);
270 {
271 const FiffTime* pTime = reinterpret_cast<const FiffTime*>(t_pTag->data());
272 start_time = FiffTime(pTime->secs, pTime->usecs);
273 found_meas_date = true;
274 }
275 break;
276
277 case FIFF_COORD_TRANS :
278 if (!stream->read_tag(t_pTag,pos))
279 return (-1);
280 t = FiffCoordTrans::readFromTag( t_pTag );
281 /*
282 * Require this particular transform!
283 */
284 if (t.from == FIFFV_COORD_DEVICE && t.to == FIFFV_COORD_HEAD) {
285 trans = t;
286 break;
287 }
288 }
289 }
290 /*
291 * Search for the coordinate transformation from
292 * HPI_RESULT block if it was not previously found
293 */
294 hpi = meas_info->dir_tree_find(FIFFB_HPI_RESULT);
295
296 if (hpi.size() > 0 && trans.isEmpty())
297 for (k = 0; k < hpi[0]->nent(); k++)
298 if (hpi[0]->dir[k]->kind == FIFF_COORD_TRANS) {
299 if (!stream->read_tag(t_pTag,hpi[0]->dir[k]->pos))
300 return (-1);
301 t = FiffCoordTrans::readFromTag( t_pTag );
302 if (t.from == FIFFV_COORD_DEVICE && t.to == FIFFV_COORD_HEAD) {
303 trans = t;
304 break;
305 }
306 }
307 if (to_find < 3) {
308 if (*lowpass < 0) {
309 *lowpass = *sfreq/2.0;
310 to_find--;
311 }
312 if (*highpass < 0) {
313 *highpass = 0.0;
314 to_find--;
315 }
316 }
317 if (to_find != 0) {
318 qCritical ("Not all essential tags were found!");
319 return (-1);
320 }
321 chp = ch;
322 /*
323 * Resolve the measurement start time using the best available source
324 */
325 if (!found_meas_date) {
326 if (id)
327 start_time = id->time;
328 else
330 }
331 return (0);
332}
333
334//=============================================================================================================
335
336int MNERawInfo::load(const QString& name, int allow_maxshield, std::unique_ptr<MNERawInfo>& infop)
337{
338 QFile file(name);
339 FiffStream::SPtr stream(new FiffStream(&file));
340
341 int res = FIFF_FAIL;
342 QList<FiffChInfo> chs; /* Channel info */
343 FiffCoordTrans trans; /* The coordinate transformation */
344 std::unique_ptr<FiffId> id; /* Measurement id */
345 QList<FiffDirEntry::SPtr> rawDir; /* Directory of raw data tags */
346 std::unique_ptr<MNERawInfo> info;
347 int nchan = 0; /* Number of channels */
348 float sfreq = 0.0; /* Sampling frequency */
349 float highpass; /* Highpass filter frequency */
350 float lowpass; /* Lowpass filter frequency */
353 int k;
354 int maxshield_data = false;
355 /*
356 * Open file
357 */
358 if(!stream->open()) {
359 stream->close(); return FIFF_FAIL;
360 }
361 raw = find_raw(stream->dirtree());
362 if (raw->isEmpty()) {
363 if (allow_maxshield) {
364 raw = find_maxshield(stream->dirtree());
365 if (raw->isEmpty()) {
366 qCritical("No raw data in this file.");
367 stream->close(); return FIFF_FAIL;
368 }
369 maxshield_data = true;
370 }
371 else {
372 qCritical("No raw data in this file.");
373 stream->close(); return FIFF_FAIL;
374 }
375 }
376 /*
377 * Get the essential measurement information
378 */
379 if (get_meas_info (stream,
380 raw,
381 id,
382 &nchan,
383 &sfreq,
384 &highpass,
385 &lowpass,
386 chs,
387 trans,
388 start_time) < 0) {
389 stream->close(); return FIFF_FAIL;
390 }
391 /*
392 * Get the raw directory
393 */
394 rawDir = raw->dir;
395 /*
396 * Ready to put everything together
397 */
398 info = std::make_unique<MNERawInfo>();
399 info->filename = name;
400 info->nchan = nchan;
401 info->chInfo = chs;
402 info->coord_frame = FIFFV_COORD_DEVICE;
403 info->trans = std::make_unique<FiffCoordTrans>(trans);
404 info->sfreq = sfreq;
405 info->lowpass = lowpass;
406 info->highpass = highpass;
407 info->maxshield_data = maxshield_data;
408 if (id) {
409 info->id = std::make_unique<FiffId>(*id);
410 }
411 /*
412 * Getting starting time from measurement ID is not too accurate...
413 */
414 info->start_time = start_time;
415 info->buf_size = 0;
416 for (k = 0; k < raw->nent(); k++) {
417 if (raw->dir[k]->kind == FIFF_DATA_BUFFER) {
418 if (raw->dir[k]->type == FIFFT_DAU_PACK16 || raw->dir[k]->type == FIFFT_SHORT)
419 info->buf_size = raw->dir[k]->size/(nchan*sizeof(fiff_short_t));
420 else if (raw->dir[k]->type == FIFFT_FLOAT)
421 info->buf_size = raw->dir[k]->size/(nchan*sizeof(fiff_float_t));
422 else if (raw->dir[k]->type == FIFFT_INT)
423 info->buf_size = raw->dir[k]->size/(nchan*sizeof(fiff_int_t));
424 else {
425 qCritical("We are not prepared to handle raw data type: %d",raw->dir[k]->type);
426 stream->close(); return FIFF_FAIL;
427 }
428 break;
429 }
430 }
431 if (info->buf_size <= 0) {
432 qCritical("No raw data buffers available.");
433 stream->close(); return FIFF_FAIL;
434 }
435 info->rawDir = rawDir;
436 info->ndir = raw->nent();
437 infop = std::move(info);
438 res = FIFF_OK;
439
440 stream->close();
441 return res;
442}
#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 FIFFT_INT
Definition fiff_file.h:231
#define FIFFT_SHORT
Definition fiff_file.h:230
#define FIFFB_MEAS
Definition fiff_file.h:362
#define FIFFB_RAW_DATA
Definition fiff_file.h:364
#define FIFFB_SMSH_RAW_DATA
Definition fiff_file.h:382
#define FIFFT_DAU_PACK16
Definition fiff_file.h:243
#define FIFF_COORD_TRANS
Definition fiff_file.h:475
#define FIFFT_FLOAT
Definition fiff_file.h:232
#define FIFFB_CONTINUOUS_DATA
Definition fiff_file.h:375
#define FIFF_MEAS_DATE
Definition fiff_file.h:457
#define FIFF_CH_INFO
Definition fiff_file.h:456
#define FIFFB_HPI_RESULT
Definition fiff_file.h:372
#define FIFF_LOWPASS
Definition fiff_file.h:472
#define FIFFB_MEAS_INFO
Definition fiff_file.h:363
#define FIFF_SFREQ
Definition fiff_file.h:454
FiffTag class declaration, which provides fiff tag I/O and processing methods.
#define FIFF_OK
#define FIFFV_COORD_DEVICE
#define FIFF_FAIL
#define FIFFV_COORD_HEAD
MNERawInfo class declaration.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
qint32 fiff_int_t
Definition fiff_types.h:89
float fiff_float_t
Definition fiff_types.h:93
qint16 fiff_short_t
Definition fiff_types.h:87
Channel info descriptor.
Coordinate transformation description.
QSharedPointer< FiffDirNode > SPtr
FIFF File I/O routines.
QSharedPointer< FiffStream > SPtr
std::unique_ptr< FiffTag > UPtr
Definition fiff_tag.h:158
Time stamp record storing seconds and microseconds since epoch.
Definition fiff_time.h:61
FIFFLIB::FiffTime start_time
QList< FIFFLIB::FiffDirEntry::SPtr > rawDir
MNERawInfo()
Constructs a default MNERawInfo.
static FIFFLIB::FiffDirNode::SPtr find_maxshield(const FIFFLIB::FiffDirNode::SPtr &node)
static FIFFLIB::FiffDirNode::SPtr find_meas_info(const FIFFLIB::FiffDirNode::SPtr &node)
static int load(const QString &name, int allow_maxshield, std::unique_ptr< MNERawInfo > &infop)
static int get_meas_info(FIFFLIB::FiffStream::SPtr &stream, FIFFLIB::FiffDirNode::SPtr &node, std::unique_ptr< FIFFLIB::FiffId > &id, int *nchan, float *sfreq, float *highpass, float *lowpass, QList< FIFFLIB::FiffChInfo > &chp, FIFFLIB::FiffCoordTrans &trans, FIFFLIB::FiffTime &start_time)
static FIFFLIB::FiffDirNode::SPtr find_raw(const FIFFLIB::FiffDirNode::SPtr &node)
static FIFFLIB::FiffDirNode::SPtr find_meas(const FIFFLIB::FiffDirNode::SPtr &node)
std::unique_ptr< FIFFLIB::FiffId > id
~MNERawInfo()
Destroys the MNERawInfo and releases owned resources.
std::unique_ptr< FIFFLIB::FiffCoordTrans > trans
static FiffCoordTrans readFromTag(const std::unique_ptr< FiffTag > &tag)