MNE-CPP 0.1.9
A Framework for Electrophysiology
Loading...
Searching...
No Matches
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
47using namespace MNELIB;
48using namespace Eigen;
49using 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
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
214MatrixXf& 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
234bool 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
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());
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//}
#define FIFF_MNE_SOURCE_SPACE_ID
#define FIFF_MNE_SOURCE_SPACE_DIST_LIMIT
#define FIFF_MNE_COORD_FRAME
#define FIFF_MNE_SOURCE_SPACE_TYPE
#define FIFF_MNE_SOURCE_SPACE_SELECTION
#define FIFF_MNE_SOURCE_SPACE_USE_TRIANGLES
#define FIFF_MNE_SOURCE_SPACE_NUSE_TRI
#define FIFF_MNE_SOURCE_SPACE_NORMALS
#define FIFF_MNE_SOURCE_SPACE_NEAREST_DIST
#define FIFF_MNE_SOURCE_SPACE_DIST
#define FIFF_MNE_SOURCE_SPACE_POINTS
#define FIFF_MNE_SOURCE_SPACE_NTRI
#define FIFF_MNE_SOURCE_SPACE_NPOINTS
#define FIFF_MNE_SOURCE_SPACE_TRIANGLES
#define FIFF_MNE_SOURCE_SPACE_NUSE
#define FIFF_MNE_SOURCE_SPACE_NEAREST
int k
Definition fiff_tag.cpp:324
MNEHemisphere class declaration.
Coordinate transformation description.
Eigen::Matrix< float, 4, 4, Eigen::DontAlign > trans
FIFF File I/O routines.
fiff_long_t start_block(fiff_int_t kind)
fiff_long_t write_float_matrix(fiff_int_t kind, const Eigen::MatrixXf &mat)
fiff_long_t write_int_matrix(fiff_int_t kind, const Eigen::MatrixXi &mat)
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)
fiff_long_t write_float(fiff_int_t kind, const float *data, fiff_int_t nel=1)
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)
Hemisphere provides geometry information.
Eigen::VectorXi vertno
void writeToStream(FIFFLIB::FiffStream *p_pStream)
Eigen::MatrixX3d tri_cent
QVector< QVector< int > > neighbor_tri
FIFFLIB::fiff_int_t ntri
Eigen::VectorXi inuse
FIFFLIB::fiff_int_t type
FIFFLIB::fiff_int_t nuse
Eigen::VectorXd use_tri_area
Eigen::VectorXi nearest
Eigen::MatrixX3d use_tri_cent
Eigen::MatrixX3i tris
Eigen::MatrixXf & getTriCoords(float p_fScaling=1.0f)
Eigen::MatrixX3f nn
Eigen::VectorXd nearest_dist
QVector< QVector< int > > neighbor_vert
Eigen::MatrixX3d tri_nn
Eigen::MatrixX3i use_tris
FIFFLIB::fiff_int_t np
Eigen::MatrixX3f rr
bool transform_hemisphere_to(FIFFLIB::fiff_int_t dest, const FIFFLIB::FiffCoordTrans &p_Trans)
MNEClusterInfo cluster_info
Eigen::MatrixX3d use_tri_nn
FIFFLIB::fiff_int_t coord_frame
Eigen::VectorXd tri_area
Eigen::SparseMatrix< double > dist
QList< Eigen::VectorXi > pinfo
Eigen::VectorXi patch_inds