65 using namespace Eigen;
73 quint32 iPreStimSamples,
74 quint32 iPostStimSamples,
75 quint32 iBaselineFromMSecs,
76 quint32 iBaselineToMSecs,
77 quint32 iTriggerIndex,
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)
99 qDebug() <<
"RtAveragingWorker::RtAveragingWorker - Number of averages <= 0. Setting to 1 as default.";
108 if(this->thread()->isInterruptionRequested()) {
124 qDebug() <<
"[RtAveragingWorker::setAverageNumber] Number of averages <= 0 are not allowed. Returning.";
132 QMutableMapIterator<double,QList<Eigen::MatrixXd> > idx(
m_mapStimAve);
134 while(idx.hasNext()) {
137 if(idx.value().size() > iDiff) {
139 for(
int i = 0; i < iDiff; ++i) {
140 idx.value().pop_front();
178 if(mapThresholds[
"Active"] == 0.0) {
238 for(
int i = 0; i < lDetectedTriggers.size(); ++i) {
240 double dTriggerType = lDetectedTriggers.at(i).second;
258 QStringList lResponsibleTriggerTypes;
260 while(idx.hasNext()) {
263 double dTriggerType = idx.key();
266 if(lDetectedTriggers.isEmpty()) {
279 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
282 if(lDetectedTriggers.isEmpty()) {
286 for(
int i = 0; i < lDetectedTriggers.size(); ++i) {
287 if(dTriggerType == lDetectedTriggers.at(i).second) {
288 int iTriggerPos = lDetectedTriggers.at(i).first;
294 tempMat = rawSegment.block(0,
299 tempMat = rawSegment.block(0,
308 if(rawSegment.cols() - iTriggerPos >=
m_mapDataPost[dTriggerType].cols()) {
313 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
320 rawSegment.cols() - iTriggerPos) = rawSegment.block(0,
323 rawSegment.cols() - iTriggerPos);
340 void RtAveragingWorker::emitEvoked(
double dTriggerType, QStringList& lResponsibleTriggerTypes)
349 if(!lResponsibleTriggerTypes.contains(QString::number(dTriggerType))) {
350 lResponsibleTriggerTypes << QString::number(dTriggerType);
365 int iResidualCols = data.cols();
368 m_mapDataPost[dTriggerType].block(0,m_mapMatDataPostIdx[dTriggerType],
m_mapDataPost[dTriggerType].rows(),iResidualCols) = data.block(0,0,data.rows(),iResidualCols);
382 if(dTriggerType != -1.0) {
398 int residual =
m_mapDataPre[dTriggerType].cols() - data.cols();
422 qDebug() <<
"[RtAveragingWorker::mergeData] Rows of m_mapDataPre (" <<
m_mapDataPre[dTriggerType].rows() <<
") and m_mapDataPost (" <<
m_mapDataPost[dTriggerType].rows() <<
") are not the same. Returning.";
431 bool bArtifactDetected =
false;
434 qDebug() <<
"[RtAveragingWorker::mergeData] Doing artifact reduction for" <<
m_mapThresholds;
436 bArtifactDetected = MNEEpochDataList::checkForArtifact(mergedData,
441 if(!bArtifactDetected) {
448 for(
int i = 0; i < iDiff; ++i) {
460 qDebug() <<
"[RtAveragingWorker::generateEvoked] m_mapStimAve is empty for type" << dTriggerType <<
"Returning.";
479 if(iEvokedIdx == -1) {
488 evoked.
comment = QString::number(dTriggerType);
494 for(
int i = 0; i <
m_mapStimAve[dTriggerType].size(); ++i) {
499 finalAverage = finalAverage/
m_mapStimAve[dTriggerType].size();
506 evoked.
data = finalAverage;
511 if(iEvokedIdx != -1) {
546 quint32 iPreStimSamples,
547 quint32 iPostStimSamples,
548 quint32 iBaselineFromSecs,
549 quint32 iBaselineToSecs,
550 quint32 iTriggerIndex,
555 qRegisterMetaType<Eigen::MatrixXd>(
"Eigen::MatrixXd");
567 worker, &QObject::deleteLater);
569 connect(
this, &RtAveraging::operate,
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,
614 const QStringList &lResponsibleTriggerTypes)
616 emit evokedStim(evokedStimSet,
617 lResponsibleTriggerTypes);
623 quint32 iPreStimSamples,
624 quint32 iPostStimSamples,
625 quint32 iBaselineFromSecs,
626 quint32 iBaselineToSecs,
627 quint32 iTriggerIndex,
642 worker, &QObject::deleteLater);
644 connect(
this, &RtAveraging::operate,
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,
685 emit averageNumberChanged(numAve);
695 emit averagePreStimChanged(samples,
706 emit averagePostStimChanged(samples,
714 emit averageTriggerChIdxChanged(idx);
721 emit averageArtifactReductionChanged(mapThresholds);
728 emit averageBaselineActiveChanged(activate);
736 emit averageBaselineFromChanged(fromSamp,
745 emit averageBaselineToChanged(toSamp,
753 emit averageResetRequested();
IOUtils class declaration.
void setPostStim(qint32 samples, qint32 secs)
QMap< double, Eigen::MatrixXd > m_mapDataPost
qint32 m_iNewPreStimSamples
QMap< double, Eigen::MatrixXd > m_mapDataPre
void setArtifactReduction(const QMap< QString, double > &mapThresholds)
Declaration of the RtAveraging and RtAveragingWorker classes.
void setAverageNumber(qint32 numAve)
qint32 m_iNewPostStimSamples
DetectTrigger declarations.
void setBaselineActive(bool activate)
void setPreStim(qint32 samples, qint32 secs)
QPair< float, float > baseline
void setArtifactReduction(const QMap< QString, double > &mapThresholds)
qint32 m_iNewTriggerIndex
QMap< double, QList< Eigen::MatrixXd > > m_mapStimAve
Real-time averaging worker.
QList< FiffEvoked > evoked
void setBaselineActive(bool activate)
RtAveragingWorker(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromMSecs, quint32 iBaselineToMSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
void setBaselineFrom(int fromSamp, int fromMSec)
bool m_bDoBaselineCorrection
bool controlValuesChanged()
QPair< float, float > m_pairBaselineSec
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)
QMap< double, bool > m_mapFillingBackBuffer
void doWork(const Eigen::MatrixXd &matData)
QPair< float, float > m_pairBaselineSamp
qint32 m_iPostStimSamples
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)
float m_fTriggerThreshold
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
void resultReady(const FIFFLIB::FiffEvokedSet &evokedStimSet, const QStringList &lResponsibleTriggerTypes)
void doAveraging(const Eigen::MatrixXd &rawSegment)
FIFFLIB::FiffInfo::SPtr m_pFiffInfo
RtAveraging(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromSecs, quint32 iBaselineToSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo, QObject *parent=0)
FIFFLIB::FiffEvokedSet m_stimEvokedSet
void setInfo(const FiffInfo &p_info, bool proj=true)
void setPreStim(qint32 samples, qint32 secs)
bool m_bActivateThreshold
void setPostStim(qint32 samples, qint32 secs)
void setTriggerChIndx(qint32 idx)
void setBaselineFrom(int fromSamp, int fromMSec)
void append(const Eigen::MatrixXd &data)
QSharedPointer< FiffInfo > SPtr
void fillFrontBuffer(const Eigen::MatrixXd &data, double dTriggerType)
QMap< QString, double > m_mapThresholds