MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
rtaveraging.cpp
Go to the documentation of this file.
1//=============================================================================================================
36//=============================================================================================================
37// INCLUDES
38//=============================================================================================================
39
40#include "rtaveraging.h"
41
43
44#include <utils/ioutils.h>
46#include <utils/mnemath.h>
47
48//=============================================================================================================
49// QT INCLUDES
50//=============================================================================================================
51
52#include <QDebug>
53
54//=============================================================================================================
55// EIGEN INCLUDES
56//=============================================================================================================
57
58//=============================================================================================================
59// USED NAMESPACES
60//=============================================================================================================
61
62using namespace RTPROCESSINGLIB;
63using namespace FIFFLIB;
64using namespace UTILSLIB;
65using namespace Eigen;
66using namespace MNELIB;
67
68//=============================================================================================================
69// DEFINE MEMBER METHODS RtAveragingWorker
70//=============================================================================================================
71
73 quint32 iPreStimSamples,
74 quint32 iPostStimSamples,
75 quint32 iBaselineFromMSecs,
76 quint32 iBaselineToMSecs,
77 quint32 iTriggerIndex,
78 FiffInfo::SPtr pFiffInfo)
79: QObject()
80, m_iNumAverages(numAverages)
81, m_iPreStimSamples(iPreStimSamples)
82, m_iPostStimSamples(iPostStimSamples)
83, m_pFiffInfo(pFiffInfo)
84, m_fTriggerThreshold(0.5f)
85, m_iTriggerChIndex(-1)
86, m_iNewTriggerIndex(iTriggerIndex)
87, m_bDoBaselineCorrection(false)
88, m_pairBaselineSec(qMakePair(float(iBaselineFromMSecs),float(iBaselineToMSecs)))
89, m_bActivateThreshold(false)
90{
91 m_mapThresholds["eog"] = 300e-6;
92
94
97
98 if(m_iNumAverages <= 0) {
99 qDebug() << "RtAveragingWorker::RtAveragingWorker - Number of averages <= 0. Setting to 1 as default.";
100 m_iNumAverages = 1;
101 }
102}
103
104//=============================================================================================================
105
106void RtAveragingWorker::doWork(const MatrixXd& rawSegment)
107{
108 if(this->thread()->isInterruptionRequested()) {
109 return;
110 }
111
113 reset();
114 }
115
116 doAveraging(rawSegment);
117}
118
119//=============================================================================================================
120
122{
123 if(numAve <= 0) {
124 qDebug() << "[RtAveragingWorker::setAverageNumber] Number of averages <= 0 are not allowed. Returning.";
125 return;
126 }
127
128 if(numAve < m_iNumAverages) {
129 int iDiff = m_iNumAverages - numAve;
130
131 //Do averaging for each trigger type
132 QMutableMapIterator<double,QList<Eigen::MatrixXd> > idx(m_mapStimAve);
133
134 while(idx.hasNext()) {
135 idx.next();
136
137 if(idx.value().size() > iDiff) {
138 //Pop data from buffer
139 for(int i = 0; i < iDiff; ++i) {
140 idx.value().pop_front();
141 }
142 }
143 }
144 }
145
146 m_iNumAverages = numAve;
147}
148
149//=============================================================================================================
150
151void RtAveragingWorker::setPreStim(qint32 samples, qint32 secs)
152{
153 Q_UNUSED(secs);
154
155 m_iNewPreStimSamples = samples;
156}
157
158//=============================================================================================================
159
160void RtAveragingWorker::setPostStim(qint32 samples, qint32 secs)
161{
162 Q_UNUSED(secs);
163
164 m_iNewPostStimSamples = samples;
165}
166
167//=============================================================================================================
168
170{
171 m_iNewTriggerIndex = idx;
172}
173
174//=============================================================================================================
175
176void RtAveragingWorker::setArtifactReduction(const QMap<QString, double> &mapThresholds)
177{
178 if(mapThresholds["Active"] == 0.0) {
179 m_bActivateThreshold = false;
180 } else {
182 }
183
184 m_mapThresholds = mapThresholds;
185}
186
187//=============================================================================================================
188
190{
191 m_bDoBaselineCorrection = activate;
192
194 for(int i = 0; i < m_stimEvokedSet.evoked.size(); ++i) {
195 m_stimEvokedSet.evoked[i].baseline = qMakePair(-1.0f, -1.0f);
196 }
197 } else {
198 for(int i = 0; i < m_stimEvokedSet.evoked.size(); ++i) {
200 }
201 }
202}
203
204//=============================================================================================================
205
207 int fromMSec)
208{
209 m_pairBaselineSec.first = float(fromMSec)/1000.0f;
210 m_pairBaselineSamp.first = float(fromSamp);
211
212 for(int i = 0; i < m_stimEvokedSet.evoked.size(); ++i) {
213 m_stimEvokedSet.evoked[i].baseline.first = float(fromMSec)/1000.0f;
214 }
215}
216
217//=============================================================================================================
218
220 int toMSec)
221{
222 m_pairBaselineSec.second = float(toMSec)/1000.0f;
223 m_pairBaselineSamp.second = float(toSamp);
224
225 for(int i = 0; i < m_stimEvokedSet.evoked.size(); ++i) {
226 m_stimEvokedSet.evoked[i].baseline.second = float(toMSec)/1000.0f;
227 }
228}
229
230//=============================================================================================================
231
232void RtAveragingWorker::doAveraging(const MatrixXd& rawSegment)
233{
234 //Detect trigger
235 QList<QPair<int,double> > lDetectedTriggers = RTPROCESSINGLIB::detectTriggerFlanksMax(rawSegment, m_iTriggerChIndex, 0, m_fTriggerThreshold, true);
236
237 //TODO: This does not permit the same trigger type twice in one data block
238 for(int i = 0; i < lDetectedTriggers.size(); ++i) {
239 if(!m_mapFillingBackBuffer.contains(lDetectedTriggers.at(i).second)) {
240 double dTriggerType = lDetectedTriggers.at(i).second;
241
242 //qDebug()<<"Adding dTriggerType"<<dTriggerType;
243
244 m_mapFillingBackBuffer[dTriggerType] = false;
245 m_mapMatDataPostIdx[dTriggerType] = 0;
246 m_mapDataPost[dTriggerType].resize(m_pFiffInfo->chs.size(), m_iPostStimSamples);
247 m_mapDataPost[dTriggerType].setZero();
248 }
249 }
250
251 //Fill front / pre stim buffer even if no triggers have been located at all yet
252 if(m_mapFillingBackBuffer.isEmpty()) {
253 fillFrontBuffer(rawSegment, -1.0);
254 }
255
256 //Do averaging for each trigger type
257 QMutableMapIterator<double,bool> idx(m_mapFillingBackBuffer);
258 QStringList lResponsibleTriggerTypes;
259
260 while(idx.hasNext()) {
261 idx.next();
262
263 double dTriggerType = idx.key();
264
265 //Fill front / pre stim buffer
266 if(lDetectedTriggers.isEmpty()) {
267 fillFrontBuffer(rawSegment, -1.0);
268 }
269
270 //Fill back buffer and decide when to do the data packing of the different buffers
271 if(m_mapFillingBackBuffer[dTriggerType]) {
272 if(m_mapMatDataPostIdx[dTriggerType] != m_iPostStimSamples) {
273 fillBackBuffer(rawSegment, dTriggerType);
274 }
275
276 if(m_mapMatDataPostIdx[dTriggerType] == m_iPostStimSamples) {
277 m_mapMatDataPostIdx[dTriggerType] = 0;
278 m_mapFillingBackBuffer[dTriggerType] = false;
279 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
280 }
281 } else {
282 if(lDetectedTriggers.isEmpty()) {
283 //Fill front / pre stim buffer
284 fillFrontBuffer(rawSegment, dTriggerType);
285 } else {
286 for(int i = 0; i < lDetectedTriggers.size(); ++i) {
287 if(dTriggerType == lDetectedTriggers.at(i).second) {
288 int iTriggerPos = lDetectedTriggers.at(i).first;
289
290 //Do front buffer stuff
291 MatrixXd tempMat;
292
293 if(iTriggerPos >= m_iPreStimSamples) {
294 tempMat = rawSegment.block(0,
295 iTriggerPos - m_iPreStimSamples,
296 rawSegment.rows(),
298 } else {
299 tempMat = rawSegment.block(0,
300 0,
301 rawSegment.rows(),
302 iTriggerPos);
303 }
304
305 fillFrontBuffer(tempMat, dTriggerType);
306
307 //Do back buffer stuff
308 if(rawSegment.cols() - iTriggerPos >= m_mapDataPost[dTriggerType].cols()) {
309 m_mapDataPost[dTriggerType] = rawSegment.block(0,
310 iTriggerPos,
311 m_mapDataPost[dTriggerType].rows(),
312 m_mapDataPost[dTriggerType].cols());
313 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
314 m_mapMatDataPostIdx[dTriggerType] = 0;
315 m_mapFillingBackBuffer[dTriggerType] = false;
316 } else {
317 m_mapDataPost[dTriggerType].block(0,
318 0,
319 m_mapDataPost[dTriggerType].rows(),
320 rawSegment.cols() - iTriggerPos) = rawSegment.block(0,
321 iTriggerPos,
322 rawSegment.rows(),
323 rawSegment.cols() - iTriggerPos);
324 m_mapMatDataPostIdx[dTriggerType] = rawSegment.cols() - iTriggerPos;
325 m_mapFillingBackBuffer[dTriggerType] = true;
326 }
327
328 //qDebug()<<"Trigger type "<<dTriggerType<<" found at "<<iTriggerPos;
329 }
330 }
331 }
332 }
333 }
334
335 //qDebug()<<"RtAveragingWorker::doAveraging() - time for procesing"<<time.elapsed();
336}
337
338//=============================================================================================================
339
340void RtAveragingWorker::emitEvoked(double dTriggerType, QStringList& lResponsibleTriggerTypes)
341{
342 //Merge the different buffers
343 mergeData(dTriggerType);
344
345 //Calculate the final average/evoked data
346 generateEvoked(dTriggerType);
347
348 //List of all trigger types which lead to the recent emit of a new evoked set. */
349 if(!lResponsibleTriggerTypes.contains(QString::number(dTriggerType))) {
350 lResponsibleTriggerTypes << QString::number(dTriggerType);
351 }
352
353 if(m_stimEvokedSet.evoked.size() > 0) {
354 emit resultReady(m_stimEvokedSet, lResponsibleTriggerTypes);
355 }
356
357// qDebug()<<"RtAveragingWorker::emitEvoked() - dTriggerType:" << dTriggerType;
358// qDebug()<<"RtAveragingWorker::emitEvoked() - m_mapStimAve[dTriggerType].size():" << m_mapStimAve[dTriggerType].size();
359}
360
361//=============================================================================================================
362
363void RtAveragingWorker::fillBackBuffer(const MatrixXd &data, double dTriggerType)
364{
365 int iResidualCols = data.cols();
366 if(m_mapMatDataPostIdx[dTriggerType] + data.cols() > m_iPostStimSamples) {
367 iResidualCols = m_iPostStimSamples - m_mapMatDataPostIdx[dTriggerType];
368 m_mapDataPost[dTriggerType].block(0,m_mapMatDataPostIdx[dTriggerType],m_mapDataPost[dTriggerType].rows(),iResidualCols) = data.block(0,0,data.rows(),iResidualCols);
369 } else {
370 m_mapDataPost[dTriggerType].block(0,m_mapMatDataPostIdx[dTriggerType],m_mapDataPost[dTriggerType].rows(),iResidualCols) = data;
371 }
372
373 m_mapMatDataPostIdx[dTriggerType] += iResidualCols;
374}
375
376//=============================================================================================================
377
378void RtAveragingWorker::fillFrontBuffer(const MatrixXd &data, double dTriggerType)
379{
380 //Init m_mapDataPre
381 if(!m_mapDataPre.contains(dTriggerType)) {
382 if(dTriggerType != -1.0) {
383 m_mapDataPre[dTriggerType] = m_mapDataPre[-1.0];
384 } else {
385 m_mapDataPre[-1.0].resize(m_pFiffInfo->chs.size(), m_iPreStimSamples);
386 m_mapDataPre[-1.0].setZero();
387 }
388 }
389
390 if(m_mapDataPre[dTriggerType].cols() <= data.cols()) {
391 if(m_iPreStimSamples > 0 && data.cols() >= m_iPreStimSamples) {
392 m_mapDataPre[dTriggerType] = data.block(0,
393 data.cols() - m_iPreStimSamples,
394 data.rows(),
396 }
397 } else {
398 int residual = m_mapDataPre[dTriggerType].cols() - data.cols();
399
400 //Copy shift data
401 m_mapDataPre[dTriggerType].block(0,
402 0,
403 m_mapDataPre[dTriggerType].rows(),
404 residual) = m_mapDataPre[dTriggerType].block(0,
405 m_mapDataPre[dTriggerType].cols() - residual,
406 m_mapDataPre[dTriggerType].rows(),
407 residual);
408
409 //Copy new data in
410 m_mapDataPre[dTriggerType].block(0,
411 residual,
412 m_mapDataPre[dTriggerType].rows(),
413 data.cols()) = data;
414 }
415}
416
417//=============================================================================================================
418
419void RtAveragingWorker::mergeData(double dTriggerType)
420{
421 if(m_mapDataPre[dTriggerType].rows() != m_mapDataPost[dTriggerType].rows()) {
422 qDebug() << "[RtAveragingWorker::mergeData] Rows of m_mapDataPre (" << m_mapDataPre[dTriggerType].rows() << ") and m_mapDataPost (" << m_mapDataPost[dTriggerType].rows() << ") are not the same. Returning.";
423 return;
424 }
425
426 MatrixXd mergedData(m_mapDataPre[dTriggerType].rows(), m_mapDataPre[dTriggerType].cols() + m_mapDataPost[dTriggerType].cols());
427
428 mergedData << m_mapDataPre[dTriggerType], m_mapDataPost[dTriggerType];
429
430 //Perform artifact threshold
431 bool bArtifactDetected = false;
432
434 qDebug() << "[RtAveragingWorker::mergeData] Doing artifact reduction for" << m_mapThresholds;
435
436 bArtifactDetected = MNEEpochDataList::checkForArtifact(mergedData,
439 }
440
441 if(!bArtifactDetected) {
442 //Add cut data to average buffer
443 m_mapStimAve[dTriggerType].append(mergedData);
444
445 //Pop data from buffer
446 int iDiff = m_mapStimAve[dTriggerType].size() - m_iNumAverages;
447 if(iDiff > 0) {
448 for(int i = 0; i < iDiff; ++i) {
449 m_mapStimAve[dTriggerType].pop_front();
450 }
451 }
452 }
453}
454
455//=============================================================================================================
456
457void RtAveragingWorker::generateEvoked(double dTriggerType)
458{
459 if(m_mapStimAve[dTriggerType].isEmpty()) {
460 qDebug() << "[RtAveragingWorker::generateEvoked] m_mapStimAve is empty for type" << dTriggerType << "Returning.";
461 return;
462 }
463
464 //Init evoked
466 FiffEvoked evoked;
467 evoked.setInfo(*m_pFiffInfo.data());
468 int iEvokedIdx = -1;
469
470 for(int i = 0; i < m_stimEvokedSet.evoked.size(); ++i) {
471 if(m_stimEvokedSet.evoked.at(i).comment == QString::number(dTriggerType)) {
472 evoked = m_stimEvokedSet.evoked.at(i);
473 iEvokedIdx = i;
474 break;
475 }
476 }
477
478 //If the evoked is not yet present add it here
479 if(iEvokedIdx == -1) {
482 evoked.times = RowVectorXf::LinSpaced(m_iPreStimSamples + m_iPostStimSamples,
485 evoked.times[m_iPreStimSamples] = 0.0;
486 evoked.first = 0;
488 evoked.comment = QString::number(dTriggerType);
489 }
490
491 // Generate final evoked
492 MatrixXd finalAverage = MatrixXd::Zero(m_mapStimAve[dTriggerType].first().rows(), m_iPreStimSamples+m_iPostStimSamples);
493
494 for(int i = 0; i < m_mapStimAve[dTriggerType].size(); ++i) {
495 finalAverage += m_mapStimAve[dTriggerType].at(i);
496 }
497
498 if(!m_mapStimAve[dTriggerType].isEmpty()) {
499 finalAverage = finalAverage/m_mapStimAve[dTriggerType].size();
500 }
501
503 finalAverage = MNEMath::rescale(finalAverage, evoked.times, m_pairBaselineSec, QString("mean"));
504 }
505
506 evoked.data = finalAverage;
507
508 evoked.nave = m_mapStimAve[dTriggerType].size();
509
510 //Add new data to evoked data set
511 if(iEvokedIdx != -1) {
512 //Evoked data is already present
513 m_stimEvokedSet.evoked[iEvokedIdx] = evoked;
514 } else {
515 //Evoked data is not present yet
516 m_stimEvokedSet.evoked.append(evoked);
517 }
518}
519
520//=============================================================================================================
521
523{
524 //Reset
528
529 //Clear all evoked data information
530 m_stimEvokedSet.evoked.clear();
531
532 //Clear all maps
533 m_mapStimAve.clear();
534 m_mapDataPre.clear();
535 m_mapDataPre[-1.0] = MatrixXd::Zero(m_pFiffInfo->chs.size(), m_iPreStimSamples);
536 m_mapDataPost.clear();
537 m_mapMatDataPostIdx.clear();
539}
540
541//=============================================================================================================
542// DEFINE MEMBER METHODS RtAveraging
543//=============================================================================================================
544
545RtAveraging::RtAveraging(quint32 numAverages,
546 quint32 iPreStimSamples,
547 quint32 iPostStimSamples,
548 quint32 iBaselineFromSecs,
549 quint32 iBaselineToSecs,
550 quint32 iTriggerIndex,
551 FiffInfo::SPtr pFiffInfo,
552 QObject *parent)
553: QObject(parent)
554{
555 qRegisterMetaType<Eigen::MatrixXd>("Eigen::MatrixXd");
556
557 RtAveragingWorker *worker = new RtAveragingWorker(numAverages,
558 iPreStimSamples,
559 iPostStimSamples,
560 iBaselineFromSecs,
561 iBaselineToSecs,
562 iTriggerIndex,
563 pFiffInfo);
564 worker->moveToThread(&m_workerThread);
565
566 connect(&m_workerThread, &QThread::finished,
567 worker, &QObject::deleteLater);
568
569 connect(this, &RtAveraging::operate,
571
572 connect(worker, &RtAveragingWorker::resultReady,
573 this, &RtAveraging::handleResults, Qt::DirectConnection);
574
575 connect(this, &RtAveraging::averageNumberChanged,
577 connect(this, &RtAveraging::averagePreStimChanged,
579 connect(this, &RtAveraging::averagePostStimChanged,
581 connect(this, &RtAveraging::averageTriggerChIdxChanged,
583 connect(this, &RtAveraging::averageArtifactReductionChanged,
585 connect(this, &RtAveraging::averageBaselineActiveChanged,
587 connect(this, &RtAveraging::averageBaselineFromChanged,
589 connect(this, &RtAveraging::averageBaselineToChanged,
591 connect(this, &RtAveraging::averageResetRequested,
592 worker, &RtAveragingWorker::reset);
593
594 m_workerThread.start();
595}
596
597//=============================================================================================================
598
603
604//=============================================================================================================
605
606void RtAveraging::append(const MatrixXd &data)
607{
608 emit operate(data);
609}
610
611//=============================================================================================================
612
614 const QStringList &lResponsibleTriggerTypes)
615{
616 emit evokedStim(evokedStimSet,
617 lResponsibleTriggerTypes);
618}
619
620//=============================================================================================================
621
622void RtAveraging::restart(quint32 numAverages,
623 quint32 iPreStimSamples,
624 quint32 iPostStimSamples,
625 quint32 iBaselineFromSecs,
626 quint32 iBaselineToSecs,
627 quint32 iTriggerIndex,
628 FiffInfo::SPtr pFiffInfo)
629{
630 stop();
631
632 RtAveragingWorker *worker = new RtAveragingWorker(numAverages,
633 iPreStimSamples,
634 iPostStimSamples,
635 iBaselineFromSecs,
636 iBaselineToSecs,
637 iTriggerIndex,
638 pFiffInfo);
639 worker->moveToThread(&m_workerThread);
640
641 connect(&m_workerThread, &QThread::finished,
642 worker, &QObject::deleteLater);
643
644 connect(this, &RtAveraging::operate,
646
647 connect(worker, &RtAveragingWorker::resultReady,
648 this, &RtAveraging::handleResults, Qt::DirectConnection);
649
650 connect(this, &RtAveraging::averageNumberChanged,
652 connect(this, &RtAveraging::averagePreStimChanged,
654 connect(this, &RtAveraging::averagePostStimChanged,
656 connect(this, &RtAveraging::averageTriggerChIdxChanged,
658 connect(this, &RtAveraging::averageArtifactReductionChanged,
660 connect(this, &RtAveraging::averageBaselineActiveChanged,
662 connect(this, &RtAveraging::averageBaselineFromChanged,
664 connect(this, &RtAveraging::averageBaselineToChanged,
666 connect(this, &RtAveraging::averageResetRequested,
667 worker, &RtAveragingWorker::reset);
668
669 m_workerThread.start();
670}
671
672//=============================================================================================================
673
675{
676 m_workerThread.requestInterruption();
677 m_workerThread.quit();
678 m_workerThread.wait();
679}
680
681//=============================================================================================================
682
684{
685 emit averageNumberChanged(numAve);
686}
687
688//=============================================================================================================
689
690void RtAveraging::setPreStim(qint32 samples,
691 qint32 secs)
692{
693 Q_UNUSED(secs);
694
695 emit averagePreStimChanged(samples,
696 secs);
697}
698
699//=============================================================================================================
700
701void RtAveraging::setPostStim(qint32 samples,
702 qint32 secs)
703{
704 Q_UNUSED(secs);
705
706 emit averagePostStimChanged(samples,
707 secs);
708}
709
710//=============================================================================================================
711
713{
714 emit averageTriggerChIdxChanged(idx);
715}
716
717//=============================================================================================================
718
719void RtAveraging::setArtifactReduction(const QMap<QString,double>& mapThresholds)
720{
721 emit averageArtifactReductionChanged(mapThresholds);
722}
723
724//=============================================================================================================
725
727{
728 emit averageBaselineActiveChanged(activate);
729}
730
731//=============================================================================================================
732
734 int fromMSec)
735{
736 emit averageBaselineFromChanged(fromSamp,
737 fromMSec);
738}
739
740//=============================================================================================================
741
743 int toMSec)
744{
745 emit averageBaselineToChanged(toSamp,
746 toMSec);
747}
748
749//=============================================================================================================
750
752{
753 emit averageResetRequested();
754}
Declaration of the RtAveraging and RtAveragingWorker classes.
DetectTrigger declarations.
RTPROCESINGSHARED_EXPORT QMap< int, QList< QPair< int, double > > > detectTriggerFlanksMax(const Eigen::MatrixXd &data, const QList< int > &lTriggerChannels, int iOffsetIndex, double dThreshold, bool bRemoveOffset, int iBurstLengthSamp=100)
IOUtils class declaration.
MNEMath class declaration.
MNEEpochDataList class declaration.
Eigen::RowVectorXf times
Eigen::MatrixXd data
void setInfo(const FiffInfo &p_info, bool proj=true)
QPair< float, float > baseline
QList< FiffEvoked > evoked
QSharedPointer< FiffInfo > SPtr
Definition fiff_info.h:87
static bool checkForArtifact(const Eigen::MatrixXd &data, const FIFFLIB::FiffInfo &pFiffInfo, const QMap< QString, double > &mapReject, const QStringList &lExcludeChs=QStringList())
Real-time averaging worker.
Definition rtaveraging.h:84
void setArtifactReduction(const QMap< QString, double > &mapThresholds)
void fillFrontBuffer(const Eigen::MatrixXd &data, double dTriggerType)
FIFFLIB::FiffInfo::SPtr m_pFiffInfo
QPair< float, float > m_pairBaselineSec
QMap< double, bool > m_mapFillingBackBuffer
RtAveragingWorker(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromMSecs, quint32 iBaselineToMSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
QPair< float, float > m_pairBaselineSamp
void setBaselineTo(int toSamp, int toMSec)
FIFFLIB::FiffEvokedSet m_stimEvokedSet
void doAveraging(const Eigen::MatrixXd &rawSegment)
QMap< double, Eigen::MatrixXd > m_mapDataPre
QMap< double, QList< Eigen::MatrixXd > > m_mapStimAve
QMap< double, qint32 > m_mapMatDataPostIdx
void setBaselineActive(bool activate)
void doWork(const Eigen::MatrixXd &matData)
QMap< double, Eigen::MatrixXd > m_mapDataPost
void setPostStim(qint32 samples, qint32 secs)
QMap< QString, double > m_mapThresholds
void resultReady(const FIFFLIB::FiffEvokedSet &evokedStimSet, const QStringList &lResponsibleTriggerTypes)
void fillBackBuffer(const Eigen::MatrixXd &data, double dTriggerType)
void setBaselineFrom(int fromSamp, int fromMSec)
void setPreStim(qint32 samples, qint32 secs)
void mergeData(double dTriggerType)
void generateEvoked(double dTriggerType)
void setBaselineFrom(int fromSamp, int fromMSec)
RtAveraging(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromSecs, quint32 iBaselineToSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo, QObject *parent=0)
void setPreStim(qint32 samples, qint32 secs)
void setBaselineTo(int toSamp, int toMSec)
void setAverageNumber(qint32 numAve)
void append(const Eigen::MatrixXd &data)
void handleResults(const FIFFLIB::FiffEvokedSet &evokedStimSet, const QStringList &lResponsibleTriggerTypes)
void setPostStim(qint32 samples, qint32 secs)
void setTriggerChIndx(qint32 idx)
void setBaselineActive(bool activate)
void setArtifactReduction(const QMap< QString, double > &mapThresholds)
void restart(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromSecs, quint32 iBaselineToSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
static Eigen::MatrixXd rescale(const Eigen::MatrixXd &data, const Eigen::RowVectorXf &times, const QPair< float, float > &baseline, QString mode)