50 quint32 iPreStimSamples,
51 quint32 iPostStimSamples,
52 quint32 iBaselineFromMSecs,
53 quint32 iBaselineToMSecs,
54 quint32 iTriggerIndex,
76 qDebug() <<
"RtAveragingWorker::RtAveragingWorker - Number of averages <= 0. Setting to 1 as default.";
85 if(this->thread()->isInterruptionRequested()) {
101 qDebug() <<
"[RtAveragingWorker::setAverageNumber] Number of averages <= 0 are not allowed. Returning.";
109 QMutableMapIterator<double,QList<Eigen::MatrixXd> > idx(
m_mapStimAve);
111 while(idx.hasNext()) {
114 if(idx.value().size() > iDiff) {
116 for(
int i = 0; i < iDiff; ++i) {
117 idx.value().pop_front();
155 if(mapThresholds[
"Active"] == 0.0) {
215 for(
int i = 0; i < lDetectedTriggers.size(); ++i) {
217 double dTriggerType = lDetectedTriggers.at(i).second;
235 QStringList lResponsibleTriggerTypes;
237 while(idx.hasNext()) {
240 double dTriggerType = idx.key();
243 if(lDetectedTriggers.isEmpty()) {
256 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
259 if(lDetectedTriggers.isEmpty()) {
263 for(
int i = 0; i < lDetectedTriggers.size(); ++i) {
264 if(dTriggerType == lDetectedTriggers.at(i).second) {
265 int iTriggerPos = lDetectedTriggers.at(i).first;
271 tempMat = rawSegment.block(0,
276 tempMat = rawSegment.block(0,
285 if(rawSegment.cols() - iTriggerPos >=
m_mapDataPost[dTriggerType].cols()) {
290 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
297 rawSegment.cols() - iTriggerPos) = rawSegment.block(0,
300 rawSegment.cols() - iTriggerPos);
326 if(!lResponsibleTriggerTypes.contains(QString::number(dTriggerType))) {
327 lResponsibleTriggerTypes << QString::number(dTriggerType);
342 int iResidualCols = data.cols();
359 if(dTriggerType != -1.0) {
375 int residual =
m_mapDataPre[dTriggerType].cols() - data.cols();
399 qDebug() <<
"[RtAveragingWorker::mergeData] Rows of m_mapDataPre (" <<
m_mapDataPre[dTriggerType].rows() <<
") and m_mapDataPost (" <<
m_mapDataPost[dTriggerType].rows() <<
") are not the same. Returning.";
408 bool bArtifactDetected =
false;
411 qDebug() <<
"[RtAveragingWorker::mergeData] Doing artifact reduction for" <<
m_mapThresholds;
418 if(!bArtifactDetected) {
425 for(
int i = 0; i < iDiff; ++i) {
437 qDebug() <<
"[RtAveragingWorker::generateEvoked] m_mapStimAve is empty for type" << dTriggerType <<
"Returning.";
448 if(
m_stimEvokedSet.evoked.at(i).comment == QString::number(dTriggerType)) {
456 if(iEvokedIdx == -1) {
465 evoked.
comment = QString::number(dTriggerType);
471 for(
int i = 0; i <
m_mapStimAve[dTriggerType].size(); ++i) {
476 finalAverage = finalAverage/
m_mapStimAve[dTriggerType].size();
483 evoked.
data = finalAverage;
488 if(iEvokedIdx != -1) {
523 quint32 iPreStimSamples,
524 quint32 iPostStimSamples,
525 quint32 iBaselineFromSecs,
526 quint32 iBaselineToSecs,
527 quint32 iTriggerIndex,
532 qRegisterMetaType<Eigen::MatrixXd>(
"Eigen::MatrixXd");
544 worker, &QObject::deleteLater);
591 const QStringList &lResponsibleTriggerTypes)
594 lResponsibleTriggerTypes);
600 quint32 iPreStimSamples,
601 quint32 iPostStimSamples,
602 quint32 iBaselineFromSecs,
603 quint32 iBaselineToSecs,
604 quint32 iTriggerIndex,
619 worker, &QObject::deleteLater);
Header-only Eigen matrix text I/O — round-trips dense matrices to whitespace-separated ASCII for cros...
Ordered list of MNELIB::MNEEpochData objects sharing a common FIFFLIB::FiffInfo.
General numerical helpers: GCD, log2, histogram binning, baseline rescaling, sparsity tests.
Real-time stimulus-locked averaging worker producing running evoked responses.
Threshold and edge-based trigger detection on streaming stim channels.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O, in-memory data structures and high-level readers/writers.
DSPSHARED_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)
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Background worker thread that accumulates and averages epochs in real time.
bool controlValuesChanged()
void emitEvoked(double dTriggerType, QStringList &lResponsibleTriggerTypes)
void setArtifactReduction(const QMap< QString, double > &mapThresholds)
void fillFrontBuffer(const Eigen::MatrixXd &data, double dTriggerType)
qint32 m_iNewTriggerIndex
qint32 m_iPostStimSamples
FIFFLIB::FiffInfo::SPtr m_pFiffInfo
qint32 m_iNewPreStimSamples
QPair< float, float > m_pairBaselineSec
void setAverageNumber(qint32 numAve)
QMap< double, bool > m_mapFillingBackBuffer
void setTriggerChIndx(qint32 idx)
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)
bool m_bActivateThreshold
FIFFLIB::FiffEvokedSet m_stimEvokedSet
void doAveraging(const Eigen::MatrixXd &rawSegment)
qint32 m_iNewPostStimSamples
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)
float m_fTriggerThreshold
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)
bool m_bDoBaselineCorrection
void mergeData(double dTriggerType)
void generateEvoked(double dTriggerType)
void averageBaselineToChanged(int toSamp, int toMSec)
void setBaselineFrom(int fromSamp, int fromMSec)
void averageBaselineActiveChanged(bool activate)
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 averagePostStimChanged(qint32 samples, qint32 secs)
void setBaselineTo(int toSamp, int toMSec)
void averageNumberChanged(qint32 numAve)
void averagePreStimChanged(qint32 samples, qint32 secs)
void setAverageNumber(qint32 numAve)
void append(const Eigen::MatrixXd &data)
void averageArtifactReductionChanged(const QMap< QString, double > &mapThresholds)
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 evokedStim(const FIFFLIB::FiffEvokedSet &evokedStimSet, const QStringList &lResponsibleTriggerTypes)
void averageBaselineFromChanged(int fromSamp, int fromMSec)
void averageTriggerChIdxChanged(qint32 idx)
void restart(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, quint32 iBaselineFromSecs, quint32 iBaselineToSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
void averageResetRequested()
void operate(const Eigen::MatrixXd &matData)
Single averaged evoked response: time axis, data, baseline, channel info and averaging metadata.
void setInfo(const FiffInfo &p_info, bool proj=true)
QPair< float, float > baseline
Set of FiffEvoked instances sharing one FiffInfo, plus channel-picking and compensation helpers.
QSharedPointer< FiffInfo > SPtr
static Eigen::MatrixXd rescale(const Eigen::MatrixXd &data, const Eigen::RowVectorXf ×, const QPair< float, float > &baseline, QString mode)
static bool checkForArtifact(const Eigen::MatrixXd &data, const FIFFLIB::FiffInfo &pFiffInfo, const QMap< QString, double > &mapReject, const QStringList &lExcludeChs=QStringList())