41 #include "fiff_evoked.h"
74 FiffEvoked::FiffEvoked(QIODevice& p_IODevice, QVariant setno, QPair<QVariant,QVariant> baseline,
bool proj, fiff_int_t p_aspect_kind)
76 if(!
FiffEvoked::read(p_IODevice, *
this, setno, baseline, proj, p_aspect_kind))
78 printf(
"\tFiff evoked data not found.\n");
87 : info(p_FiffEvoked.info)
88 , nave(p_FiffEvoked.nave)
89 , aspect_kind(p_FiffEvoked.aspect_kind)
90 , first(p_FiffEvoked.first)
91 , last(p_FiffEvoked.last)
92 , comment(p_FiffEvoked.comment)
93 , times(p_FiffEvoked.times)
94 , data(p_FiffEvoked.data)
95 , proj(p_FiffEvoked.proj)
119 times = RowVectorXf();
129 if(include.size() == 0 && exclude.size() == 0)
135 qWarning(
"Warning : No channels match the selection.\n");
147 MatrixXd selBlock(1,1);
149 if(selBlock.rows() != sel.cols() || selBlock.cols() != res.
data.cols())
150 selBlock.resize(sel.cols(), res.
data.cols());
151 for(qint32 l = 0; l < sel.cols(); ++l)
153 selBlock.block(l,0,1,selBlock.cols()) = res.
data.block(sel(0,l),0,1,selBlock.cols());
155 res.
data.resize(sel.cols(), res.
data.cols());
164 bool FiffEvoked::read(QIODevice& p_IODevice,
FiffEvoked& p_FiffEvoked, QVariant setno, QPair<QVariant,QVariant> baseline,
bool proj, fiff_int_t p_aspect_kind)
166 p_FiffEvoked.
clear();
172 QString t_sFileName = t_pStream->streamName();
174 printf(
"Reading %s ...\n",t_sFileName.toUtf8().constData());
176 QList<FiffDirEntry> t_Dir;
178 if(!t_pStream->open(t_Tree, t_Dir))
185 if(!t_pStream->read_meas_info(t_Tree, info, meas))
191 QList<FiffDirTree> processed = meas.
dir_tree_find(FIFFB_PROCESSED_DATA);
192 if (processed.size() == 0)
194 qWarning(
"Could not find processed data");
198 QList<FiffDirTree> evoked_node = meas.
dir_tree_find(FIFFB_EVOKED);
199 if (evoked_node.size() == 0)
201 qWarning(
"Could not find evoked data");
208 if (evoked_node.size() > 1)
210 QStringList comments;
211 QList<fiff_int_t> aspect_kinds;
213 if(!t_pStream->get_evoked_entries(evoked_node, comments, aspect_kinds, t))
214 t = QString(
"None found, must use integer");
215 qWarning(
"%d datasets present, setno parameter must be set. Candidate setno names:\n%s", evoked_node.size(), t.toLatin1().constData());
224 bool t_bIsInteger =
true;
225 setno.toInt(&t_bIsInteger);
230 qWarning(
"kindStat must be \"FIFFV_ASPECT_AVERAGE\" or \"FIFFV_ASPECT_STD_ERR\"");
234 QStringList comments;
235 QList<fiff_int_t> aspect_kinds;
237 t_pStream->get_evoked_entries(evoked_node, comments, aspect_kinds, t);
240 for(qint32 i = 0; i < comments.size(); ++i)
242 if(comments[i].compare(setno.toString()) == 0 && p_aspect_kind == aspect_kinds[i])
251 qWarning() <<
"setno " << setno <<
" (" << p_aspect_kind <<
") not found, out of found datasets:\n " << t;
257 if (setno.toInt() >= evoked_node.size() || setno.toInt() < 0)
259 qWarning(
"Data set selector out of range");
263 FiffDirTree my_evoked = evoked_node[setno.toInt()];
268 QList<FiffDirTree> aspects = my_evoked.
dir_tree_find(FIFFB_ASPECT);
270 if(aspects.size() > 1)
271 printf(
"\tMultiple (%d) aspects found. Taking first one.\n", aspects.size());
278 fiff_int_t nchan = 0;
280 QList<FiffChInfo> chs;
285 for (k = 0; k < my_evoked.
nent; ++k)
287 kind = my_evoked.
dir[k].kind;
288 pos = my_evoked.
dir[k].pos;
293 comment = t_pTag->toString();
295 case FIFF_FIRST_SAMPLE:
297 first = *t_pTag->toInt();
299 case FIFF_LAST_SAMPLE:
301 last = *t_pTag->toInt();
305 nchan = *t_pTag->toInt();
309 sfreq = *t_pTag->toFloat();
313 chs.append( t_pTag->toChInfo() );
317 if (comment.isEmpty())
318 comment = QString(
"No comment");
327 qWarning(
"Local channel information was not found when it was expected.");
330 if (chs.size() != nchan)
332 qWarning(
"Number of channels and number of channel definitions are different.");
337 printf(
"\tFound channel information in evoked data. nchan = %d\n",nchan);
341 qint32 nsamp =
last-first+1;
342 printf(
"\tFound the data of interest:\n");
343 printf(
"\t\tt = %10.2f ... %10.2f ms (%s)\n", 1000*(
float)first/info.
sfreq, 1000*(
float)
last/info.
sfreq,comment.toUtf8().constData());
344 if (info.
comps.size() > 0)
345 printf(
"\t\t%d CTF compensation matrices available\n", info.
comps.size());
351 fiff_int_t
nave = -1;
352 QList<FiffTag> epoch;
353 for (k = 0; k < my_aspect.
nent; ++k)
355 kind = my_aspect.
dir[k].kind;
356 pos = my_aspect.
dir[k].pos;
362 comment = t_pTag->toString();
364 case FIFF_ASPECT_KIND:
366 aspect_kind = *t_pTag->toInt();
370 nave = *t_pTag->toInt();
374 epoch.append(
FiffTag(t_pTag.data()));
380 printf(
"\t\tnave = %d - aspect type = %d\n", nave, aspect_kind);
382 qint32 nepoch = epoch.size();
389 all_data = epoch[0].toFloatMatrix().cast<
double>();
390 all_data.transposeInPlace();
394 if (all_data.cols() == 1 && info.
nchan == 1)
395 all_data.transposeInPlace();
402 all_data = epoch[0].toFloatMatrix().cast<
double>();
403 all_data.transposeInPlace();
405 for (k = 1; k < nepoch; ++k)
407 oldsize = all_data.rows();
408 MatrixXd tmp = epoch[k].toFloatMatrix().cast<
double>();
409 tmp.transposeInPlace();
410 all_data.conservativeResize(oldsize+tmp.rows(), all_data.cols());
411 all_data.block(oldsize, 0, tmp.rows(), tmp.cols()) = tmp;
414 if (all_data.cols() != nsamp)
416 qWarning(
"Incorrect number of samples (%d instead of %d)", (
int) all_data.cols(), nsamp);
423 printf(
"\n\tPreprocessing...\n");
424 printf(
"\t%d channels remain after picking\n",info.
nchan);
426 typedef Eigen::Triplet<double> T;
427 std::vector<T> tripletList;
428 tripletList.reserve(info.
nchan);
429 for(k = 0; k < info.
nchan; ++k)
430 tripletList.push_back(T(k, k, info.
chs[k].cal));
431 SparseMatrix<double> cals(info.
nchan, info.
nchan);
432 cals.setFromTriplets(tripletList.begin(), tripletList.end());
434 all_data = cals * all_data;
436 RowVectorXf
times = RowVectorXf(
last-first+1);
437 for (k = 0; k < times.size(); ++k)
438 times[k] = ((
float)(first+k)) / info.
sfreq;
445 printf(
"\tNo projector specified for these data.\n");
446 p_FiffEvoked.
proj = MatrixXd();
455 printf(
"\tThe projection vectors do not apply to these channels\n");
456 p_FiffEvoked.
proj = MatrixXd();
460 printf(
"\tCreated an SSP operator (subspace dimension = %d)\n", nproj);
461 p_FiffEvoked.
proj = projection;
468 if(p_FiffEvoked.
proj.rows() > 0)
470 all_data = p_FiffEvoked.
proj * all_data;
471 printf(
"\tSSP projectors applied to the evoked data\n");
475 all_data = MNEMath::rescale(all_data, times, baseline, QString(
"mean"));
476 printf(
"Applying baseline correction ... (mode: mean)");
486 p_FiffEvoked.
data = all_data;
502 printf(
"\tNo projector specified for these data.\n");
503 this->proj = MatrixXd();
512 printf(
"\tThe projection vectors do not apply to these channels\n");
513 this->proj = MatrixXd();
517 printf(
"\tCreated an SSP operator (subspace dimension = %d)\n", nproj);
518 this->proj = projection;
QList< FiffCtfComp > comps
FIFF measurement file information.
QList< FiffDirTree > dir_tree_find(fiff_int_t p_kind) const
FiffInfo pick_info(const RowVectorXi &sel=defaultVectorXi) const
QSharedPointer< FiffTag > SPtr
static void activate_projs(QList< FiffProj > &p_qListFiffProj)
static bool read_tag(FiffStream *p_pStream, FiffTag::SPtr &p_pTag, qint64 pos=-1)
QSharedPointer< FiffStream > SPtr
FiffStream class declaration.
Directory tree structure.
#define FIFFV_ASPECT_AVERAGE
QList< FiffDirEntry > dir
FiffEvoked pick_channels(const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList) const
qint32 make_projector(MatrixXd &proj) const
#define FIFFV_ASPECT_STD_ERR
FiffTag class declaration, which provides fiff tag I/O and processing methods.
MNEMath class declaration.
static RowVectorXi pick_channels(const QStringList &ch_names, const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList)
void setInfo(FiffInfo &p_info, bool proj=true)
static bool read(QIODevice &p_IODevice, FiffEvoked &p_FiffEvoked, QVariant setno=0, QPair< QVariant, QVariant > baseline=defaultVariantPair, bool proj=true, fiff_int_t p_aspect_kind=FIFFV_ASPECT_AVERAGE)