v2.0.0
Loading...
Searching...
No Matches
mne_source_spaces.cpp
Go to the documentation of this file.
1//=============================================================================================================
18
19//=============================================================================================================
20// INCLUDES
21//=============================================================================================================
22
23#include "mne_source_spaces.h"
24#include "mne_nearest.h"
25
26#include <math/linalg.h>
27#include <fs/fs_label.h>
28
29//=============================================================================================================
30// QT INCLUDES
31//=============================================================================================================
32
33#include <QFile>
34
35#include <stdexcept>
36//=============================================================================================================
37// USED NAMESPACES
38//=============================================================================================================
39
40using namespace UTILSLIB;
41using namespace FSLIB;
42using namespace MNELIB;
43using namespace Eigen;
44using namespace FIFFLIB;
45
46//=============================================================================================================
47// DEFINE MEMBER METHODS
48//=============================================================================================================
49
53
54//=============================================================================================================
55
57{
58 m_sourceSpaces.reserve(p_MNESourceSpaces.m_sourceSpaces.size());
59 for (const auto& sp : p_MNESourceSpaces.m_sourceSpaces)
60 m_sourceSpaces.push_back(sp->clone());
61}
62
63//=============================================================================================================
64
68
69//=============================================================================================================
70
72{
73 m_sourceSpaces.clear();
74}
75
76//=============================================================================================================
77
79{
80 m_sourceSpaces.push_back(space.clone());
81}
82
83//=============================================================================================================
84
85QList<VectorXi> MNESourceSpaces::get_vertno() const
86{
87 QList<VectorXi> p_vertices;
88 for (qint32 i = 0; i < static_cast<qint32>(m_sourceSpaces.size()); ++i)
89 p_vertices.push_back(m_sourceSpaces[i]->vertno);
90 return p_vertices;
91}
92
93//=============================================================================================================
94
95QList<VectorXi> MNESourceSpaces::label_src_vertno_sel(const FsLabel& p_label, VectorXi& src_sel) const
96{
97 // if(src[0].['type'] != 'surf')
98 // return Exception('FsLabel are only supported with surface source spaces')
99
100 QList<VectorXi> vertno;
101 vertno << this->m_sourceSpaces[0]->vertno << this->m_sourceSpaces[1]->vertno;
102
103 if (p_label.hemi == 0) //lh
104 {
105 VectorXi vertno_sel = Linalg::intersect(vertno[0], p_label.vertices, src_sel);
106 vertno[0] = vertno_sel;
107 vertno[1] = VectorXi();
108 } else if (p_label.hemi == 1) //rh
109 {
110 VectorXi vertno_sel = Linalg::intersect(vertno[1], p_label.vertices, src_sel);
111 src_sel.array() += static_cast<int>(vertno[0].size());
112 vertno[0] = VectorXi();
113 vertno[1] = vertno_sel;
114 }
115
116 // if (p_label.hemi == 0) //lh
117 // {
118 // VectorXi vertno_sel = Linalg::intersect(vertno[0], p_label.vertices[0], src_sel);
119 // vertno[0] = vertno_sel;
120 // vertno[1] = VectorXi();
121 // }
122 // else if (p_label.hemi == 1) //rh
123 // {
124 // VectorXi vertno_sel = Linalg::intersect(vertno[1], p_label.vertices[1], src_sel);
125 // src_sel.array() += p_label.vertices[0].size();
126 // vertno[0] = VectorXi();
127 // vertno[1] = vertno_sel;
128 // }
129 // else if (p_label.hemi == 2) //both
130 // {
131 // VectorXi src_sel_lh, src_sel_rh;
132 // VectorXi vertno_sel_lh = Linalg::intersect(vertno[0], p_label.vertices[0], src_sel_lh);
133 // VectorXi vertno_sel_rh = Linalg::intersect(vertno[1], p_label.vertices[1], src_sel_rh);
134 // src_sel.resize(src_sel_lh.size() + src_sel_rh.size());
135 // src_sel.block(0,0,src_sel_lh.size(),1) = src_sel_lh;
136 // src_sel.block(src_sel_lh.size(),0,src_sel_rh.size(),1) = src_sel_rh;
137 // vertno[0] = vertno_sel_lh;
138 // vertno[0] = vertno_sel_rh;
139 // }
140 else {
141 qWarning("Unknown hemisphere type\n");
142 vertno[0] = VectorXi::Zero(0);
143 vertno[1] = VectorXi::Zero(0);
144 }
145
146 return vertno;
147}
148
149//=============================================================================================================
150
151MNESourceSpaces MNESourceSpaces::pick_regions(const QList<FsLabel>& p_qListLabels) const
152{
153 Q_UNUSED(p_qListLabels);
154
155 MNESourceSpaces selectedSrc(*this);
156
157 for (qint32 h = 0; h < 2; ++h) {
158 auto& srcSpace = *selectedSrc.m_sourceSpaces[h];
159 const auto& origSpace = *this->m_sourceSpaces[h];
160 auto* selHemi = dynamic_cast<MNEHemisphere*>(&srcSpace);
161 auto* origHemi = dynamic_cast<const MNEHemisphere*>(&origSpace);
162
163 VectorXi selVertices;
164
165 //get vertices indeces for new selection
166 qint32 iSize = 0;
167 for (qint32 i = 0; i < p_qListLabels.size(); ++i) {
168 if (p_qListLabels[i].hemi == h) {
169 VectorXi currentSelection;
170
171 Linalg::intersect(origSpace.vertno, p_qListLabels[i].vertices, currentSelection);
172
173 selVertices.conservativeResize(iSize + currentSelection.size());
174 selVertices.block(iSize, 0, currentSelection.size(), 1) = currentSelection;
175 iSize = selVertices.size();
176 }
177 }
178
179 Linalg::sort(selVertices, false);
180
181 VectorXi newVertno(selVertices.size());
182
183 srcSpace.inuse = VectorXi::Zero(srcSpace.np);
184
185 for (qint32 i = 0; i < selVertices.size(); ++i) {
186 newVertno[i] = origSpace.vertno[selVertices[i]];
187 srcSpace.inuse[newVertno[i]] = 1;
188 }
189
190 srcSpace.nuse = selVertices.size();
191 srcSpace.vertno = newVertno;
192
193 //
194 // Tris
195 //
196 VectorXi idx_select = VectorXi::Zero(origSpace.use_itris.rows());
197 for (qint32 i = 0; i < 3; ++i) {
198 VectorXi tri_dim = origSpace.use_itris.col(i);
199 VectorXi idx_dim;
200 Linalg::intersect(tri_dim, newVertno, idx_dim);
201
202 for (qint32 j = 0; j < idx_dim.size(); ++j)
203 idx_select[idx_dim[j]] = 1;
204 }
205
206 qint32 countSel = 0;
207 for (qint32 i = 0; i < idx_select.size(); ++i)
208 if (idx_select[i] == 1)
209 ++countSel;
210
211 srcSpace.nuse_tri = countSel;
212
213 MatrixX3i use_tris_new(countSel, 3);
214 MatrixX3d use_tri_cent_new(countSel, 3);
215 MatrixX3d use_tri_nn_new(countSel, 3);
216 VectorXd use_tri_area_new(countSel);
217
218 countSel = 0;
219 for (qint32 i = 0; i < idx_select.size(); ++i) {
220 if (idx_select[i] == 1) {
221 use_tris_new.row(countSel) = origSpace.use_itris.row(i);
222 if (origHemi && selHemi) {
223 use_tri_cent_new.row(countSel) = origHemi->use_tri_cent.row(i);
224 use_tri_nn_new.row(countSel) = origHemi->use_tri_nn.row(i);
225 use_tri_area_new[countSel] = origHemi->use_tri_area[i];
226 }
227 ++countSel;
228 }
229 }
230
231 srcSpace.use_itris = use_tris_new;
232 if (selHemi) {
233 selHemi->use_tri_cent = use_tri_cent_new;
234 selHemi->use_tri_nn = use_tri_nn_new;
235 selHemi->use_tri_area = use_tri_area_new;
236 // patch_inds is indexed by used source, so it must follow the selection
237 if (origHemi && origHemi->patch_inds.size() == origSpace.nuse) {
238 selHemi->patch_inds.resize(selVertices.size());
239 for (qint32 i = 0; i < selVertices.size(); ++i)
240 selHemi->patch_inds[i] = origHemi->patch_inds[selVertices[i]];
241 }
242 }
243 }
244
245 return selectedSrc;
246}
247
248//=============================================================================================================
249
251 bool add_geom,
252 MNESourceSpaces& p_SourceSpace)
253{
254 // if (p_pSourceSpace != NULL)
255 // delete p_pSourceSpace;
256 p_SourceSpace = MNESourceSpaces();
257
258 //
259 // Open the file, create directory
260 //
261 bool open_here = false;
262 QFile t_file; //ToDo TCPSocket;
263
264 if (!p_pStream->device()->isOpen()) {
265 QString t_sFileName = p_pStream->streamName();
266
267 t_file.setFileName(t_sFileName);
268 p_pStream = FiffStream::SPtr(new FiffStream(&t_file));
269 if (!p_pStream->open())
270 return false;
271 open_here = true;
272 // if(t_pDir)
273 // delete t_pDir;
274 }
275 //
276 // Find all source spaces
277 //
278 QList<FiffDirNode::SPtr> spaces = p_pStream->dirtree()->dir_tree_find(FIFFB_MNE_SOURCE_SPACE);
279 if (spaces.size() == 0) {
280 if (open_here)
281 p_pStream->close();
282 qWarning() << "No source spaces found";
283 return false;
284 }
285
286 for (int k = 0; k < spaces.size(); ++k) {
287 auto p_Hemisphere = std::make_shared<MNEHemisphere>();
288 qInfo("\tReading a source space...");
289 MNESourceSpaces::read_source_space(p_pStream, spaces[k], *p_Hemisphere);
290 qInfo("\t[done]\n");
291 if (add_geom)
292 p_Hemisphere->complete_source_space_info();
293
294 p_SourceSpace.m_sourceSpaces.push_back(p_Hemisphere);
295
296 // src(k) = this;
297 }
298
299 qInfo("\t%lld source spaces read\n", static_cast<long long>(spaces.size()));
300
301 if (open_here)
302 p_pStream->close();
303
304 return true;
305}
306
307//=============================================================================================================
308
310{
311 return p_SourceSpace.find_source_space_hemi();
312}
313
314//=============================================================================================================
315
317{
318 for (size_t k = 0; k < this->m_sourceSpaces.size(); ++k) {
319 auto* hemi = dynamic_cast<MNEHemisphere*>(m_sourceSpaces[k].get());
320 if (hemi) {
321 if (!hemi->transform_hemisphere_to(dest, trans)) {
322 qWarning("Could not transform source space.");
323 return false;
324 }
325 }
326 }
327 return true;
328}
329
330//=============================================================================================================
331
332bool MNESourceSpaces::read_source_space(FiffStream::SPtr& p_pStream, const FiffDirNode::SPtr& p_Tree, MNEHemisphere& p_Hemisphere)
333{
334 p_Hemisphere.clear();
335
336 FiffTag::UPtr t_pTag;
337
338 //=====================================================================
339 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_ID, t_pTag))
340 p_Hemisphere.id = FIFFV_MNE_SURF_UNKNOWN;
341 else
342 p_Hemisphere.id = *t_pTag->toInt();
343
344 // qDebug() << "Read SourceSpace ID; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
345
346 //=====================================================================
347 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NPOINTS, t_pTag)) {
348 p_pStream->close();
349 throw std::runtime_error("error: Number of vertices not found.");
350 }
351 // qDebug() << "Number of vertice; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
352 p_Hemisphere.np = *t_pTag->toInt();
353
354 //=====================================================================
355 if (!p_Tree->find_tag(p_pStream, FIFF_BEM_SURF_NTRI, t_pTag)) {
356 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NTRI, t_pTag))
357 p_Hemisphere.ntri = 0;
358 else
359 p_Hemisphere.ntri = *t_pTag->toInt();
360 } else {
361 p_Hemisphere.ntri = *t_pTag->toInt();
362 }
363 // qDebug() << "Number of Tris; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
364
365 //=====================================================================
366 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_COORD_FRAME, t_pTag)) {
367 p_pStream->close();
368 throw std::runtime_error("Coordinate frame information not found.");
369 }
370 p_Hemisphere.coord_frame = *t_pTag->toInt();
371 // qDebug() << "Coord Frame; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
372
373 //=====================================================================
374 //
375 // Vertices, normals, and triangles
376 //
377 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_POINTS, t_pTag)) {
378 p_pStream->close();
379 throw std::runtime_error("Vertex data not found.");
380 }
381
382 p_Hemisphere.rr = t_pTag->toFloatMatrix().transpose();
383 qint32 rows_rr = p_Hemisphere.rr.rows();
384 // qDebug() << "last element rr: " << p_Hemisphere.rr(rows_rr-1, 0) << p_Hemisphere.rr(rows_rr-1, 1) << p_Hemisphere.rr(rows_rr-1, 2);
385
386 if (rows_rr != p_Hemisphere.np) {
387 p_pStream->close();
388 throw std::runtime_error("Vertex information is incorrect.");
389 }
390 // qDebug() << "Source Space Points; type:" << t_pTag->getType();
391
392 //=====================================================================
393 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NORMALS, t_pTag)) {
394 p_pStream->close();
395 throw std::runtime_error("Vertex normals not found.");
396 }
397
398 p_Hemisphere.nn = t_pTag->toFloatMatrix().transpose();
399 qint32 rows_nn = p_Hemisphere.nn.rows();
400
401 if (rows_nn != p_Hemisphere.np) {
402 p_pStream->close();
403 throw std::runtime_error("Vertex normal information is incorrect.");
404 }
405 // qDebug() << "Source Space Normals; type:" << t_pTag->getType();
406
407 //=====================================================================
408 if (p_Hemisphere.ntri > 0) {
409 if (!p_Tree->find_tag(p_pStream, FIFF_BEM_SURF_TRIANGLES, t_pTag)) {
410 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_TRIANGLES, t_pTag)) {
411 p_pStream->close();
412 throw std::runtime_error("Triangulation not found.");
413 } else {
414 p_Hemisphere.itris = t_pTag->toIntMatrix().transpose();
415 p_Hemisphere.itris.array() -= 1; //0 based indizes
416 }
417 } else {
418 p_Hemisphere.itris = t_pTag->toIntMatrix().transpose();
419 p_Hemisphere.itris.array() -= 1; //0 based indizes
420 }
421 if (p_Hemisphere.itris.rows() != p_Hemisphere.ntri) {
422 p_pStream->close();
423 throw std::runtime_error("Triangulation information is incorrect.");
424 }
425 } else {
426 p_Hemisphere.itris.resize(0, 3);
427 }
428 // qDebug() << "Triangles; type:" << t_pTag->getType() << "rows:" << p_Hemisphere.itris.rows() << "cols:" << p_Hemisphere.itris.cols();
429
430 //
431 // Which vertices are active
432 //
433 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NUSE, t_pTag)) {
434 p_Hemisphere.nuse = 0;
435 p_Hemisphere.inuse = VectorXi::Zero(p_Hemisphere.nuse);
436 VectorXi p_defaultVector;
437 p_Hemisphere.vertno = p_defaultVector;
438 } else {
439 p_Hemisphere.nuse = *t_pTag->toInt();
440 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_SELECTION, t_pTag)) {
441 p_pStream->close();
442 throw std::runtime_error("Source selection information missing.");
443 }
444 p_Hemisphere.inuse = VectorXi(Map<VectorXi>(t_pTag->toInt(), t_pTag->size() / 4, 1)); //use copy constructor, for the sake of easy memory management
445
446 p_Hemisphere.vertno = VectorXi::Zero(p_Hemisphere.nuse);
447 if (p_Hemisphere.inuse.rows() != p_Hemisphere.np) {
448 p_pStream->close();
449 throw std::runtime_error("Incorrect number of entries in source space selection.");
450 }
451 int pp = 0;
452 for (int p = 0; p < p_Hemisphere.np; ++p) {
453 if (p_Hemisphere.inuse(p) == 1) {
454 p_Hemisphere.vertno(pp) = p;
455 ++pp;
456 }
457 }
458 }
459 // qDebug() << "Vertices; type:" << t_pTag->getType() << "nuse:" << p_Hemisphere.nuse;
460
461 //
462 // Use triangulation
463 //
464 FiffTag::UPtr t_pTag1;
465 FiffTag::UPtr t_pTag2;
466 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NUSE_TRI, t_pTag1) || !p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_USE_TRIANGLES, t_pTag2)) {
467 MatrixX3i p_defaultMatrix;
468 p_Hemisphere.nuse_tri = 0;
469 p_Hemisphere.use_itris = p_defaultMatrix;
470 } else {
471 p_Hemisphere.nuse_tri = *t_pTag1->toInt();
472 p_Hemisphere.use_itris = t_pTag2->toIntMatrix().transpose();
473 p_Hemisphere.use_itris.array() -= 1; //0 based indizes
474 }
475 // qDebug() << "triangulation; type:" << t_pTag2->getType() << "use_itris:" << p_Hemisphere.use_itris.rows()<< "x" << p_Hemisphere.use_itris.cols();
476
477 //
478 // Patch-related information
479 //
480 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NEAREST, t_pTag1) || !p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NEAREST_DIST, t_pTag2)) {
481 p_Hemisphere.nearest.clear();
482 } else {
483 //res.nearest = tag1.data + 1;
484 VectorXi nearestIdx = VectorXi(Map<VectorXi>(t_pTag1->toInt(), t_pTag1->size() / 4, 1));
485 VectorXd nearestDist = VectorXd((Map<const VectorXf>(t_pTag2->toFloat(), t_pTag2->size() / 4, 1)).cast<double>());
486 p_Hemisphere.setNearestData(nearestIdx, nearestDist);
487 }
488
489 // patch_info(p_Hemisphere.nearest, p_Hemisphere.pinfo);
490 if (p_Hemisphere.compute_patch_info())
491 qInfo("\tPatch information added...");
492 //
493 // Distances
494 //
495 if (!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_DIST, t_pTag1) || !p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_DIST_LIMIT, t_pTag2)) {
496 p_Hemisphere.dist = FiffSparseMatrix();
497 p_Hemisphere.dist_limit = 0;
498 } else {
499 auto dist_lower = FiffSparseMatrix::fiff_get_float_sparse_matrix(t_pTag1);
500 if (dist_lower) {
501 auto dist_full = dist_lower->mne_add_upper_triangle_rcs();
502 if (dist_full) {
503 p_Hemisphere.dist = std::move(*dist_full);
504 }
505 }
506 p_Hemisphere.dist_limit = *t_pTag2->toFloat(); //ToDo Check if this is realy always a float and not a matrix
507 }
508
509 return true;
510}
511
512//=============================================================================================================
513
515{
516 return p_Hemisphere.compute_patch_info();
517}
518
519//=============================================================================================================
520
521bool MNESourceSpaces::complete_source_space_info(MNEHemisphere& p_Hemisphere)
522{
523 return p_Hemisphere.complete_source_space_info();
524}
525
526//=============================================================================================================
527
529{
530 for (size_t h = 0; h < m_sourceSpaces.size(); ++h) {
531 qInfo("\tWrite a source space... ");
533 auto* hemi = dynamic_cast<MNEHemisphere*>(m_sourceSpaces[h].get());
534 if (hemi)
535 hemi->writeToStream(p_pStream);
537 qInfo("[done]\n");
538 }
539 qInfo("\t%zu source spaces written\n", m_sourceSpaces.size());
540}
541
542//=============================================================================================================
543
545{
546 if (static_cast<qint32>(m_sourceSpaces.size()) > idx)
547 return *m_sourceSpaces[idx];
548 else {
549 qWarning("Warning: Index out of bound! Returning last element.");
550 return *m_sourceSpaces.back();
551 }
552}
553
554//=============================================================================================================
555
557{
558 if (static_cast<qint32>(m_sourceSpaces.size()) > idx)
559 return *m_sourceSpaces[idx];
560 else {
561 qWarning("Warning: Index out of bound! Returning last element.");
562 return *m_sourceSpaces.back();
563 }
564}
565
566//=============================================================================================================
567
569{
570 if (idt.compare("lh") == 0)
571 return *m_sourceSpaces[0];
572 else if (idt.compare("rh") == 0)
573 return *m_sourceSpaces[1];
574 else {
575 qWarning("Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
576 return *m_sourceSpaces[0];
577 }
578}
579
580//=============================================================================================================
581
583{
584 if (idt.compare("lh") == 0)
585 return *m_sourceSpaces[0];
586 else if (idt.compare("rh") == 0)
587 return *m_sourceSpaces[1];
588 else {
589 qWarning("Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
590 return *m_sourceSpaces[0];
591 }
592}
593
594//=============================================================================================================
595
597{
598 if (idx >= 0 && idx < static_cast<qint32>(m_sourceSpaces.size()))
599 return dynamic_cast<MNEHemisphere*>(m_sourceSpaces[idx].get());
600 return nullptr;
601}
602
603//=============================================================================================================
604
606{
607 if (idx >= 0 && idx < static_cast<qint32>(m_sourceSpaces.size()))
608 return dynamic_cast<const MNEHemisphere*>(m_sourceSpaces[idx].get());
609 return nullptr;
610}
611
612//=============================================================================================================
613
614std::shared_ptr<MNESourceSpace>& MNESourceSpaces::at(qint32 idx)
615{
616 return m_sourceSpaces.at(idx);
617}
618
619//=============================================================================================================
620
621const std::shared_ptr<MNESourceSpace>& MNESourceSpaces::at(qint32 idx) const
622{
623 return m_sourceSpaces.at(idx);
624}
#define FIFF_MNE_SOURCE_SPACE_ID
#define FIFF_MNE_SOURCE_SPACE_DIST_LIMIT
#define FIFF_MNE_COORD_FRAME
#define FIFFV_MNE_SURF_UNKNOWN
#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 FIFFB_MNE_SOURCE_SPACE
#define FIFF_MNE_SOURCE_SPACE_NPOINTS
#define FIFF_MNE_SOURCE_SPACE_TRIANGLES
#define FIFF_MNE_SOURCE_SPACE_NUSE
#define FIFF_MNE_SOURCE_SPACE_NEAREST
#define FIFF_BEM_SURF_TRIANGLES
Definition fiff_file.h:729
#define FIFF_BEM_SURF_NTRI
Definition fiff_file.h:727
Static linear-algebra helpers: SVD-based conditioning, block-diagonal assembly, sorted index pairs.
Reader and in-memory representation of a FreeSurfer/MNE surface label (.label).
Container pairing the left and right cortical source spaces of a subject.
Per-source-space-vertex nearest-cortex-vertex mapping.
Core MNE data structures (source spaces, source estimates, hemispheres).
FreeSurfer surface, annotation and parcellation I/O for mne-cpp.
FIFF file I/O, in-memory data structures and high-level readers/writers.
qint32 fiff_int_t
Definition fiff_types.h:86
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
QSharedPointer< FiffDirNode > SPtr
static FiffSparseMatrix::UPtr fiff_get_float_sparse_matrix(const FIFFLIB::FiffTag::UPtr &tag)
FIFF tag-stream reader/writer: wraps a QIODevice and exposes typed read_* / write_* methods for every...
fiff_long_t start_block(fiff_int_t kind)
QSharedPointer< FiffStream > SPtr
fiff_long_t end_block(fiff_int_t kind, fiff_int_t next=FIFFV_NEXT_SEQ)
std::unique_ptr< FiffTag > UPtr
Definition fiff_tag.h:165
A FreeSurfer/MNE surface label: per-vertex indices, Tk-RAS positions and scalar values for one hemisp...
Definition fs_label.h:81
Eigen::VectorXi vertices
Definition fs_label.h:166
static Eigen::VectorXi sort(Eigen::Matrix< T, Eigen::Dynamic, 1 > &v, bool desc=true)
Definition linalg.h:298
static Eigen::VectorXi intersect(const Eigen::VectorXi &v1, const Eigen::VectorXi &v2, Eigen::VectorXi &idx_sel)
Definition linalg.cpp:160
Hemisphere provides geometry information.
void writeToStream(FIFFLIB::FiffStream *p_pStream)
This defines a source space.
virtual MNESourceSpace::SPtr clone() const
qint32 find_source_space_hemi() const
void writeToStream(FIFFLIB::FiffStream *p_pStream)
MNESourceSpaces pick_regions(const QList< FSLIB::FsLabel > &p_qListLabels) const
bool transform_source_space_to(FIFFLIB::fiff_int_t dest, FIFFLIB::FiffCoordTrans &trans)
MNEHemisphere * hemisphereAt(qint32 idx)
void append(const MNESourceSpace &space)
static bool patch_info(MNEHemisphere &p_Hemisphere)
static qint32 find_source_space_hemi(MNESourceSpace &p_SourceSpace)
QList< Eigen::VectorXi > label_src_vertno_sel(const FSLIB::FsLabel &p_label, Eigen::VectorXi &src_sel) const
MNESourceSpace & operator[](qint32 idx)
static bool readFromStream(FIFFLIB::FiffStream::SPtr &p_pStream, bool add_geom, MNESourceSpaces &p_SourceSpace)
std::shared_ptr< MNESourceSpace > & at(qint32 idx)
QList< Eigen::VectorXi > get_vertno() const
void setNearestData(const Eigen::VectorXi &nearestIdx, const Eigen::VectorXd &nearestDist)
FIFFLIB::FiffSparseMatrix dist
std::vector< MNENearest > nearest