40 QMutexLocker locker(&m_mutex);
41 m_sInterpolationFunction = sInterpolationFunction;
48 QMutexLocker locker(&m_mutex);
49 m_dCancelDist = dCancelDist;
55 const Eigen::MatrixX3f& matVertices,
56 const std::vector<Eigen::VectorXi>& vecNeighborVertices,
57 const Eigen::VectorXi& vecSourceVertices)
59 QMutexLocker locker(&m_mutex);
60 m_matVerticesLh = matVertices;
61 m_vecNeighborsLh = vecNeighborVertices;
62 m_vecSourceVerticesLh = vecSourceVertices;
63 m_hasLh = (!matVertices.isZero(0) && matVertices.rows() > 0 && vecSourceVertices.size() > 0);
69 const Eigen::MatrixX3f& matVertices,
70 const std::vector<Eigen::VectorXi>& vecNeighborVertices,
71 const Eigen::VectorXi& vecSourceVertices)
73 QMutexLocker locker(&m_mutex);
74 m_matVerticesRh = matVertices;
75 m_vecNeighborsRh = vecNeighborVertices;
76 m_vecSourceVerticesRh = vecSourceVertices;
77 m_hasRh = (!matVertices.isZero(0) && matVertices.rows() > 0 && vecSourceVertices.size() > 0);
84 QMutexLocker locker(&m_mutex);
85 m_iVisualizationType = iVisType;
91 const QList<FSLIB::FsLabel>& lLabels,
92 const Eigen::VectorXi& vecVertNo)
94 if (vecLabelIds.rows() == 0 || lLabels.isEmpty()) {
95 qDebug() <<
"RtSourceInterpolationMatWorker::setAnnotationInfoLeft - FsAnnotation data is empty.";
99 QMutexLocker locker(&m_mutex);
100 m_lLabelsLh = lLabels;
101 m_nAnnotationVerticesLh =
static_cast<int>(vecLabelIds.rows());
102 m_mapLabelIdSourcesLh.clear();
105 for (qint32 i = 0; i < vecVertNo.rows(); ++i) {
106 m_mapLabelIdSourcesLh.insert(vecVertNo(i), vecLabelIds(vecVertNo(i)));
107 m_vertNosLh.append(vecVertNo(i));
110 m_bAnnotationLhInit =
true;
116 const QList<FSLIB::FsLabel>& lLabels,
117 const Eigen::VectorXi& vecVertNo)
119 if (vecLabelIds.rows() == 0 || lLabels.isEmpty()) {
120 qDebug() <<
"RtSourceInterpolationMatWorker::setAnnotationInfoRight - FsAnnotation data is empty.";
124 QMutexLocker locker(&m_mutex);
125 m_lLabelsRh = lLabels;
126 m_nAnnotationVerticesRh =
static_cast<int>(vecLabelIds.rows());
127 m_mapLabelIdSourcesRh.clear();
130 for (qint32 i = 0; i < vecVertNo.rows(); ++i) {
131 m_mapLabelIdSourcesRh.insert(vecVertNo(i), vecLabelIds(vecVertNo(i)));
132 m_vertNosRh.append(vecVertNo(i));
135 m_bAnnotationRhInit =
true;
140double (*RtSourceInterpolationMatWorker::resolveInterpolationFunction(
const QString& name))(double)
142 if (name == QStringLiteral(
"linear"))
144 if (name == QStringLiteral(
"gaussian"))
146 if (name == QStringLiteral(
"square"))
148 if (name == QStringLiteral(
"cubic"))
157QSharedPointer<Eigen::SparseMatrix<float>> RtSourceInterpolationMatWorker::computeHemi(
158 const Eigen::MatrixX3f& matVertices,
159 const std::vector<Eigen::VectorXi>& vecNeighborVertices,
160 Eigen::VectorXi vecSourceVertices,
162 double (*interpFunc)(
double))
164 if (matVertices.rows() == 0 || vecSourceVertices.size() == 0) {
165 return QSharedPointer<Eigen::SparseMatrix<float>>();
175 if (!distTable || distTable->rows() == 0) {
176 qWarning() <<
"RtSourceInterpolationMatWorker: SCDC computation failed.";
177 return QSharedPointer<Eigen::SparseMatrix<float>>();
195 Eigen::MatrixX3f vertsLh, vertsRh;
196 std::vector<Eigen::VectorXi> neighborsLh, neighborsRh;
197 Eigen::VectorXi srcVertsLh, srcVertsRh;
200 QString interpFuncName;
204 QList<FSLIB::FsLabel> labelsLh, labelsRh;
205 QMap<qint32, qint32> mapLabelIdSrcLh, mapLabelIdSrcRh;
206 QList<int> vertNosLh, vertNosRh;
207 bool annotLhInit, annotRhInit;
208 int nAnnotVertsLh, nAnnotVertsRh;
211 QMutexLocker locker(&m_mutex);
212 vertsLh = m_matVerticesLh;
213 vertsRh = m_matVerticesRh;
214 neighborsLh = m_vecNeighborsLh;
215 neighborsRh = m_vecNeighborsRh;
216 srcVertsLh = m_vecSourceVerticesLh;
217 srcVertsRh = m_vecSourceVerticesRh;
220 cancelDist = m_dCancelDist;
221 interpFuncName = m_sInterpolationFunction;
222 visType = m_iVisualizationType;
224 labelsLh = m_lLabelsLh;
225 labelsRh = m_lLabelsRh;
226 mapLabelIdSrcLh = m_mapLabelIdSourcesLh;
227 mapLabelIdSrcRh = m_mapLabelIdSourcesRh;
228 vertNosLh = m_vertNosLh;
229 vertNosRh = m_vertNosRh;
230 annotLhInit = m_bAnnotationLhInit;
231 annotRhInit = m_bAnnotationRhInit;
232 nAnnotVertsLh = m_nAnnotationVerticesLh;
233 nAnnotVertsRh = m_nAnnotationVerticesRh;
238 qDebug() <<
"RtSourceInterpolationMatWorker: Computing annotation matrices...";
241 auto mat = computeAnnotationOperator(labelsLh, mapLabelIdSrcLh, vertNosLh, nAnnotVertsLh);
242 if (mat && mat->rows() > 0) {
243 qDebug() <<
"RtSourceInterpolationMatWorker: LH annotation matrix:"
244 << mat->rows() <<
"x" << mat->cols();
250 auto mat = computeAnnotationOperator(labelsRh, mapLabelIdSrcRh, vertNosRh, nAnnotVertsRh);
251 if (mat && mat->rows() > 0) {
252 qDebug() <<
"RtSourceInterpolationMatWorker: RH annotation matrix:"
253 << mat->rows() <<
"x" << mat->cols();
258 qDebug() <<
"RtSourceInterpolationMatWorker: FsAnnotation matrix computation complete.";
263 if (!hasLh && !hasRh) {
264 qDebug() <<
"RtSourceInterpolationMatWorker: No hemisphere data set, skipping.";
268 auto interpFunc = resolveInterpolationFunction(interpFuncName);
270 qDebug() <<
"RtSourceInterpolationMatWorker: Computing interpolation matrices"
271 <<
"(cancelDist=" << cancelDist <<
", func=" << interpFuncName <<
")...";
275 qDebug() <<
"RtSourceInterpolationMatWorker: Computing LH matrix ("
276 << vertsLh.rows() <<
"verts," << srcVertsLh.size() <<
"sources)...";
278 auto mat = computeHemi(vertsLh, neighborsLh, srcVertsLh, cancelDist, interpFunc);
280 if (mat && mat->rows() > 0) {
281 qDebug() <<
"RtSourceInterpolationMatWorker: LH matrix computed:"
282 << mat->rows() <<
"x" << mat->cols();
285 qWarning() <<
"RtSourceInterpolationMatWorker: LH interpolation matrix computation failed.";
291 qDebug() <<
"RtSourceInterpolationMatWorker: Computing RH matrix ("
292 << vertsRh.rows() <<
"verts," << srcVertsRh.size() <<
"sources)...";
294 auto mat = computeHemi(vertsRh, neighborsRh, srcVertsRh, cancelDist, interpFunc);
296 if (mat && mat->rows() > 0) {
297 qDebug() <<
"RtSourceInterpolationMatWorker: RH matrix computed:"
298 << mat->rows() <<
"x" << mat->cols();
301 qWarning() <<
"RtSourceInterpolationMatWorker: RH interpolation matrix computation failed.";
305 qDebug() <<
"RtSourceInterpolationMatWorker: Interpolation matrix computation complete.";
310QSharedPointer<Eigen::SparseMatrix<float>> RtSourceInterpolationMatWorker::computeAnnotationOperator(
311 const QList<FSLIB::FsLabel>& lLabels,
312 const QMap<qint32, qint32>& mapLabelIdSrc,
313 const QList<int>& vertNos,
316 if (lLabels.isEmpty() || vertNos.isEmpty() || nVertices <= 0) {
317 return QSharedPointer<Eigen::SparseMatrix<float>>();
321 auto mat = QSharedPointer<Eigen::SparseMatrix<float>>(
322 new Eigen::SparseMatrix<float>(nVertices, vertNos.size()));
325 for (
int i = 0; i < lLabels.size(); ++i) {
327 QList<qint32> listSourcesVertNoLabel = mapLabelIdSrc.keys(label.
label_id);
329 for (
int j = 0; j < label.
vertices.rows(); ++j) {
330 for (
int k = 0; k < listSourcesVertNoLabel.size(); ++k) {
331 int colIdx = vertNos.indexOf(listSourcesVertNoLabel.at(k));
332 if (colIdx >= 0 && label.
vertices(j) >= 0 && label.
vertices(j) < nVertices) {
333 mat->coeffRef(label.
vertices(j), colIdx) = 1.0f / listSourcesVertNoLabel.size();
Background worker that builds the sparse source-to-vertex interpolation matrix for one hemisphere.
Distance-based sparse interpolation weights and per-frame signal smoothing on triangulated meshes.
Surface-constrained geodesic distance and sensor-to-mesh projection helpers.
Reader and in-memory representation of a FreeSurfer/MNE surface label (.label).
3-D brain visualisation using the Qt RHI rendering backend.
static QSharedPointer< Eigen::MatrixXd > scdc(const Eigen::MatrixX3f &matVertices, const std::vector< Eigen::VectorXi > &vecNeighborVertices, Eigen::VectorXi &vecVertSubset, double dCancelDist=FLOAT_INFINITY)
scdc Calculates surface constrained distances on a mesh.
static double gaussian(const double dIn)
gaussian Gaussian interpolation function (sigma=1).
static double linear(const double dIn)
linear Identity interpolation function.
static double cubic(const double dIn)
cubic Cubic hyperbola interpolation function.
static QSharedPointer< Eigen::SparseMatrix< float > > createInterpolationMat(const Eigen::VectorXi &vecProjectedSensors, const QSharedPointer< Eigen::MatrixXd > matDistanceTable, double(*interpolationFunction)(double), const double dCancelDist=FLOAT_INFINITY, const Eigen::VectorXi &vecExcludeIndex=Eigen::VectorXi())
createInterpolationMat Calculates the weight matrix for interpolation.
static double square(const double dIn)
square Negative parabola interpolation function with y-offset of 1.
void setInterpolationFunction(const QString &sInterpolationFunction)
void computeInterpolationMatrix()
void setInterpolationInfoLeft(const Eigen::MatrixX3f &matVertices, const std::vector< Eigen::VectorXi > &vecNeighborVertices, const Eigen::VectorXi &vecSourceVertices)
void setCancelDistance(double dCancelDist)
void setAnnotationInfoLeft(const Eigen::VectorXi &vecLabelIds, const QList< FSLIB::FsLabel > &lLabels, const Eigen::VectorXi &vecVertNo)
RtSourceInterpolationMatWorker(QObject *parent=nullptr)
void newInterpolationMatrixRightAvailable(QSharedPointer< Eigen::SparseMatrix< float > > interpMat)
void setInterpolationInfoRight(const Eigen::MatrixX3f &matVertices, const std::vector< Eigen::VectorXi > &vecNeighborVertices, const Eigen::VectorXi &vecSourceVertices)
void newInterpolationMatrixLeftAvailable(QSharedPointer< Eigen::SparseMatrix< float > > interpMat)
void setVisualizationType(int iVisType)
void setAnnotationInfoRight(const Eigen::VectorXi &vecLabelIds, const QList< FSLIB::FsLabel > &lLabels, const Eigen::VectorXi &vecVertNo)
A FreeSurfer/MNE surface label: per-vertex indices, Tk-RAS positions and scalar values for one hemisp...