v2.0.0
Loading...
Searching...
No Matches
rtsourcedatacontroller.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
18#include "rtsourcedataworker.h"
20
21#include <fs/fs_label.h>
22
23#include <QThread>
24#include <QTimer>
25#include <QDebug>
26
27namespace DISP3DLIB
28{
29
30//=============================================================================================================
31// DEFINE MEMBER METHODS
32//=============================================================================================================
33
35: QObject(parent)
36{
37 // Create data worker
38 m_pWorker = new DISP3DLIB::RtSourceDataWorker();
39
40 // Create and configure data thread
41 m_pWorkerThread = new QThread(this);
42 m_pWorker->moveToThread(m_pWorkerThread);
43
44 // Clean up worker when thread finishes
45 connect(m_pWorkerThread, &QThread::finished, m_pWorker, &QObject::deleteLater);
46
47 // Forward worker signals to controller signals
52
53 // Create timer for driving the streaming cadence
54 m_pTimer = new QTimer(this);
55 m_pTimer->setTimerType(Qt::PreciseTimer);
56 connect(m_pTimer, &QTimer::timeout, m_pWorker, &DISP3DLIB::RtSourceDataWorker::streamData);
57
58 // Start the data worker thread
59 m_pWorkerThread->start();
60
61 // Create interpolation matrix worker
62 m_pInterpWorker = new DISP3DLIB::RtSourceInterpolationMatWorker();
63 m_pInterpThread = new QThread(this);
64 m_pInterpWorker->moveToThread(m_pInterpThread);
65
66 connect(m_pInterpThread, &QThread::finished, m_pInterpWorker, &QObject::deleteLater);
67
68 // Forward interpolation results: auto-apply to data worker + re-emit
70 this, &RtSourceDataController::onNewInterpolationMatrixLeft);
72 this, &RtSourceDataController::onNewInterpolationMatrixRight);
73
74 m_pInterpThread->start();
75
76 qDebug() << "RtSourceDataController: Initialized with" << m_iTimeInterval << "ms interval";
77}
78
79//=============================================================================================================
80
82{
83 // Stop timer
84 if (m_pTimer) {
85 m_pTimer->stop();
86 }
87
88 // Stop the data worker thread
89 if (m_pWorkerThread) {
90 m_pWorkerThread->quit();
91 m_pWorkerThread->wait();
92 }
93
94 // Stop the interpolation worker thread
95 if (m_pInterpThread) {
96 m_pInterpThread->quit();
97 m_pInterpThread->wait();
98 }
99}
100
101//=============================================================================================================
102
103void RtSourceDataController::addData(const Eigen::VectorXd& data)
104{
105 if (m_pWorker) {
106 // Direct call is thread-safe because RtSourceDataWorker uses a mutex
107 m_pWorker->addData(data);
108 }
109}
110
111//=============================================================================================================
112
113void RtSourceDataController::setInterpolationMatrixLeft(QSharedPointer<Eigen::SparseMatrix<float>> mat)
114{
115 if (m_pWorker) {
116 m_pWorker->setInterpolationMatrixLeft(mat);
117 }
118}
119
120//=============================================================================================================
121
122void RtSourceDataController::setInterpolationMatrixRight(QSharedPointer<Eigen::SparseMatrix<float>> mat)
123{
124 if (m_pWorker) {
125 m_pWorker->setInterpolationMatrixRight(mat);
126 }
127}
128
129//=============================================================================================================
130
132{
133 m_bIsStreaming = state;
134
135 if (state) {
136 m_pTimer->start(m_iTimeInterval);
137 qDebug() << "RtSourceDataController: Streaming started at" << m_iTimeInterval << "ms interval";
138 } else {
139 m_pTimer->stop();
140 qDebug() << "RtSourceDataController: Streaming stopped";
141 }
142}
143
144//=============================================================================================================
145
147{
148 return m_bIsStreaming;
149}
150
151//=============================================================================================================
152
154{
155 m_iTimeInterval = qMax(1, msec);
156
157 if (m_bIsStreaming) {
158 m_pTimer->setInterval(m_iTimeInterval);
159 }
160
161 qDebug() << "RtSourceDataController: Time interval set to" << m_iTimeInterval << "ms";
162}
163
164//=============================================================================================================
165
167{
168 if (m_pWorker) {
169 m_pWorker->setNumberAverages(numAvr);
170 }
171}
172
173//=============================================================================================================
174
176{
177 if (m_pWorker) {
178 m_pWorker->setColormapType(name);
179 }
180}
181
182//=============================================================================================================
183
184void RtSourceDataController::setThresholds(double min, double mid, double max)
185{
186 if (m_pWorker) {
187 m_pWorker->setThresholds(min, mid, max);
188 }
189}
190
191//=============================================================================================================
192
194{
195 if (m_pWorker) {
196 m_pWorker->setLoopState(enabled);
197 }
198}
199
200//=============================================================================================================
201
203{
204 if (m_pWorker) {
205 m_pWorker->setSFreq(sFreq);
206 }
207}
208
209//=============================================================================================================
210
212{
213 if (m_pWorker) {
214 m_pWorker->clear();
215 }
216}
217
218//=============================================================================================================
219
220void RtSourceDataController::setSurfaceColor(const QVector<uint32_t>& baseColorsLh,
221 const QVector<uint32_t>& baseColorsRh)
222{
223 if (m_pWorker) {
224 m_pWorker->setSurfaceColor(baseColorsLh, baseColorsRh);
225 }
226}
227
228//=============================================================================================================
229
231{
232 if (m_pWorker) {
233 m_pWorker->setStreamSmoothedData(bStreamSmoothedData);
234 }
235}
236
237//=============================================================================================================
238
239void RtSourceDataController::setInterpolationFunction(const QString& sInterpolationFunction)
240{
241 if (m_pInterpWorker) {
242 m_pInterpWorker->setInterpolationFunction(sInterpolationFunction);
243 }
244}
245
246//=============================================================================================================
247
249{
250 if (m_pInterpWorker) {
251 m_pInterpWorker->setCancelDistance(dCancelDist);
252 }
253}
254
255//=============================================================================================================
256
257void RtSourceDataController::setInterpolationInfoLeft(const Eigen::MatrixX3f& matVertices,
258 const std::vector<Eigen::VectorXi>& vecNeighborVertices,
259 const Eigen::VectorXi& vecSourceVertices)
260{
261 if (m_pInterpWorker) {
262 m_pInterpWorker->setInterpolationInfoLeft(matVertices, vecNeighborVertices, vecSourceVertices);
263 }
264}
265
266//=============================================================================================================
267
268void RtSourceDataController::setInterpolationInfoRight(const Eigen::MatrixX3f& matVertices,
269 const std::vector<Eigen::VectorXi>& vecNeighborVertices,
270 const Eigen::VectorXi& vecSourceVertices)
271{
272 if (m_pInterpWorker) {
273 m_pInterpWorker->setInterpolationInfoRight(matVertices, vecNeighborVertices, vecSourceVertices);
274 }
275}
276
277//=============================================================================================================
278
280{
281 if (m_pInterpWorker) {
282 QMetaObject::invokeMethod(m_pInterpWorker, "computeInterpolationMatrix", Qt::QueuedConnection);
283 }
284}
285
286//=============================================================================================================
287
288void RtSourceDataController::onNewInterpolationMatrixLeft(QSharedPointer<Eigen::SparseMatrix<float>> interpMat)
289{
290 // Auto-forward to data worker so it immediately uses the new matrix
291 if (m_pWorker) {
292 m_pWorker->setInterpolationMatrixLeft(interpMat);
293 }
294 // Re-emit so external listeners can react
296}
297
298//=============================================================================================================
299
300void RtSourceDataController::onNewInterpolationMatrixRight(QSharedPointer<Eigen::SparseMatrix<float>> interpMat)
301{
302 // Auto-forward to data worker so it immediately uses the new matrix
303 if (m_pWorker) {
304 m_pWorker->setInterpolationMatrixRight(interpMat);
305 }
306 // Re-emit so external listeners can react
308}
309
310//=============================================================================================================
311
313{
314 if (m_pInterpWorker) {
315 m_pInterpWorker->setVisualizationType(iVisType);
316 }
317}
318
319//=============================================================================================================
320
321void RtSourceDataController::setAnnotationInfoLeft(const Eigen::VectorXi& vecLabelIds,
322 const QList<FSLIB::FsLabel>& lLabels,
323 const Eigen::VectorXi& vecVertNo)
324{
325 if (m_pInterpWorker) {
326 m_pInterpWorker->setAnnotationInfoLeft(vecLabelIds, lLabels, vecVertNo);
327 }
328}
329
330//=============================================================================================================
331
332void RtSourceDataController::setAnnotationInfoRight(const Eigen::VectorXi& vecLabelIds,
333 const QList<FSLIB::FsLabel>& lLabels,
334 const Eigen::VectorXi& vecVertNo)
335{
336 if (m_pInterpWorker) {
337 m_pInterpWorker->setAnnotationInfoRight(vecLabelIds, lLabels, vecVertNo);
338 }
339}
340
341} // namespace DISP3DLIB
Background worker that converts streaming source vectors into smoothed per-vertex ABGR colour buffers...
Background worker that builds the sparse source-to-vertex interpolation matrix for one hemisphere.
Real-time source-estimate streaming controller that owns the data worker and the per-hemisphere inter...
Reader and in-memory representation of a FreeSurfer/MNE surface label (.label).
3-D brain visualisation using the Qt RHI rendering backend.
void setAnnotationInfoLeft(const Eigen::VectorXi &vecLabelIds, const QList< FSLIB::FsLabel > &lLabels, const Eigen::VectorXi &vecVertNo)
void setInterpolationMatrixRight(QSharedPointer< Eigen::SparseMatrix< float > > mat)
void addData(const Eigen::VectorXd &data)
void setInterpolationMatrixLeft(QSharedPointer< Eigen::SparseMatrix< float > > mat)
void newRawDataAvailable(const Eigen::VectorXd &dataLh, const Eigen::VectorXd &dataRh)
RtSourceDataController(QObject *parent=nullptr)
void newInterpolationMatrixLeftAvailable(QSharedPointer< Eigen::SparseMatrix< float > > interpMat)
void setSurfaceColor(const QVector< uint32_t > &baseColorsLh, const QVector< uint32_t > &baseColorsRh)
void setStreamSmoothedData(bool bStreamSmoothedData)
void setThresholds(double min, double mid, double max)
void setInterpolationInfoRight(const Eigen::MatrixX3f &matVertices, const std::vector< Eigen::VectorXi > &vecNeighborVertices, const Eigen::VectorXi &vecSourceVertices)
void setInterpolationInfoLeft(const Eigen::MatrixX3f &matVertices, const std::vector< Eigen::VectorXi > &vecNeighborVertices, const Eigen::VectorXi &vecSourceVertices)
void newInterpolationMatrixRightAvailable(QSharedPointer< Eigen::SparseMatrix< float > > interpMat)
void setInterpolationFunction(const QString &sInterpolationFunction)
void newSmoothedDataAvailable(const QVector< uint32_t > &colorsLh, const QVector< uint32_t > &colorsRh)
void setAnnotationInfoRight(const Eigen::VectorXi &vecLabelIds, const QList< FSLIB::FsLabel > &lLabels, const Eigen::VectorXi &vecVertNo)
Background worker for real-time source estimate streaming.
void setInterpolationMatrixLeft(QSharedPointer< Eigen::SparseMatrix< float > > mat)
void newRtRawData(const Eigen::VectorXd &dataLh, const Eigen::VectorXd &dataRh)
void newRtSmoothedData(const QVector< uint32_t > &colorsLh, const QVector< uint32_t > &colorsRh)
Background worker for computing source interpolation matrices.
void newInterpolationMatrixRightAvailable(QSharedPointer< Eigen::SparseMatrix< float > > interpMat)
void newInterpolationMatrixLeftAvailable(QSharedPointer< Eigen::SparseMatrix< float > > interpMat)