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