MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
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
64using namespace DISP3DLIB;
65using namespace Eigen;
66using namespace DISPLIB;
67using 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
90void 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
112void 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
128void RtSourceDataWorker::setStreamSmoothedData(bool bStreamSmoothedData)
129{
130 m_bStreamSmoothedData = bStreamSmoothedData;
131}
132
133//=============================================================================================================
134
135void 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
144void 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
155{
156 m_bIsLooping = bLoopState;
157}
158
159//=============================================================================================================
160
161void RtSourceDataWorker::setSFreq(const double dSFreq)
162{
163 m_dSFreq = dSFreq;
164}
165
166//=============================================================================================================
167
168void RtSourceDataWorker::setInterpolationMatrixLeft(QSharedPointer<Eigen::SparseMatrix<float> > pMatInterpolationMatrixLeft)
169{
170 m_lHemiVisualizationInfo[0].pMatInterpolationMatrix = pMatInterpolationMatrixLeft;
171}
172
173//=============================================================================================================
174
175void 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()) {
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()) {
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
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}
RtSourceDataWorker class declaration.
QSharedPointer< Eigen::SparseMatrix< float > > pMatInterpolationMatrix
void setColormapType(const QString &sColormapType)
QList< Eigen::VectorXd > m_lDataLoopQ
void newRtRawData(const Eigen::VectorXd &vecDataVectorLeftHemi, const Eigen::VectorXd &vecDataVectorRightHemi)
void setInterpolationMatrixRight(QSharedPointer< Eigen::SparseMatrix< float > > pMatInterpolationMatrixRight)
QList< Eigen::VectorXd > m_lDataQ
static void generateColorsFromSensorValues(VisualizationInfo &visualizationInfoHemi)
generateColorsFromSensorValues Produces the final color matrix that is to be emitted
void setSFreq(const double dSFreq)
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...
void setInterpolationMatrixLeft(QSharedPointer< Eigen::SparseMatrix< float > > pMatInterpolationMatrixLeft)
void addData(const Eigen::MatrixXd &data)
void setThresholds(const QVector3D &vecThresholds)
void setStreamSmoothedData(bool bStreamSmoothedData)
void newRtSmoothedData(const Eigen::MatrixX4f &matColorMatrixLeftHemi, const Eigen::MatrixX4f &matColorMatrixRightHemi)
void setSurfaceColor(const Eigen::MatrixX4f &matColorLeft, const Eigen::MatrixX4f &matColorRight)
static Eigen::VectorXf interpolateSignal(const QSharedPointer< Eigen::SparseMatrix< float > > matInterpolationMatrix, const QSharedPointer< Eigen::VectorXf > &vecMeasurementData)