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 m_sourceSpaces.push_back(space.
clone());
106 QList<VectorXi> p_vertices;
107 for(qint32 i = 0; i < static_cast<qint32>(m_sourceSpaces.size()); ++i)
108 p_vertices.push_back(m_sourceSpaces[i]->vertno);
119 QList<VectorXi> vertno;
120 vertno << this->m_sourceSpaces[0]->vertno << this->m_sourceSpaces[1]->vertno;
122 if (p_label.
hemi == 0)
125 vertno[0] = vertno_sel;
126 vertno[1] = VectorXi();
128 else if (p_label.
hemi == 1)
131 src_sel.array() += p_label.
vertices.size();
132 vertno[0] = VectorXi();
133 vertno[1] = vertno_sel;
162 qWarning(
"Unknown hemisphere type\n");
163 vertno[0] = VectorXi::Zero(0);
164 vertno[1] = VectorXi::Zero(0);
174 Q_UNUSED(p_qListLabels);
178 for(qint32 h = 0; h < 2; ++h)
180 auto& srcSpace = *selectedSrc.m_sourceSpaces[h];
181 const auto& origSpace = *this->m_sourceSpaces[h];
183 auto* origHemi =
dynamic_cast<const MNEHemisphere*
>(&origSpace);
185 VectorXi selVertices;
189 for(qint32 i = 0; i < p_qListLabels.size(); ++i)
191 if(p_qListLabels[i].hemi == h)
193 VectorXi currentSelection;
195 Linalg::intersect(origSpace.vertno, p_qListLabels[i].vertices, currentSelection);
197 selVertices.conservativeResize(iSize+currentSelection.size());
198 selVertices.block(iSize,0,currentSelection.size(),1) = currentSelection;
199 iSize = selVertices.size();
205 VectorXi newVertno(selVertices.size());
207 srcSpace.inuse = VectorXi::Zero(srcSpace.np);
209 for(qint32 i = 0; i < selVertices.size(); ++i)
211 srcSpace.inuse[selVertices[i]] = 1;
212 newVertno[i] = origSpace.vertno[selVertices[i]];
215 srcSpace.nuse = selVertices.size();
216 srcSpace.vertno = newVertno;
221 VectorXi idx_select = VectorXi::Zero(origSpace.use_itris.rows());
222 for(qint32 i = 0; i < 3; ++i)
224 VectorXi tri_dim = origSpace.use_itris.col(i);
228 for(qint32 j = 0; j < idx_dim.size(); ++j)
229 idx_select[idx_dim[j]] = 1;
233 for(qint32 i = 0; i < idx_select.size(); ++i)
234 if(idx_select[i] == 1)
237 srcSpace.nuse_tri = countSel;
239 MatrixX3i use_tris_new(countSel,3);
240 MatrixX3d use_tri_cent_new(countSel,3);
241 MatrixX3d use_tri_nn_new(countSel,3);
242 VectorXd use_tri_area_new(countSel);
245 for(qint32 i = 0; i < idx_select.size(); ++i)
247 if(idx_select[i] == 1)
249 use_tris_new.row(countSel) = origSpace.use_itris.row(i);
250 if (origHemi && selHemi) {
251 use_tri_cent_new.row(countSel) = origHemi->use_tri_cent.row(i);
252 use_tri_nn_new.row(countSel) = origHemi->use_tri_nn.row(i);
253 use_tri_area_new[countSel] = origHemi->use_tri_area[i];
259 srcSpace.use_itris = use_tris_new;
261 selHemi->use_tri_cent = use_tri_cent_new;
262 selHemi->use_tri_nn = use_tri_nn_new;
263 selHemi->use_tri_area = use_tri_area_new;
283 bool open_here =
false;
286 if (!p_pStream->device()->isOpen())
288 QString t_sFileName = p_pStream->streamName();
290 t_file.setFileName(t_sFileName);
292 if(!p_pStream->open())
302 if (spaces.size() == 0)
306 std::cout <<
"No source spaces found";
310 for(
int k = 0; k < spaces.size(); ++k)
312 auto p_Hemisphere = std::make_shared<MNEHemisphere>();
313 qInfo(
"\tReading a source space...");
314 MNESourceSpaces::read_source_space(p_pStream, spaces[k], *p_Hemisphere);
315 qInfo(
"\t[done]\n" );
317 p_Hemisphere->complete_source_space_info();
319 p_SourceSpace.m_sourceSpaces.push_back(p_Hemisphere);
324 qInfo(
"\t%lld source spaces read\n", spaces.size());
343 for(
size_t k = 0; k < this->m_sourceSpaces.size(); ++k)
345 auto* hemi =
dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[k].get());
347 if(!hemi->transform_hemisphere_to(dest,trans))
349 qWarning(
"Could not transform source space.");
361 p_Hemisphere.
clear();
369 p_Hemisphere.
id = *t_pTag->toInt();
377 std::cout <<
"error: Number of vertices not found.";
381 p_Hemisphere.
np = *t_pTag->toInt();
387 p_Hemisphere.
ntri = 0;
389 p_Hemisphere.
ntri = *t_pTag->toInt();
393 p_Hemisphere.
ntri = *t_pTag->toInt();
401 std::cout <<
"Coordinate frame information not found.";
414 std::cout <<
"Vertex data not found.";
418 p_Hemisphere.
rr = t_pTag->toFloatMatrix().transpose();
419 qint32 rows_rr = p_Hemisphere.
rr.rows();
422 if (rows_rr != p_Hemisphere.
np)
425 std::cout <<
"Vertex information is incorrect.";
434 std::cout <<
"Vertex normals not found.";
438 p_Hemisphere.
nn = t_pTag->toFloatMatrix().transpose();
439 qint32 rows_nn = p_Hemisphere.
nn.rows();
441 if (rows_nn != p_Hemisphere.
np)
444 std::cout <<
"Vertex normal information is incorrect.";
450 if (p_Hemisphere.
ntri > 0)
457 std::cout <<
"Triangulation not found.";
462 p_Hemisphere.
itris = t_pTag->toIntMatrix().transpose();
463 p_Hemisphere.
itris.array() -= 1;
468 p_Hemisphere.
itris = t_pTag->toIntMatrix().transpose();
469 p_Hemisphere.
itris.array() -= 1;
471 if (p_Hemisphere.
itris.rows() != p_Hemisphere.
ntri)
474 std::cout <<
"Triangulation information is incorrect.";
480 MatrixXi p_defaultMatrix(0, 0);
481 p_Hemisphere.
itris = p_defaultMatrix;
490 p_Hemisphere.
nuse = 0;
491 p_Hemisphere.
inuse = VectorXi::Zero(p_Hemisphere.
nuse);
492 VectorXi p_defaultVector;
493 p_Hemisphere.
vertno = p_defaultVector;
497 p_Hemisphere.
nuse = *t_pTag->toInt();
501 std::cout <<
"Source selection information missing.";
504 p_Hemisphere.
inuse = VectorXi(Map<VectorXi>(t_pTag->toInt(), t_pTag->size()/4, 1));
506 p_Hemisphere.
vertno = VectorXi::Zero(p_Hemisphere.
nuse);
507 if (p_Hemisphere.
inuse.rows() != p_Hemisphere.
np)
510 std::cout <<
"Incorrect number of entries in source space selection.";
514 for (
int p = 0; p < p_Hemisphere.
np; ++p)
516 if(p_Hemisphere.
inuse(p) == 1)
518 p_Hemisphere.
vertno(pp) = p;
532 MatrixX3i p_defaultMatrix;
534 p_Hemisphere.
use_itris = p_defaultMatrix;
538 p_Hemisphere.
nuse_tri = *t_pTag1->toInt();
539 p_Hemisphere.
use_itris = t_pTag2->toIntMatrix().transpose();
554 VectorXi nearestIdx = VectorXi(Map<VectorXi>(t_pTag1->toInt(), t_pTag1->size()/4, 1));
555 VectorXd nearestDist = VectorXd((Map<VectorXf>(t_pTag2->toFloat(), t_pTag1->size()/4, 1)).cast<
double>());
561 qInfo(
"\tPatch information added...");
567 p_Hemisphere.
dist = FiffSparseMatrix();
574 auto dist_full = dist_lower->mne_add_upper_triangle_rcs();
576 p_Hemisphere.
dist = std::move(*dist_full);
579 p_Hemisphere.
dist_limit = *t_pTag2->toFloat();
594bool MNESourceSpaces::complete_source_space_info(
MNEHemisphere& p_Hemisphere)
603 for(
size_t h = 0; h < m_sourceSpaces.size(); ++h)
605 qInfo(
"\tWrite a source space... ");
607 auto* hemi =
dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[h].get());
613 qInfo(
"\t%zu source spaces written\n", m_sourceSpaces.size());
620 if(
static_cast<qint32
>(m_sourceSpaces.size()) > idx)
621 return *m_sourceSpaces[idx];
624 qWarning(
"Warning: Index out of bound! Returning last element.");
625 return *m_sourceSpaces.back();
633 if(
static_cast<qint32
>(m_sourceSpaces.size()) > idx)
634 return *m_sourceSpaces[idx];
637 qWarning(
"Warning: Index out of bound! Returning last element.");
638 return *m_sourceSpaces.back();
646 if(idt.compare(
"lh") == 0)
647 return *m_sourceSpaces[0];
648 else if(idt.compare(
"rh") == 0)
649 return *m_sourceSpaces[1];
652 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
653 return *m_sourceSpaces[0];
661 if(idt.compare(
"lh") == 0)
662 return *m_sourceSpaces[0];
663 else if(idt.compare(
"rh") == 0)
664 return *m_sourceSpaces[1];
667 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
668 return *m_sourceSpaces[0];
676 if(idx >= 0 && idx <
static_cast<qint32
>(m_sourceSpaces.size()))
677 return dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[idx].get());
685 if(idx >= 0 && idx <
static_cast<qint32
>(m_sourceSpaces.size()))
686 return dynamic_cast<const MNEHemisphere*
>(m_sourceSpaces[idx].get());
694 return m_sourceSpaces.at(idx);
701 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
MNESourceSpaces class declaration.
MNENearest class declaration.
FsLabel class declaration.
Linalg 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(const FIFFLIB::FiffTag::UPtr &tag)
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
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)
Hemisphere provides geometry information.
void writeToStream(FIFFLIB::FiffStream *p_pStream)
bool complete_source_space_info()
bool compute_patch_info()
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