v2.0.0
Loading...
Searching...
No Matches
mne_raw_info.cpp
Go to the documentation of this file.
1//=============================================================================================================
16
17//=============================================================================================================
18// INCLUDES
19//=============================================================================================================
20
21#include "mne_raw_info.h"
22
23#include <fiff/fiff_tag.h>
24
25#include <Eigen/Core>
26
27#include <QFile>
28#include <QDebug>
29
30//=============================================================================================================
31// USED NAMESPACES
32//=============================================================================================================
33
34using namespace Eigen;
35using namespace FIFFLIB;
36using namespace MNELIB;
37
38//=============================================================================================================
39// DEFINE MEMBER METHODS
40//=============================================================================================================
41
43: nchan(0)
44, coord_frame(0)
45, sfreq(0.0f)
46, lowpass(0.0f)
47, highpass(0.0f)
48, buf_size(0)
50, ndir(0)
51{
52}
53
54//=============================================================================================================
55
59
60//=============================================================================================================
61
63{
64 FiffDirNode::SPtr empty_node;
65 FiffDirNode::SPtr tmp_node = node;
66
67 while (tmp_node->type != FIFFB_MEAS) {
68 if (tmp_node->parent == nullptr)
69 return empty_node;
70 tmp_node = tmp_node->parent;
71 }
72 return tmp_node;
73}
74
75//=============================================================================================================
76
78{
79 int k;
80 FiffDirNode::SPtr empty_node;
81 FiffDirNode::SPtr tmp_node = node;
82
83 while (tmp_node->type != FIFFB_MEAS) {
84 if (tmp_node->parent == nullptr)
85 return empty_node;
86 tmp_node = tmp_node->parent;
87 }
88 for (k = 0; k < tmp_node->nchild(); k++)
89 if (tmp_node->children[k]->type == FIFFB_MEAS_INFO)
90 return (tmp_node->children[k]);
91 return empty_node;
92}
93
94//=============================================================================================================
95
97{
99 QList<FiffDirNode::SPtr> temp;
100 temp = node->dir_tree_find(FIFFB_RAW_DATA);
101 if (temp.size() == 0) {
102 temp = node->dir_tree_find(FIFFB_CONTINUOUS_DATA);
103 if (temp.size() > 0)
104 raw = temp[0];
105 } else
106 raw = temp[0];
107 return raw;
108}
109
110//=============================================================================================================
111
113
114{
116 QList<FiffDirNode::SPtr> temp;
117 temp = node->dir_tree_find(FIFFB_SMSH_RAW_DATA);
118 if (temp.size() > 0)
119 raw = temp[0];
120 return (raw);
121}
122
123//=============================================================================================================
124
126 FiffDirNode::SPtr& node,
127 std::unique_ptr<FiffId>& id,
128 int* nchan,
129 float* sfreq,
130 float* highpass,
131 float* lowpass,
132 QList<FiffChInfo>& chp,
134{
135 FiffTime dummy;
136 return get_meas_info(stream, node, id, nchan, sfreq, highpass, lowpass, chp, trans, dummy);
137}
138
139//=============================================================================================================
140
142 FiffDirNode::SPtr& node,
143 std::unique_ptr<FiffId>& id,
144 int* nchan,
145 float* sfreq,
146 float* highpass,
147 float* lowpass,
148 QList<FiffChInfo>& chp,
151{
152 FiffTag::UPtr t_pTag;
153 QList<FiffChInfo> ch;
154 FiffChInfo this_ch;
156 int j, k;
157 int to_find = 4;
158 QList<FiffDirNode::SPtr> hpi;
160 FiffDirNode::SPtr meas_info;
161 fiff_int_t kind, pos;
162 bool found_meas_date = false;
163
165 id.reset();
167 /*
168 * Find desired parents
169 */
170 if (!(meas = find_meas(node))) {
171 qCritical("Meas. block not found!");
172 return (-1);
173 }
174
175 if (!(meas_info = find_meas_info(node))) {
176 qCritical("Meas. info not found!");
177 return (-1);
178 }
179 /*
180 * Is there a block id is in the FIFFB_MEAS node?
181 */
182 if (!meas->id.isEmpty()) {
183 id = std::make_unique<FiffId>();
184 id->version = meas->id.version;
185 id->machid[0] = meas->id.machid[0];
186 id->machid[1] = meas->id.machid[1];
187 id->time = meas->id.time;
188 }
189 /*
190 * Others from FIFFB_MEAS_INFO
191 */
192 *lowpass = -1;
193 *highpass = -1;
194 for (k = 0; k < meas_info->nent(); k++) {
195 kind = meas_info->dir[k]->kind;
196 pos = meas_info->dir[k]->pos;
197 switch (kind) {
198 case FIFF_NCHAN:
199 if (!stream->read_tag(t_pTag, pos))
200 return (-1);
201 *nchan = *t_pTag->toInt();
202
203 for (j = 0; j < *nchan; j++) {
204 ch.append(FiffChInfo());
205 ch[j].scanNo = -1;
206 }
207 to_find = to_find + *nchan - 1;
208 break;
209
210 case FIFF_SFREQ:
211 if (!stream->read_tag(t_pTag, pos))
212 return (-1);
213 *sfreq = *t_pTag->toFloat();
214 to_find--;
215 break;
216
217 case FIFF_LOWPASS:
218 if (!stream->read_tag(t_pTag, pos))
219 return (-1);
220 *lowpass = *t_pTag->toFloat();
221 to_find--;
222 break;
223
224 case FIFF_HIGHPASS:
225 if (!stream->read_tag(t_pTag, pos))
226 return (-1);
227 *highpass = *t_pTag->toFloat();
228 to_find--;
229 break;
230
231 case FIFF_CH_INFO:
232 if (!stream->read_tag(t_pTag, pos))
233 return (-1);
234
235 this_ch = t_pTag->toChInfo();
236 if (this_ch.scanNo <= 0 || this_ch.scanNo > *nchan) {
237 qCritical("FIFF_CH_INFO : scan # out of range!");
238 return (-1);
239 } else
240 ch[this_ch.scanNo - 1] = this_ch;
241 to_find--;
242 break;
243
244 case FIFF_MEAS_DATE:
245 if (!stream->read_tag(t_pTag, pos))
246 return (-1);
247 {
248 const FiffTime* pTime = reinterpret_cast<const FiffTime*>(t_pTag->data());
249 start_time = FiffTime(pTime->secs, pTime->usecs);
250 found_meas_date = true;
251 }
252 break;
253
254 case FIFF_COORD_TRANS:
255 if (!stream->read_tag(t_pTag, pos))
256 return (-1);
257 t = FiffCoordTrans::readFromTag(t_pTag);
258 /*
259 * Require this particular transform!
260 */
261 if (t.from == FIFFV_COORD_DEVICE && t.to == FIFFV_COORD_HEAD) {
262 trans = t;
263 break;
264 }
265 }
266 }
267 /*
268 * Search for the coordinate transformation from
269 * HPI_RESULT block if it was not previously found
270 */
271 hpi = meas_info->dir_tree_find(FIFFB_HPI_RESULT);
272
273 if (hpi.size() > 0 && trans.isEmpty())
274 for (k = 0; k < hpi[0]->nent(); k++)
275 if (hpi[0]->dir[k]->kind == FIFF_COORD_TRANS) {
276 if (!stream->read_tag(t_pTag, hpi[0]->dir[k]->pos))
277 return (-1);
278 t = FiffCoordTrans::readFromTag(t_pTag);
279 if (t.from == FIFFV_COORD_DEVICE && t.to == FIFFV_COORD_HEAD) {
280 trans = t;
281 break;
282 }
283 }
284 if (to_find < 3) {
285 if (*lowpass < 0) {
286 *lowpass = *sfreq / 2.0;
287 to_find--;
288 }
289 if (*highpass < 0) {
290 *highpass = 0.0;
291 to_find--;
292 }
293 }
294 if (to_find != 0) {
295 qCritical("Not all essential tags were found!");
296 return (-1);
297 }
298 chp = ch;
299 /*
300 * Resolve the measurement start time using the best available source
301 */
302 if (!found_meas_date) {
303 if (id)
304 start_time = id->time;
305 else
307 }
308 return (0);
309}
310
311//=============================================================================================================
312
313int MNERawInfo::load(const QString& name, int allow_maxshield, std::unique_ptr<MNERawInfo>& infop)
314{
315 QFile file(name);
316 FiffStream::SPtr stream(new FiffStream(&file));
317
318 int res = FIFF_FAIL;
319 QList<FiffChInfo> chs; /* Channel info */
320 FiffCoordTrans trans; /* The coordinate transformation */
321 std::unique_ptr<FiffId> id; /* Measurement id */
322 QList<FiffDirEntry::SPtr> rawDir; /* Directory of raw data tags */
323 std::unique_ptr<MNERawInfo> info;
324 int nchan = 0; /* Number of channels */
325 float sfreq = 0.0; /* Sampling frequency */
326 float highpass; /* Highpass filter frequency */
327 float lowpass; /* Lowpass filter frequency */
330 int k;
331 int maxshield_data = false;
332 /*
333 * Open file
334 */
335 if (!stream->open()) {
336 stream->close();
337 return FIFF_FAIL;
338 }
339 raw = find_raw(stream->dirtree());
340 if (raw->isEmpty()) {
341 if (allow_maxshield) {
342 raw = find_maxshield(stream->dirtree());
343 if (raw->isEmpty()) {
344 qCritical("No raw data in this file.");
345 stream->close();
346 return FIFF_FAIL;
347 }
348 maxshield_data = true;
349 } else {
350 qCritical("No raw data in this file.");
351 stream->close();
352 return FIFF_FAIL;
353 }
354 }
355 /*
356 * Get the essential measurement information
357 */
358 if (get_meas_info(stream,
359 raw,
360 id,
361 &nchan,
362 &sfreq,
363 &highpass,
364 &lowpass,
365 chs,
366 trans,
367 start_time) < 0) {
368 stream->close();
369 return FIFF_FAIL;
370 }
371 /*
372 * Get the raw directory
373 */
374 rawDir = raw->dir;
375 /*
376 * Ready to put everything together
377 */
378 info = std::make_unique<MNERawInfo>();
379 info->filename = name;
380 info->nchan = nchan;
381 info->chInfo = chs;
382 info->coord_frame = FIFFV_COORD_DEVICE;
383 info->trans = std::make_unique<FiffCoordTrans>(trans);
384 info->sfreq = sfreq;
385 info->lowpass = lowpass;
386 info->highpass = highpass;
387 info->maxshield_data = maxshield_data;
388 if (id) {
389 info->id = std::make_unique<FiffId>(*id);
390 }
391 /*
392 * Getting starting time from measurement ID is not too accurate...
393 */
394 info->start_time = start_time;
395 info->buf_size = 0;
396 for (k = 0; k < raw->nent(); k++) {
397 if (raw->dir[k]->kind == FIFF_DATA_BUFFER) {
398 if (raw->dir[k]->type == FIFFT_DAU_PACK16 || raw->dir[k]->type == FIFFT_SHORT)
399 info->buf_size = raw->dir[k]->size / (nchan * sizeof(fiff_short_t));
400 else if (raw->dir[k]->type == FIFFT_FLOAT)
401 info->buf_size = raw->dir[k]->size / (nchan * sizeof(fiff_float_t));
402 else if (raw->dir[k]->type == FIFFT_INT)
403 info->buf_size = raw->dir[k]->size / (nchan * sizeof(fiff_int_t));
404 else if (raw->dir[k]->type == FIFFT_DOUBLE)
405 info->buf_size = raw->dir[k]->size / (nchan * sizeof(double));
406 else {
407 qCritical("We are not prepared to handle raw data type: %d", raw->dir[k]->type);
408 stream->close();
409 return FIFF_FAIL;
410 }
411 break;
412 }
413 }
414 if (info->buf_size <= 0) {
415 qCritical("No raw data buffers available.");
416 stream->close();
417 return FIFF_FAIL;
418 }
419 info->rawDir = rawDir;
420 info->ndir = raw->nent();
421 infop = std::move(info);
422 res = FIFF_OK;
423
424 stream->close();
425 return res;
426}
#define FIFF_OK
#define FIFFV_COORD_DEVICE
#define FIFF_FAIL
#define FIFFV_COORD_HEAD
FIFF tag: the 16-byte tag header (kind, type, size, next) plus its decoded payload.
#define FIFF_DATA_BUFFER
Definition fiff_file.h:549
#define FIFF_NCHAN
Definition fiff_file.h:446
#define FIFF_HIGHPASS
Definition fiff_file.h:469
#define FIFFT_INT
Definition fiff_file.h:224
#define FIFFT_SHORT
Definition fiff_file.h:223
#define FIFFB_MEAS
Definition fiff_file.h:355
#define FIFFB_RAW_DATA
Definition fiff_file.h:357
#define FIFFB_SMSH_RAW_DATA
Definition fiff_file.h:375
#define FIFFT_DAU_PACK16
Definition fiff_file.h:236
#define FIFFT_DOUBLE
Definition fiff_file.h:226
#define FIFF_COORD_TRANS
Definition fiff_file.h:468
#define FIFFT_FLOAT
Definition fiff_file.h:225
#define FIFFB_CONTINUOUS_DATA
Definition fiff_file.h:368
#define FIFF_MEAS_DATE
Definition fiff_file.h:450
#define FIFF_CH_INFO
Definition fiff_file.h:449
#define FIFFB_HPI_RESULT
Definition fiff_file.h:365
#define FIFF_LOWPASS
Definition fiff_file.h:465
#define FIFFB_MEAS_INFO
Definition fiff_file.h:356
#define FIFF_SFREQ
Definition fiff_file.h:447
return FiffCoordTrans(from_frame, to_frame, R, moveVec)
Subset of FIFF measurement info needed by the legacy raw-data path.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O, in-memory data structures and high-level readers/writers.
qint32 fiff_int_t
Definition fiff_types.h:86
float fiff_float_t
Definition fiff_types.h:90
qint16 fiff_short_t
Definition fiff_types.h:84
Per-channel FIFF descriptor: identifiers, kind, calibration, coil type, channel-frame coil position a...
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
static FiffCoordTrans readFromTag(const std::unique_ptr< FiffTag > &tag)
QSharedPointer< FiffDirNode > SPtr
FIFF tag-stream reader/writer: wraps a QIODevice and exposes typed read_* / write_* methods for every...
QSharedPointer< FiffStream > SPtr
std::unique_ptr< FiffTag > UPtr
Definition fiff_tag.h:165
FIFF time stamp: Unix seconds plus a microsecond fraction matching the on-disk fiffTimeRec record.
Definition fiff_time.h:52
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