55 #include <QMutexLocker>
76 , m_iNumAverages(numAverages)
77 , m_iPreStimSamples(p_iPreStimSamples)
78 , m_iPostStimSamples(p_iPostStimSamples)
79 , m_pFiffInfo(p_pFiffInfo)
83 qRegisterMetaType<FiffEvoked::SPtr>(
"FiffEvoked::SPtr");
100 QMutexLocker locker(&m_qMutex);
102 if(!m_pRawMatrixBuffer)
105 m_pRawMatrixBuffer->
push(&p_DataSegment);
114 m_iNumAverages = numAve;
124 QMutexLocker locker(&m_qMutex);
125 m_iNewPreStimSamples = samples;
133 QMutexLocker locker(&m_qMutex);
134 m_iNewPostStimSamples = samples;
140 void RtAve::assemblePostStimulus(
const QList<QPair<QList<qint32>, MatrixXd> > &p_qListRawMatBuf, qint32 p_iStimIdx)
142 QMutexLocker locker(&m_qMutex);
143 if(m_iPostStimSamples > 0)
146 float ratio = (float)m_iPreStimSamples/((
float)(m_iPreStimSamples+m_iPostStimSamples));
147 qint32 t_iBuffWithStim = floor((p_qListRawMatBuf.size()-1)*ratio) + 1;
149 qint32 nrows = p_qListRawMatBuf[t_iBuffWithStim].second.rows();
150 qint32 ncols = p_qListRawMatBuf[t_iBuffWithStim].second.cols();
153 qint32 t_iRowIdx = m_qListStimChannelIdcs[p_iStimIdx];
155 qint32 nSampleCount = 0;
157 MatrixXd t_matPostStim(nrows, m_iPostStimSamples);
158 qint32 t_curBufIdx = t_iBuffWithStim;
163 p_qListRawMatBuf[t_iBuffWithStim].second.row(t_iRowIdx).maxCoeff(&pos);
172 t_iSize = ncols - pos;
173 if(t_iSize <= m_iPostStimSamples)
175 t_matPostStim.block(0, 0, nrows, t_iSize) = p_qListRawMatBuf[t_iBuffWithStim].second.block(0, pos, nrows, t_iSize);
176 nSampleCount += t_iSize;
180 t_matPostStim.block(0, 0, nrows, m_iPostStimSamples) = p_qListRawMatBuf[t_iBuffWithStim].second.block(0, pos, nrows, m_iPostStimSamples);
181 nSampleCount = m_iPostStimSamples;
188 while(nSampleCount < m_iPostStimSamples)
190 t_iSize = m_iPostStimSamples-nSampleCount;
194 t_matPostStim.block(0, nSampleCount, nrows, ncols) = p_qListRawMatBuf[t_curBufIdx].second.block(0, 0, nrows, ncols);
195 nSampleCount += ncols;
199 t_matPostStim.block(0, nSampleCount, nrows, t_iSize) = p_qListRawMatBuf[t_curBufIdx].second.block(0, 0, nrows, t_iSize);
200 nSampleCount = m_iPostStimSamples;
209 m_qListQListPostStimBuf[p_iStimIdx].append(t_matPostStim);
216 void RtAve::assemblePreStimulus(
const QList<QPair<QList<qint32>, MatrixXd> > &p_qListRawMatBuf, qint32 p_iStimIdx)
218 QMutexLocker locker(&m_qMutex);
219 if(m_iPreStimSamples > 0)
222 float ratio = (float)m_iPreStimSamples/((
float)(m_iPreStimSamples+m_iPostStimSamples));
223 qint32 t_iBuffWithStim = floor((p_qListRawMatBuf.size()-1)*ratio) + 1;
224 qint32 nrows = p_qListRawMatBuf[t_iBuffWithStim].second.rows();
225 qint32 ncols = p_qListRawMatBuf[t_iBuffWithStim].second.cols();
228 qint32 t_iRowIdx = m_qListStimChannelIdcs[p_iStimIdx];
230 qint32 nSampleCount = m_iPreStimSamples;
232 MatrixXd t_matPreStim(nrows, m_iPreStimSamples);
233 qint32 t_curBufIdx = t_iBuffWithStim;
238 p_qListRawMatBuf[t_iBuffWithStim].second.row(t_iRowIdx).maxCoeff(&pos);
247 t_iStart = m_iPreStimSamples - pos;
250 t_matPreStim.block(0, t_iStart, nrows, pos) = p_qListRawMatBuf[t_iBuffWithStim].second.block(0, 0, nrows, pos);
255 t_matPreStim.block(0, 0, nrows, m_iPreStimSamples) = p_qListRawMatBuf[t_iBuffWithStim].second.block(0, -t_iStart, nrows, m_iPreStimSamples);
262 while(nSampleCount > 0)
264 t_iStart = nSampleCount - ncols;
268 t_matPreStim.block(0, t_iStart, nrows, ncols) = p_qListRawMatBuf[t_curBufIdx].second.block(0, 0, nrows, ncols);
269 nSampleCount -= ncols;
273 t_matPreStim.block(0, 0, nrows, nSampleCount) = p_qListRawMatBuf[t_curBufIdx].second.block(0, -t_iStart, nrows, nSampleCount);
283 m_qListQListPreStimBuf[p_iStimIdx].append(t_matPreStim);
311 m_bIsRunning =
false;
316 m_pRawMatrixBuffer->
clear();
330 quint32 t_nSamplesPerBuf = 0;
331 QList<QPair<QList<qint32>, MatrixXd> > t_qListRawMatBuf;
338 m_qListQListPreStimBuf.clear();
339 m_qListQListPostStimBuf.clear();
340 m_qListPreStimAve.clear();
341 m_qListPostStimAve.clear();
342 m_qListStimAve.clear();
347 m_qListStimChannelIdcs.clear();
349 QList<MatrixXd> t_qListMat;
350 for(i = 0; i < m_pFiffInfo->nchan; ++i)
352 if(m_pFiffInfo->chs[i].kind == FIFFV_STIM_CH && (m_pFiffInfo->chs[i].ch_name != QString(
"STI 014")))
354 m_qListStimChannelIdcs.append(i);
356 m_qListQListPreStimBuf.push_back(t_qListMat);
357 m_qListQListPostStimBuf.push_back(t_qListMat);
358 m_qListPreStimAve.push_back(t_mat);
359 m_qListPostStimAve.push_back(t_mat);
360 m_qListStimAve.push_back(t_mat);
365 float T = 1.0/m_pFiffInfo->sfreq;
369 t_preStimEvoked.
setInfo(*m_pFiffInfo.data());
370 t_preStimEvoked.
nave = m_iNumAverages;
372 t_preStimEvoked.
times.resize(m_iPreStimSamples);
373 t_preStimEvoked.
times[0] = -T*m_iPreStimSamples;
374 for(i = 1; i < t_preStimEvoked.
times.size(); ++i)
375 t_preStimEvoked.
times[i] = t_preStimEvoked.
times[i-1] + T;
376 t_preStimEvoked.
first = t_preStimEvoked.
times[0];
377 t_preStimEvoked.
last = t_preStimEvoked.
times[t_preStimEvoked.
times.size()-1];
381 t_postStimEvoked.
setInfo(*m_pFiffInfo.data());
382 t_postStimEvoked.
nave = m_iNumAverages;
384 t_postStimEvoked.
times.resize(m_iPostStimSamples);
385 t_postStimEvoked.
times[0] = 0;
386 for(i = 1; i < t_postStimEvoked.
times.size(); ++i)
387 t_postStimEvoked.
times[i] = t_postStimEvoked.
times[i-1] + T;
388 t_postStimEvoked.
first = t_postStimEvoked.
times[0];
389 t_postStimEvoked.
last = t_postStimEvoked.
times[t_postStimEvoked.
times.size()-1];
393 t_stimEvoked.
setInfo(*m_pFiffInfo.data());
394 t_stimEvoked.
nave = m_iNumAverages;
396 t_stimEvoked.
times.resize(m_iPreStimSamples+m_iPostStimSamples);
397 t_stimEvoked.
times[0] = -T*m_iPreStimSamples;
398 for(i = 1; i < t_stimEvoked.
times.size(); ++i)
399 t_stimEvoked.
times[i] = t_stimEvoked.
times[i-1] + T;
401 t_stimEvoked.
last = t_stimEvoked.
times[t_stimEvoked.
times.size()-1];
406 m_iNewPreStimSamples = m_iPreStimSamples;
407 m_iNewPostStimSamples = m_iPostStimSamples;
415 QMutexLocker locker(&m_qMutex);
420 bool doProcessing =
false;
422 QMutexLocker locker(&m_qMutex);
423 if(m_pRawMatrixBuffer)
433 if(m_iNewPreStimSamples != m_iPreStimSamples || m_iNewPostStimSamples != m_iPostStimSamples)
435 m_iPreStimSamples = m_iNewPreStimSamples;
436 m_iPostStimSamples = m_iNewPostStimSamples;
439 t_preStimEvoked.
times.resize(m_iPreStimSamples);
440 t_preStimEvoked.
times[0] = -T*m_iPreStimSamples;
441 for(i = 1; i < t_preStimEvoked.
times.size(); ++i)
442 t_preStimEvoked.
times[i] = t_preStimEvoked.
times[i-1] + T;
443 t_preStimEvoked.
first = t_preStimEvoked.
times[0];
444 t_preStimEvoked.
last = t_preStimEvoked.
times[t_preStimEvoked.
times.size()-1];
447 t_postStimEvoked.
times.resize(m_iPostStimSamples);
448 t_postStimEvoked.
times[0] = 0;
449 for(i = 1; i < t_postStimEvoked.
times.size(); ++i)
450 t_postStimEvoked.
times[i] = t_postStimEvoked.
times[i-1] + T;
451 t_postStimEvoked.
first = t_postStimEvoked.
times[0];
452 t_postStimEvoked.
last = t_postStimEvoked.
times[t_postStimEvoked.
times.size()-1];
455 t_stimEvoked.
times.resize(m_iPreStimSamples+m_iPostStimSamples);
456 t_stimEvoked.
times[0] = -T*m_iPreStimSamples;
457 for(i = 1; i < t_stimEvoked.
times.size(); ++i)
458 t_stimEvoked.
times[i] = t_stimEvoked.
times[i-1] + T;
460 t_stimEvoked.
last = t_stimEvoked.
times[t_stimEvoked.
times.size()-1];
464 t_qListRawMatBuf.clear();
465 m_qListPreStimAve.clear();
466 m_qListPostStimAve.clear();
467 m_qListStimAve.clear();
469 for(qint32 i = 0; i < m_qListQListPreStimBuf.size(); ++i)
471 m_qListQListPreStimBuf[i].clear();
472 m_qListQListPostStimBuf[i].clear();
473 m_qListPreStimAve.push_back(t_resetMat);
474 m_qListPostStimAve.push_back(t_resetMat);
475 m_qListStimAve.push_back(t_resetMat);
483 MatrixXd rawSegment = m_pRawMatrixBuffer->
pop();
484 if(t_nSamplesPerBuf == 0)
485 t_nSamplesPerBuf = rawSegment.cols();
492 QList<qint32> t_qListStimuli;
493 for(i = 0; i < m_qListStimChannelIdcs.size(); ++i)
495 qint32 idx = m_qListStimChannelIdcs[i];
496 RowVectorXi stimSegment = rawSegment.row(idx).cast<
int>();
497 int iMax = stimSegment.maxCoeff();
500 t_qListStimuli.append(i);
506 t_qListRawMatBuf.push_back(qMakePair(t_qListStimuli, rawSegment));
509 qint32 minSize = (m_iPreStimSamples+m_iPostStimSamples) + (2 * t_nSamplesPerBuf);
512 if(t_nSamplesPerBuf*t_qListRawMatBuf.size() > minSize)
517 float ratio = (float)m_iPreStimSamples/((
float)(m_iPreStimSamples+m_iPostStimSamples));
518 qint32 t_iBuffWithStim = floor((t_qListRawMatBuf.size()-1)*ratio) + 1;
520 if(t_iBuffWithStim > 0 && t_qListRawMatBuf[t_iBuffWithStim].first.size() != 0)
522 for(i = 0; i < t_qListRawMatBuf[t_iBuffWithStim].first.size(); ++i)
525 if(!t_qListRawMatBuf[t_iBuffWithStim-1].first.contains(t_qListRawMatBuf[t_iBuffWithStim].first[i]))
527 qint32 t_iStimIndex = t_qListRawMatBuf[t_iBuffWithStim].first[i];
532 this->assemblePreStimulus(t_qListRawMatBuf, t_iStimIndex);
537 this->assemblePostStimulus(t_qListRawMatBuf, t_iStimIndex);
539 qDebug() << m_pFiffInfo->ch_names[m_qListStimChannelIdcs[t_iStimIndex]] <<
": Buffer Size" << m_qListQListPreStimBuf[t_iStimIndex].size();
544 if(m_qListQListPreStimBuf[t_iStimIndex].size() >= m_iNumAverages)
546 while(m_qListQListPreStimBuf[t_iStimIndex].size() >= (m_iNumAverages+1))
547 m_qListQListPreStimBuf[t_iStimIndex].pop_front();
549 m_qListPreStimAve[t_iStimIndex] = m_qListQListPreStimBuf[t_iStimIndex][0];
550 for(j = 1; j < m_qListQListPreStimBuf[t_iStimIndex].size(); ++j)
551 m_qListPreStimAve[t_iStimIndex] += m_qListQListPreStimBuf[t_iStimIndex][j];
553 m_qListPreStimAve[t_iStimIndex].array() /= (double)m_iNumAverages;
555 m_qListQListPreStimBuf[t_iStimIndex].pop_front();
563 if(m_qListQListPostStimBuf[t_iStimIndex].size() >= m_iNumAverages)
565 while(m_qListQListPostStimBuf[t_iStimIndex].size() >= (m_iNumAverages+1))
566 m_qListQListPostStimBuf[t_iStimIndex].pop_front();
568 m_qListPostStimAve[t_iStimIndex] = m_qListQListPostStimBuf[t_iStimIndex][0];
569 for(j = 1; j < m_qListQListPostStimBuf[t_iStimIndex].size(); ++j)
570 m_qListPostStimAve[t_iStimIndex] += m_qListQListPostStimBuf[t_iStimIndex][j];
572 m_qListPostStimAve[t_iStimIndex].array() /= (double)m_iNumAverages;
574 m_qListQListPostStimBuf[t_iStimIndex].pop_front();
580 if(m_qListPreStimAve[t_iStimIndex].size() > 0)
585 m_qListStimAve[t_iStimIndex].resize(m_qListPreStimAve[t_iStimIndex].rows(), m_qListPreStimAve[t_iStimIndex].cols() + m_qListPostStimAve[t_iStimIndex].cols());
587 m_qListStimAve[t_iStimIndex].block(0,0,m_qListPreStimAve[t_iStimIndex].rows(),m_qListPreStimAve[t_iStimIndex].cols()) = m_qListPreStimAve[t_iStimIndex];
589 m_qListStimAve[t_iStimIndex].block(0,m_qListPreStimAve[t_iStimIndex].cols(),m_qListPostStimAve[t_iStimIndex].rows(),m_qListPostStimAve[t_iStimIndex].cols()) = m_qListPostStimAve[t_iStimIndex];
594 QString t_sStimChName = m_pFiffInfo->ch_names[m_qListStimChannelIdcs[t_iStimIndex]];
596 t_pEvokedPreStim->nave = m_iNumAverages;
597 t_pEvokedPreStim->comment = t_sStimChName;
598 t_pEvokedPreStim->data = m_qListPreStimAve[t_iStimIndex];
602 t_pEvokedPostStim->nave = m_iNumAverages;
603 t_pEvokedPostStim->comment = t_sStimChName;
604 t_pEvokedPostStim->data = m_qListPostStimAve[t_iStimIndex];
608 t_pEvokedStim->nave = m_iNumAverages;
609 t_pEvokedStim->comment = t_sStimChName;
610 t_pEvokedStim->data = m_qListStimAve[t_iStimIndex];
622 t_qListRawMatBuf.pop_front();
RtAve(quint32 numAverages, quint32 p_iPreStimSamples, quint32 p_iPostStimSamples, FiffInfo::SPtr p_pFiffInfo, QObject *parent=0)
void evokedPostStim(FIFFLIB::FiffEvoked::SPtr p_pEvokedPostStim)
void numAveragesChanged()
void setPreStim(qint32 samples)
void evokedStim(FIFFLIB::FiffEvoked::SPtr p_pEvokedStim)
QSharedPointer< CircularMatrixBuffer > SPtr
QSharedPointer< FiffInfo > SPtr
void push(const Matrix< _Tp, Dynamic, Dynamic > *pMatrix)
QSharedPointer< FiffEvoked > SPtr
void setAverages(qint32 numAve)
void setPostStim(qint32 samples)
#define FIFFV_ASPECT_AVERAGE
Matrix< _Tp, Dynamic, Dynamic > pop()
void evokedPreStim(FIFFLIB::FiffEvoked::SPtr p_pEvokedPreStim)
void append(const MatrixXd &p_DataSegment)
IOUtils class declaration.
void setInfo(FiffInfo &p_info, bool proj=true)