86 if(!forward.
sol || forward.
sol->data.size() == 0) {
87 qWarning(
"InvLCMV::makeLCMV - Forward solution has no gain matrix!");
91 MatrixXd G = forward.
sol->data;
92 const int nChannels =
static_cast<int>(G.rows());
94 const int nSources =
static_cast<int>(G.cols()) / nOrient;
96 qInfo(
"InvLCMV::makeLCMV - Leadfield: %d channels x %d sources (n_orient=%d)",
97 nChannels, nSources, nOrient);
103 if(noiseCov.
data.size() > 0) {
106 if(noiseCov.
eig.size() > 0 && noiseCov.
eigvec.size() > 0) {
107 VectorXd invSqrtEig(noiseCov.
eig.size());
108 for(
int i = 0; i < noiseCov.
eig.size(); ++i) {
109 invSqrtEig(i) = (noiseCov.
eig(i) > 1e-30)
110 ? 1.0 / std::sqrt(noiseCov.
eig(i))
113 whitener = invSqrtEig.asDiagonal() * noiseCov.
eigvec.transpose();
116 whitener = MatrixXd::Identity(nChannels, nChannels);
119 whitener = MatrixXd::Identity(nChannels, nChannels);
125 MatrixXd projMat = MatrixXd::Identity(nChannels, nChannels);
134 MatrixXd Gw = whitener * G;
136 MatrixXd CmData = dataCov.
data;
137 if(CmData.rows() != nChannels || CmData.cols() != nChannels) {
138 qWarning(
"InvLCMV::makeLCMV - Data covariance dimension (%d x %d) "
139 "does not match leadfield channels (%d)!",
140 static_cast<int>(CmData.rows()),
static_cast<int>(CmData.cols()), nChannels);
144 MatrixXd CmW = whitener * CmData * whitener.transpose();
146 CmW = (CmW + CmW.transpose()) * 0.5;
151 MatrixX3d nn = forward.
source_nn.cast<
double>();
160 Gw, CmW, reg, nOrient,
161 weightNorm, pickOri, reduceRank, invMethod,
165 qWarning(
"InvLCMV::makeLCMV - Beamformer computation failed!");
174 result.
proj = projMat;
184 result.
rank =
static_cast<int>(CmW.rows());
191 verts.resize(forward.
src[0].vertno.
size() + forward.
src[1].vertno.
size());
192 verts << forward.
src[0].vertno, forward.
src[1].vertno;
193 }
else if(forward.
src.
size() == 1) {
194 verts = forward.
src[0].vertno;
198 qInfo(
"InvLCMV::makeLCMV - Done. Filter: %d x %d (sources=%d, orient=%d)",
199 static_cast<int>(W.rows()),
static_cast<int>(W.cols()), nSources, result.
nOrient());
206MatrixXd InvLCMV::applyFilter(
const MatrixXd &data,
const InvBeamformer &filters)
209 MatrixXd processed = data;
212 if(filters.
proj.size() > 0 && filters.
proj.rows() == data.rows()) {
213 processed = filters.
proj * processed;
217 if(filters.
whitener.size() > 0 && filters.
whitener.cols() == processed.rows()) {
218 processed = filters.
whitener * processed;
222 return filters.
weights[0] * processed;
230 qWarning(
"InvLCMV::applyLCMV - Invalid or non-LCMV filters!");
236 if(filters.
chNames.size() > 0 &&
237 static_cast<int>(filters.
chNames.size()) != evoked.
data.rows()) {
239 const int nFilterCh =
static_cast<int>(filters.
chNames.size());
240 const int nTimes =
static_cast<int>(evoked.
data.cols());
241 data.resize(nFilterCh, nTimes);
242 for(
int i = 0; i < nFilterCh; ++i) {
245 qWarning(
"InvLCMV::applyLCMV - Channel %s not found in evoked!",
246 qPrintable(filters.
chNames[i]));
249 data.row(i) = evoked.
data.row(idx);
255 MatrixXd sol = applyFilter(data, filters);
258 const int nOrient = filters.
nOrient();
261 const int nSources =
static_cast<int>(sol.rows()) / 3;
262 const int nTimes =
static_cast<int>(sol.cols());
263 MatrixXd combined(nSources, nTimes);
264 for(
int s = 0; s < nSources; ++s) {
265 combined.row(s) = sol.middleRows(s * 3, 3).colwise().norm();
270 float tmin = evoked.
times.size() > 0 ? evoked.
times[0] : 0.0f;
289 qWarning(
"InvLCMV::applyLCMVRaw - Invalid or non-LCMV filters!");
293 MatrixXd sol = applyFilter(data, filters);
295 const int nOrient = filters.
nOrient();
297 const int nSources =
static_cast<int>(sol.rows()) / 3;
298 const int nTimes =
static_cast<int>(sol.cols());
299 MatrixXd combined(nSources, nTimes);
300 for(
int s = 0; s < nSources; ++s) {
301 combined.row(s) = sol.middleRows(s * 3, 3).colwise().norm();
320 qWarning(
"InvLCMV::applyLCMVCov - Invalid or non-LCMV filters!");
325 MatrixXd CmW = dataCov.
data;
330 const int nOrient = filters.
nOrient();
334 MatrixXd powerMat = power;
Linalg class declaration.
Shared beamformer computation routines for LCMV and DICS.
InvLCMV class declaration — Linearly Constrained Minimum Variance beamformer.
FiffEvoked class declaration.
FiffInfo class declaration.
FiffCov class declaration.
#define FIFFV_MNE_FREE_ORI
MNEForwardSolution class declaration.
Core MNE data structures (source spaces, source estimates, hemispheres).
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
FIFF measurement file information.
Computed beamformer spatial filter container.
BeamformerPickOri pickOri
BeamformerWeightNorm weightNorm
Eigen::MatrixX3f sourceNn
BeamformerInversion inversion
Eigen::MatrixX3d maxPowerOri
std::vector< Eigen::MatrixXd > weights
static Eigen::VectorXd computePower(const Eigen::MatrixXd &Cm, const Eigen::MatrixXd &W, int nOrient)
static bool computeBeamformer(const Eigen::MatrixXd &G, const Eigen::MatrixXd &Cm, double reg, int nOrient, BeamformerWeightNorm weightNorm, BeamformerPickOri pickOri, bool reduceRank, BeamformerInversion invMethod, const Eigen::MatrixX3d &nn, Eigen::MatrixXd &W, Eigen::MatrixX3d &maxPowerOri)
static InvSourceEstimate applyLCMVCov(const FIFFLIB::FiffCov &dataCov, const InvBeamformer &filters)
static InvBeamformer makeLCMV(const FIFFLIB::FiffInfo &info, const MNELIB::MNEForwardSolution &forward, const FIFFLIB::FiffCov &dataCov, double reg=0.05, const FIFFLIB::FiffCov &noiseCov=FIFFLIB::FiffCov(), BeamformerPickOri pickOri=BeamformerPickOri::None, BeamformerWeightNorm weightNorm=BeamformerWeightNorm::UnitNoiseGain, bool reduceRank=false, BeamformerInversion invMethod=BeamformerInversion::Matrix)
static InvSourceEstimate applyLCMV(const FIFFLIB::FiffEvoked &evoked, const InvBeamformer &filters)
static InvSourceEstimate applyLCMVRaw(const Eigen::MatrixXd &data, float tmin, float tstep, const InvBeamformer &filters)
InvSourceSpaceType sourceSpaceType
InvOrientationType orientationType
MNELIB::MNESourceSpaces src
FIFFLIB::fiff_int_t source_ori
Eigen::MatrixX3f source_nn
FIFFLIB::FiffNamedMatrix::SDPtr sol