v2.0.0
Loading...
Searching...
No Matches
mne_forward_solution.h
Go to the documentation of this file.
1//=============================================================================================================
22
23#ifndef MNE_FORWARD_SOLUTION_H
24#define MNE_FORWARD_SOLUTION_H
25
26//=============================================================================================================
27// INCLUDES
28//=============================================================================================================
29
30#include "mne_global.h"
31
33
34#include <math/kmeans.h>
35
36#include <fs/fs_annotationset.h>
37
38#include <fiff/fiff_constants.h>
40#include <fiff/fiff_types.h>
41#include <fiff/fiff_info_base.h>
42#include <fiff/fiff_cov.h>
43
44#include <math.h>
45#include <memory>
46
47//=============================================================================================================
48// EIGEN INCLUDES
49//=============================================================================================================
50
51#include <Eigen/Core>
52
53//=============================================================================================================
54// QT INCLUDES
55//=============================================================================================================
56
57#include <QSharedPointer>
58
59//=============================================================================================================
60// DEFINE NAMESPACE MNELIB
61//=============================================================================================================
62
63namespace MNELIB
64{
65
66//=========================================================================================================
73{
74 Eigen::VectorXi roiIdx;
75 Eigen::MatrixXd ctrs;
76 Eigen::VectorXd sumd;
77 Eigen::MatrixXd D;
78
79 qint32 iLabelIdxOut;
80};
81
82//=========================================================================================================
89{
90 Eigen::MatrixXd matRoiG;
91 Eigen::MatrixXd matRoiGWhitened;
93
94 Eigen::MatrixXd matRoiGOrig;
95
96 qint32 nClusters;
97
98 Eigen::VectorXi idcs;
99 qint32 iLabelIdxIn;
100 QString sDistMeasure;
101
103 {
104 QString t_sDistMeasure;
105 if(sDistMeasure.isEmpty())
106 t_sDistMeasure = QString("cityblock");
107 else
108 t_sDistMeasure = sDistMeasure;
109
110 // Kmeans Reduction
111 RegionDataOut p_RegionDataOut;
112
113 UTILSLIB::KMeans t_kMeans(t_sDistMeasure, QString("sample"), 5);
114
115 if(bUseWhitened)
116 {
117 t_kMeans.calculate(this->matRoiGWhitened, this->nClusters, p_RegionDataOut.roiIdx, p_RegionDataOut.ctrs, p_RegionDataOut.sumd, p_RegionDataOut.D);
118
119 Eigen::MatrixXd newCtrs = Eigen::MatrixXd::Zero(p_RegionDataOut.ctrs.rows(), p_RegionDataOut.ctrs.cols());
120 for(qint32 c = 0; c < p_RegionDataOut.ctrs.rows(); ++c)
121 {
122 qint32 num = 0;
123
124 for(qint32 idx = 0; idx < p_RegionDataOut.roiIdx.size(); ++idx)
125 {
126 if(c == p_RegionDataOut.roiIdx[idx])
127 {
128 newCtrs.row(c) += this->matRoiG.row(idx); //just take whitened to get indeces calculate centroids using the original matrix
129 ++num;
130 }
131 }
132
133 if(num > 0)
134 newCtrs.row(c) /= num;
135 }
136 p_RegionDataOut.ctrs = newCtrs; //Replace whitened with original
137 }
138 else
139 t_kMeans.calculate(this->matRoiG, this->nClusters, p_RegionDataOut.roiIdx, p_RegionDataOut.ctrs, p_RegionDataOut.sumd, p_RegionDataOut.D);
140
141 p_RegionDataOut.iLabelIdxOut = this->iLabelIdxIn;
142
143 return p_RegionDataOut;
144 }
145};
146
147const static FIFFLIB::FiffCov defaultCov;
148const static FIFFLIB::FiffInfo defaultInfo;
149static Eigen::MatrixXd defaultD;
150
151//=============================================================================================================
160{
161public:
162 typedef QSharedPointer<MNEForwardSolution> SPtr;
163 typedef QSharedPointer<const MNEForwardSolution> ConstSPtr;
164 typedef std::unique_ptr<MNEForwardSolution> UPtr;
165
166 //=========================================================================================================
171
172 //=========================================================================================================
184 MNEForwardSolution(QIODevice &p_IODevice,
185 bool force_fixed = false,
186 bool surf_ori = false,
187 const QStringList& include = FIFFLIB::defaultQStringList,
188 const QStringList& exclude = FIFFLIB::defaultQStringList,
189 bool bExcludeBads = false);
190
191 //=========================================================================================================
197 MNEForwardSolution(const MNEForwardSolution &p_MNEForwardSolution);
198
199 //=========================================================================================================
208
209 //=========================================================================================================
214
215 //=========================================================================================================
220
221 //=========================================================================================================
226
227 //=========================================================================================================
231 void clear();
232
233 //=========================================================================================================
248 qint32 p_iClusterSize,
249 Eigen::MatrixXd& p_D = defaultD,
250 const FIFFLIB::FiffCov &p_pNoise_cov = defaultCov,
251 const FIFFLIB::FiffInfo &p_pInfo = defaultInfo,
252 QString p_sMethod = "cityblock") const;
253
254 //=========================================================================================================
262 FIFFLIB::FiffCov compute_orient_prior(float loose = 0.2);
263
264 //=========================================================================================================
278 static FIFFLIB::FiffCov compute_depth_prior(const Eigen::MatrixXd &Gain,
279 const FIFFLIB::FiffInfo &gain_info,
280 bool is_fixed_ori,
281 double exp = 0.8,
282 double limit = 10.0,
283 const Eigen::MatrixXd &patch_areas = FIFFLIB::defaultConstMatrixXd,
284 bool limit_depth_chs = false);
285
286 //=========================================================================================================
292 bool isClustered() const;
293
294 //=========================================================================================================
300 inline bool isEmpty() const;
301
302 //=========================================================================================================
308 inline bool isFixedOrient() const;
309
310 //=========================================================================================================
321 MNEForwardSolution pick_channels(const QStringList& include = FIFFLIB::defaultQStringList,
322 const QStringList& exclude = FIFFLIB::defaultQStringList) const;
323
324 //=========================================================================================================
332 MNEForwardSolution pick_regions(const QList<FSLIB::FsLabel> &p_qListLabels) const;
333
334 //=========================================================================================================
348 bool eeg,
349 const QStringList& include = FIFFLIB::defaultQStringList,
350 const QStringList& exclude = FIFFLIB::defaultQStringList) const;
351
352 //=========================================================================================================
365 void prepare_forward(const FIFFLIB::FiffInfo &p_info,
366 const FIFFLIB::FiffCov &p_noise_cov,
367 bool p_pca,
368 FIFFLIB::FiffInfo &p_outFwdInfo,
369 Eigen::MatrixXd &gain,
370 FIFFLIB::FiffCov &p_outNoiseCov,
371 Eigen::MatrixXd &p_outWhitener,
372 qint32 &p_outNumNonZero) const;
373
374 //=========================================================================================================
378 Eigen::VectorXi tripletSelection(const Eigen::VectorXi& p_vecIdxSelection) const
379 {
380 Eigen::MatrixXi triSelect = p_vecIdxSelection.transpose().replicate(3,1).array() * 3;//repmat((p_vecIdxSelection - 1) * 3 + 1, 3, 1);
381 triSelect.row(1).array() += 1;
382 triSelect.row(2).array() += 2;
383 Eigen::VectorXi retTriSelect(triSelect.cols()*3);
384 for(int i = 0; i < triSelect.cols(); ++i)
385 retTriSelect.block(i*3,0,3,1) = triSelect.col(i);
386 return retTriSelect;
387 } // tripletSelection
388
389 //=========================================================================================================
405 static bool read(QIODevice& p_IODevice,
407 bool force_fixed = false,
408 bool surf_ori = false,
409 const QStringList& include = FIFFLIB::defaultQStringList,
410 const QStringList& exclude = FIFFLIB::defaultQStringList,
411 bool bExcludeBads = true);
412
413 //=========================================================================================================
427 bool write(QIODevice& p_IODevice) const;
428
429 //=========================================================================================================
438 MNEForwardSolution reduce_forward_solution(qint32 p_iNumDipoles, Eigen::MatrixXd& p_D) const;
439
440 //=========================================================================================================
447 static void restrict_gain_matrix(Eigen::MatrixXd &G, const FIFFLIB::FiffInfo &info);
448
449 //=========================================================================================================
453 void to_fixed_ori();
454
455 //=========================================================================================================
464 friend std::ostream& operator<<(std::ostream& out, const MNELIB::MNEForwardSolution &p_MNEForwardSolution);
465
473 friend bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b);
474
475 //=========================================================================================================
484 Eigen::MatrixX3f getSourcePositionsByLabel(const QList<FSLIB::FsLabel> &lPickedLabels,
485 const FSLIB::FsSurfaceSet& tSurfSetInflated);
486
487private:
488 //=========================================================================================================
500 static bool read_one(FIFFLIB::FiffStream::SPtr& p_pStream,
501 const FIFFLIB::FiffDirNode::SPtr& p_Node,
502 MNEForwardSolution& one);
503
504public:
506 FIFFLIB::fiff_int_t source_ori;
507 bool surf_ori;
508 FIFFLIB::fiff_int_t coord_frame;
509 FIFFLIB::fiff_int_t nsource;
510 FIFFLIB::fiff_int_t nchan;
514 QString mri_filename;
517 Eigen::MatrixX3f source_rr;
518 Eigen::MatrixX3f source_nn;
519};
520
521//=============================================================================================================
522// INLINE DEFINITIONS
523//=============================================================================================================
524
526{
527 return this->nchan <= 0;
528}
529
530//=============================================================================================================
531
533{
534 return this->source_ori == FIFFV_MNE_FIXED_ORI;
535}
536
537//=============================================================================================================
538
539inline std::ostream& operator<<(std::ostream& out, const MNELIB::MNEForwardSolution &p_MNEForwardSolution)
540{
541 out << "#### MNE Forward Solution ####\n";
542
543 out << "\n source_ori: " << p_MNEForwardSolution.source_ori << std::endl;
544 out << "\n coord_frame: " << p_MNEForwardSolution.coord_frame << std::endl;
545 out << "\n nsource: " << p_MNEForwardSolution.nsource << std::endl;
546 out << "\n nchan: " << p_MNEForwardSolution.nchan << std::endl;
547 out << "\n sol:\n\t" << *p_MNEForwardSolution.sol.data() << std::endl;
548 out << "\n sol_grad:\n\t" << *p_MNEForwardSolution.sol_grad.data() << std::endl;
549
550 return out;
551}
552
553//=============================================================================================================
554
555inline bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b)
556{
557 return (a.info == b.info &&
558 a.source_ori == b.source_ori &&
559 a.surf_ori == b.surf_ori &&
560 a.coord_frame == b.coord_frame &&
561 a.nsource == b.nsource &&
562 a.nchan == b.nchan &&
563 *a.sol == *b.sol &&
564 *a.sol_grad == *b.sol_grad &&
565 a.mri_head_t == b.mri_head_t &&
566 a.src == b.src &&
567 a.source_rr.isApprox(b.source_rr, 0.0001f) &&
568 a.source_nn.isApprox(b.source_nn, 0.0001f));
569}
570} // NAMESPACE
571
572#endif // MNE_FORWARD_SOLUTION_H
bool operator==(const BIDSPath &a, const BIDSPath &b)
Bi-hemispheric pair of FreeSurfer annotations (lh + rh) for one parcellation atlas.
MNELIB shared-library export/import macros and library build metadata.
#define MNESHARED_EXPORT
Definition mne_global.h:40
Container pairing the left and right cortical source spaces of a subject.
Symbolic FIFF tag, block, value, unit and channel-type constants shared across FIFFLIB.
#define FIFFV_MNE_FIXED_ORI
Minimal measurement-info subset (channel list, sampling rate, basic transforms) shared by FIFF reader...
Noise / data covariance matrix as stored under FIFFB_MNE_COV, with channel names, kind,...
4x4 affine FIFF coordinate transform (FIFF_COORD_TRANS) annotated with source/destination coordinate-...
Primitive scalar typedefs and forward-compatible aliases backing the FIFF type system.
K-means partitional clustering with multiple distance metrics, initialisations and empty-cluster poli...
Core MNE data structures (source spaces, source estimates, hemispheres).
std::ostream & operator<<(std::ostream &out, const MNELIB::MNEForwardSolution &p_MNEForwardSolution)
bool operator==(const MNEClusterInfo &a, const MNEClusterInfo &b)
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
FIFF noise / data covariance: matrix, channel names, kind, applied projectors, bads,...
Definition fiff_cov.h:79
QSharedPointer< FiffDirNode > SPtr
128-bit FIFF identifier: hardware machine ID plus creation time, stamped on every file and block.
Definition fiff_id.h:66
Full FIFF measurement info: per-channel descriptors, sampling and filter setup, projectors,...
Definition fiff_info.h:88
Stripped FIFF measurement info: channel list, sampling rate, device→head transform and bad-channel li...
QSharedDataPointer< FiffNamedMatrix > SDPtr
QSharedPointer< FiffStream > SPtr
Container holding the lh and/or rh FsAnnotation for one parcellation atlas.
Container holding the lh and/or rh FsSurface for one subject and one surface kind.
Lloyd-style K-means clustering with configurable metric, seeding and replicates.
Definition kmeans.h:110
bool calculate(const Eigen::MatrixXd &X, qint32 kClusters, Eigen::VectorXi &idx, Eigen::MatrixXd &C, Eigen::VectorXd &sumD, Eigen::MatrixXd &D)
Definition kmeans.cpp:131
Output of a cluster-based forward solution computation for a single cortical region.
Input parameters for cluster-based forward solution computation on a single cortical region.
Eigen::MatrixXd matRoiGWhitened
Eigen::MatrixXd matRoiGOrig
RegionDataOut cluster() const
In-memory representation of an -fwd.fif forward solution.
static FIFFLIB::FiffCov compute_depth_prior(const Eigen::MatrixXd &Gain, const FIFFLIB::FiffInfo &gain_info, bool is_fixed_ori, double exp=0.8, double limit=10.0, const Eigen::MatrixXd &patch_areas=FIFFLIB::defaultConstMatrixXd, bool limit_depth_chs=false)
MNELIB::MNESourceSpaces src
MNEForwardSolution cluster_forward_solution(const FSLIB::FsAnnotationSet &p_AnnotationSet, qint32 p_iClusterSize, Eigen::MatrixXd &p_D=defaultD, const FIFFLIB::FiffCov &p_pNoise_cov=defaultCov, const FIFFLIB::FiffInfo &p_pInfo=defaultInfo, QString p_sMethod="cityblock") const
MNEForwardSolution & operator=(const MNEForwardSolution &other)
void prepare_forward(const FIFFLIB::FiffInfo &p_info, const FIFFLIB::FiffCov &p_noise_cov, bool p_pca, FIFFLIB::FiffInfo &p_outFwdInfo, Eigen::MatrixXd &gain, FIFFLIB::FiffCov &p_outNoiseCov, Eigen::MatrixXd &p_outWhitener, qint32 &p_outNumNonZero) const
FIFFLIB::FiffCoordTrans mri_head_t
QSharedPointer< MNEForwardSolution > SPtr
MNEForwardSolution pick_channels(const QStringList &include=FIFFLIB::defaultQStringList, const QStringList &exclude=FIFFLIB::defaultQStringList) const
FIFFLIB::FiffNamedMatrix::SDPtr sol_grad
MNEForwardSolution & operator=(MNEForwardSolution &&other)=default
Eigen::VectorXi tripletSelection(const Eigen::VectorXi &p_vecIdxSelection) const
std::unique_ptr< MNEForwardSolution > UPtr
MNEForwardSolution(MNEForwardSolution &&other)=default
QSharedPointer< const MNEForwardSolution > ConstSPtr
FIFFLIB::FiffCov compute_orient_prior(float loose=0.2)
MNEForwardSolution pick_regions(const QList< FSLIB::FsLabel > &p_qListLabels) const
MNEForwardSolution pick_types(bool meg, bool eeg, const QStringList &include=FIFFLIB::defaultQStringList, const QStringList &exclude=FIFFLIB::defaultQStringList) const
FIFFLIB::FiffNamedMatrix::SDPtr sol
List of MNESourceSpace objects forming a subject source space.