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 }
109 else if (p_label.hemi == 1) //rh
110 {
111 VectorXi vertno_sel = Linalg::intersect(vertno[1], p_label.vertices, src_sel);
112 src_sel.array() += p_label.vertices.size();
113 vertno[0] = VectorXi();
114 vertno[1] = vertno_sel;
115 }
116
117// if (p_label.hemi == 0) //lh
118// {
119// VectorXi vertno_sel = Linalg::intersect(vertno[0], p_label.vertices[0], src_sel);
120// vertno[0] = vertno_sel;
121// vertno[1] = VectorXi();
122// }
123// else if (p_label.hemi == 1) //rh
124// {
125// VectorXi vertno_sel = Linalg::intersect(vertno[1], p_label.vertices[1], src_sel);
126// src_sel.array() += p_label.vertices[0].size();
127// vertno[0] = VectorXi();
128// vertno[1] = vertno_sel;
129// }
130// else if (p_label.hemi == 2) //both
131// {
132// VectorXi src_sel_lh, src_sel_rh;
133// VectorXi vertno_sel_lh = Linalg::intersect(vertno[0], p_label.vertices[0], src_sel_lh);
134// VectorXi vertno_sel_rh = Linalg::intersect(vertno[1], p_label.vertices[1], src_sel_rh);
135// src_sel.resize(src_sel_lh.size() + src_sel_rh.size());
136// src_sel.block(0,0,src_sel_lh.size(),1) = src_sel_lh;
137// src_sel.block(src_sel_lh.size(),0,src_sel_rh.size(),1) = src_sel_rh;
138// vertno[0] = vertno_sel_lh;
139// vertno[0] = vertno_sel_rh;
140// }
141 else
142 {
143 qWarning("Unknown hemisphere type\n");
144 vertno[0] = VectorXi::Zero(0);
145 vertno[1] = VectorXi::Zero(0);
146 }
147
148 return vertno;
149}
150
151//=============================================================================================================
152
153MNESourceSpaces MNESourceSpaces::pick_regions(const QList<FsLabel> &p_qListLabels) const
154{
155 Q_UNUSED(p_qListLabels);
156
157 MNESourceSpaces selectedSrc(*this);
158
159 for(qint32 h = 0; h < 2; ++h)
160 {
161 auto& srcSpace = *selectedSrc.m_sourceSpaces[h];
162 const auto& origSpace = *this->m_sourceSpaces[h];
163 auto* selHemi = dynamic_cast<MNEHemisphere*>(&srcSpace);
164 auto* origHemi = dynamic_cast<const MNEHemisphere*>(&origSpace);
165
166 VectorXi selVertices;
167
168 //get vertices indeces for new selection
169 qint32 iSize = 0;
170 for(qint32 i = 0; i < p_qListLabels.size(); ++i)
171 {
172 if(p_qListLabels[i].hemi == h)
173 {
174 VectorXi currentSelection;
175
176 Linalg::intersect(origSpace.vertno, p_qListLabels[i].vertices, currentSelection);
177
178 selVertices.conservativeResize(iSize+currentSelection.size());
179 selVertices.block(iSize,0,currentSelection.size(),1) = currentSelection;
180 iSize = selVertices.size();
181 }
182 }
183
184 Linalg::sort(selVertices, false);
185
186 VectorXi newVertno(selVertices.size());
187
188 srcSpace.inuse = VectorXi::Zero(srcSpace.np);
189
190 for(qint32 i = 0; i < selVertices.size(); ++i)
191 {
192 srcSpace.inuse[selVertices[i]] = 1;
193 newVertno[i] = origSpace.vertno[selVertices[i]];
194 }
195
196 srcSpace.nuse = selVertices.size();
197 srcSpace.vertno = newVertno;
198
199 //
200 // Tris
201 //
202 VectorXi idx_select = VectorXi::Zero(origSpace.use_itris.rows());
203 for(qint32 i = 0; i < 3; ++i)
204 {
205 VectorXi tri_dim = origSpace.use_itris.col(i);
206 VectorXi idx_dim;
207 Linalg::intersect(tri_dim, newVertno, idx_dim);
208
209 for(qint32 j = 0; j < idx_dim.size(); ++j)
210 idx_select[idx_dim[j]] = 1;
211 }
212
213 qint32 countSel = 0;
214 for(qint32 i = 0; i < idx_select.size(); ++i)
215 if(idx_select[i] == 1)
216 ++countSel;
217
218 srcSpace.nuse_tri = countSel;
219
220 MatrixX3i use_tris_new(countSel,3);
221 MatrixX3d use_tri_cent_new(countSel,3);
222 MatrixX3d use_tri_nn_new(countSel,3);
223 VectorXd use_tri_area_new(countSel);
224
225 countSel = 0;
226 for(qint32 i = 0; i < idx_select.size(); ++i)
227 {
228 if(idx_select[i] == 1)
229 {
230 use_tris_new.row(countSel) = origSpace.use_itris.row(i);
231 if (origHemi && selHemi) {
232 use_tri_cent_new.row(countSel) = origHemi->use_tri_cent.row(i);
233 use_tri_nn_new.row(countSel) = origHemi->use_tri_nn.row(i);
234 use_tri_area_new[countSel] = origHemi->use_tri_area[i];
235 }
236 ++countSel;
237 }
238 }
239
240 srcSpace.use_itris = use_tris_new;
241 if (selHemi) {
242 selHemi->use_tri_cent = use_tri_cent_new;
243 selHemi->use_tri_nn = use_tri_nn_new;
244 selHemi->use_tri_area = use_tri_area_new;
245 }
246 }
247
248 return selectedSrc;
249}
250
251//=============================================================================================================
252
254 bool add_geom,
255 MNESourceSpaces& p_SourceSpace)
256{
257// if (p_pSourceSpace != NULL)
258// delete p_pSourceSpace;
259 p_SourceSpace = MNESourceSpaces();
260
261 //
262 // Open the file, create directory
263 //
264 bool open_here = false;
265 QFile t_file;//ToDo TCPSocket;
266
267 if (!p_pStream->device()->isOpen())
268 {
269 QString t_sFileName = p_pStream->streamName();
270
271 t_file.setFileName(t_sFileName);
272 p_pStream = FiffStream::SPtr(new FiffStream(&t_file));
273 if(!p_pStream->open())
274 return false;
275 open_here = true;
276// if(t_pDir)
277// delete t_pDir;
278 }
279 //
280 // Find all source spaces
281 //
282 QList<FiffDirNode::SPtr> spaces = p_pStream->dirtree()->dir_tree_find(FIFFB_MNE_SOURCE_SPACE);
283 if (spaces.size() == 0)
284 {
285 if(open_here)
286 p_pStream->close();
287 qWarning() << "No source spaces found";
288 return false;
289 }
290
291 for(int k = 0; k < spaces.size(); ++k)
292 {
293 auto p_Hemisphere = std::make_shared<MNEHemisphere>();
294 qInfo("\tReading a source space...");
295 MNESourceSpaces::read_source_space(p_pStream, spaces[k], *p_Hemisphere);
296 qInfo("\t[done]\n" );
297 if (add_geom)
298 p_Hemisphere->complete_source_space_info();
299
300 p_SourceSpace.m_sourceSpaces.push_back(p_Hemisphere);
301
302// src(k) = this;
303 }
304
305 qInfo("\t%lld source spaces read\n", spaces.size());
306
307 if(open_here)
308 p_pStream->close();
309
310 return true;
311}
312
313//=============================================================================================================
314
316{
317 return p_SourceSpace.find_source_space_hemi();
318}
319
320//=============================================================================================================
321
323{
324 for(size_t k = 0; k < this->m_sourceSpaces.size(); ++k)
325 {
326 auto* hemi = dynamic_cast<MNEHemisphere*>(m_sourceSpaces[k].get());
327 if(hemi) {
328 if(!hemi->transform_hemisphere_to(dest,trans))
329 {
330 qWarning("Could not transform source space.");
331 return false;
332 }
333 }
334 }
335 return true;
336}
337
338//=============================================================================================================
339
340bool MNESourceSpaces::read_source_space(FiffStream::SPtr& p_pStream, const FiffDirNode::SPtr& p_Tree, MNEHemisphere& p_Hemisphere)
341{
342 p_Hemisphere.clear();
343
344 FiffTag::UPtr t_pTag;
345
346 //=====================================================================
347 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_ID, t_pTag))
348 p_Hemisphere.id = FIFFV_MNE_SURF_UNKNOWN;
349 else
350 p_Hemisphere.id = *t_pTag->toInt();
351
352// qDebug() << "Read SourceSpace ID; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
353
354 //=====================================================================
355 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NPOINTS, t_pTag))
356 {
357 p_pStream->close();
358 throw std::runtime_error("error: Number of vertices not found.");
359 }
360// qDebug() << "Number of vertice; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
361 p_Hemisphere.np = *t_pTag->toInt();
362
363 //=====================================================================
364 if(!p_Tree->find_tag(p_pStream, FIFF_BEM_SURF_NTRI, t_pTag))
365 {
366 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NTRI, t_pTag))
367 p_Hemisphere.ntri = 0;
368 else
369 p_Hemisphere.ntri = *t_pTag->toInt();
370 }
371 else
372 {
373 p_Hemisphere.ntri = *t_pTag->toInt();
374 }
375// qDebug() << "Number of Tris; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
376
377 //=====================================================================
378 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_COORD_FRAME, t_pTag))
379 {
380 p_pStream->close();
381 throw std::runtime_error("Coordinate frame information not found.");
382 }
383 p_Hemisphere.coord_frame = *t_pTag->toInt();
384// qDebug() << "Coord Frame; type:" << t_pTag->getType() << "value:" << *t_pTag->toInt();
385
386 //=====================================================================
387 //
388 // Vertices, normals, and triangles
389 //
390 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_POINTS, t_pTag))
391 {
392 p_pStream->close();
393 throw std::runtime_error("Vertex data not found.");
394 }
395
396 p_Hemisphere.rr = t_pTag->toFloatMatrix().transpose();
397 qint32 rows_rr = p_Hemisphere.rr.rows();
398// 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);
399
400 if (rows_rr != p_Hemisphere.np)
401 {
402 p_pStream->close();
403 throw std::runtime_error("Vertex information is incorrect.");
404 }
405// qDebug() << "Source Space Points; type:" << t_pTag->getType();
406
407 //=====================================================================
408 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NORMALS, t_pTag))
409 {
410 p_pStream->close();
411 throw std::runtime_error("Vertex normals not found.");
412 }
413
414 p_Hemisphere.nn = t_pTag->toFloatMatrix().transpose();
415 qint32 rows_nn = p_Hemisphere.nn.rows();
416
417 if (rows_nn != p_Hemisphere.np)
418 {
419 p_pStream->close();
420 throw std::runtime_error("Vertex normal information is incorrect.");
421 }
422// qDebug() << "Source Space Normals; type:" << t_pTag->getType();
423
424 //=====================================================================
425 if (p_Hemisphere.ntri > 0)
426 {
427 if(!p_Tree->find_tag(p_pStream, FIFF_BEM_SURF_TRIANGLES, t_pTag))
428 {
429 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_TRIANGLES, t_pTag))
430 {
431 p_pStream->close();
432 throw std::runtime_error("Triangulation not found.");
433 }
434 else
435 {
436 p_Hemisphere.itris = t_pTag->toIntMatrix().transpose();
437 p_Hemisphere.itris.array() -= 1;//0 based indizes
438 }
439 }
440 else
441 {
442 p_Hemisphere.itris = t_pTag->toIntMatrix().transpose();
443 p_Hemisphere.itris.array() -= 1;//0 based indizes
444 }
445 if (p_Hemisphere.itris.rows() != p_Hemisphere.ntri)
446 {
447 p_pStream->close();
448 throw std::runtime_error("Triangulation information is incorrect.");
449 }
450 }
451 else
452 {
453 p_Hemisphere.itris.resize(0, 3);
454 }
455// qDebug() << "Triangles; type:" << t_pTag->getType() << "rows:" << p_Hemisphere.itris.rows() << "cols:" << p_Hemisphere.itris.cols();
456
457 //
458 // Which vertices are active
459 //
460 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_NUSE, t_pTag))
461 {
462 p_Hemisphere.nuse = 0;
463 p_Hemisphere.inuse = VectorXi::Zero(p_Hemisphere.nuse);
464 VectorXi p_defaultVector;
465 p_Hemisphere.vertno = p_defaultVector;
466 }
467 else
468 {
469 p_Hemisphere.nuse = *t_pTag->toInt();
470 if(!p_Tree->find_tag(p_pStream, FIFF_MNE_SOURCE_SPACE_SELECTION, t_pTag))
471 {
472 p_pStream->close();
473 throw std::runtime_error("Source selection information missing.");
474 }
475 p_Hemisphere.inuse = VectorXi(Map<VectorXi>(t_pTag->toInt(), t_pTag->size()/4, 1));//use copy constructor, for the sake of easy memory management
476
477 p_Hemisphere.vertno = VectorXi::Zero(p_Hemisphere.nuse);
478 if (p_Hemisphere.inuse.rows() != p_Hemisphere.np)
479 {
480 p_pStream->close();
481 throw std::runtime_error("Incorrect number of entries in source space selection.");
482 }
483 int pp = 0;
484 for (int p = 0; p < p_Hemisphere.np; ++p)
485 {
486 if(p_Hemisphere.inuse(p) == 1)
487 {
488 p_Hemisphere.vertno(pp) = p;
489 ++pp;
490 }
491 }
492 }
493// qDebug() << "Vertices; type:" << t_pTag->getType() << "nuse:" << p_Hemisphere.nuse;
494
495 //
496 // Use triangulation
497 //
498 FiffTag::UPtr t_pTag1;
499 FiffTag::UPtr t_pTag2;
500 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))
501 {
502 MatrixX3i p_defaultMatrix;
503 p_Hemisphere.nuse_tri = 0;
504 p_Hemisphere.use_itris = p_defaultMatrix;
505 }
506 else
507 {
508 p_Hemisphere.nuse_tri = *t_pTag1->toInt();
509 p_Hemisphere.use_itris = t_pTag2->toIntMatrix().transpose();
510 p_Hemisphere.use_itris.array() -= 1; //0 based indizes
511 }
512// qDebug() << "triangulation; type:" << t_pTag2->getType() << "use_itris:" << p_Hemisphere.use_itris.rows()<< "x" << p_Hemisphere.use_itris.cols();
513
514 //
515 // Patch-related information
516 //
517 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))
518 {
519 p_Hemisphere.nearest.clear();
520 }
521 else
522 {
523 //res.nearest = tag1.data + 1;
524 VectorXi nearestIdx = VectorXi(Map<VectorXi>(t_pTag1->toInt(), t_pTag1->size()/4, 1));
525 VectorXd nearestDist = VectorXd((Map<const VectorXf>(t_pTag2->toFloat(), t_pTag2->size()/4, 1)).cast<double>());
526 p_Hemisphere.setNearestData(nearestIdx, nearestDist);
527 }
528
529// patch_info(p_Hemisphere.nearest, p_Hemisphere.pinfo);
530 if (p_Hemisphere.compute_patch_info())
531 qInfo("\tPatch information added...");
532 //
533 // Distances
534 //
535 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))
536 {
537 p_Hemisphere.dist = FiffSparseMatrix();
538 p_Hemisphere.dist_limit = 0;
539 }
540 else
541 {
542 auto dist_lower = FiffSparseMatrix::fiff_get_float_sparse_matrix(t_pTag1);
543 if (dist_lower) {
544 auto dist_full = dist_lower->mne_add_upper_triangle_rcs();
545 if (dist_full) {
546 p_Hemisphere.dist = std::move(*dist_full);
547 }
548 }
549 p_Hemisphere.dist_limit = *t_pTag2->toFloat(); //ToDo Check if this is realy always a float and not a matrix
550 }
551
552 return true;
553}
554
555//=============================================================================================================
556
558{
559 return p_Hemisphere.compute_patch_info();
560}
561
562//=============================================================================================================
563
564bool MNESourceSpaces::complete_source_space_info(MNEHemisphere& p_Hemisphere)
565{
566 return p_Hemisphere.complete_source_space_info();
567}
568
569//=============================================================================================================
570
572{
573 for(size_t h = 0; h < m_sourceSpaces.size(); ++h)
574 {
575 qInfo("\tWrite a source space... ");
577 auto* hemi = dynamic_cast<MNEHemisphere*>(m_sourceSpaces[h].get());
578 if (hemi)
579 hemi->writeToStream(p_pStream);
581 qInfo("[done]\n");
582 }
583 qInfo("\t%zu source spaces written\n", m_sourceSpaces.size());
584}
585
586//=============================================================================================================
587
589{
590 if(static_cast<qint32>(m_sourceSpaces.size()) > idx)
591 return *m_sourceSpaces[idx];
592 else
593 {
594 qWarning("Warning: Index out of bound! Returning last element.");
595 return *m_sourceSpaces.back();
596 }
597}
598
599//=============================================================================================================
600
602{
603 if(static_cast<qint32>(m_sourceSpaces.size()) > idx)
604 return *m_sourceSpaces[idx];
605 else
606 {
607 qWarning("Warning: Index out of bound! Returning last element.");
608 return *m_sourceSpaces.back();
609 }
610}
611
612//=============================================================================================================
613
615{
616 if(idt.compare("lh") == 0)
617 return *m_sourceSpaces[0];
618 else if(idt.compare("rh") == 0)
619 return *m_sourceSpaces[1];
620 else
621 {
622 qWarning("Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
623 return *m_sourceSpaces[0];
624 }
625}
626
627//=============================================================================================================
628
630{
631 if(idt.compare("lh") == 0)
632 return *m_sourceSpaces[0];
633 else if(idt.compare("rh") == 0)
634 return *m_sourceSpaces[1];
635 else
636 {
637 qWarning("Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
638 return *m_sourceSpaces[0];
639 }
640}
641
642//=============================================================================================================
643
645{
646 if(idx >= 0 && idx < static_cast<qint32>(m_sourceSpaces.size()))
647 return dynamic_cast<MNEHemisphere*>(m_sourceSpaces[idx].get());
648 return nullptr;
649}
650
651//=============================================================================================================
652
654{
655 if(idx >= 0 && idx < static_cast<qint32>(m_sourceSpaces.size()))
656 return dynamic_cast<const MNEHemisphere*>(m_sourceSpaces[idx].get());
657 return nullptr;
658}
659
660//=============================================================================================================
661
662std::shared_ptr<MNESourceSpace>& MNESourceSpaces::at(qint32 idx)
663{
664 return m_sourceSpaces.at(idx);
665}
666
667//=============================================================================================================
668
669const std::shared_ptr<MNESourceSpace>& MNESourceSpaces::at(qint32 idx) const
670{
671 return m_sourceSpaces.at(idx);
672}
Reader and in-memory representation of a FreeSurfer/MNE surface label (.label).
Per-source-space-vertex nearest-cortex-vertex mapping.
Container pairing the left and right cortical source spaces of a subject.
#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.
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.
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:164
A FreeSurfer/MNE surface label: per-vertex indices, Tk-RAS positions and scalar values for one hemisp...
Definition fs_label.h:79
Eigen::VectorXi vertices
Definition fs_label.h:164
static Eigen::VectorXi sort(Eigen::Matrix< T, Eigen::Dynamic, 1 > &v, bool desc=true)
Definition linalg.h:280
static Eigen::VectorXi intersect(const Eigen::VectorXi &v1, const Eigen::VectorXi &v2, Eigen::VectorXi &idx_sel)
Definition linalg.cpp:163
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