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