MNE-CPP  0.1.9
A Framework for Electrophysiology
mne_hemisphere.cpp
Go to the documentation of this file.
1 //=============================================================================================================
37 //=============================================================================================================
38 // INCLUDES
39 //=============================================================================================================
40 
41 #include "mne_hemisphere.h"
42 
43 //=============================================================================================================
44 // USED NAMESPACES
45 //=============================================================================================================
46 
47 using namespace MNELIB;
48 using namespace Eigen;
49 using namespace FIFFLIB;
50 
51 //=============================================================================================================
52 // DEFINE MEMBER METHODS
53 //=============================================================================================================
54 
56 : type(1)
57 , id(-1)
58 , np(-1)
59 , ntri(-1)
60 , coord_frame(-1)
61 , rr(MatrixX3f::Zero(0,3))
62 , nn(MatrixX3f::Zero(0,3))
63 , tris(MatrixX3i::Zero(0,3))
64 , nuse(-1)
65 , inuse(VectorXi::Zero(0))
66 , vertno(VectorXi::Zero(0))
67 , nuse_tri(-1)
68 , use_tris(MatrixX3i::Zero(0,3))
69 , nearest(VectorXi::Zero(0))
70 , nearest_dist(VectorXd::Zero(0))
71 , patch_inds(VectorXi::Zero(0))
72 , dist_limit(-1)
73 , dist(SparseMatrix<double>())
74 , tri_cent(MatrixX3d::Zero(0,3))
75 , tri_nn(MatrixX3d::Zero(0,3))
76 , tri_area(VectorXd::Zero(0))
77 , use_tri_cent(MatrixX3d::Zero(0,3))
78 , use_tri_nn(MatrixX3d::Zero(0,3))
79 , use_tri_area(VectorXd::Zero(0))
80 //, m_TriCoords()
81 //, m_pGeometryData(NULL)
82 {
83 }
84 
85 //=============================================================================================================
86 
88 : type(p_MNEHemisphere.type)
89 , id(p_MNEHemisphere.id)
90 , np(p_MNEHemisphere.np)
91 , ntri(p_MNEHemisphere.ntri)
92 , coord_frame(p_MNEHemisphere.coord_frame)
93 , rr(p_MNEHemisphere.rr)
94 , nn(p_MNEHemisphere.nn)
95 , tris(p_MNEHemisphere.tris)
96 , nuse(p_MNEHemisphere.nuse)
97 , inuse(p_MNEHemisphere.inuse)
98 , vertno(p_MNEHemisphere.vertno)
99 , nuse_tri(p_MNEHemisphere.nuse_tri)
100 , use_tris(p_MNEHemisphere.use_tris)
101 , nearest(p_MNEHemisphere.nearest)
102 , nearest_dist(p_MNEHemisphere.nearest_dist)
103 , pinfo(p_MNEHemisphere.pinfo)
104 , patch_inds(p_MNEHemisphere.patch_inds)
105 , dist_limit(p_MNEHemisphere.dist_limit)
106 , dist(p_MNEHemisphere.dist)
107 , tri_cent(p_MNEHemisphere.tri_cent)
108 , tri_nn(p_MNEHemisphere.tri_nn)
109 , tri_area(p_MNEHemisphere.tri_area)
110 , use_tri_cent(p_MNEHemisphere.use_tri_cent)
111 , use_tri_nn(p_MNEHemisphere.use_tri_nn)
112 , use_tri_area(p_MNEHemisphere.use_tri_area)
113 , neighbor_tri(p_MNEHemisphere.neighbor_tri)
114 , neighbor_vert(p_MNEHemisphere.neighbor_vert)
115 , cluster_info(p_MNEHemisphere.cluster_info)
116 , m_TriCoords(p_MNEHemisphere.m_TriCoords)
117 {
118  //*m_pGeometryData = *p_MNEHemisphere.m_pGeometryData;
119 }
120 
121 //=============================================================================================================
122 
124 {
125 }
126 
127 //=============================================================================================================
128 
130 {
131  int k,c,p,q;
132  bool found;
133 
134  //Create neighboring triangle vector
135  neighbor_tri = QVector<QVector<int> >(this->tris.rows());
136 
137  //Create neighbor_tri information
138  for (p = 0; p < this->tris.rows(); p++) {
139  for (k = 0; k < 3; k++) {
140  this->neighbor_tri[this->tris(p,k)].append(p);
141  }
142  }
143 
144  //Create the neighboring vertices vector
145  neighbor_vert = QVector<QVector<int> >(this->np);
146 
147  for (k = 0; k < this->np; k++) {
148  for (p = 0; p < this->neighbor_tri[k].size(); p++) {
149  //Fit in the other vertices of the neighboring triangle
150  for (c = 0; c < 3; c++) {
151  int vert = this->tris(this->neighbor_tri[k][p], c);
152 
153  if (vert != k) {
154  found = false;
155 
156  for (q = 0; q < this->neighbor_vert[k].size(); q++) {
157  if (this->neighbor_vert[k][q] == vert) {
158  found = true;
159  break;
160  }
161  }
162 
163  if(!found) {
164  this->neighbor_vert[k].append(vert);
165  }
166  }
167  }
168  }
169  }
170 
171  return true;
172 }
173 
174 //=============================================================================================================
175 
177 {
178  type = 1;
179  id = -1;
180  np = -1;
181  ntri = -1;
182  coord_frame = -1;
183  rr = MatrixX3f::Zero(0,3);
184  nn = MatrixX3f::Zero(0,3);
185  tris = MatrixX3i::Zero(0,3);
186  nuse = -1;
187  inuse = VectorXi::Zero(0);
188  vertno = VectorXi::Zero(0);
189  nuse_tri = -1;
190  use_tris = MatrixX3i::Zero(0,3);
191  nearest = VectorXi::Zero(0);
192  nearest_dist = VectorXd::Zero(0);
193  pinfo.clear();
194  patch_inds = VectorXi::Zero(0);
195  dist_limit = -1;
196  dist = SparseMatrix<double>();
197  tri_cent = MatrixX3d::Zero(0,3);
198  tri_nn = MatrixX3d::Zero(0,3);
199  tri_area = VectorXd::Zero(0);
200  use_tri_cent = MatrixX3d::Zero(0,3);
201  use_tri_nn = MatrixX3d::Zero(0,3);
202  use_tri_area = VectorXd::Zero(0);
203 
204  neighbor_tri.clear();
205  neighbor_vert.clear();
206 
208 
209  m_TriCoords = MatrixXf();
210 }
211 
212 //=============================================================================================================
213 
214 MatrixXf& MNEHemisphere::getTriCoords(float p_fScaling)
215 {
216  if(m_TriCoords.size() == 0)
217  {
218  m_TriCoords = MatrixXf(3,3*tris.rows());
219  for(qint32 i = 0; i < tris.rows(); ++i)
220  {
221  m_TriCoords.col(i*3) = rr.row( tris(i,0) ).transpose().cast<float>();
222  m_TriCoords.col(i*3+1) = rr.row( tris(i,1) ).transpose().cast<float>();
223  m_TriCoords.col(i*3+2) = rr.row( tris(i,2) ).transpose().cast<float>();
224  }
225  }
226 
227  m_TriCoords *= p_fScaling;
228 
229  return m_TriCoords;
230 }
231 
232 //=============================================================================================================
233 
234 bool MNEHemisphere::transform_hemisphere_to(fiff_int_t dest, const FiffCoordTrans &p_Trans)
235 {
236  FiffCoordTrans trans(p_Trans);
237 
238  if (this->coord_frame == dest)
239  {
240 // res = src;
241  return true;
242  }
243 
244  if (trans.to == this->coord_frame && trans.from == dest)
245  trans.invert_transform();
246  else if(trans.from != this->coord_frame || trans.to != dest)
247  {
248  printf("Cannot transform the source space using this coordinate transformation");//Consider throw
249  return false;
250  }
251 
252  MatrixXf t = trans.trans.block(0,0,3,4);
253 // res = src;
254  this->coord_frame = dest;
255  MatrixXf t_rr = MatrixXf::Ones(this->np, 4);
256  t_rr.block(0, 0, this->np, 3) = this->rr;
257  MatrixXf t_nn = MatrixXf::Zero(this->np, 4);
258  t_nn.block(0, 0, this->np, 3) = this->nn;
259 
260  this->rr = (t*t_rr.transpose()).transpose();
261  this->nn = (t*t_nn.transpose()).transpose();
262 
263  return true;
264 }
265 
266 //=============================================================================================================
267 //ToDo
269 {
270  if(this->type == 1 || this->type == 2)
271  p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_TYPE, &this->type);
272  else
273  printf("Unknown source space type (%d)\n", this->type);
274  p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_ID, &this->id);
275 
276 // data = this.get('subject_his_id', None)
277 // if data:
278 // write_string(fid, FIFF.FIFF_SUBJ_HIS_ID, data)
279  p_pStream->write_int(FIFF_MNE_COORD_FRAME, &this->coord_frame);
280 
281  if(this->type == 2) //2 = Vol
282  {
283  qDebug() << "ToDo: Write Volume not implemented yet!!!!!!!!";
284 // p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_VOXEL_DIMS, this->shape)
285 // p_pStream->write_coord_trans(this->src_mri_t);
286 
287  p_pStream->start_block(FIFFB_MNE_PARENT_MRI_FILE);
288 // write_coord_trans(fid, this['vox_mri_t'])
289 
290 // write_coord_trans(fid, this['mri_ras_t'])
291 
292 // write_float_sparse_rcs(fid, FIFF.FIFF_MNE_SOURCE_SPACE_INTERPOLATOR,
293 // this['interpolator'])
294 
295 // if 'mri_file' in this and this['mri_file'] is not None:
296 // write_string(fid, FIFF.FIFF_MNE_SOURCE_SPACE_MRI_FILE,
297 // this['mri_file'])
298 
299 // write_int(fid, FIFF.FIFF_MRI_WIDTH, this['mri_width'])
300 // write_int(fid, FIFF.FIFF_MRI_HEIGHT, this['mri_height'])
301 // write_int(fid, FIFF.FIFF_MRI_DEPTH, this['mri_depth'])
302 
303  p_pStream->end_block(FIFFB_MNE_PARENT_MRI_FILE);
304  }
305 
306  p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_NPOINTS, &this->np);
309 
310  // Which vertices are active
311  p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_SELECTION, this->inuse.data(), this->inuse.size());
312  p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_NUSE, &this->nuse);
313 
314  p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_NTRI, &this->ntri);
315  if (this->ntri > 0)
316  p_pStream->write_int_matrix(FIFF_MNE_SOURCE_SPACE_TRIANGLES, this->tris.array() + 1);
317 
318  if (this->type != 2 && this->use_tris.rows() > 0)
319  {
320  // Use triangulation
322  p_pStream->write_int_matrix(FIFF_MNE_SOURCE_SPACE_USE_TRIANGLES, this->use_tris.array() + 1);
323  }
324 
325  // Patch-related information
326  if (this->nearest.size() > 0)
327  {
328  p_pStream->write_int(FIFF_MNE_SOURCE_SPACE_NEAREST, this->nearest.data(), this->nearest.size());
329  p_pStream->write_float_matrix(FIFF_MNE_SOURCE_SPACE_NEAREST_DIST, this->nearest_dist.cast<float>());
330  }
331 
332  // Distances
333  if (this->dist.rows() > 0)
334  {
335  // Save only upper triangular portion of the matrix
336  typedef Eigen::Triplet<float> T;
337  std::vector<T> tripletList;
338  tripletList.reserve(this->dist.nonZeros());
339  for (int k=0; k < this->dist.outerSize(); ++k)
340  for (SparseMatrix<double>::InnerIterator it(this->dist,k); it; ++it)
341  if(it.col() >= it.row())//only upper triangle -> todo iteration can be optimized
342  tripletList.push_back(T(it.row(), it.col(), (float)it.value()));
343  SparseMatrix<float> dists(this->dist.rows(), this->dist.cols());
344  dists.setFromTriplets(tripletList.begin(), tripletList.end());
345 
347  //ToDo check if write_float_matrix or write float is okay
348  p_pStream->write_float(FIFF_MNE_SOURCE_SPACE_DIST_LIMIT, &this->dist_limit); //p_pStream->write_float_matrix(FIFF_MNE_SOURCE_SPACE_DIST_LIMIT, this->dist_limit);
349  }
350 }
351 
353 
354 //QGeometryData* MNEHemisphere::getGeometryData(float p_fScaling)
355 //{
356 // if(m_pGeometryData == NULL)
357 // {
358 // m_pGeometryData = new QGeometryData();
359 
360 // MatrixXd* triCoords = getTriCoords(p_fScaling);
361 
362 // m_pGeometryData->appendVertexArray(QArray<QVector3D>::fromRawData( reinterpret_cast<const QVector3D*>(triCoords->data()), triCoords->cols() ));
363 // }
364 
365 // return m_pGeometryData;
366 //}
Eigen::MatrixX3f rr
Eigen::MatrixX3d use_tri_cent
Eigen::VectorXi patch_inds
FIFFLIB::fiff_int_t nuse
FIFFLIB::fiff_int_t coord_frame
Eigen::VectorXi inuse
Eigen::VectorXi nearest
QList< Eigen::VectorXi > pinfo
FIFFLIB::fiff_int_t np
#define FIFF_MNE_SOURCE_SPACE_USE_TRIANGLES
Eigen::MatrixX3i tris
fiff_long_t write_float_matrix(fiff_int_t kind, const Eigen::MatrixXf &mat)
#define FIFF_MNE_SOURCE_SPACE_NUSE
Coordinate transformation description.
Eigen::MatrixX3d use_tri_nn
MNEClusterInfo cluster_info
Eigen::SparseMatrix< double > dist
#define FIFF_MNE_SOURCE_SPACE_TYPE
#define FIFF_MNE_SOURCE_SPACE_SELECTION
FIFFLIB::fiff_int_t ntri
fiff_long_t write_int_matrix(fiff_int_t kind, const Eigen::MatrixXi &mat)
#define FIFF_MNE_SOURCE_SPACE_TRIANGLES
Eigen::MatrixX3d tri_cent
fiff_long_t write_float(fiff_int_t kind, const float *data, fiff_int_t nel=1)
#define FIFF_MNE_SOURCE_SPACE_NORMALS
#define FIFF_MNE_SOURCE_SPACE_NEAREST_DIST
Eigen::VectorXi vertno
fiff_long_t start_block(fiff_int_t kind)
#define FIFF_MNE_SOURCE_SPACE_NTRI
#define FIFF_MNE_SOURCE_SPACE_POINTS
fiff_long_t write_int(fiff_int_t kind, const fiff_int_t *data, fiff_int_t nel=1, fiff_int_t next=FIFFV_NEXT_SEQ)
Hemisphere provides geometry information.
Eigen::MatrixXf & getTriCoords(float p_fScaling=1.0f)
FIFF File I/O routines.
Definition: fiff_stream.h:104
void writeToStream(FIFFLIB::FiffStream *p_pStream)
Eigen::VectorXd tri_area
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > trans
Eigen::VectorXd nearest_dist
Eigen::VectorXd use_tri_area
Eigen::MatrixX3d tri_nn
FIFFLIB::fiff_int_t type
FIFFLIB::fiff_int_t id
#define FIFF_MNE_SOURCE_SPACE_DIST
MNEHemisphere class declaration.
QVector< QVector< int > > neighbor_tri
#define FIFF_MNE_SOURCE_SPACE_DIST_LIMIT
#define FIFF_MNE_SOURCE_SPACE_ID
#define FIFF_MNE_SOURCE_SPACE_NEAREST
QVector< QVector< int > > neighbor_vert
Eigen::MatrixX3i use_tris
fiff_long_t write_float_sparse_rcs(fiff_int_t kind, const Eigen::SparseMatrix< float > &mat)
fiff_long_t end_block(fiff_int_t kind, fiff_int_t next=FIFFV_NEXT_SEQ)
#define FIFF_MNE_SOURCE_SPACE_NPOINTS
#define FIFF_MNE_SOURCE_SPACE_NUSE_TRI
bool transform_hemisphere_to(FIFFLIB::fiff_int_t dest, const FIFFLIB::FiffCoordTrans &p_Trans)
Eigen::MatrixX3f nn
#define FIFF_MNE_COORD_FRAME