v2.0.0
Loading...
Searching...
No Matches
fiff_cov.cpp
Go to the documentation of this file.
1//=============================================================================================================
36
37//=============================================================================================================
38// INCLUDES
39//=============================================================================================================
40
41#include "fiff_cov.h"
42#include "fiff_stream.h"
43#include "fiff_raw_data.h"
44#include "fiff_info_base.h"
45#include "fiff_dir_node.h"
46#include "fiff_file.h"
47
48#include <math/linalg.h>
49
50//=============================================================================================================
51// QT INCLUDES
52//=============================================================================================================
53
54#include <QPair>
55#include <QFile>
56
57//=============================================================================================================
58// EIGEN INCLUDES
59//=============================================================================================================
60
61#include <Eigen/SVD>
62#include <QDebug>
63
64//=============================================================================================================
65// USED NAMESPACES
66//=============================================================================================================
67
68using namespace FIFFLIB;
69using namespace UTILSLIB;
70using namespace Eigen;
71
72//=============================================================================================================
73// DEFINE MEMBER METHODS
74//=============================================================================================================
75
77: kind(-1)
78, diag(false)
79, dim(-1)
80, nfree(-1)
81{
82 qRegisterMetaType<QSharedPointer<FIFFLIB::FiffCov> >("QSharedPointer<FIFFLIB::FiffCov>");
83 qRegisterMetaType<FIFFLIB::FiffCov>("FIFFLIB::FiffCov");
84}
85
86//=============================================================================================================
87
88FiffCov::FiffCov(QIODevice &p_IODevice)
89: kind(-1)
90, diag(false)
91, dim(-1)
92, nfree(-1)
93{
94 FiffStream::SPtr t_pStream(new FiffStream(&p_IODevice));
95
96 if(!t_pStream->open())
97 {
98 qWarning("\tNot able to open IODevice.\n");//ToDo Throw here
99 return;
100 }
101
102 if(!t_pStream->read_cov(t_pStream->dirtree(), FIFFV_MNE_NOISE_COV, *this))
103 qWarning("\tFiff covariance not found.\n");//ToDo Throw here
104
105 qRegisterMetaType<QSharedPointer<FIFFLIB::FiffCov> >("QSharedPointer<FIFFLIB::FiffCov>");
106 qRegisterMetaType<FIFFLIB::FiffCov>("FIFFLIB::FiffCov");
107}
108
109//=============================================================================================================
110
111FiffCov::FiffCov(const FiffCov &p_FiffCov)
112: QSharedData(p_FiffCov)
113, kind(p_FiffCov.kind)
114, diag(p_FiffCov.diag)
115, dim(p_FiffCov.dim)
116, names(p_FiffCov.names)
117, data(p_FiffCov.data)
118, projs(p_FiffCov.projs)
119, bads(p_FiffCov.bads)
120, nfree(p_FiffCov.nfree)
121, eig(p_FiffCov.eig)
122, eigvec(p_FiffCov.eigvec)
123{
124 qRegisterMetaType<QSharedPointer<FIFFLIB::FiffCov> >("QSharedPointer<FIFFLIB::FiffCov>");
125 qRegisterMetaType<FIFFLIB::FiffCov>("FIFFLIB::FiffCov");
126}
127
128//=============================================================================================================
129
133
134//=============================================================================================================
135
137{
138 kind = -1;
139 diag = false;
140 dim = -1;
141 names.clear();
142 data = MatrixXd();
143 projs.clear();
144 bads.clear();
145 nfree = -1;
146 eig = VectorXd();
147 eigvec = MatrixXd();
148}
149
150//=============================================================================================================
151
152FiffCov FiffCov::pick_channels(const QStringList &p_include, const QStringList &p_exclude)
153{
154 RowVectorXi sel = FiffInfoBase::pick_channels(this->names, p_include, p_exclude);
155 FiffCov res;//No deep copy here - since almost everything else is adapted anyway
156
157 res.kind = this->kind;
158 res.diag = this->diag;
159 res.dim = sel.size();
160
161 for(qint32 k = 0; k < sel.size(); ++k)
162 res.names << this->names[sel(k)];
163
164 res.data.resize(res.dim, res.dim);
165 for(qint32 i = 0; i < res.dim; ++i)
166 for(qint32 j = 0; j < res.dim; ++j)
167 res.data(i, j) = this->data(sel(i), sel(j));
168 res.projs = this->projs;
169
170 for(qint32 k = 0; k < this->bads.size(); ++k)
171 if(res.names.contains(this->bads[k]))
172 res.bads << this->bads[k];
173 res.nfree = this->nfree;
174
175 return res;
176}
177
178//=============================================================================================================
179
180FiffCov FiffCov::prepare_noise_cov(const FiffInfo &p_Info, const QStringList &p_ChNames) const
181{
182 FiffCov p_NoiseCov(*this);
183
184 VectorXi C_ch_idx = VectorXi::Zero(p_NoiseCov.names.size());
185 qint32 count = 0;
186 for(qint32 i = 0; i < p_ChNames.size(); ++i)
187 {
188 qint32 idx = p_NoiseCov.names.indexOf(p_ChNames[i]);
189 if(idx > -1)
190 {
191 C_ch_idx[count] = idx;
192 ++count;
193 }
194 }
195 C_ch_idx.conservativeResize(count);
196
197 MatrixXd C(count, count);
198
199 if(!p_NoiseCov.diag)
200 for(qint32 i = 0; i < count; ++i)
201 for(qint32 j = 0; j < count; ++j)
202 C(i,j) = p_NoiseCov.data(C_ch_idx(i), C_ch_idx(j));
203 else
204 {
205 qWarning("Warning in FiffCov::prepare_noise_cov: This has to be debugged - not done before!");
206 C = MatrixXd::Zero(count, count);
207 for(qint32 i = 0; i < count; ++i)
208 C.diagonal()[i] = p_NoiseCov.data(C_ch_idx(i),0);
209 }
210
211 MatrixXd proj;
212 qint32 ncomp = p_Info.make_projector(proj, p_ChNames);
213
214 //Create the projection operator
215 if (ncomp > 0 && proj.rows() == count)
216 {
217 qInfo("Created an SSP operator (subspace dimension = %d)\n", ncomp);
218 C = proj * (C * proj.transpose());
219 } else {
220 qWarning("Warning in FiffCov::prepare_noise_cov: No projections applied since no projectors specified or projector dimensions do not match!");
221 }
222
223 RowVectorXi pick_meg = p_Info.pick_types(true, false, false, defaultQStringList, p_Info.bads);
224 RowVectorXi pick_eeg = p_Info.pick_types(false, true, false, defaultQStringList, p_Info.bads);
225
226 QStringList meg_names, eeg_names;
227
228 for(qint32 i = 0; i < pick_meg.size(); ++i)
229 meg_names << p_Info.chs[pick_meg[i]].ch_name;
230 VectorXi C_meg_idx = VectorXi::Zero(p_NoiseCov.names.size());
231 count = 0;
232 for(qint32 k = 0; k < C.rows(); ++k)
233 {
234 if(meg_names.indexOf(p_ChNames[k]) > -1)
235 {
236 C_meg_idx[count] = k;
237 ++count;
238 }
239 }
240 if(count > 0)
241 C_meg_idx.conservativeResize(count);
242 else
243 C_meg_idx = VectorXi();
244
245 //
246 for(qint32 i = 0; i < pick_eeg.size(); ++i)
247 eeg_names << p_Info.chs[pick_eeg(0,i)].ch_name;
248 VectorXi C_eeg_idx = VectorXi::Zero(p_NoiseCov.names.size());
249 count = 0;
250 for(qint32 k = 0; k < C.rows(); ++k)
251 {
252 if(eeg_names.indexOf(p_ChNames[k]) > -1)
253 {
254 C_eeg_idx[count] = k;
255 ++count;
256 }
257 }
258
259 if(count > 0)
260 C_eeg_idx.conservativeResize(count);
261 else
262 C_eeg_idx = VectorXi();
263
264 bool has_meg = C_meg_idx.size() > 0;
265 bool has_eeg = C_eeg_idx.size() > 0;
266
267 MatrixXd C_meg, C_eeg;
268 VectorXd C_meg_eig, C_eeg_eig;
269 MatrixXd C_meg_eigvec, C_eeg_eigvec;
270 if (has_meg)
271 {
272 count = C_meg_idx.rows();
273 C_meg = MatrixXd(count,count);
274 for(qint32 i = 0; i < count; ++i)
275 for(qint32 j = 0; j < count; ++j)
276 C_meg(i,j) = C(C_meg_idx(i), C_meg_idx(j));
277 Linalg::get_whitener(C_meg, false, QString("MEG"), C_meg_eig, C_meg_eigvec);
278 }
279
280 if (has_eeg)
281 {
282 count = C_eeg_idx.rows();
283 C_eeg = MatrixXd(count,count);
284 for(qint32 i = 0; i < count; ++i)
285 for(qint32 j = 0; j < count; ++j)
286 C_eeg(i,j) = C(C_eeg_idx(i), C_eeg_idx(j));
287 Linalg::get_whitener(C_eeg, false, QString("EEG"), C_eeg_eig, C_eeg_eigvec);
288 }
289
290 qint32 n_chan = p_ChNames.size();
291 p_NoiseCov.eigvec = MatrixXd::Zero(n_chan, n_chan);
292 p_NoiseCov.eig = VectorXd::Zero(n_chan);
293
294 if(has_meg)
295 {
296 for(qint32 i = 0; i < C_meg_idx.rows(); ++i)
297 for(qint32 j = 0; j < C_meg_idx.rows(); ++j)
298 p_NoiseCov.eigvec(C_meg_idx[i], C_meg_idx[j]) = C_meg_eigvec(i, j);
299 for(qint32 i = 0; i < C_meg_idx.rows(); ++i)
300 p_NoiseCov.eig(C_meg_idx[i]) = C_meg_eig[i];
301 }
302 if(has_eeg)
303 {
304 for(qint32 i = 0; i < C_eeg_idx.rows(); ++i)
305 for(qint32 j = 0; j < C_eeg_idx.rows(); ++j)
306 p_NoiseCov.eigvec(C_eeg_idx[i], C_eeg_idx[j]) = C_eeg_eigvec(i, j);
307 for(qint32 i = 0; i < C_eeg_idx.rows(); ++i)
308 p_NoiseCov.eig(C_eeg_idx[i]) = C_eeg_eig[i];
309 }
310
311 if (C_meg_idx.size() + C_eeg_idx.size() != n_chan)
312 {
313 qWarning("Error in FiffCov::prepare_noise_cov: channel sizes do no match!\n");//ToDo Throw here
314 return FiffCov();
315 }
316
317 p_NoiseCov.data = C;
318 p_NoiseCov.dim = p_ChNames.size();
319 p_NoiseCov.diag = false;
320 p_NoiseCov.names = p_ChNames;
321
322 return p_NoiseCov;
323}
324
325//=============================================================================================================
326
327FiffCov FiffCov::regularize(const FiffInfo& p_info, double p_fRegMag, double p_fRegGrad, double p_fRegEeg, bool p_bProj, QStringList p_exclude) const
328{
329 FiffCov cov(*this);
330
331 if(p_exclude.size() == 0)
332 {
333 p_exclude = p_info.bads;
334 for(qint32 i = 0; i < cov.bads.size(); ++i)
335 if(!p_exclude.contains(cov.bads[i]))
336 p_exclude << cov.bads[i];
337 }
338
339 //Allways exclude all STI channels from covariance computation
340 int iNoStimCh = 0;
341
342 for(int i=0; i<p_info.chs.size(); i++) {
343 if(p_info.chs[i].kind == FIFFV_STIM_CH) {
344 p_exclude << p_info.chs[i].ch_name;
345 iNoStimCh++;
346 }
347 }
348
349 RowVectorXi sel_eeg = p_info.pick_types(false, true, false, defaultQStringList, p_exclude);
350 RowVectorXi sel_mag = p_info.pick_types(QString("mag"), false, false, defaultQStringList, p_exclude);
351 RowVectorXi sel_grad = p_info.pick_types(QString("grad"), false, false, defaultQStringList, p_exclude);
352
353 QStringList info_ch_names = p_info.ch_names;
354 QStringList ch_names_eeg, ch_names_mag, ch_names_grad;
355 for(qint32 i = 0; i < sel_eeg.size(); ++i)
356 ch_names_eeg << info_ch_names[sel_eeg(i)];
357 for(qint32 i = 0; i < sel_mag.size(); ++i)
358 ch_names_mag << info_ch_names[sel_mag(i)];
359 for(qint32 i = 0; i < sel_grad.size(); ++i)
360 ch_names_grad << info_ch_names[sel_grad(i)];
361
362 // This actually removes bad channels from the cov, which is not backward
363 // compatible, so let's leave all channels in
364 FiffCov cov_good = cov.pick_channels(info_ch_names, p_exclude);
365 QStringList ch_names = cov_good.names;
366
367 std::vector<qint32> idx_eeg, idx_mag, idx_grad;
368 for(qint32 i = 0; i < ch_names.size(); ++i)
369 {
370 if(ch_names_eeg.contains(ch_names[i]))
371 idx_eeg.push_back(i);
372 else if(ch_names_mag.contains(ch_names[i]))
373 idx_mag.push_back(i);
374 else if(ch_names_grad.contains(ch_names[i]))
375 idx_grad.push_back(i);
376 }
377
378 MatrixXd C(cov_good.data);
379
380 //Subtract number of found stim channels because they are still in C but not the idx_eeg, idx_mag or idx_grad
381 if((unsigned) C.rows() - iNoStimCh != idx_eeg.size() + idx_mag.size() + idx_grad.size()) {
382 qWarning("Error in FiffCov::regularize: Channel dimensions do not fit.\n");//ToDo Throw
383 }
384
385 QList<FiffProj> t_listProjs;
386 if(p_bProj)
387 {
388 t_listProjs = p_info.projs + cov_good.projs;
389 FiffProj::activate_projs(t_listProjs);
390 }
391
392 //Build regularization MAP
393 QMap<QString, QPair<double, std::vector<qint32> > > regData;
394 regData.insert("EEG", QPair<double, std::vector<qint32> >(p_fRegEeg, idx_eeg));
395 regData.insert("MAG", QPair<double, std::vector<qint32> >(p_fRegMag, idx_mag));
396 regData.insert("GRAD", QPair<double, std::vector<qint32> >(p_fRegGrad, idx_grad));
397
398 //
399 //Regularize
400 //
401 QMap<QString, QPair<double, std::vector<qint32> > >::Iterator it;
402 for(it = regData.begin(); it != regData.end(); ++it)
403 {
404 QString desc(it.key());
405 double reg = it.value().first;
406 std::vector<qint32> idx = it.value().second;
407
408 if(idx.size() == 0 || reg == 0.0)
409 qInfo("\tNothing to regularize within %s data.\n", desc.toUtf8().constData());
410 else
411 {
412 qInfo("\tRegularize %s: %f\n", desc.toUtf8().constData(), reg);
413 MatrixXd this_C(idx.size(), idx.size());
414 for(quint32 i = 0; i < idx.size(); ++i)
415 for(quint32 j = 0; j < idx.size(); ++j)
416 this_C(i,j) = cov_good.data(idx[i], idx[j]);
417
418 MatrixXd U;
419 qint32 ncomp;
420 if(p_bProj)
421 {
422 QStringList this_ch_names;
423 for(quint32 k = 0; k < idx.size(); ++k)
424 this_ch_names << ch_names[idx[k]];
425
426 MatrixXd P;
427 ncomp = FiffProj::make_projector(t_listProjs, this_ch_names, P); //ToDo: Synchronize with mne-python and debug
428
429 JacobiSVD<MatrixXd> svd(P, ComputeFullU);
430 //Sort singular values and singular vectors
431 VectorXd t_s = svd.singularValues();
432 MatrixXd t_U = svd.matrixU();
433 Linalg::sort<double>(t_s, t_U);
434
435 U = t_U.block(0,0, t_U.rows(), t_U.cols()-ncomp);
436
437 if (ncomp > 0)
438 {
439 qInfo("\tCreated an SSP operator for %s (dimension = %d).\n", desc.toUtf8().constData(), ncomp);
440 this_C = U.transpose() * (this_C * U);
441 }
442 }
443
444 double sigma = this_C.diagonal().mean();
445 this_C.diagonal() = this_C.diagonal().array() + reg * sigma; // modify diag inplace
446 if(p_bProj && ncomp > 0)
447 this_C = U * (this_C * U.transpose());
448
449 for(qint32 i = 0; i < this_C.rows(); ++i)
450 for(qint32 j = 0; j < this_C.cols(); ++j)
451 C(idx[i],idx[j]) = this_C(i,j);
452 }
453 }
454
455 // Put data back in correct locations
456 RowVectorXi idx = FiffInfo::pick_channels(cov.names, info_ch_names, p_exclude);
457 for(qint32 i = 0; i < idx.size(); ++i)
458 for(qint32 j = 0; j < idx.size(); ++j)
459 cov.data(idx[i], idx[j]) = C(i, j);
460
461 return cov;
462}
463
464//=============================================================================================================
465
467{
468 if (this != &rhs) // protect against invalid self-assignment
469 {
470 kind = rhs.kind;
471 diag = rhs.diag;
472 dim = rhs.dim;
473 names = rhs.names;
474 data = rhs.data;
475 projs = rhs.projs;
476 bads = rhs.bads;
477 nfree = rhs.nfree;
478 eig = rhs.eig;
479 eigvec = rhs.eigvec;
480 }
481 // to support chained assignment operators (a=b=c), always return *this
482 return *this;
483}
484
485//=============================================================================================================
486
488 const MatrixXi &events,
489 const QList<int> &eventCodes,
490 float tmin,
491 float tmax,
492 float bmin,
493 float bmax,
494 bool doBaseline,
495 bool removeMean,
496 unsigned int ignoreMask,
497 float delay)
498{
499 FiffCov cov;
500 float sfreq = raw.info.sfreq;
501 int nchan = raw.info.nchan;
502
503 int minSamp = static_cast<int>(std::round(tmin * sfreq));
504 int maxSamp = static_cast<int>(std::round(tmax * sfreq));
505 int ns = maxSamp - minSamp + 1;
506 int delaySamp = static_cast<int>(std::round(delay * sfreq));
507
508 if (ns <= 0) {
509 qWarning() << "[FiffCov::compute_from_epochs] Invalid time window.";
510 return cov;
511 }
512
513 int bminSamp = 0, bmaxSamp = 0;
514 if (doBaseline) {
515 bminSamp = static_cast<int>(std::round(bmin * sfreq)) - minSamp;
516 bmaxSamp = static_cast<int>(std::round(bmax * sfreq)) - minSamp;
517 }
518
519 MatrixXd covAccum = MatrixXd::Zero(nchan, nchan);
520 VectorXd meanAccum = VectorXd::Zero(nchan);
521 int totalSamples = 0;
522 int nAccepted = 0;
523
524 for (int k = 0; k < events.rows(); ++k) {
525 int evFrom = events(k, 1) & ~static_cast<int>(ignoreMask);
526 int evTo = events(k, 2) & ~static_cast<int>(ignoreMask);
527
528 // Check if event matches any of the desired event codes
529 bool match = false;
530 for (int ec = 0; ec < eventCodes.size(); ++ec) {
531 if (evFrom == 0 && evTo == eventCodes[ec]) {
532 match = true;
533 break;
534 }
535 }
536 if (!match)
537 continue;
538
539 int evSample = events(k, 0);
540 int epochStart = evSample + delaySamp + minSamp;
541 int epochEnd = evSample + delaySamp + maxSamp;
542
543 if (epochStart < raw.first_samp || epochEnd > raw.last_samp)
544 continue;
545
546 MatrixXd epochData;
547 MatrixXd epochTimes;
548 if (!raw.read_raw_segment(epochData, epochTimes, epochStart, epochEnd))
549 continue;
550
551 // Baseline subtraction
552 if (doBaseline) {
553 int bminIdx = qMax(0, bminSamp);
554 int bmaxIdx = qMin(static_cast<int>(epochData.cols()) - 1, bmaxSamp);
555 if (bmaxIdx > bminIdx) {
556 int nBase = bmaxIdx - bminIdx;
557 for (int c = 0; c < nchan; ++c) {
558 double baseVal = epochData.row(c).segment(bminIdx, nBase).mean();
559 epochData.row(c).array() -= baseVal;
560 }
561 }
562 }
563
564 // Accumulate
565 if (removeMean) {
566 VectorXd epochMean = epochData.rowwise().mean();
567 meanAccum += epochMean * static_cast<double>(ns);
568 }
569 covAccum += epochData * epochData.transpose();
570 totalSamples += ns;
571 nAccepted++;
572 }
573
574 if (totalSamples < 2) {
575 qWarning() << "[FiffCov::compute_from_epochs] Not enough data.";
576 return cov;
577 }
578
579 if (removeMean) {
580 VectorXd grandMean = meanAccum / static_cast<double>(totalSamples);
581 cov.data = (covAccum / static_cast<double>(totalSamples - 1))
582 - (grandMean * grandMean.transpose()) * (static_cast<double>(totalSamples) / (totalSamples - 1));
583 } else {
584 cov.data = covAccum / static_cast<double>(totalSamples - 1);
585 }
586
588 cov.dim = nchan;
589 cov.names = raw.info.ch_names;
590 cov.nfree = totalSamples - 1;
591 cov.bads = raw.info.bads;
592 cov.projs = raw.info.projs;
593
594 qInfo() << "[FiffCov::compute_from_epochs] Computed:" << nchan << "channels,"
595 << nAccepted << "epochs," << totalSamples << "total samples.";
596
597 return cov;
598}
599
600//=============================================================================================================
601
602bool FiffCov::save(const QString &fileName) const
603{
604 if (fileName.isEmpty()) {
605 qWarning() << "[FiffCov::save] Output file not specified.";
606 return false;
607 }
608
609 QFile file(fileName);
611 if (!pStream) {
612 qWarning() << "[FiffCov::save] Cannot open" << fileName;
613 return false;
614 }
615
616 pStream->start_block(FIFFB_MEAS);
617 pStream->write_id(FIFF_BLOCK_ID);
618 pStream->write_cov(*this);
619 pStream->end_block(FIFFB_MEAS);
620 pStream->end_file();
621
622 qInfo() << "[FiffCov::save] Saved covariance matrix to" << fileName;
623 return true;
624}
625
626//=============================================================================================================
627
628FiffCov FiffCov::computeGrandAverage(const QList<FiffCov> &covs)
629{
630 FiffCov grandCov;
631
632 if (covs.isEmpty()) {
633 qWarning() << "[FiffCov::computeGrandAverage] No covariance matrices provided.";
634 return grandCov;
635 }
636
637 grandCov = covs[0];
638 MatrixXd sumCov = grandCov.data * static_cast<double>(grandCov.nfree);
639 int totalNfree = grandCov.nfree;
640
641 for (int k = 1; k < covs.size(); ++k) {
642 if (covs[k].dim != grandCov.dim) {
643 qWarning() << "[FiffCov::computeGrandAverage] Dimension mismatch.";
644 return FiffCov();
645 }
646 sumCov += covs[k].data * static_cast<double>(covs[k].nfree);
647 totalNfree += covs[k].nfree;
648 }
649
650 grandCov.data = sumCov / static_cast<double>(totalNfree);
651 grandCov.nfree = totalNfree;
652
653 return grandCov;
654}
#define FIFFV_MNE_NOISE_COV
#define FIFFV_STIM_CH
FiffStream class declaration.
FiffInfoBase class declaration.
FiffRawData class declaration.
FiffDirNode class declaration, which provides fiff dir tree processing methods.
FiffCov class declaration.
Header file describing the numerical values used in fif files.
#define FIFFB_MEAS
Definition fiff_file.h:362
#define FIFF_BLOCK_ID
Definition fiff_file.h:326
Linalg class declaration.
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
QList< FiffProj > projs
Definition fiff_cov.h:255
fiff_int_t nfree
Definition fiff_cov.h:257
fiff_int_t dim
Definition fiff_cov.h:252
Eigen::MatrixXd eigvec
Definition fiff_cov.h:259
FiffCov regularize(const FiffInfo &p_info, double p_fMag=0.1, double p_fGrad=0.1, double p_fEeg=0.1, bool p_bProj=true, QStringList p_exclude=defaultQStringList) const
Definition fiff_cov.cpp:327
static FiffCov compute_from_epochs(const FiffRawData &raw, const Eigen::MatrixXi &events, const QList< int > &eventCodes, float tmin, float tmax, float bmin=0.0f, float bmax=0.0f, bool doBaseline=false, bool removeMean=true, unsigned int ignoreMask=0, float delay=0.0f)
Definition fiff_cov.cpp:487
FiffCov pick_channels(const QStringList &p_include=defaultQStringList, const QStringList &p_exclude=defaultQStringList)
Definition fiff_cov.cpp:152
fiff_int_t kind
Definition fiff_cov.h:249
static FiffCov computeGrandAverage(const QList< FiffCov > &covs)
Definition fiff_cov.cpp:628
FiffCov & operator=(const FiffCov &rhs)
Definition fiff_cov.cpp:466
QStringList bads
Definition fiff_cov.h:256
QStringList names
Definition fiff_cov.h:253
Eigen::VectorXd eig
Definition fiff_cov.h:258
Eigen::MatrixXd data
Definition fiff_cov.h:254
FiffCov prepare_noise_cov(const FiffInfo &p_info, const QStringList &p_chNames) const
Definition fiff_cov.cpp:180
bool save(const QString &fileName) const
Definition fiff_cov.cpp:602
FIFF measurement file information.
Definition fiff_info.h:86
qint32 make_projector(Eigen::MatrixXd &proj) const
Definition fiff_info.h:285
QList< FiffProj > projs
Definition fiff_info.h:275
static Eigen::RowVectorXi pick_channels(const QStringList &ch_names, const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList)
QList< FiffChInfo > chs
Eigen::RowVectorXi pick_types(const QString meg, bool eeg=false, bool stim=false, const QStringList &include=defaultQStringList, const QStringList &exclude=defaultQStringList) const
static fiff_int_t make_projector(const QList< FiffProj > &projs, const QStringList &ch_names, Eigen::MatrixXd &proj, const QStringList &bads=defaultQStringList, Eigen::MatrixXd &U=defaultMatrixXd)
static void activate_projs(QList< FiffProj > &p_qListFiffProj)
FIFF raw measurement data.
bool read_raw_segment(Eigen::MatrixXd &data, Eigen::MatrixXd &times, fiff_int_t from=-1, fiff_int_t to=-1, const Eigen::RowVectorXi &sel=defaultRowVectorXi, bool do_debug=false) const
FIFF File I/O routines.
QSharedPointer< FiffStream > SPtr
static FiffStream::SPtr start_file(QIODevice &p_IODevice)
static Eigen::VectorXi sort(Eigen::Matrix< T, Eigen::Dynamic, 1 > &v, bool desc=true)
Definition linalg.h:284
static void get_whitener(Eigen::MatrixXd &A, bool pca, QString ch_type, Eigen::VectorXd &eig, Eigen::MatrixXd &eigvec)