MNE-CPP  0.1.9
A Framework for Electrophysiology
rtsourcedataworker.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "rtsourcedataworker.h"
42 #include "../../../../helpers/interpolation/interpolation.h"
43 #include "../../items/common/abstractmeshtreeitem.h"
44 
45 //=============================================================================================================
46 // QT INCLUDES
47 //=============================================================================================================
48 
49 #include <QVector3D>
50 #include <QDebug>
51 #include <QElapsedTimer>
52 #include <QtConcurrent>
53 
54 //=============================================================================================================
55 // EIGEN INCLUDES
56 //=============================================================================================================
57 
58 #include <Eigen/Core>
59 
60 //=============================================================================================================
61 // USED NAMESPACES
62 //=============================================================================================================
63 
64 using namespace DISP3DLIB;
65 using namespace Eigen;
66 using namespace DISPLIB;
67 using namespace FIFFLIB;
68 
69 //=============================================================================================================
70 // DEFINE MEMBER METHODS
71 //=============================================================================================================
72 
74 : m_bIsLooping(true)
75 , m_iAverageSamples(1)
76 , m_dSFreq(1000.0)
77 , m_bStreamSmoothedData(true)
78 , m_iCurrentSample(0)
79 , m_iSampleCtr(0)
80 {
81  VisualizationInfo leftHemiInfo;
82  VisualizationInfo rightHemiInfo;
83  leftHemiInfo.pMatInterpolationMatrix = QSharedPointer<SparseMatrix<float> >(new SparseMatrix<float>());
84  rightHemiInfo.pMatInterpolationMatrix = QSharedPointer<SparseMatrix<float> >(new SparseMatrix<float>());
85  m_lHemiVisualizationInfo << leftHemiInfo << rightHemiInfo;
86 }
87 
88 //=============================================================================================================
89 
90 void RtSourceDataWorker::addData(const MatrixXd& data)
91 {
92  if(data.rows() == 0) {
93  qDebug() <<"RtSourceDataWorker::addData - Passed data is empty!";
94  return;
95  }
96 
97  //Transform from matrix to list for easier handling in non loop mode
98  for(int i = 0; i<data.cols(); i++) {
99  if(m_lDataQ.size() < m_dSFreq) {
100  m_lDataQ.push_back(data.col(i));
101  } else {
102  qDebug() <<"RtSourceDataWorker::addData - worker is full ("<<m_lDataQ.size()<<")";
103  break;
104  }
105  }
106 
108 }
109 
110 //=============================================================================================================
111 
112 void RtSourceDataWorker::setSurfaceColor(const MatrixX4f &matColorLeft,
113  const MatrixX4f &matColorRight)
114 {
115  m_lHemiVisualizationInfo[0].matOriginalVertColor = matColorLeft;
116  m_lHemiVisualizationInfo[1].matOriginalVertColor = matColorRight;
117 }
118 
119 //=============================================================================================================
120 
122 {
123  m_iAverageSamples = iNumAvr;
124 }
125 
126 //=============================================================================================================
127 
128 void RtSourceDataWorker::setStreamSmoothedData(bool bStreamSmoothedData)
129 {
130  m_bStreamSmoothedData = bStreamSmoothedData;
131 }
132 
133 //=============================================================================================================
134 
135 void RtSourceDataWorker::setColormapType(const QString& sColormapType)
136 {
137  //Create function handler to corresponding color map function
138  m_lHemiVisualizationInfo[0].sColormapType = sColormapType;
139  m_lHemiVisualizationInfo[1].sColormapType = sColormapType;
140 }
141 
142 //=============================================================================================================
143 
144 void RtSourceDataWorker::setThresholds(const QVector3D& vecThresholds)
145 {
146  m_lHemiVisualizationInfo[0].dThresholdX = vecThresholds.x();
147  m_lHemiVisualizationInfo[0].dThresholdZ = vecThresholds.z();
148  m_lHemiVisualizationInfo[1].dThresholdX = vecThresholds.x();
149  m_lHemiVisualizationInfo[1].dThresholdZ = vecThresholds.z();
150 }
151 
152 //=============================================================================================================
153 
154 void RtSourceDataWorker::setLoopState(bool bLoopState)
155 {
156  m_bIsLooping = bLoopState;
157 }
158 
159 //=============================================================================================================
160 
161 void RtSourceDataWorker::setSFreq(const double dSFreq)
162 {
163  m_dSFreq = dSFreq;
164 }
165 
166 //=============================================================================================================
167 
168 void RtSourceDataWorker::setInterpolationMatrixLeft(QSharedPointer<Eigen::SparseMatrix<float> > pMatInterpolationMatrixLeft)
169 {
170  m_lHemiVisualizationInfo[0].pMatInterpolationMatrix = pMatInterpolationMatrixLeft;
171 }
172 
173 //=============================================================================================================
174 
175 void RtSourceDataWorker::setInterpolationMatrixRight(QSharedPointer<Eigen::SparseMatrix<float> > pMatInterpolationMatrixRight)
176 {
177  m_lHemiVisualizationInfo[1].pMatInterpolationMatrix = pMatInterpolationMatrixRight;
178 }
179 
180 //=============================================================================================================
181 
183 {
184 // QElapsedTimer timer;
185 // qint64 iTime = 0;
186 // timer.start();
187 
188  if(m_iAverageSamples != 0 && !m_lDataLoopQ.isEmpty()) {
189  int iSampleCtr = 0;
190 
191  //Perform the actual interpolation and send signal
192  while((iSampleCtr <= m_iAverageSamples)) {
193  if(m_lDataQ.isEmpty()) {
194  if(m_bIsLooping && !m_lDataLoopQ.isEmpty()) {
195  if(m_vecAverage.rows() != m_lDataLoopQ.front().rows()) {
196  m_vecAverage = m_lDataLoopQ.front();
198  iSampleCtr++;
199  } else if (m_iCurrentSample < m_lDataLoopQ.size()){
202  iSampleCtr++;
203  }
204 
205  //Set iterator back to the front if needed
206  if(m_iCurrentSample >= m_lDataLoopQ.size()) {
207  m_iCurrentSample = 0;
208  break;
209  }
210  } else {
211  return;
212  }
213  } else {
214  if(m_vecAverage.rows() != m_lDataQ.front().rows()) {
215  m_vecAverage = m_lDataQ.takeFirst();
217  iSampleCtr++;
218  } else {
219  m_vecAverage += m_lDataQ.takeFirst();
221  iSampleCtr++;
222  }
223 
224  //Set iterator back to the front if needed
225  if(m_iCurrentSample >= m_lDataQ.size()) {
226  m_iCurrentSample = 0;
227  break;
228  }
229  }
230  }
231 
232  if(m_lHemiVisualizationInfo[0].pMatInterpolationMatrix->cols() != 0
233  && m_lHemiVisualizationInfo[1].pMatInterpolationMatrix->cols() != 0) {
234  //Perform the actual interpolation and send signal
235  m_vecAverage /= (double)m_iAverageSamples;
236 
238  m_lHemiVisualizationInfo[0].vecSensorValues = m_vecAverage.segment(0, m_lHemiVisualizationInfo[0].pMatInterpolationMatrix->cols());
239  m_lHemiVisualizationInfo[1].vecSensorValues = m_vecAverage.segment(m_lHemiVisualizationInfo[0].pMatInterpolationMatrix->cols(), m_lHemiVisualizationInfo[1].pMatInterpolationMatrix->cols());
240 
241  //Do calculations for both hemispheres in parallel
242  QFuture<void> result = QtConcurrent::map(m_lHemiVisualizationInfo,
244  result.waitForFinished();
245 
246  emit newRtSmoothedData(m_lHemiVisualizationInfo[0].matFinalVertColor,
247  m_lHemiVisualizationInfo[1].matFinalVertColor);
248  } else {
249  emit newRtRawData(m_vecAverage.segment(0, m_lHemiVisualizationInfo[0].pMatInterpolationMatrix->cols()),
250  m_vecAverage.segment(m_lHemiVisualizationInfo[0].pMatInterpolationMatrix->cols(), m_lHemiVisualizationInfo[1].pMatInterpolationMatrix->cols()));
251  }
252  m_vecAverage.setZero(m_vecAverage.rows());
253  }
254  }
255 
256 //iTime = timer.elapsed();
257 //qWarning() << "RtSourceDataWorker::streamData iTime" << iTime;
258 //timer.restart();
259 
260  //qDebug()<<"RtSourceDataWorker::streamData - this->thread() "<< this->thread();
261  //qDebug()<<"RtSourceDataWorker::streamData - time.elapsed()" << time.elapsed();
262 }
263 
264 //=============================================================================================================
265 
267 {
268  if(visualizationInfoHemi.vecSensorValues.rows() != visualizationInfoHemi.pMatInterpolationMatrix->cols()) {
269  qDebug() << "RtSourceDataWorker::generateColorsFromSensorValues - Number of new vertex colors (" << visualizationInfoHemi.vecSensorValues.rows() << ") do not match with previously set number of sensors (" << visualizationInfoHemi.pMatInterpolationMatrix->cols() << "). Returning...";
270  return;
271  }
272 
273  // interpolate sensor signals
274  VectorXf vecIntrpltdVals = Interpolation::interpolateSignal(*visualizationInfoHemi.pMatInterpolationMatrix, visualizationInfoHemi.vecSensorValues.cast<float>());
275 
276  // Reset to original color as default
277  visualizationInfoHemi.matFinalVertColor = visualizationInfoHemi.matOriginalVertColor;
278 
279  //Generate color data for vertices
280  normalizeAndTransformToColor(vecIntrpltdVals,
281  visualizationInfoHemi.matFinalVertColor,
282  visualizationInfoHemi.dThresholdX,
283  visualizationInfoHemi.dThresholdZ,
284  visualizationInfoHemi.functionHandlerColorMap,
285  visualizationInfoHemi.sColormapType);
286 }
287 
288 //=============================================================================================================
289 
291  MatrixX4f& matFinalVertColor,
292  double dThresholdX,
293  double dThresholdZ,
294  QRgb (*functionHandlerColorMap)(double v, const QString& sColorMap),
295  const QString& sColorMap)
296 {
297  //Note: This function needs to be implemented extremly efficient.
298  if(vecData.rows() != matFinalVertColor.rows()) {
299  qDebug() << "RtSourceDataWorker::normalizeAndTransformToColor - Sizes of input data (" << vecData.rows() <<") do not match output data ("<< matFinalVertColor.rows() <<"). Returning ...";
300  return;
301  }
302 
303  float fSample;
304  QRgb qRgb;
305  const double dTresholdDiff = dThresholdZ - dThresholdX;
306 
307  for(int r = 0; r < vecData.rows(); ++r) {
308  //Take the absolute values because the histogram threshold is also calcualted using the absolute values
309  fSample = std::fabs(vecData(r));
310 
311  if(fSample >= dThresholdX) {
312  //Check lower and upper thresholds and normalize to one
313  if(fSample >= dThresholdZ) {
314  fSample = 1.0f;
315  } else {
316  if(fSample != 0.0f && dTresholdDiff != 0.0 ) {
317  fSample = (fSample - dThresholdX) / (dTresholdDiff);
318  } else {
319  fSample = 0.0f;
320  }
321  }
322 
323  qRgb = functionHandlerColorMap(fSample, sColorMap);
324 
325  QColor color(qRgb);
326 // QColor color (matFinalVertColor(r,0) * 255 * (1.0-0.60) + (float)qRed(qRgb)*0.60,
327 // matFinalVertColor(r,1) * 255 * (1.0-0.60) + (float)qGreen(qRgb)*0.60,
328 // matFinalVertColor(r,2) * 255 * (1.0-0.60) + (float)qBlue(qRgb)*0.60,
329 // 255.0 + 0.75 * (255.0-255.0));
330 
331  //qDebug() << "RtSourceDataWorker::normalizeAndTransformToColor color" << color;
332 
333  matFinalVertColor(r,0) = color.redF();
334  matFinalVertColor(r,1) = color.greenF();
335  matFinalVertColor(r,2) = color.blueF();
336  matFinalVertColor(r,3) = color.alphaF();
337 
338 // matFinalVertColor(r,0) = (float)qRed(qRgb)/255.0f;
339 // matFinalVertColor(r,1) = (float)qGreen(qRgb)/255.0f;
340 // matFinalVertColor(r,2) = (float)qBlue(qRgb)/255.0f;
341 // matFinalVertColor(r,3) = 1.0f;
342  } else {
343  matFinalVertColor(r,3) = 0.0f; //Use this if you want only vertices with activation to be plotted
344  }
345  }
346 }
void setColormapType(const QString &sColormapType)
void setSurfaceColor(const Eigen::MatrixX4f &matColorLeft, const Eigen::MatrixX4f &matColorRight)
void setInterpolationMatrixLeft(QSharedPointer< Eigen::SparseMatrix< float > > pMatInterpolationMatrixLeft)
void newRtRawData(const Eigen::VectorXd &vecDataVectorLeftHemi, const Eigen::VectorXd &vecDataVectorRightHemi)
static void generateColorsFromSensorValues(VisualizationInfo &visualizationInfoHemi)
generateColorsFromSensorValues Produces the final color matrix that is to be emitted ...
QList< VisualizationInfo > m_lHemiVisualizationInfo
static void normalizeAndTransformToColor(const Eigen::VectorXf &vecData, Eigen::MatrixX4f &matFinalVertColor, double dThresholdX, double dThresholdZ, QRgb(*functionHandlerColorMap)(double v, const QString &sColorMap), const QString &sColorMap)
normalizeAndTransformToColor This method normalizes final values for all vertices of the mesh and con...
QList< Eigen::VectorXd > m_lDataQ
QList< Eigen::VectorXd > m_lDataLoopQ
RtSourceDataWorker class declaration.
void setInterpolationMatrixRight(QSharedPointer< Eigen::SparseMatrix< float > > pMatInterpolationMatrixRight)
void setThresholds(const QVector3D &vecThresholds)
void newRtSmoothedData(const Eigen::MatrixX4f &matColorMatrixLeftHemi, const Eigen::MatrixX4f &matColorMatrixRightHemi)
QSharedPointer< Eigen::SparseMatrix< float > > pMatInterpolationMatrix
void addData(const Eigen::MatrixXd &data)
void setSFreq(const double dSFreq)
static Eigen::VectorXf interpolateSignal(const QSharedPointer< Eigen::SparseMatrix< float > > matInterpolationMatrix, const QSharedPointer< Eigen::VectorXf > &vecMeasurementData)
void setStreamSmoothedData(bool bStreamSmoothedData)
void setLoopState(bool bLoopState)