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#include <stdexcept>
65//=============================================================================================================
66// USED NAMESPACES
67//=============================================================================================================
68
69using namespace FIFFLIB;
70using namespace UTILSLIB;
71using namespace Eigen;
72
73//=============================================================================================================
74// DEFINE MEMBER METHODS
75//=============================================================================================================
76
78: kind(-1)
79, diag(false)
80, dim(-1)
81, nfree(-1)
82{
83 qRegisterMetaType<QSharedPointer<FIFFLIB::FiffCov> >("QSharedPointer<FIFFLIB::FiffCov>");
84 qRegisterMetaType<FIFFLIB::FiffCov>("FIFFLIB::FiffCov");
85}
86
87//=============================================================================================================
88
89FiffCov::FiffCov(QIODevice &p_IODevice)
90: kind(-1)
91, diag(false)
92, dim(-1)
93, nfree(-1)
94{
95 FiffStream::SPtr t_pStream(new FiffStream(&p_IODevice));
96
97 if(!t_pStream->open())
98 {
99 throw std::runtime_error("Not able to open IODevice");
100 }
101
102 if(!t_pStream->read_cov(t_pStream->dirtree(), FIFFV_MNE_NOISE_COV, *this))
103 throw std::runtime_error("Fiff covariance not found");
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("FiffCov::prepare_noise_cov: %lld MEG + %lld EEG channels != %d total (unclassified channels present)",
314 (long long)C_meg_idx.size(), (long long)C_eeg_idx.size(), n_chan);
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 //Check dimension consistency (channels not classified as EEG/MAG/GRAD, e.g. EOG/MISC, are expected)
381 if(static_cast<unsigned>(C.rows()) != idx_eeg.size() + idx_mag.size() + idx_grad.size()) {
382 qWarning("FiffCov::regularize: %lld channels in cov but only %zu classified as EEG/MAG/GRAD (others will not be regularized)",
383 static_cast<long long>(C.rows()), idx_eeg.size() + idx_mag.size() + idx_grad.size());
384 }
385
386 QList<FiffProj> t_listProjs;
387 if(p_bProj)
388 {
389 t_listProjs = p_info.projs + cov_good.projs;
390 FiffProj::activate_projs(t_listProjs);
391 }
392
393 //Build regularization MAP
394 QMap<QString, QPair<double, std::vector<qint32> > > regData;
395 regData.insert("EEG", QPair<double, std::vector<qint32> >(p_fRegEeg, idx_eeg));
396 regData.insert("MAG", QPair<double, std::vector<qint32> >(p_fRegMag, idx_mag));
397 regData.insert("GRAD", QPair<double, std::vector<qint32> >(p_fRegGrad, idx_grad));
398
399 //
400 //Regularize
401 //
402 QMap<QString, QPair<double, std::vector<qint32> > >::Iterator it;
403 for(it = regData.begin(); it != regData.end(); ++it)
404 {
405 QString desc(it.key());
406 double reg = it.value().first;
407 std::vector<qint32> idx = it.value().second;
408
409 if(idx.size() == 0 || reg == 0.0)
410 qInfo("\tNothing to regularize within %s data.\n", desc.toUtf8().constData());
411 else
412 {
413 qInfo("\tRegularize %s: %f\n", desc.toUtf8().constData(), reg);
414 MatrixXd this_C(idx.size(), idx.size());
415 for(quint32 i = 0; i < idx.size(); ++i)
416 for(quint32 j = 0; j < idx.size(); ++j)
417 this_C(i,j) = cov_good.data(idx[i], idx[j]);
418
419 MatrixXd U;
420 qint32 ncomp;
421 if(p_bProj)
422 {
423 QStringList this_ch_names;
424 for(quint32 k = 0; k < idx.size(); ++k)
425 this_ch_names << ch_names[idx[k]];
426
427 MatrixXd P;
428 ncomp = FiffProj::make_projector(t_listProjs, this_ch_names, P); //ToDo: Synchronize with mne-python and debug
429
430 JacobiSVD<MatrixXd> svd(P, ComputeFullU);
431 //Sort singular values and singular vectors
432 VectorXd t_s = svd.singularValues();
433 MatrixXd t_U = svd.matrixU();
434 Linalg::sort<double>(t_s, t_U);
435
436 U = t_U.block(0,0, t_U.rows(), t_U.cols()-ncomp);
437
438 if (ncomp > 0)
439 {
440 qInfo("\tCreated an SSP operator for %s (dimension = %d).\n", desc.toUtf8().constData(), ncomp);
441 this_C = U.transpose() * (this_C * U);
442 }
443 }
444
445 double sigma = this_C.diagonal().mean();
446 this_C.diagonal() = this_C.diagonal().array() + reg * sigma; // modify diag inplace
447 if(p_bProj && ncomp > 0)
448 this_C = U * (this_C * U.transpose());
449
450 for(qint32 i = 0; i < this_C.rows(); ++i)
451 for(qint32 j = 0; j < this_C.cols(); ++j)
452 C(idx[i],idx[j]) = this_C(i,j);
453 }
454 }
455
456 // Put data back in correct locations
457 RowVectorXi idx = FiffInfo::pick_channels(cov.names, info_ch_names, p_exclude);
458 for(qint32 i = 0; i < idx.size(); ++i)
459 for(qint32 j = 0; j < idx.size(); ++j)
460 cov.data(idx[i], idx[j]) = C(i, j);
461
462 return cov;
463}
464
465//=============================================================================================================
466
468{
469 if (this != &rhs) // protect against invalid self-assignment
470 {
471 kind = rhs.kind;
472 diag = rhs.diag;
473 dim = rhs.dim;
474 names = rhs.names;
475 data = rhs.data;
476 projs = rhs.projs;
477 bads = rhs.bads;
478 nfree = rhs.nfree;
479 eig = rhs.eig;
480 eigvec = rhs.eigvec;
481 }
482 // to support chained assignment operators (a=b=c), always return *this
483 return *this;
484}
485
486//=============================================================================================================
487
489 const MatrixXi &events,
490 const QList<int> &eventCodes,
491 float tmin,
492 float tmax,
493 float bmin,
494 float bmax,
495 bool doBaseline,
496 bool removeMean,
497 unsigned int ignoreMask,
498 float delay)
499{
500 FiffCov cov;
501 float sfreq = raw.info.sfreq;
502 int nchan = raw.info.nchan;
503
504 int minSamp = static_cast<int>(std::round(tmin * sfreq));
505 int maxSamp = static_cast<int>(std::round(tmax * sfreq));
506 int ns = maxSamp - minSamp + 1;
507 int delaySamp = static_cast<int>(std::round(delay * sfreq));
508
509 if (ns <= 0) {
510 qWarning() << "[FiffCov::compute_from_epochs] Invalid time window.";
511 return cov;
512 }
513
514 int bminSamp = 0, bmaxSamp = 0;
515 if (doBaseline) {
516 bminSamp = static_cast<int>(std::round(bmin * sfreq)) - minSamp;
517 bmaxSamp = static_cast<int>(std::round(bmax * sfreq)) - minSamp;
518 }
519
520 MatrixXd covAccum = MatrixXd::Zero(nchan, nchan);
521 VectorXd meanAccum = VectorXd::Zero(nchan);
522 int totalSamples = 0;
523 int nAccepted = 0;
524
525 for (int k = 0; k < events.rows(); ++k) {
526 int evFrom = events(k, 1) & ~static_cast<int>(ignoreMask);
527 int evTo = events(k, 2) & ~static_cast<int>(ignoreMask);
528
529 // Check if event matches any of the desired event codes
530 bool match = false;
531 for (int ec = 0; ec < eventCodes.size(); ++ec) {
532 if (evFrom == 0 && evTo == eventCodes[ec]) {
533 match = true;
534 break;
535 }
536 }
537 if (!match)
538 continue;
539
540 int evSample = events(k, 0);
541 int epochStart = evSample + delaySamp + minSamp;
542 int epochEnd = evSample + delaySamp + maxSamp;
543
544 if (epochStart < raw.first_samp || epochEnd > raw.last_samp)
545 continue;
546
547 MatrixXd epochData;
548 MatrixXd epochTimes;
549 if (!raw.read_raw_segment(epochData, epochTimes, epochStart, epochEnd))
550 continue;
551
552 // Baseline subtraction
553 if (doBaseline) {
554 int bminIdx = qMax(0, bminSamp);
555 int bmaxIdx = qMin(static_cast<int>(epochData.cols()) - 1, bmaxSamp);
556 if (bmaxIdx > bminIdx) {
557 int nBase = bmaxIdx - bminIdx;
558 for (int c = 0; c < nchan; ++c) {
559 double baseVal = epochData.row(c).segment(bminIdx, nBase).mean();
560 epochData.row(c).array() -= baseVal;
561 }
562 }
563 }
564
565 // Accumulate
566 if (removeMean) {
567 VectorXd epochMean = epochData.rowwise().mean();
568 meanAccum += epochMean * static_cast<double>(ns);
569 }
570 covAccum += epochData * epochData.transpose();
571 totalSamples += ns;
572 nAccepted++;
573 }
574
575 if (totalSamples < 2) {
576 qWarning() << "[FiffCov::compute_from_epochs] Not enough data.";
577 return cov;
578 }
579
580 if (removeMean) {
581 VectorXd grandMean = meanAccum / static_cast<double>(totalSamples);
582 cov.data = (covAccum / static_cast<double>(totalSamples - 1))
583 - (grandMean * grandMean.transpose()) * (static_cast<double>(totalSamples) / (totalSamples - 1));
584 } else {
585 cov.data = covAccum / static_cast<double>(totalSamples - 1);
586 }
587
589 cov.dim = nchan;
590 cov.names = raw.info.ch_names;
591 cov.nfree = totalSamples - 1;
592 cov.bads = raw.info.bads;
593 cov.projs = raw.info.projs;
594
595 qInfo() << "[FiffCov::compute_from_epochs] Computed:" << nchan << "channels,"
596 << nAccepted << "epochs," << totalSamples << "total samples.";
597
598 return cov;
599}
600
601//=============================================================================================================
602
603bool FiffCov::save(const QString &fileName) const
604{
605 if (fileName.isEmpty()) {
606 qWarning() << "[FiffCov::save] Output file not specified.";
607 return false;
608 }
609
610 QFile file(fileName);
612 if (!pStream) {
613 qWarning() << "[FiffCov::save] Cannot open" << fileName;
614 return false;
615 }
616
617 pStream->start_block(FIFFB_MEAS);
618 pStream->write_id(FIFF_BLOCK_ID);
619 pStream->write_cov(*this);
620 pStream->end_block(FIFFB_MEAS);
621 pStream->end_file();
622
623 qInfo() << "[FiffCov::save] Saved covariance matrix to" << fileName;
624 return true;
625}
626
627//=============================================================================================================
628
629FiffCov FiffCov::computeGrandAverage(const QList<FiffCov> &covs)
630{
631 FiffCov grandCov;
632
633 if (covs.isEmpty()) {
634 qWarning() << "[FiffCov::computeGrandAverage] No covariance matrices provided.";
635 return grandCov;
636 }
637
638 grandCov = covs[0];
639 MatrixXd sumCov = grandCov.data * static_cast<double>(grandCov.nfree);
640 int totalNfree = grandCov.nfree;
641
642 for (int k = 1; k < covs.size(); ++k) {
643 if (covs[k].dim != grandCov.dim) {
644 qWarning() << "[FiffCov::computeGrandAverage] Dimension mismatch.";
645 return FiffCov();
646 }
647 sumCov += covs[k].data * static_cast<double>(covs[k].nfree);
648 totalNfree += covs[k].nfree;
649 }
650
651 grandCov.data = sumCov / static_cast<double>(totalNfree);
652 grandCov.nfree = totalNfree;
653
654 return grandCov;
655}
Linalg class declaration.
FiffRawData class declaration.
FiffInfoBase class declaration.
FiffDirNode class declaration, which provides fiff dir tree processing methods.
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
FiffStream class declaration.
FiffCov class declaration.
#define FIFFV_MNE_NOISE_COV
#define FIFFV_STIM_CH
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:488
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:629
FiffCov & operator=(const FiffCov &rhs)
Definition fiff_cov.cpp:467
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:603
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)