21#include <QMutexLocker>
40 QMutexLocker locker(&m_mutex);
43 if (m_lDataQ.size() <
static_cast<int>(m_dSFreq)) {
44 m_lDataQ.append(data);
49 m_lDataLoopQ.append(data);
51 if (m_lDataLoopQ.size() >
static_cast<int>(m_dSFreq) * 10) {
52 m_lDataLoopQ.removeFirst();
61 QMutexLocker locker(&m_mutex);
64 m_vecAverage = Eigen::VectorXf();
73 QMutexLocker locker(&m_mutex);
74 m_sSurfaceKey = surfaceKey;
82 QMutexLocker locker(&m_mutex);
83 m_iNumAverages = qMax(1, numAvr);
90 QMutexLocker locker(&m_mutex);
91 m_sColormapType = name;
98 QMutexLocker locker(&m_mutex);
99 if (min == 0.0 && max == 0.0) {
100 m_bUseAutoNorm =
true;
104 m_bUseAutoNorm =
false;
114 QMutexLocker locker(&m_mutex);
115 m_bIsLooping = enabled;
122 QMutexLocker locker(&m_mutex);
123 m_dSFreq = qMax(1.0, sFreq);
130 QMutexLocker locker(&m_mutex);
131 m_bStreamSmoothedData = bStreamSmoothedData;
138 QMutexLocker locker(&m_mutex);
141 Eigen::VectorXf vecCurrentData;
143 if (!m_lDataQ.isEmpty()) {
144 vecCurrentData = m_lDataQ.takeFirst();
145 }
else if (m_bIsLooping && !m_lDataLoopQ.isEmpty()) {
147 vecCurrentData = m_lDataLoopQ[m_iCurrentSample % m_lDataLoopQ.size()];
155 if (m_iNumAverages > 1) {
156 if (m_vecAverage.size() != vecCurrentData.size()) {
157 m_vecAverage = vecCurrentData;
160 m_vecAverage += vecCurrentData;
164 if (m_iSampleCtr < m_iNumAverages) {
168 vecCurrentData = m_vecAverage /
static_cast<float>(m_iSampleCtr);
169 m_vecAverage = Eigen::VectorXf();
174 if (!m_bStreamSmoothedData) {
176 Eigen::VectorXf rawData = vecCurrentData;
183 QVector<uint32_t> colors = computeSurfaceColors(vecCurrentData);
184 const QString surfaceKey = m_sSurfaceKey;
189 if (!colors.isEmpty()) {
196QVector<uint32_t> RtSensorDataWorker::computeSurfaceColors(
const Eigen::VectorXf& sensorData)
const
198 if (sensorData.size() == 0 || !m_mappingMat || m_mappingMat->rows() == 0) {
199 return QVector<uint32_t>();
203 if (m_mappingMat->cols() != sensorData.size()) {
204 qWarning() <<
"RtSensorDataWorker: Mapping matrix cols" << m_mappingMat->cols()
205 <<
"!= sensor data size" << sensorData.size();
206 return QVector<uint32_t>();
210 Eigen::VectorXf mapped = (*m_mappingMat) * sensorData;
212 int nVertices = mapped.size();
215 float normMin, normMax;
216 if (m_bUseAutoNorm) {
219 for (
int i = 0; i < nVertices; ++i) {
220 maxAbs = std::max(maxAbs, std::abs(mapped(i)));
228 normMin =
static_cast<float>(m_dThreshMin);
229 normMax =
static_cast<float>(m_dThreshMax);
230 if (normMax <= normMin)
231 normMax = normMin + 1.0f;
234 float range = normMax - normMin;
237 QVector<uint32_t> colors(nVertices);
239 for (
int i = 0; i < nVertices; ++i) {
241 double norm =
static_cast<double>(mapped(i) - normMin) /
static_cast<double>(range);
242 norm = qBound(0.0, norm, 1.0);
246 uint32_t r = qRed(rgb);
247 uint32_t g = qGreen(rgb);
248 uint32_t b = qBlue(rgb);
Static scalar-to-colour lookup helpers (Jet, Hot, Bone, Viridis, Cool, RedBlue, MNE) used by every pl...
Background worker that turns queued sensor packets into per-vertex ABGR colour buffers via a dense ma...
Lightweight render-related enums (ShaderMode, VisualizationMode) shared across disp3D.
3-D brain visualisation using the Qt RHI rendering backend.
uint32_t packABGR(uint32_t r, uint32_t g, uint32_t b, uint32_t a=0xFF)
static QRgb valueToColor(double v, const QString &sMap)
void setMappingMatrix(const QString &surfaceKey, std::shared_ptr< Eigen::MatrixXf > mat)
void setSFreq(double sFreq)
void newRtSensorColors(const QString &surfaceKey, const QVector< uint32_t > &colors)
void setLoopState(bool enabled)
void setThresholds(double min, double max)
void addData(const Eigen::VectorXf &data)
RtSensorDataWorker(QObject *parent=nullptr)
void setColormapType(const QString &name)
void setStreamSmoothedData(bool bStreamSmoothedData)
void setNumberAverages(int numAvr)
void newRtRawSensorData(const Eigen::VectorXf &data)