v2.0.0
Loading...
Searching...
No Matches
rtsensorstreammanager.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
18#include "sensorfieldmapper.h"
21
22#include <QDebug>
23
24namespace DISP3DLIB
25{
26
27//=============================================================================================================
28// DEFINE MEMBER METHODS
29//=============================================================================================================
30
32: QObject(parent)
33{
34}
35
36//=============================================================================================================
37
42
43//=============================================================================================================
44
46 const SensorFieldMapper& fieldMapper,
47 const QMap<QString, std::shared_ptr<BrainSurface>>& surfaces)
48{
49 if (m_isStreaming) {
50 qDebug() << "RtSensorStreamManager: Real-time sensor streaming already active";
51 return false;
52 }
53
54 // Require loaded evoked data and a built mapping matrix
55 if (!fieldMapper.isLoaded() || fieldMapper.evoked().isEmpty()) {
56 qWarning() << "RtSensorStreamManager: Cannot start sensor streaming — no evoked data loaded";
57 return false;
58 }
59
60 // Select the mapping matrix and pick vector based on modality
61 std::shared_ptr<Eigen::MatrixXf> mappingMat;
62 Eigen::VectorXi pick;
63 QString surfaceKey;
64
65 if (modality == QStringLiteral("MEG")) {
66 mappingMat = fieldMapper.megMapping();
67 pick = fieldMapper.megPick();
68 surfaceKey = fieldMapper.megSurfaceKey();
69 } else if (modality == QStringLiteral("EEG")) {
70 mappingMat = fieldMapper.eegMapping();
71 pick = fieldMapper.eegPick();
72 surfaceKey = fieldMapper.eegSurfaceKey();
73 } else {
74 qWarning() << "RtSensorStreamManager: Unknown modality:" << modality;
75 return false;
76 }
77
78 if (!mappingMat || mappingMat->rows() == 0 || pick.size() == 0) {
79 qWarning() << "RtSensorStreamManager: Mapping matrix not built for" << modality
80 << "— call loadSensorField() first";
81 return false;
82 }
83
84 if (surfaceKey.isEmpty() || !surfaces.contains(surfaceKey)) {
85 qWarning() << "RtSensorStreamManager: Target surface not found for" << modality
86 << "streaming (key:" << surfaceKey << ")";
87 return false;
88 }
89
90 m_modality = modality;
91
92 // Create controller on first use
93 if (!m_controller) {
94 m_controller = std::make_unique<RtSensorDataController>(this);
95 connect(m_controller.get(), &RtSensorDataController::newSensorColorsAvailable,
97 }
98
99 // Propagate mapping matrix
100 m_controller->setMappingMatrix(surfaceKey, mappingMat);
101
102 // Propagate current visualization parameters
103 m_controller->setColormapType(fieldMapper.colormap());
104
105 // Compute sampling frequency from evoked data
106 double sFreq = 1000.0;
107 if (fieldMapper.evoked().times.size() > 1) {
108 double dt = fieldMapper.evoked().times(1) - fieldMapper.evoked().times(0);
109 if (dt > 0)
110 sFreq = 1.0 / dt;
111 }
112 m_controller->setSFreq(sFreq);
113
114 // Feed evoked time points as data into the queue
115 const int nTimePoints = static_cast<int>(fieldMapper.evoked().times.size());
116 qDebug() << "RtSensorStreamManager: Feeding" << nTimePoints << modality
117 << "sensor time points into real-time queue";
118 m_controller->clearData();
119
120 for (int t = 0; t < nTimePoints; ++t) {
121 Eigen::VectorXf meas(pick.size());
122 for (int i = 0; i < pick.size(); ++i) {
123 meas(i) = static_cast<float>(fieldMapper.evoked().data(pick(i), t));
124 }
125 m_controller->addData(meas);
126 }
127
128 // Start streaming
129 m_controller->setStreamingState(true);
130 m_isStreaming = true;
131
132 qDebug() << "RtSensorStreamManager: Real-time sensor streaming started for" << modality;
133 return true;
134}
135
136//=============================================================================================================
137
139{
140 if (!m_isStreaming)
141 return;
142
143 if (m_controller)
144 m_controller->setStreamingState(false);
145
146 m_isStreaming = false;
147 qDebug() << "RtSensorStreamManager: Real-time sensor streaming stopped";
148}
149
150//=============================================================================================================
151
152void RtSensorStreamManager::pushData(const Eigen::VectorXf& data)
153{
154 if (m_controller)
155 m_controller->addData(data);
156}
157
158//=============================================================================================================
159
161{
162 if (m_controller)
163 m_controller->setTimeInterval(msec);
164}
165
166//=============================================================================================================
167
169{
170 if (m_controller)
171 m_controller->setLoopState(enabled);
172}
173
174//=============================================================================================================
175
177{
178 if (m_controller)
179 m_controller->setNumberAverages(numAvr);
180}
181
182//=============================================================================================================
183
184void RtSensorStreamManager::setColormap(const QString& name)
185{
186 if (m_controller)
187 m_controller->setColormapType(name);
188}
189
190} // namespace DISP3DLIB
Real-time MEG / EEG sensor streaming controller that orchestrates the data and field-mapping workers.
Renderable cortical / BEM mesh with interleaved vertex attributes and Qt-RHI buffer management.
Manager that wires real-time sensor data into the scene: owns the data controller,...
Builds the dense sensor-to-surface mapping matrix and the iso-contour overlay for MEG / EEG evoked da...
3-D brain visualisation using the Qt RHI rendering backend.
RtSensorStreamManager(QObject *parent=nullptr)
void colorsAvailable(const QString &surfaceKey, const QVector< uint32_t > &colors)
void pushData(const Eigen::VectorXf &data)
bool startStreaming(const QString &modality, const SensorFieldMapper &fieldMapper, const QMap< QString, std::shared_ptr< BrainSurface > > &surfaces)
Sensor-to-surface field mapper that interpolates MEG/EEG measurements onto cortical meshes and genera...
const Eigen::VectorXi & megPick() const
const Eigen::VectorXi & eegPick() const
const QString & eegSurfaceKey() const
std::shared_ptr< Eigen::MatrixXf > eegMapping() const
const QString & megSurfaceKey() const
std::shared_ptr< Eigen::MatrixXf > megMapping() const
const FIFFLIB::FiffEvoked & evoked() const
const QString & colormap() const
void newSensorColorsAvailable(const QString &surfaceKey, const QVector< uint32_t > &colors)
Eigen::RowVectorXf times
bool isEmpty() const