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