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