MNE-CPP  0.1.9
A Framework for Electrophysiology
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 
62 using namespace RTPROCESSINGLIB;
63 using namespace FIFFLIB;
64 using namespace UTILSLIB;
65 using namespace Eigen;
66 using 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 
106 void RtAveragingWorker::doWork(const MatrixXd& rawSegment)
107 {
108  if(this->thread()->isInterruptionRequested()) {
109  return;
110  }
111 
112  if(controlValuesChanged()) {
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 
151 void RtAveragingWorker::setPreStim(qint32 samples, qint32 secs)
152 {
153  Q_UNUSED(secs);
154 
155  m_iNewPreStimSamples = samples;
156 }
157 
158 //=============================================================================================================
159 
160 void 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 
176 void RtAveragingWorker::setArtifactReduction(const QMap<QString, double> &mapThresholds)
177 {
178  if(mapThresholds["Active"] == 0.0) {
179  m_bActivateThreshold = false;
180  } else {
181  m_bActivateThreshold = true;
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 
232 void 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 
340 void 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 
363 void 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 
378 void 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 
419 void 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,
437  *m_pFiffInfo,
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 
457 void 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
465  m_stimEvokedSet.info = *m_pFiffInfo.data();
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) {
480  evoked.baseline = m_pairBaselineSec;
481  evoked.times.resize(m_iPreStimSamples + m_iPostStimSamples);
482  evoked.times = RowVectorXf::LinSpaced(m_iPreStimSamples + m_iPostStimSamples,
483  -1*m_iPreStimSamples/m_pFiffInfo->sfreq,
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();
538  m_mapFillingBackBuffer.clear();
539 }
540 
541 //=============================================================================================================
542 // DEFINE MEMBER METHODS RtAveraging
543 //=============================================================================================================
544 
545 RtAveraging::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,
570  worker, &RtAveragingWorker::doWork);
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 
600 {
601  stop();
602 }
603 
604 //=============================================================================================================
605 
606 void RtAveraging::append(const MatrixXd &data)
607 {
608  emit operate(data);
609 }
610 
611 //=============================================================================================================
612 
613 void RtAveraging::handleResults(const FiffEvokedSet& evokedStimSet,
614  const QStringList &lResponsibleTriggerTypes)
615 {
616  emit evokedStim(evokedStimSet,
617  lResponsibleTriggerTypes);
618 }
619 
620 //=============================================================================================================
621 
622 void 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,
645  worker, &RtAveragingWorker::doWork);
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 
683 void RtAveraging::setAverageNumber(qint32 numAve)
684 {
685  emit averageNumberChanged(numAve);
686 }
687 
688 //=============================================================================================================
689 
690 void RtAveraging::setPreStim(qint32 samples,
691  qint32 secs)
692 {
693  Q_UNUSED(secs);
694 
695  emit averagePreStimChanged(samples,
696  secs);
697 }
698 
699 //=============================================================================================================
700 
701 void 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 
719 void 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 }
IOUtils class declaration.
void setPostStim(qint32 samples, qint32 secs)
Eigen::RowVectorXf times
Definition: fiff_evoked.h:230
QMap< double, Eigen::MatrixXd > m_mapDataPost
Definition: rtaveraging.h:262
QMap< double, Eigen::MatrixXd > m_mapDataPre
Definition: rtaveraging.h:261
void setArtifactReduction(const QMap< QString, double > &mapThresholds)
Declaration of the RtAveraging and RtAveragingWorker classes.
void setAverageNumber(qint32 numAve)
DetectTrigger declarations.
void setBaselineActive(bool activate)
void setPreStim(qint32 samples, qint32 secs)
QPair< float, float > baseline
Definition: fiff_evoked.h:233
void setArtifactReduction(const QMap< QString, double > &mapThresholds)
QMap< double, QList< Eigen::MatrixXd > > m_mapStimAve
Definition: rtaveraging.h:260
Real-time averaging worker.
Definition: rtaveraging.h:83
evoked data set
QList< FiffEvoked > evoked
void setBaselineActive(bool activate)
RtAveragingWorker(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromMSecs, quint32 iBaselineToMSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
Definition: rtaveraging.cpp:72
void setBaselineFrom(int fromSamp, int fromMSec)
QPair< float, float > m_pairBaselineSec
Definition: rtaveraging.h:253
void generateEvoked(double dTriggerType)
void restart(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromSecs, quint32 iBaselineToSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
void handleResults(const FIFFLIB::FiffEvokedSet &evokedStimSet, const QStringList &lResponsibleTriggerTypes)
void setBaselineTo(int toSamp, int toMSec)
evoked data
Definition: fiff_evoked.h:77
QMap< double, bool > m_mapFillingBackBuffer
Definition: rtaveraging.h:264
void doWork(const Eigen::MatrixXd &matData)
QPair< float, float > m_pairBaselineSamp
Definition: rtaveraging.h:254
RTPROCESINGSHARED_EXPORT QList< QPair< int, double > > detectTriggerFlanksMax(const Eigen::MatrixXd &data, int iTriggerChannelIdx, int iOffsetIndex, double dThreshold, bool bRemoveOffset, int iBurstLengthSamp=100)
void setAverageNumber(qint32 numAve)
void setBaselineTo(int toSamp, int toMSec)
MNEMath class declaration.
void setTriggerChIndx(qint32 idx)
void fillBackBuffer(const Eigen::MatrixXd &data, double dTriggerType)
MNEEpochDataList class declaration.
void mergeData(double dTriggerType)
QMap< double, qint32 > m_mapMatDataPostIdx
Definition: rtaveraging.h:263
void resultReady(const FIFFLIB::FiffEvokedSet &evokedStimSet, const QStringList &lResponsibleTriggerTypes)
void doAveraging(const Eigen::MatrixXd &rawSegment)
FIFFLIB::FiffInfo::SPtr m_pFiffInfo
Definition: rtaveraging.h:256
RtAveraging(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromSecs, quint32 iBaselineToSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo, QObject *parent=0)
FIFFLIB::FiffEvokedSet m_stimEvokedSet
Definition: rtaveraging.h:257
void setInfo(const FiffInfo &p_info, bool proj=true)
void setPreStim(qint32 samples, qint32 secs)
Eigen::MatrixXd data
Definition: fiff_evoked.h:231
void setPostStim(qint32 samples, qint32 secs)
void setBaselineFrom(int fromSamp, int fromMSec)
void append(const Eigen::MatrixXd &data)
QSharedPointer< FiffInfo > SPtr
Definition: fiff_info.h:87
void fillFrontBuffer(const Eigen::MatrixXd &data, double dTriggerType)
QMap< QString, double > m_mapThresholds
Definition: rtaveraging.h:259