v2.0.0
Loading...
Searching...
No Matches
mne_forwardsolution.h
Go to the documentation of this file.
1//=============================================================================================================
37
38#ifndef MNE_FORWARDSOLUTION_H
39#define MNE_FORWARDSOLUTION_H
40
41//=============================================================================================================
42// INCLUDES
43//=============================================================================================================
44
45#include "mne_global.h"
46#include "mne_source_spaces.h"
47
48#include <utils/mnemath.h>
49#include <utils/kmeans.h>
50
51#include <fs/annotationset.h>
52
53#include <fiff/fiff_constants.h>
55#include <fiff/fiff_types.h>
56#include <fiff/fiff_info_base.h>
57#include <fiff/fiff_cov.h>
58
59#include <math.h>
60
61//=============================================================================================================
62// EIGEN INCLUDES
63//=============================================================================================================
64
65#include <Eigen/Core>
66
67//=============================================================================================================
68// QT INCLUDES
69//=============================================================================================================
70
71#include <QFile>
72#include <QSharedPointer>
73#include <QDataStream>
74
75//=============================================================================================================
76// DEFINE NAMESPACE MNELIB
77//=============================================================================================================
78
79namespace MNELIB
80{
81
82//=========================================================================================================
89{
90 Eigen::VectorXi roiIdx;
91 Eigen::MatrixXd ctrs;
92 Eigen::VectorXd sumd;
93 Eigen::MatrixXd D;
94
95 qint32 iLabelIdxOut;
96};
97
98//=========================================================================================================
105{
106 Eigen::MatrixXd matRoiG;
107 Eigen::MatrixXd matRoiGWhitened;
109
110 Eigen::MatrixXd matRoiGOrig;
111// Eigen::MatrixXd matRoiGOrigWhitened; /**< Whitened region gain matrix sensors x sources(x,y,z)*/
112
113 qint32 nClusters;
114
115 Eigen::VectorXi idcs;
116 qint32 iLabelIdxIn;
117 QString sDistMeasure;
118
120 {
121 QString t_sDistMeasure;
122 if(sDistMeasure.isEmpty())
123 t_sDistMeasure = QString("cityblock");
124 else
125 t_sDistMeasure = sDistMeasure;
126
127 // Kmeans Reduction
128 RegionDataOut p_RegionDataOut;
129
130 UTILSLIB::KMeans t_kMeans(t_sDistMeasure, QString("sample"), 5);
131
132 if(bUseWhitened)
133 {
134 t_kMeans.calculate(this->matRoiGWhitened, this->nClusters, p_RegionDataOut.roiIdx, p_RegionDataOut.ctrs, p_RegionDataOut.sumd, p_RegionDataOut.D);
135
136 Eigen::MatrixXd newCtrs = Eigen::MatrixXd::Zero(p_RegionDataOut.ctrs.rows(), p_RegionDataOut.ctrs.cols());
137 for(qint32 c = 0; c < p_RegionDataOut.ctrs.rows(); ++c)
138 {
139 qint32 num = 0;
140
141 for(qint32 idx = 0; idx < p_RegionDataOut.roiIdx.size(); ++idx)
142 {
143 if(c == p_RegionDataOut.roiIdx[idx])
144 {
145 newCtrs.row(c) += this->matRoiG.row(idx); //just take whitened to get indeces calculate centroids using the original matrix
146 ++num;
147 }
148 }
149
150 if(num > 0)
151 newCtrs.row(c) /= num;
152 }
153 p_RegionDataOut.ctrs = newCtrs; //Replace whitened with original
154 }
155 else
156 t_kMeans.calculate(this->matRoiG, this->nClusters, p_RegionDataOut.roiIdx, p_RegionDataOut.ctrs, p_RegionDataOut.sumd, p_RegionDataOut.D);
157
158 p_RegionDataOut.iLabelIdxOut = this->iLabelIdxIn;
159
160 return p_RegionDataOut;
161 }
162};
163
164const static FIFFLIB::FiffCov defaultCov;
165const static FIFFLIB::FiffInfo defaultInfo;
166static Eigen::MatrixXd defaultD;
167
168//=============================================================================================================
175{
176public:
177 typedef QSharedPointer<MNEForwardSolution> SPtr;
178 typedef QSharedPointer<const MNEForwardSolution> ConstSPtr;
179
180 //=========================================================================================================
185
186 //=========================================================================================================
198 MNEForwardSolution(QIODevice &p_IODevice,
199 bool force_fixed = false,
200 bool surf_ori = false,
201 const QStringList& include = FIFFLIB::defaultQStringList,
202 const QStringList& exclude = FIFFLIB::defaultQStringList,
203 bool bExcludeBads = false);
204
205 //=========================================================================================================
211 MNEForwardSolution(const MNEForwardSolution &p_MNEForwardSolution);
212
213 //=========================================================================================================
218
219 //=========================================================================================================
223 void clear();
224
225 //=========================================================================================================
240 qint32 p_iClusterSize,
241 Eigen::MatrixXd& p_D = defaultD,
242 const FIFFLIB::FiffCov &p_pNoise_cov = defaultCov,
243 const FIFFLIB::FiffInfo &p_pInfo = defaultInfo,
244 QString p_sMethod = "cityblock") const;
245
246 //=========================================================================================================
254 FIFFLIB::FiffCov compute_orient_prior(float loose = 0.2);
255
256 //=========================================================================================================
270 static FIFFLIB::FiffCov compute_depth_prior(const Eigen::MatrixXd &Gain,
271 const FIFFLIB::FiffInfo &gain_info,
272 bool is_fixed_ori,
273 double exp = 0.8,
274 double limit = 10.0,
275 const Eigen::MatrixXd &patch_areas = FIFFLIB::defaultConstMatrixXd,
276 bool limit_depth_chs = false);
277
278 //=========================================================================================================
284 inline bool isClustered() const;
285
286 //=========================================================================================================
292 inline bool isEmpty() const;
293
294 //=========================================================================================================
300 inline bool isFixedOrient() const;
301
302 //=========================================================================================================
313 MNEForwardSolution pick_channels(const QStringList& include = FIFFLIB::defaultQStringList,
314 const QStringList& exclude = FIFFLIB::defaultQStringList) const;
315
316 //=========================================================================================================
324 MNEForwardSolution pick_regions(const QList<FSLIB::Label> &p_qListLabels) const;
325
326 //=========================================================================================================
340 bool eeg,
341 const QStringList& include = FIFFLIB::defaultQStringList,
342 const QStringList& exclude = FIFFLIB::defaultQStringList) const;
343
344 //=========================================================================================================
357 void prepare_forward(const FIFFLIB::FiffInfo &p_info,
358 const FIFFLIB::FiffCov &p_noise_cov,
359 bool p_pca,
360 FIFFLIB::FiffInfo &p_outFwdInfo,
361 Eigen::MatrixXd &gain,
362 FIFFLIB::FiffCov &p_outNoiseCov,
363 Eigen::MatrixXd &p_outWhitener,
364 qint32 &p_outNumNonZero) const;
365
366// //=========================================================================================================
367// /**
368// * Prepares a forward solution, Bad channels, after clustering etc ToDo...
369// *
370// * @param[in] p_FiffInfo Fif measurement info
371// *
372// */
373// void prepare_forward(const FiffInfo& p_FiffInfo)
374// {
375// QStringList fwdChNames = this->sol->row_names;
376// QStringList chNames;
377// for(qint32 i = 0; i < p_FiffInfo.ch_names.size(); ++i)
378// {
379// bool inBads = false;
380// bool inFwd = false;
381
382// for(qint32 j = 0; j < p_FiffInfo.bads.size(); ++j)
383// {
384// if(QString::compare(p_FiffInfo.bads[j], p_FiffInfo.ch_names[i]) == 0)
385// {
386// inBads = true;
387// break;
388// }
389// }
390
391// for(qint32 j = 0; j < fwdChNames.size(); ++j)
392// {
393// if(QString::compare(fwdChNames[j], p_FiffInfo.ch_names[i]) == 0)
394// {
395// inFwd = true;
396// break;
397// }
398// }
399
400// if(!inBads && inFwd)
401// chNames.append(p_FiffInfo.ch_names[i]);
402// }
403
404// qint32 nchan = chNames.size();
405// }
406
407 //=========================================================================================================
411 Eigen::VectorXi tripletSelection(const Eigen::VectorXi& p_vecIdxSelection) const
412 {
413 Eigen::MatrixXi triSelect = p_vecIdxSelection.transpose().replicate(3,1).array() * 3;//repmat((p_vecIdxSelection - 1) * 3 + 1, 3, 1);
414 triSelect.row(1).array() += 1;
415 triSelect.row(2).array() += 2;
416 Eigen::VectorXi retTriSelect(triSelect.cols()*3);
417 for(int i = 0; i < triSelect.cols(); ++i)
418 retTriSelect.block(i*3,0,3,1) = triSelect.col(i);
419 return retTriSelect;
420 } // tripletSelection
421
422 //=========================================================================================================
438 static bool read(QIODevice& p_IODevice,
440 bool force_fixed = false,
441 bool surf_ori = false,
442 const QStringList& include = FIFFLIB::defaultQStringList,
443 const QStringList& exclude = FIFFLIB::defaultQStringList,
444 bool bExcludeBads = true);
445
446 //ToDo readFromStream
447
448 //=========================================================================================================
457 MNEForwardSolution reduce_forward_solution(qint32 p_iNumDipoles, Eigen::MatrixXd& p_D) const;
458
459 //=========================================================================================================
466 static void restrict_gain_matrix(Eigen::MatrixXd &G, const FIFFLIB::FiffInfo &info);
467
468 //=========================================================================================================
472 void to_fixed_ori();
473
474 //=========================================================================================================
483 friend std::ostream& operator<<(std::ostream& out, const MNELIB::MNEForwardSolution &p_MNEForwardSolution);
484
492 friend bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b);
493
494 //=========================================================================================================
503 Eigen::MatrixX3f getSourcePositionsByLabel(const QList<FSLIB::Label> &lPickedLabels,
504 const FSLIB::SurfaceSet& tSurfSetInflated);
505
506private:
507 //=========================================================================================================
519 static bool read_one(FIFFLIB::FiffStream::SPtr& p_pStream,
520 const FIFFLIB::FiffDirNode::SPtr& p_Node,
521 MNEForwardSolution& one);
522
523public:
526 bool surf_ori;
534 Eigen::MatrixX3f source_rr;
535 Eigen::MatrixX3f source_nn;
536};
537
538//=============================================================================================================
539// INLINE DEFINITIONS
540//=============================================================================================================
541
543{
544 auto* hemi = src.hemisphereAt(0);
545 return hemi && hemi->isClustered();
546}
547
548//=============================================================================================================
549
551{
552 return this->nchan <= 0;
553}
554
555//=============================================================================================================
556
558{
559 return this->source_ori == FIFFV_MNE_FIXED_ORI;
560}
561
562//=============================================================================================================
563
564inline std::ostream& operator<<(std::ostream& out, const MNELIB::MNEForwardSolution &p_MNEForwardSolution)
565{
566 out << "#### MNE Forward Solution ####\n";
567
568 out << "\n source_ori: " << p_MNEForwardSolution.source_ori << std::endl;
569 out << "\n coord_frame: " << p_MNEForwardSolution.coord_frame << std::endl;
570 out << "\n nsource: " << p_MNEForwardSolution.nsource << std::endl;
571 out << "\n nchan: " << p_MNEForwardSolution.nchan << std::endl;
572 out << "\n sol:\n\t" << *p_MNEForwardSolution.sol.data() << std::endl;
573 out << "\n sol_grad:\n\t" << *p_MNEForwardSolution.sol_grad.data() << std::endl;
574
575 return out;
576}
577
578//=============================================================================================================
579
580inline bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b)
581{
582 return (a.info == b.info &&
583 a.source_ori == b.source_ori &&
584 a.surf_ori == b.surf_ori &&
585 a.coord_frame == b.coord_frame &&
586 a.nsource == b.nsource &&
587 a.nchan == b.nchan &&
588 *a.sol == *b.sol &&
589 *a.sol_grad == *b.sol_grad &&
590 a.mri_head_t == b.mri_head_t &&
591 a.src == b.src &&
592 a.source_rr.isApprox(b.source_rr, 0.0001f) &&
593 a.source_nn.isApprox(b.source_nn, 0.0001f));
594}
595} // NAMESPACE
596
597#endif // MNE_FORWARDSOLUTION_H
Fiff constants.
#define FIFFV_MNE_FIXED_ORI
FiffInfoBase class declaration.
FiffCov class declaration.
Old fiff_type declarations - replace them.
FiffCoordTrans class declaration.
MNEMath class declaration.
KMeans class declaration.
MNESourceSpaces class declaration.
mne library export/import macros.
#define MNESHARED_EXPORT
Definition mne_global.h:52
AnnotationSet class declaration.
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)
qint32 fiff_int_t
Definition fiff_types.h:89
Coordinate transformation description.
covariance data
Definition fiff_cov.h:84
QSharedPointer< FiffDirNode > SPtr
FIFF measurement file information.
Definition fiff_info.h:85
light measurement info
QSharedDataPointer< FiffNamedMatrix > SDPtr
QSharedPointer< FiffStream > SPtr
Annotation set.
A hemisphere set of surfaces.
Definition surfaceset.h:72
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
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)
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_regions(const QList< FSLIB::Label > &p_qListLabels) const
MNEForwardSolution pick_channels(const QStringList &include=FIFFLIB::defaultQStringList, const QStringList &exclude=FIFFLIB::defaultQStringList) const
FIFFLIB::FiffNamedMatrix::SDPtr sol_grad
MNEForwardSolution cluster_forward_solution(const FSLIB::AnnotationSet &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
Eigen::VectorXi tripletSelection(const Eigen::VectorXi &p_vecIdxSelection) const
QSharedPointer< const MNEForwardSolution > ConstSPtr
FIFFLIB::FiffCov compute_orient_prior(float loose=0.2)
MNEForwardSolution pick_types(bool meg, bool eeg, const QStringList &include=FIFFLIB::defaultQStringList, const QStringList &exclude=FIFFLIB::defaultQStringList) const
FIFFLIB::FiffNamedMatrix::SDPtr sol
Source Space descritpion.
K-Means Clustering.
Definition kmeans.h:73
bool calculate(Eigen::MatrixXd X, qint32 kClusters, Eigen::VectorXi &idx, Eigen::MatrixXd &C, Eigen::VectorXd &sumD, Eigen::MatrixXd &D)
Definition kmeans.cpp:120