v2.0.0
Loading...
Searching...
No Matches
stcloadingworker.cpp
Go to the documentation of this file.
1//=============================================================================================================
12
13//=============================================================================================================
14// INCLUDES
15//=============================================================================================================
16
17#include "stcloadingworker.h"
19
22
23#include <QFile>
24#include <QDebug>
25
26namespace DISP3DLIB
27{
28
29//=============================================================================================================
30// DEFINE MEMBER METHODS
31//=============================================================================================================
32
34 const QString& rhPath,
35 BrainSurface* lhSurface,
36 BrainSurface* rhSurface,
37 double cancelDist,
38 QObject* parent)
39: QObject(parent)
40, m_lhPath(lhPath)
41, m_rhPath(rhPath)
42, m_lhSurface(lhSurface)
43, m_rhSurface(rhSurface)
44, m_cancelDist(cancelDist)
45{
46}
47
48//=============================================================================================================
49
53
54//=============================================================================================================
55
56QSharedPointer<Eigen::SparseMatrix<float>> StcLoadingWorker::computeInterpolationMatrix(
57 const Eigen::MatrixX3f& matVertices,
58 Eigen::VectorXi& vecSourceVertices,
59 double cancelDist,
60 const QString& hemiLabel,
61 int progressStart,
62 int progressEnd)
63{
64 emit progress(progressStart, QString("Computing %1 geodesic interpolation...").arg(hemiLabel));
65
66 // Compute neighbors from the appropriate surface
67 std::vector<Eigen::VectorXi> vecNeighbors;
68 if (hemiLabel == "LH" && m_lhSurface) {
69 vecNeighbors = m_lhSurface->computeNeighbors();
70 } else if (hemiLabel == "RH" && m_rhSurface) {
71 vecNeighbors = m_rhSurface->computeNeighbors();
72 }
73
74 // Use sparse SCDC+interpolation: runs Dijkstra per source vertex and directly
75 // builds the sparse interpolation matrix without a dense intermediate distance table.
76 // This produces identical results to the old scdc() + createInterpolationMat() pipeline
77 // but uses ~18 MB instead of ~8.7 GB for a typical fsaverage source space.
78 const int progressRange = progressEnd - progressStart;
79 auto progressCallback = [this, &hemiLabel, progressStart, progressRange](int current, int total) {
80 if (m_cancelled.load(std::memory_order_relaxed))
81 return;
82 int pct = progressStart + (progressRange * current) / total;
83 emit progress(pct, QString("%1 geodesic interpolation %2/%3").arg(hemiLabel).arg(current).arg(total));
84 };
85
87 matVertices,
88 vecNeighbors,
89 vecSourceVertices,
91 cancelDist,
92 progressCallback,
93 &m_cancelled);
94
95 if (m_cancelled.load(std::memory_order_relaxed))
96 return QSharedPointer<Eigen::SparseMatrix<float>>();
97
98 emit progress(progressEnd, QString("%1 interpolation matrix ready").arg(hemiLabel));
99 return interpMat;
100}
101
102//=============================================================================================================
103
105{
106 emit progress(0, "Loading STC files...");
107
108 // Load LH STC file
109 if (!m_lhPath.isEmpty()) {
110 QFile file(m_lhPath);
112 if (INVLIB::InvSourceEstimate::read(file, stc)) {
113 m_stcLh = stc;
114 m_hasLh = true;
115 } else {
116 emit error(QString("Failed to read LH STC file: %1").arg(m_lhPath));
117 }
118 }
119
120 emit progress(5, "Loading RH STC file...");
121
122 // Load RH STC file
123 if (!m_rhPath.isEmpty()) {
124 QFile file(m_rhPath);
126 if (INVLIB::InvSourceEstimate::read(file, stc)) {
127 m_stcRh = stc;
128 m_hasRh = true;
129 } else {
130 emit error(QString("Failed to read RH STC file: %1").arg(m_rhPath));
131 }
132 }
133
134 if (!m_hasLh && !m_hasRh) {
135 emit error("No STC data could be loaded.");
136 emit finished(false);
137 return;
138 }
139
140 if (m_cancelled.load(std::memory_order_relaxed)) {
141 emit finished(false);
142 return;
143 }
144
145 // Compute LH interpolation matrix
146 if (m_hasLh && m_lhSurface) {
147 Eigen::MatrixX3f matVertices = m_lhSurface->verticesAsMatrix();
148 Eigen::VectorXi vecSourceVertices = m_stcLh.vertices;
149
150 if (vecSourceVertices.size() > 0) {
151 m_interpMatLh = computeInterpolationMatrix(matVertices, vecSourceVertices, m_cancelDist,
152 "LH", 10, 45);
153 if (m_cancelled.load(std::memory_order_relaxed)) {
154 emit finished(false);
155 return;
156 }
157 }
158 }
159
160 // Compute RH interpolation matrix
161 if (m_hasRh && m_rhSurface) {
162 Eigen::MatrixX3f matVertices = m_rhSurface->verticesAsMatrix();
163 Eigen::VectorXi vecSourceVertices = m_stcRh.vertices;
164
165 if (vecSourceVertices.size() > 0) {
166 m_interpMatRh = computeInterpolationMatrix(matVertices, vecSourceVertices, m_cancelDist,
167 "RH", 50, 90);
168 if (m_cancelled.load(std::memory_order_relaxed)) {
169 emit finished(false);
170 return;
171 }
172 }
173 }
174
175 emit progress(95, "Finalizing...");
176 emit progress(100, "Complete");
177 emit finished(true);
178}
179
180} // namespace DISP3DLIB
Background worker that loads source-time-course (.stc) files and prepares per-hemisphere interpolatio...
Renderable cortical / BEM mesh with interleaved vertex attributes and Qt-RHI buffer management.
Distance-based sparse interpolation weights and per-frame signal smoothing on triangulated meshes.
Surface-constrained geodesic distance and sensor-to-mesh projection helpers.
3-D brain visualisation using the Qt RHI rendering backend.
static QSharedPointer< Eigen::SparseMatrix< float > > scdcInterpolationMat(const Eigen::MatrixX3f &matVertices, const std::vector< Eigen::VectorXi > &vecNeighborVertices, const Eigen::VectorXi &vecVertSubset, double(*interpolationFunction)(double), double dCancelDist, std::function< void(int, int)> progressCallback=nullptr, const std::atomic< bool > *cancelledFlag=nullptr)
scdcInterpolationMat Computes geodesic distances (SCDC) and builds the sparse interpolation matrix in...
static double cubic(const double dIn)
cubic Cubic hyperbola interpolation function.
Renderable cortical surface mesh with per-vertex color, curvature data, and GPU buffer management.
std::vector< Eigen::VectorXi > computeNeighbors() const
void finished(bool success)
void progress(int percent, const QString &message)
StcLoadingWorker(const QString &lhPath, const QString &rhPath, BrainSurface *lhSurface, BrainSurface *rhSurface, double cancelDist=0.05, QObject *parent=nullptr)
void error(const QString &message)
Source-space inverse-solution container with dense grid plus optional focal-dipole,...
static bool read(QIODevice &p_IODevice, InvSourceEstimate &p_stc)