77 m_sourceSpaces.reserve(p_MNESourceSpaces.m_sourceSpaces.size());
78 for (
const auto& sp : p_MNESourceSpaces.m_sourceSpaces)
79 m_sourceSpaces.push_back(sp->clone());
92 m_sourceSpaces.clear();
99 QList<VectorXi> p_vertices;
100 for(qint32 i = 0; i < static_cast<qint32>(m_sourceSpaces.size()); ++i)
101 p_vertices.push_back(m_sourceSpaces[i]->vertno);
112 QList<VectorXi> vertno;
113 vertno << this->m_sourceSpaces[0]->vertno << this->m_sourceSpaces[1]->vertno;
115 if (p_label.
hemi == 0)
118 vertno[0] = vertno_sel;
119 vertno[1] = VectorXi();
121 else if (p_label.
hemi == 1)
124 src_sel.array() += p_label.
vertices.size();
125 vertno[0] = VectorXi();
126 vertno[1] = vertno_sel;
155 qWarning(
"Unknown hemisphere type\n");
156 vertno[0] = VectorXi::Zero(0);
157 vertno[1] = VectorXi::Zero(0);
167 Q_UNUSED(p_qListLabels);
171 for(qint32 h = 0; h < 2; ++h)
173 auto& srcSpace = *selectedSrc.m_sourceSpaces[h];
174 const auto& origSpace = *this->m_sourceSpaces[h];
176 auto* origHemi =
dynamic_cast<const MNEHemisphere*
>(&origSpace);
178 VectorXi selVertices;
182 for(qint32 i = 0; i < p_qListLabels.size(); ++i)
184 if(p_qListLabels[i].hemi == h)
186 VectorXi currentSelection;
190 selVertices.conservativeResize(iSize+currentSelection.size());
191 selVertices.block(iSize,0,currentSelection.size(),1) = currentSelection;
192 iSize = selVertices.size();
198 VectorXi newVertno(selVertices.size());
200 srcSpace.inuse = VectorXi::Zero(srcSpace.np);
202 for(qint32 i = 0; i < selVertices.size(); ++i)
204 srcSpace.inuse[selVertices[i]] = 1;
205 newVertno[i] = origSpace.vertno[selVertices[i]];
208 srcSpace.nuse = selVertices.size();
209 srcSpace.vertno = newVertno;
214 VectorXi idx_select = VectorXi::Zero(origSpace.use_itris.rows());
215 for(qint32 i = 0; i < 3; ++i)
217 VectorXi tri_dim = origSpace.use_itris.col(i);
221 for(qint32 j = 0; j < idx_dim.size(); ++j)
222 idx_select[idx_dim[j]] = 1;
226 for(qint32 i = 0; i < idx_select.size(); ++i)
227 if(idx_select[i] == 1)
230 srcSpace.nuse_tri = countSel;
232 MatrixX3i use_tris_new(countSel,3);
233 MatrixX3d use_tri_cent_new(countSel,3);
234 MatrixX3d use_tri_nn_new(countSel,3);
235 VectorXd use_tri_area_new(countSel);
238 for(qint32 i = 0; i < idx_select.size(); ++i)
240 if(idx_select[i] == 1)
242 use_tris_new.row(countSel) = origSpace.use_itris.row(i);
243 if (origHemi && selHemi) {
244 use_tri_cent_new.row(countSel) = origHemi->use_tri_cent.row(i);
245 use_tri_nn_new.row(countSel) = origHemi->use_tri_nn.row(i);
246 use_tri_area_new[countSel] = origHemi->use_tri_area[i];
252 srcSpace.use_itris = use_tris_new;
254 selHemi->use_tri_cent = use_tri_cent_new;
255 selHemi->use_tri_nn = use_tri_nn_new;
256 selHemi->use_tri_area = use_tri_area_new;
276 bool open_here =
false;
279 if (!p_pStream->device()->isOpen())
281 QString t_sFileName = p_pStream->streamName();
283 t_file.setFileName(t_sFileName);
285 if(!p_pStream->open())
295 if (spaces.size() == 0)
299 std::cout <<
"No source spaces found";
303 for(
int k = 0; k < spaces.size(); ++k)
305 auto p_Hemisphere = std::make_shared<MNEHemisphere>();
306 printf(
"\tReading a source space...");
307 MNESourceSpaces::read_source_space(p_pStream, spaces[k], *p_Hemisphere);
308 printf(
"\t[done]\n" );
310 p_Hemisphere->complete_source_space_info();
312 p_SourceSpace.m_sourceSpaces.push_back(p_Hemisphere);
317 printf(
"\t%lld source spaces read\n", spaces.size());
336 for(
size_t k = 0; k < this->m_sourceSpaces.size(); ++k)
338 auto* hemi =
dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[k].get());
340 if(!hemi->transform_hemisphere_to(dest,trans))
342 printf(
"Could not transform source space.\n");
354 p_Hemisphere.
clear();
362 p_Hemisphere.
id = *t_pTag->toInt();
370 std::cout <<
"error: Number of vertices not found.";
374 p_Hemisphere.
np = *t_pTag->toInt();
380 p_Hemisphere.
ntri = 0;
382 p_Hemisphere.
ntri = *t_pTag->toInt();
386 p_Hemisphere.
ntri = *t_pTag->toInt();
394 std::cout <<
"Coordinate frame information not found.";
407 std::cout <<
"Vertex data not found.";
411 p_Hemisphere.
rr = t_pTag->toFloatMatrix().transpose();
412 qint32 rows_rr = p_Hemisphere.
rr.rows();
415 if (rows_rr != p_Hemisphere.
np)
418 std::cout <<
"Vertex information is incorrect.";
427 std::cout <<
"Vertex normals not found.";
431 p_Hemisphere.
nn = t_pTag->toFloatMatrix().transpose();
432 qint32 rows_nn = p_Hemisphere.
nn.rows();
434 if (rows_nn != p_Hemisphere.
np)
437 std::cout <<
"Vertex normal information is incorrect.";
443 if (p_Hemisphere.
ntri > 0)
450 std::cout <<
"Triangulation not found.";
455 p_Hemisphere.
itris = t_pTag->toIntMatrix().transpose();
456 p_Hemisphere.
itris.array() -= 1;
461 p_Hemisphere.
itris = t_pTag->toIntMatrix().transpose();
462 p_Hemisphere.
itris.array() -= 1;
464 if (p_Hemisphere.
itris.rows() != p_Hemisphere.
ntri)
467 std::cout <<
"Triangulation information is incorrect.";
473 MatrixXi p_defaultMatrix(0, 0);
474 p_Hemisphere.
itris = p_defaultMatrix;
483 p_Hemisphere.
nuse = 0;
484 p_Hemisphere.
inuse = VectorXi::Zero(p_Hemisphere.
nuse);
485 VectorXi p_defaultVector;
486 p_Hemisphere.
vertno = p_defaultVector;
490 p_Hemisphere.
nuse = *t_pTag->toInt();
494 std::cout <<
"Source selection information missing.";
497 p_Hemisphere.
inuse = VectorXi(Map<VectorXi>(t_pTag->toInt(), t_pTag->size()/4, 1));
499 p_Hemisphere.
vertno = VectorXi::Zero(p_Hemisphere.
nuse);
500 if (p_Hemisphere.
inuse.rows() != p_Hemisphere.
np)
503 std::cout <<
"Incorrect number of entries in source space selection.";
507 for (
int p = 0; p < p_Hemisphere.
np; ++p)
509 if(p_Hemisphere.
inuse(p) == 1)
511 p_Hemisphere.
vertno(pp) = p;
525 MatrixX3i p_defaultMatrix;
527 p_Hemisphere.
use_itris = p_defaultMatrix;
531 p_Hemisphere.
nuse_tri = *t_pTag1->toInt();
532 p_Hemisphere.
use_itris = t_pTag2->toIntMatrix().transpose();
547 VectorXi nearestIdx = VectorXi(Map<VectorXi>(t_pTag1->toInt(), t_pTag1->size()/4, 1));
548 VectorXd nearestDist = VectorXd((Map<VectorXf>(t_pTag2->toFloat(), t_pTag1->size()/4, 1)).cast<
double>());
554 printf(
"\tPatch information added...");
561 p_Hemisphere.
dist = FiffSparseMatrix();
568 auto dist_full = dist_lower->mne_add_upper_triangle_rcs();
570 p_Hemisphere.
dist = std::move(*dist_full);
573 p_Hemisphere.
dist_limit = *t_pTag2->toFloat();
588bool MNESourceSpaces::complete_source_space_info(
MNEHemisphere& p_Hemisphere)
597 for(
size_t h = 0; h < m_sourceSpaces.size(); ++h)
599 printf(
"\tWrite a source space... ");
601 auto* hemi =
dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[h].get());
607 printf(
"\t%zu source spaces written\n", m_sourceSpaces.size());
614 if(
static_cast<qint32
>(m_sourceSpaces.size()) > idx)
615 return *m_sourceSpaces[idx];
618 qWarning(
"Warning: Index out of bound! Returning last element.");
619 return *m_sourceSpaces.back();
627 if(
static_cast<qint32
>(m_sourceSpaces.size()) > idx)
628 return *m_sourceSpaces[idx];
631 qWarning(
"Warning: Index out of bound! Returning last element.");
632 return *m_sourceSpaces.back();
640 if(idt.compare(
"lh") == 0)
641 return *m_sourceSpaces[0];
642 else if(idt.compare(
"rh") == 0)
643 return *m_sourceSpaces[1];
646 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
647 return *m_sourceSpaces[0];
655 if(idt.compare(
"lh") == 0)
656 return *m_sourceSpaces[0];
657 else if(idt.compare(
"rh") == 0)
658 return *m_sourceSpaces[1];
661 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
662 return *m_sourceSpaces[0];
670 if(idx >= 0 && idx <
static_cast<qint32
>(m_sourceSpaces.size()))
671 return dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[idx].get());
679 if(idx >= 0 && idx <
static_cast<qint32
>(m_sourceSpaces.size()))
680 return dynamic_cast<const MNEHemisphere*
>(m_sourceSpaces[idx].get());
688 return m_sourceSpaces.at(idx);
695 return m_sourceSpaces.at(idx);
#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
#define FIFF_BEM_SURF_NTRI
MNEMath 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).
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(FIFFLIB::FiffTag::SPtr &tag)
fiff_long_t start_block(fiff_int_t kind)
fiff_long_t end_block(fiff_int_t kind, fiff_int_t next=FIFFV_NEXT_SEQ)
QSharedPointer< FiffStream > SPtr
QSharedPointer< FiffTag > SPtr
Hemisphere provides geometry information.
void writeToStream(FIFFLIB::FiffStream *p_pStream)
bool complete_source_space_info()
bool compute_patch_info()
This defines a source space.
qint32 find_source_space_hemi() const
QList< Eigen::VectorXi > label_src_vertno_sel(const FSLIB::Label &p_label, Eigen::VectorXi &src_sel) const
void writeToStream(FIFFLIB::FiffStream *p_pStream)
MNESourceSpaces pick_regions(const QList< FSLIB::Label > &p_qListLabels) const
bool transform_source_space_to(FIFFLIB::fiff_int_t dest, FIFFLIB::FiffCoordTrans &trans)
MNEHemisphere * hemisphereAt(qint32 idx)
static bool patch_info(MNEHemisphere &p_Hemisphere)
static qint32 find_source_space_hemi(MNESourceSpace &p_SourceSpace)
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
static Eigen::VectorXi sort(Eigen::Matrix< T, Eigen::Dynamic, 1 > &v, bool desc=true)
static Eigen::VectorXi intersect(const Eigen::VectorXi &v1, const Eigen::VectorXi &v2, Eigen::VectorXi &idx_sel)