v2.0.0
Loading...
Searching...
No Matches
inv_resolution_matrix.cpp
Go to the documentation of this file.
1//=============================================================================================================
18
19//=============================================================================================================
20// INCLUDES
21//=============================================================================================================
22
24
25//=============================================================================================================
26// QT INCLUDES
27//=============================================================================================================
28
29#include <QDebug>
30
31//=============================================================================================================
32// USED NAMESPACES
33//=============================================================================================================
34
35using namespace INVLIB;
36using namespace Eigen;
37
38//=============================================================================================================
39// DEFINE MEMBER METHODS
40//=============================================================================================================
41
42MatrixXd InvResolutionMatrix::compute(const MatrixXd& matInverseKernel,
43 const MatrixXd& matLeadField)
44{
45 if (matInverseKernel.cols() != matLeadField.rows()) {
46 qWarning() << "[InvResolutionMatrix::compute] Dimension mismatch:"
47 << "inverse kernel cols" << matInverseKernel.cols()
48 << "!= lead field rows" << matLeadField.rows();
49 return MatrixXd();
50 }
51
52 return matInverseKernel * matLeadField;
53}
54
55//=============================================================================================================
56
57VectorXd InvResolutionMatrix::getPsf(const MatrixXd& matResolution, int iSourceIdx)
58{
59 if (iSourceIdx < 0 || iSourceIdx >= matResolution.cols()) {
60 qWarning() << "[InvResolutionMatrix::getPsf] Index out of range:" << iSourceIdx;
61 return VectorXd();
62 }
63
64 return matResolution.col(iSourceIdx);
65}
66
67//=============================================================================================================
68
69VectorXd InvResolutionMatrix::getCtf(const MatrixXd& matResolution, int iSourceIdx)
70{
71 if (iSourceIdx < 0 || iSourceIdx >= matResolution.rows()) {
72 qWarning() << "[InvResolutionMatrix::getCtf] Index out of range:" << iSourceIdx;
73 return VectorXd();
74 }
75
76 return matResolution.row(iSourceIdx).transpose();
77}
78
79//=============================================================================================================
80
81MatrixXd InvResolutionMatrix::getPsfs(const MatrixXd& matResolution,
82 const VectorXi& vecSourceIdx)
83{
84 const int nIdx = static_cast<int>(vecSourceIdx.size());
85 MatrixXd result(matResolution.rows(), nIdx);
86
87 for (int i = 0; i < nIdx; ++i) {
88 if (vecSourceIdx[i] >= 0 && vecSourceIdx[i] < matResolution.cols())
89 result.col(i) = matResolution.col(vecSourceIdx[i]);
90 else
91 result.col(i).setZero();
92 }
93
94 return result;
95}
96
97//=============================================================================================================
98
99MatrixXd InvResolutionMatrix::getCtfs(const MatrixXd& matResolution,
100 const VectorXi& vecSourceIdx)
101{
102 const int nIdx = static_cast<int>(vecSourceIdx.size());
103 MatrixXd result(nIdx, matResolution.cols());
104
105 for (int i = 0; i < nIdx; ++i) {
106 if (vecSourceIdx[i] >= 0 && vecSourceIdx[i] < matResolution.rows())
107 result.row(i) = matResolution.row(vecSourceIdx[i]);
108 else
109 result.row(i).setZero();
110 }
111
112 return result;
113}
114
115//=============================================================================================================
116
117VectorXd InvResolutionMatrix::spatialSpread(const MatrixXd& matResolution,
118 const MatrixX3d& matPositions)
119{
120 const int nSrc = static_cast<int>(matResolution.rows());
121 VectorXd spread(nSrc);
122
123 for (int s = 0; s < nSrc; ++s) {
124 // PSF = column s (or row s for CTF-based; here we use PSF convention)
125 VectorXd psf = matResolution.col(s).cwiseAbs2();
126 double psfSum = psf.sum();
127 if (psfSum < 1e-30) {
128 spread[s] = 0.0;
129 continue;
130 }
131
132 // Normalise to distribution
133 psf /= psfSum;
134
135 // Compute weighted mean distance from source s
136 double meanDist = 0.0;
137 double meanDist2 = 0.0;
138 for (int j = 0; j < nSrc; ++j) {
139 double dist = (matPositions.row(j) - matPositions.row(s)).norm();
140 meanDist += psf[j] * dist;
141 meanDist2 += psf[j] * dist * dist;
142 }
143
144 // Standard deviation of the distance distribution
145 spread[s] = std::sqrt(std::max(0.0, meanDist2 - meanDist * meanDist));
146 }
147
148 return spread;
149}
150
151//=============================================================================================================
152
153VectorXd InvResolutionMatrix::peakLocalisationError(const MatrixXd& matResolution,
154 const MatrixX3d& matPositions)
155{
156 const int nSrc = static_cast<int>(matResolution.rows());
157 VectorXd ple(nSrc);
158
159 for (int s = 0; s < nSrc; ++s) {
160 // Find peak of PSF (column s)
161 VectorXd psf = matResolution.col(s).cwiseAbs();
162 Index peakIdx = 0;
163 psf.maxCoeff(&peakIdx);
164
165 ple[s] = (matPositions.row(peakIdx) - matPositions.row(s)).norm();
166 }
167
168 return ple;
169}
Resolution-matrix analysis for linear inverse operators — point-spread and cross-talk functions.
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
static Eigen::MatrixXd compute(const Eigen::MatrixXd &matInverseKernel, const Eigen::MatrixXd &matLeadField)
static Eigen::VectorXd peakLocalisationError(const Eigen::MatrixXd &matResolution, const Eigen::MatrixX3d &matPositions)
static Eigen::MatrixXd getCtfs(const Eigen::MatrixXd &matResolution, const Eigen::VectorXi &vecSourceIdx)
static Eigen::MatrixXd getPsfs(const Eigen::MatrixXd &matResolution, const Eigen::VectorXi &vecSourceIdx)
static Eigen::VectorXd spatialSpread(const Eigen::MatrixXd &matResolution, const Eigen::MatrixX3d &matPositions)
static Eigen::VectorXd getCtf(const Eigen::MatrixXd &matResolution, int iSourceIdx)
static Eigen::VectorXd getPsf(const Eigen::MatrixXd &matResolution, int iSourceIdx)