155 QPair<float,float> t_baseline,
157 fiff_int_t p_aspect_kind)
159 p_FiffEvoked.
clear();
165 QString t_sFileName = t_pStream->streamName();
167 qInfo(
"Reading %s ...\n",t_sFileName.toUtf8().constData());
169 if(!t_pStream->open())
176 if(!t_pStream->read_meas_info(t_pStream->dirtree(),
info, meas))
178 info.filename = t_sFileName;
183 if (processed.size() == 0)
185 qWarning(
"Could not find processed data");
189 QList<FiffDirNode::SPtr> evoked_node = meas->dir_tree_find(
FIFFB_EVOKED);
190 if (evoked_node.size() == 0)
192 qWarning(
"Could not find evoked data");
199 if (evoked_node.size() > 1)
201 QStringList comments;
202 QList<fiff_int_t> aspect_kinds;
204 if(!t_pStream->get_evoked_entries(evoked_node, comments, aspect_kinds, t))
205 t = QString(
"None found, must use integer");
206 qWarning(
"%lld datasets present, setno parameter must be set. Candidate setno names:\n%s", evoked_node.size(), t.toUtf8().constData());
215 bool t_bIsInteger =
true;
216 setno.toInt(&t_bIsInteger);
221 qWarning(
"kindStat must be \"FIFFV_ASPECT_AVERAGE\" or \"FIFFV_ASPECT_STD_ERR\"");
225 QStringList comments;
226 QList<fiff_int_t> aspect_kinds;
228 t_pStream->get_evoked_entries(evoked_node, comments, aspect_kinds, t);
231 for(qint32 i = 0; i < comments.size(); ++i)
233 if(comments[i].compare(setno.toString()) == 0 && p_aspect_kind == aspect_kinds[i])
242 qWarning() <<
"setno " << setno <<
" (" << p_aspect_kind <<
") not found, out of found datasets:\n " << t;
248 if (setno.toInt() >= evoked_node.size() || setno.toInt() < 0)
250 qWarning(
"Data set selector out of range");
259 QList<FiffDirNode::SPtr> aspects = my_evoked->dir_tree_find(
FIFFB_ASPECT);
261 if(aspects.size() > 1)
262 qInfo(
"\tMultiple (%lld) aspects found. Taking first one.\n", aspects.size());
269 fiff_int_t nchan = 0;
271 QList<FiffChInfo> chs;
276 for (k = 0; k < my_evoked->nent(); ++k)
278 kind = my_evoked->dir[k]->kind;
279 pos = my_evoked->dir[k]->pos;
283 t_pStream->read_tag(t_pTag,pos);
287 t_pStream->read_tag(t_pTag,pos);
288 first = *t_pTag->toInt();
291 t_pStream->read_tag(t_pTag,pos);
292 last = *t_pTag->toInt();
295 t_pStream->read_tag(t_pTag,pos);
296 nchan = *t_pTag->toInt();
299 t_pStream->read_tag(t_pTag,pos);
300 sfreq = *t_pTag->toFloat();
303 t_pStream->read_tag(t_pTag, pos);
304 chs.append( t_pTag->toChInfo() );
309 comment = QString(
"No comment");
318 qWarning(
"Local channel information was not found when it was expected.");
321 if (chs.size() != nchan)
323 qWarning(
"Number of channels and number of channel definitions are different.");
328 qInfo(
"\tFound channel information in evoked data. nchan = %d\n",nchan);
333 qInfo(
"\tFound the data of interest:\n");
334 qInfo(
"\t\tt = %10.2f ... %10.2f ms (%s)\n", 1000*
static_cast<float>(
first)/
info.sfreq, 1000*
static_cast<float>(
last)/
info.sfreq,
comment.toUtf8().constData());
335 if (
info.comps.size() > 0)
336 qInfo(
"\t\t%lld CTF compensation matrices available\n",
info.comps.size());
342 fiff_int_t
nave = -1;
343 QList<FiffTag> epoch;
344 for (k = 0; k < my_aspect->nent(); ++k)
346 kind = my_aspect->dir[k]->kind;
347 pos = my_aspect->dir[k]->pos;
352 t_pStream->read_tag(t_pTag, pos);
356 t_pStream->read_tag(t_pTag, pos);
360 t_pStream->read_tag(t_pTag, pos);
361 nave = *t_pTag->toInt();
364 t_pStream->read_tag(t_pTag, pos);
365 epoch.append(
FiffTag(*t_pTag));
373 qint32 nepoch = epoch.size();
380 all_data = epoch[0].toFloatMatrix().cast<
double>();
381 all_data.transposeInPlace();
385 if (all_data.cols() == 1 &&
info.nchan == 1)
386 all_data.transposeInPlace();
393 all_data = epoch[0].toFloatMatrix().cast<
double>();
394 all_data.transposeInPlace();
396 for (k = 1; k < nepoch; ++k)
398 oldsize = all_data.rows();
399 MatrixXd tmp = epoch[k].toFloatMatrix().cast<
double>();
400 tmp.transposeInPlace();
401 all_data.conservativeResize(oldsize+tmp.rows(), all_data.cols());
402 all_data.block(oldsize, 0, tmp.rows(), tmp.cols()) = tmp;
405 if (all_data.cols() != nsamp)
407 qWarning(
"Incorrect number of samples (%d instead of %d)", (
int) all_data.cols(), nsamp);
414 qInfo(
"\n\tPreprocessing...\n");
415 qInfo(
"\t%d channels remain after picking\n",
info.nchan);
417 using T = Eigen::Triplet<double>;
418 std::vector<T> tripletList;
419 tripletList.reserve(
info.nchan);
420 for(k = 0; k <
info.nchan; ++k)
421 tripletList.push_back(T(k, k,
info.chs[k].cal));
422 SparseMatrix<double> cals(
info.nchan,
info.nchan);
423 cals.setFromTriplets(tripletList.begin(), tripletList.end());
425 all_data = cals * all_data;
428 for (k = 0; k <
times.size(); ++k)
436 qInfo(
"\tNo projector specified for these data.\n");
437 p_FiffEvoked.
proj = MatrixXd();
443 qint32 nproj =
info.make_projector(projection);
446 qWarning(
"\tThe projection vectors do not apply to these channels\n");
447 p_FiffEvoked.
proj = MatrixXd();
451 qInfo(
"\tCreated an SSP operator (subspace dimension = %d)\n", nproj);
452 p_FiffEvoked.
proj = projection;
459 if(p_FiffEvoked.
proj.rows() > 0)
461 all_data = p_FiffEvoked.
proj * all_data;
462 qInfo(
"\tSSP projectors applied to the evoked data\n");
473 p_FiffEvoked.
data = all_data;
478 if (t_baseline.first != t_baseline.second) {
482 qInfo(
"\tNo baseline correction applied\n");