50 quint32 iPreStimSamples,
51 quint32 iPostStimSamples,
52 qint32 iBaselineFromMSecs,
53 qint32 iBaselineToMSecs,
54 quint32 iTriggerIndex,
65,
m_pairBaselineSec(qMakePair(float(iBaselineFromMSecs) / 1000.0f, float(iBaselineToMSecs) / 1000.0f))
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;
229 MatrixXd matHistoryAndBlock(rawSegment.rows(),
m_matPreHistory.cols() + rawSegment.cols());
234 QStringList lResponsibleTriggerTypes;
236 while (idx.hasNext()) {
239 double dTriggerType = idx.key();
250 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
253 for (
int i = 0; i < lDetectedTriggers.size(); ++i) {
254 if (dTriggerType == lDetectedTriggers.at(i).second) {
255 int iTriggerPos = lDetectedTriggers.at(i).first;
260 if (rawSegment.cols() - iTriggerPos >=
m_mapDataPost[dTriggerType].cols()) {
265 emitEvoked(dTriggerType, lResponsibleTriggerTypes);
272 rawSegment.cols() - iTriggerPos) = rawSegment.block(0,
275 rawSegment.cols() - iTriggerPos);
298 if (!lResponsibleTriggerTypes.contains(QString::number(dTriggerType))) {
299 lResponsibleTriggerTypes << QString::number(dTriggerType);
314 int iResidualCols = data.cols();
330 qDebug() <<
"[RtAveragingWorker::mergeData] Rows of m_mapDataPre (" <<
m_mapDataPre[dTriggerType].rows() <<
") and m_mapDataPost (" <<
m_mapDataPost[dTriggerType].rows() <<
") are not the same. Returning.";
339 bool bArtifactDetected =
false;
342 qDebug() <<
"[RtAveragingWorker::mergeData] Doing artifact reduction for" <<
m_mapThresholds;
349 if (!bArtifactDetected) {
356 for (
int i = 0; i < iDiff; ++i) {
368 qDebug() <<
"[RtAveragingWorker::generateEvoked] m_mapStimAve is empty for type" << dTriggerType <<
"Returning.";
379 if (
m_stimEvokedSet.evoked.at(i).comment == QString::number(dTriggerType)) {
387 if (iEvokedIdx == -1) {
395 evoked.
comment = QString::number(dTriggerType);
401 for (
int i = 0; i <
m_mapStimAve[dTriggerType].size(); ++i) {
406 finalAverage = finalAverage /
m_mapStimAve[dTriggerType].size();
413 evoked.
data = finalAverage;
418 if (iEvokedIdx != -1) {
453 quint32 iPreStimSamples,
454 quint32 iPostStimSamples,
455 qint32 iBaselineFromMSecs,
456 qint32 iBaselineToMSecs,
457 quint32 iTriggerIndex,
462 qRegisterMetaType<Eigen::MatrixXd>(
"Eigen::MatrixXd");
474 worker, &QObject::deleteLater);
521 const QStringList& lResponsibleTriggerTypes)
524 lResponsibleTriggerTypes);
530 quint32 iPreStimSamples,
531 quint32 iPostStimSamples,
532 qint32 iBaselineFromMSecs,
533 qint32 iBaselineToMSecs,
534 quint32 iTriggerIndex,
549 worker, &QObject::deleteLater);
Header-only Eigen matrix text I/O — round-trips dense matrices to whitespace-separated ASCII for cros...
Threshold and edge-based trigger detection on streaming stim channels.
Real-time stimulus-locked averaging worker producing running evoked responses.
General numerical helpers: GCD, log2, histogram binning, baseline rescaling, sparsity tests.
Ordered list of MNELIB::MNEEpochData objects sharing a common FIFFLIB::FiffInfo.
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)
qint32 m_iNewTriggerIndex
qint32 m_iPostStimSamples
FIFFLIB::FiffInfo::SPtr m_pFiffInfo
QPair< float, float > m_pairBaselineSamp
qint32 m_iNewPreStimSamples
void setAverageNumber(qint32 numAve)
void setTriggerChIndx(qint32 idx)
RtAveragingWorker(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, qint32 iBaselineFromMSecs, qint32 iBaselineToMSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
Eigen::MatrixXd m_matPreHistory
QMap< double, qint32 > m_mapMatDataPostIdx
QMap< double, Eigen::MatrixXd > m_mapDataPost
void setBaselineTo(int toSamp, int toMSec)
QMap< double, Eigen::MatrixXd > m_mapDataPre
QMap< QString, double > m_mapThresholds
bool m_bActivateThreshold
FIFFLIB::FiffEvokedSet m_stimEvokedSet
QPair< float, float > m_pairBaselineSec
void doAveraging(const Eigen::MatrixXd &rawSegment)
qint32 m_iNewPostStimSamples
QMap< double, bool > m_mapFillingBackBuffer
void setBaselineActive(bool activate)
void doWork(const Eigen::MatrixXd &matData)
void setPostStim(qint32 samples, qint32 secs)
float m_fTriggerThreshold
QMap< double, QList< Eigen::MatrixXd > > m_mapStimAve
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 restart(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, qint32 iBaselineFromMSecs, qint32 iBaselineToMSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo)
void averageBaselineActiveChanged(bool activate)
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)
RtAveraging(quint32 numAverages, quint32 iPreStimSamples, quint32 iPostStimSamples, qint32 iBaselineFromMSecs, qint32 iBaselineToMSecs, quint32 iTriggerIndex, FIFFLIB::FiffInfo::SPtr pFiffInfo, QObject *parent=0)
void averageResetRequested()
void operate(const Eigen::MatrixXd &matData)
Single averaged evoked response: time axis, data, baseline, channel info and averaging metadata.
QPair< float, float > baseline
void setInfo(const FiffInfo &p_info, bool applyProj=true)
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())