66 const QMap<QString, std::shared_ptr<BrainSurface>> &surfaces)
69 qDebug() <<
"RtSensorStreamManager: Real-time sensor streaming already active";
75 qWarning() <<
"RtSensorStreamManager: Cannot start sensor streaming — no evoked data loaded";
80 QSharedPointer<Eigen::MatrixXf> mappingMat;
84 if (
modality == QStringLiteral(
"MEG")) {
88 }
else if (
modality == QStringLiteral(
"EEG")) {
93 qWarning() <<
"RtSensorStreamManager: Unknown modality:" <<
modality;
97 if (!mappingMat || mappingMat->rows() == 0 || pick.isEmpty()) {
98 qWarning() <<
"RtSensorStreamManager: Mapping matrix not built for" <<
modality
99 <<
"— call loadSensorField() first";
103 if (surfaceKey.isEmpty() || !surfaces.contains(surfaceKey)) {
104 qWarning() <<
"RtSensorStreamManager: Target surface not found for" <<
modality
105 <<
"streaming (key:" << surfaceKey <<
")";
113 m_controller = std::make_unique<RtSensorDataController>(
this);
119 m_controller->setMappingMatrix(mappingMat);
122 m_controller->setColormapType(fieldMapper.
colormap());
125 double sFreq = 1000.0;
128 if (dt > 0) sFreq = 1.0 / dt;
130 m_controller->setSFreq(sFreq);
133 const int nTimePoints =
static_cast<int>(fieldMapper.
evoked().times.size());
134 qDebug() <<
"RtSensorStreamManager: Feeding" << nTimePoints <<
modality
135 <<
"sensor time points into real-time queue";
136 m_controller->clearData();
138 for (
int t = 0; t < nTimePoints; ++t) {
139 Eigen::VectorXf meas(pick.size());
140 for (
int i = 0; i < pick.size(); ++i) {
141 meas(i) =
static_cast<float>(fieldMapper.
evoked().data(pick[i], t));
143 m_controller->addData(meas);
147 m_controller->setStreamingState(
true);
148 m_isStreaming =
true;
150 qDebug() <<
"RtSensorStreamManager: Real-time sensor streaming started for" <<
modality;