MNE-CPP  0.1.9
A Framework for Electrophysiology
mne_forwardsolution.h
Go to the documentation of this file.
1 //=============================================================================================================
38 #ifndef MNE_FORWARDSOLUTION_H
39 #define MNE_FORWARDSOLUTION_H
40 
41 //=============================================================================================================
42 // INCLUDES
43 //=============================================================================================================
44 
45 #include "mne_global.h"
46 #include "mne_sourcespace.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>
54 #include <fiff/fiff_coord_trans.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 
79 namespace MNELIB
80 {
81 
82 //=========================================================================================================
87 {
88  Eigen::VectorXi roiIdx;
89  Eigen::MatrixXd ctrs;
90  Eigen::VectorXd sumd;
91  Eigen::MatrixXd D;
93  qint32 iLabelIdxOut;
94 };
95 
96 //=========================================================================================================
101 {
102  Eigen::MatrixXd matRoiG;
103  Eigen::MatrixXd matRoiGWhitened;
106  Eigen::MatrixXd matRoiGOrig;
107 // Eigen::MatrixXd matRoiGOrigWhitened; /**< Whitened region gain matrix sensors x sources(x,y,z)*/
108 
109  qint32 nClusters;
111  Eigen::VectorXi idcs;
112  qint32 iLabelIdxIn;
113  QString sDistMeasure;
115  RegionDataOut cluster() const
116  {
117  QString t_sDistMeasure;
118  if(sDistMeasure.isEmpty())
119  t_sDistMeasure = QString("cityblock");
120  else
121  t_sDistMeasure = sDistMeasure;
122 
123  // Kmeans Reduction
124  RegionDataOut p_RegionDataOut;
125 
126  UTILSLIB::KMeans t_kMeans(t_sDistMeasure, QString("sample"), 5);
127 
128  if(bUseWhitened)
129  {
130  t_kMeans.calculate(this->matRoiGWhitened, this->nClusters, p_RegionDataOut.roiIdx, p_RegionDataOut.ctrs, p_RegionDataOut.sumd, p_RegionDataOut.D);
131 
132  Eigen::MatrixXd newCtrs = Eigen::MatrixXd::Zero(p_RegionDataOut.ctrs.rows(), p_RegionDataOut.ctrs.cols());
133  for(qint32 c = 0; c < p_RegionDataOut.ctrs.rows(); ++c)
134  {
135  qint32 num = 0;
136 
137  for(qint32 idx = 0; idx < p_RegionDataOut.roiIdx.size(); ++idx)
138  {
139  if(c == p_RegionDataOut.roiIdx[idx])
140  {
141  newCtrs.row(c) += this->matRoiG.row(idx); //just take whitened to get indeces calculate centroids using the original matrix
142  ++num;
143  }
144  }
145 
146  if(num > 0)
147  newCtrs.row(c) /= num;
148  }
149  p_RegionDataOut.ctrs = newCtrs; //Replace whitened with original
150  }
151  else
152  t_kMeans.calculate(this->matRoiG, this->nClusters, p_RegionDataOut.roiIdx, p_RegionDataOut.ctrs, p_RegionDataOut.sumd, p_RegionDataOut.D);
153 
154  p_RegionDataOut.iLabelIdxOut = this->iLabelIdxIn;
155 
156  return p_RegionDataOut;
157  }
158 };
159 
160 const static FIFFLIB::FiffCov defaultCov;
161 const static FIFFLIB::FiffInfo defaultInfo;
162 static Eigen::MatrixXd defaultD;
163 
164 //=============================================================================================================
171 {
172 public:
173  typedef QSharedPointer<MNEForwardSolution> SPtr;
174  typedef QSharedPointer<const MNEForwardSolution> ConstSPtr;
176  //=========================================================================================================
181 
182  //=========================================================================================================
194  MNEForwardSolution(QIODevice &p_IODevice,
195  bool force_fixed = false,
196  bool surf_ori = false,
197  const QStringList& include = FIFFLIB::defaultQStringList,
198  const QStringList& exclude = FIFFLIB::defaultQStringList,
199  bool bExcludeBads = false);
200 
201  //=========================================================================================================
207  MNEForwardSolution(const MNEForwardSolution &p_MNEForwardSolution);
208 
209  //=========================================================================================================
214 
215  //=========================================================================================================
219  void clear();
220 
221  //=========================================================================================================
235  MNEForwardSolution cluster_forward_solution(const FSLIB::AnnotationSet &p_AnnotationSet,
236  qint32 p_iClusterSize,
237  Eigen::MatrixXd& p_D = defaultD,
238  const FIFFLIB::FiffCov &p_pNoise_cov = defaultCov,
239  const FIFFLIB::FiffInfo &p_pInfo = defaultInfo,
240  QString p_sMethod = "cityblock") const;
241 
242  //=========================================================================================================
250  FIFFLIB::FiffCov compute_orient_prior(float loose = 0.2);
251 
252  //=========================================================================================================
266  static FIFFLIB::FiffCov compute_depth_prior(const Eigen::MatrixXd &Gain,
267  const FIFFLIB::FiffInfo &gain_info,
268  bool is_fixed_ori,
269  double exp = 0.8,
270  double limit = 10.0,
271  const Eigen::MatrixXd &patch_areas = FIFFLIB::defaultConstMatrixXd,
272  bool limit_depth_chs = false);
273 
274  //=========================================================================================================
280  inline bool isClustered() const;
281 
282  //=========================================================================================================
288  inline bool isEmpty() const;
289 
290  //=========================================================================================================
296  inline bool isFixedOrient() const;
297 
298  //=========================================================================================================
309  MNEForwardSolution pick_channels(const QStringList& include = FIFFLIB::defaultQStringList,
310  const QStringList& exclude = FIFFLIB::defaultQStringList) const;
311 
312  //=========================================================================================================
320  MNEForwardSolution pick_regions(const QList<FSLIB::Label> &p_qListLabels) const;
321 
322  //=========================================================================================================
335  MNEForwardSolution pick_types(bool meg,
336  bool eeg,
337  const QStringList& include = FIFFLIB::defaultQStringList,
338  const QStringList& exclude = FIFFLIB::defaultQStringList) const;
339 
340  //=========================================================================================================
353  void prepare_forward(const FIFFLIB::FiffInfo &p_info,
354  const FIFFLIB::FiffCov &p_noise_cov,
355  bool p_pca,
356  FIFFLIB::FiffInfo &p_outFwdInfo,
357  Eigen::MatrixXd &gain,
358  FIFFLIB::FiffCov &p_outNoiseCov,
359  Eigen::MatrixXd &p_outWhitener,
360  qint32 &p_outNumNonZero) const;
361 
362 // //=========================================================================================================
363 // /**
364 // * Prepares a forward solution, Bad channels, after clustering etc ToDo...
365 // *
366 // * @param[in] p_FiffInfo Fif measurement info
367 // *
368 // */
369 // void prepare_forward(const FiffInfo& p_FiffInfo)
370 // {
371 // QStringList fwdChNames = this->sol->row_names;
372 // QStringList chNames;
373 // for(qint32 i = 0; i < p_FiffInfo.ch_names.size(); ++i)
374 // {
375 // bool inBads = false;
376 // bool inFwd = false;
377 
378 // for(qint32 j = 0; j < p_FiffInfo.bads.size(); ++j)
379 // {
380 // if(QString::compare(p_FiffInfo.bads[j], p_FiffInfo.ch_names[i]) == 0)
381 // {
382 // inBads = true;
383 // break;
384 // }
385 // }
386 
387 // for(qint32 j = 0; j < fwdChNames.size(); ++j)
388 // {
389 // if(QString::compare(fwdChNames[j], p_FiffInfo.ch_names[i]) == 0)
390 // {
391 // inFwd = true;
392 // break;
393 // }
394 // }
395 
396 // if(!inBads && inFwd)
397 // chNames.append(p_FiffInfo.ch_names[i]);
398 // }
399 
400 // qint32 nchan = chNames.size();
401 // }
402 
403  //=========================================================================================================
407  Eigen::VectorXi tripletSelection(const Eigen::VectorXi& p_vecIdxSelection) const
408  {
409  Eigen::MatrixXi triSelect = p_vecIdxSelection.transpose().replicate(3,1).array() * 3;//repmat((p_vecIdxSelection - 1) * 3 + 1, 3, 1);
410  triSelect.row(1).array() += 1;
411  triSelect.row(2).array() += 2;
412  Eigen::VectorXi retTriSelect(triSelect.cols()*3);
413  for(int i = 0; i < triSelect.cols(); ++i)
414  retTriSelect.block(i*3,0,3,1) = triSelect.col(i);
415  return retTriSelect;
416  } // tripletSelection
417 
418  //=========================================================================================================
434  static bool read(QIODevice& p_IODevice,
435  MNEForwardSolution& fwd,
436  bool force_fixed = false,
437  bool surf_ori = false,
438  const QStringList& include = FIFFLIB::defaultQStringList,
439  const QStringList& exclude = FIFFLIB::defaultQStringList,
440  bool bExcludeBads = true);
441 
442  //ToDo readFromStream
443 
444  //=========================================================================================================
453  MNEForwardSolution reduce_forward_solution(qint32 p_iNumDipoles, Eigen::MatrixXd& p_D) const;
454 
455  //=========================================================================================================
462  static void restrict_gain_matrix(Eigen::MatrixXd &G, const FIFFLIB::FiffInfo &info);
463 
464  //=========================================================================================================
468  void to_fixed_ori();
469 
470  //=========================================================================================================
479  friend std::ostream& operator<<(std::ostream& out, const MNELIB::MNEForwardSolution &p_MNEForwardSolution);
480 
488  friend bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b);
489 
490  //=========================================================================================================
499  Eigen::MatrixX3f getSourcePositionsByLabel(const QList<FSLIB::Label> &lPickedLabels,
500  const FSLIB::SurfaceSet& tSurfSetInflated);
501 
502 private:
503  //=========================================================================================================
515  static bool read_one(FIFFLIB::FiffStream::SPtr& p_pStream,
516  const FIFFLIB::FiffDirNode::SPtr& p_Node,
517  MNEForwardSolution& one);
518 
519 public:
521  FIFFLIB::fiff_int_t source_ori;
522  bool surf_ori;
523  FIFFLIB::fiff_int_t coord_frame;
524  FIFFLIB::fiff_int_t nsource;
525  FIFFLIB::fiff_int_t nchan;
530  Eigen::MatrixX3f source_rr;
531  Eigen::MatrixX3f source_nn;
532 };
533 
534 //=============================================================================================================
535 // INLINE DEFINITIONS
536 //=============================================================================================================
537 
539 {
540  return src[0].isClustered();
541 }
542 
543 //=============================================================================================================
544 
545 inline bool MNEForwardSolution::isEmpty() const
546 {
547  return this->nchan <= 0;
548 }
549 
550 //=============================================================================================================
551 
553 {
554  return this->source_ori == FIFFV_MNE_FIXED_ORI;
555 }
556 
557 //=============================================================================================================
558 
559 inline std::ostream& operator<<(std::ostream& out, const MNELIB::MNEForwardSolution &p_MNEForwardSolution)
560 {
561  out << "#### MNE Forward Solution ####\n";
562 
563  out << "\n source_ori: " << p_MNEForwardSolution.source_ori << std::endl;
564  out << "\n coord_frame: " << p_MNEForwardSolution.coord_frame << std::endl;
565  out << "\n nsource: " << p_MNEForwardSolution.nsource << std::endl;
566  out << "\n nchan: " << p_MNEForwardSolution.nchan << std::endl;
567  out << "\n sol:\n\t" << *p_MNEForwardSolution.sol.data() << std::endl;
568  out << "\n sol_grad:\n\t" << *p_MNEForwardSolution.sol_grad.data() << std::endl;
569 
570  return out;
571 }
572 
573 //=============================================================================================================
574 
575 inline bool operator== (const MNEForwardSolution &a, const MNEForwardSolution &b)
576 {
577  return (a.info == b.info &&
578  a.source_ori == b.source_ori &&
579  a.surf_ori == b.surf_ori &&
580  a.coord_frame == b.coord_frame &&
581  a.nsource == b.nsource &&
582  a.nchan == b.nchan &&
583  *a.sol == *b.sol &&
584  *a.sol_grad == *b.sol_grad &&
585  a.mri_head_t == b.mri_head_t &&
586  a.src == b.src &&
587  a.source_rr.isApprox(b.source_rr, 0.0001f) &&
588  a.source_nn.isApprox(b.source_nn, 0.0001f));
589 }
590 } // NAMESPACE
591 
592 #endif // MNE_FORWARDSOLUTION_H
FiffInfoBase class declaration.
Old fiff_type declarations - replace them.
QSharedDataPointer< FiffNamedMatrix > SDPtr
FiffCoordTrans class declaration.
Eigen::MatrixXd matRoiG
K-Means Clustering.
Definition: kmeans.h:72
Eigen::MatrixXd matRoiGWhitened
QSharedPointer< MNEForwardSolution > SPtr
QSharedPointer< const MNEForwardSolution > ConstSPtr
FIFF measurement file information.
Definition: fiff_info.h:84
QSharedPointer< FiffDirNode > SPtr
Definition: fiff_dir_node.h:77
KMeans class declaration.
Annotation set.
Definition: annotationset.h:80
Coordinate transformation description.
Eigen::MatrixXd matRoiGOrig
FiffCov class declaration.
MNESourceSpace class declaration.
Fiff constants.
FIFFLIB::fiff_int_t coord_frame
bool calculate(Eigen::MatrixXd X, qint32 kClusters, Eigen::VectorXi &idx, Eigen::MatrixXd &C, Eigen::VectorXd &sumD, Eigen::MatrixXd &D)
Definition: kmeans.cpp:120
Source Space descritpion.
A hemisphere set of surfaces.
Definition: surfaceset.h:71
FIFFLIB::FiffInfoBase info
light measurement info
FIFFLIB::fiff_int_t source_ori
MNEMath class declaration.
mne library export/import macros.
#define MNESHARED_EXPORT
Definition: mne_global.h:56
Eigen::VectorXi tripletSelection(const Eigen::VectorXi &p_vecIdxSelection) const
FIFFLIB::FiffCoordTrans mri_head_t
AnnotationSet class declaration.
QSharedPointer< FiffStream > SPtr
Definition: fiff_stream.h:107
FIFFLIB::FiffNamedMatrix::SDPtr sol
FIFFLIB::FiffNamedMatrix::SDPtr sol_grad
covariance data
Definition: fiff_cov.h:77