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());
91 m_sourceSpaces.clear();
98 m_sourceSpaces.push_back(space.
clone());
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);
118 QList<VectorXi> vertno;
119 vertno << this->m_sourceSpaces[0]->vertno << this->m_sourceSpaces[1]->vertno;
121 if (p_label.
hemi == 0)
124 vertno[0] = vertno_sel;
125 vertno[1] = VectorXi();
127 else if (p_label.
hemi == 1)
130 src_sel.array() += p_label.
vertices.size();
131 vertno[0] = VectorXi();
132 vertno[1] = vertno_sel;
161 qWarning(
"Unknown hemisphere type\n");
162 vertno[0] = VectorXi::Zero(0);
163 vertno[1] = VectorXi::Zero(0);
173 Q_UNUSED(p_qListLabels);
177 for(qint32 h = 0; h < 2; ++h)
179 auto& srcSpace = *selectedSrc.m_sourceSpaces[h];
180 const auto& origSpace = *this->m_sourceSpaces[h];
182 auto* origHemi =
dynamic_cast<const MNEHemisphere*
>(&origSpace);
184 VectorXi selVertices;
188 for(qint32 i = 0; i < p_qListLabels.size(); ++i)
190 if(p_qListLabels[i].hemi == h)
192 VectorXi currentSelection;
194 Linalg::intersect(origSpace.vertno, p_qListLabels[i].vertices, currentSelection);
196 selVertices.conservativeResize(iSize+currentSelection.size());
197 selVertices.block(iSize,0,currentSelection.size(),1) = currentSelection;
198 iSize = selVertices.size();
204 VectorXi newVertno(selVertices.size());
206 srcSpace.inuse = VectorXi::Zero(srcSpace.np);
208 for(qint32 i = 0; i < selVertices.size(); ++i)
210 srcSpace.inuse[selVertices[i]] = 1;
211 newVertno[i] = origSpace.vertno[selVertices[i]];
214 srcSpace.nuse = selVertices.size();
215 srcSpace.vertno = newVertno;
220 VectorXi idx_select = VectorXi::Zero(origSpace.use_itris.rows());
221 for(qint32 i = 0; i < 3; ++i)
223 VectorXi tri_dim = origSpace.use_itris.col(i);
227 for(qint32 j = 0; j < idx_dim.size(); ++j)
228 idx_select[idx_dim[j]] = 1;
232 for(qint32 i = 0; i < idx_select.size(); ++i)
233 if(idx_select[i] == 1)
236 srcSpace.nuse_tri = countSel;
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);
244 for(qint32 i = 0; i < idx_select.size(); ++i)
246 if(idx_select[i] == 1)
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];
258 srcSpace.use_itris = use_tris_new;
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;
282 bool open_here =
false;
285 if (!p_pStream->device()->isOpen())
287 QString t_sFileName = p_pStream->streamName();
289 t_file.setFileName(t_sFileName);
291 if(!p_pStream->open())
301 if (spaces.size() == 0)
305 qWarning() <<
"No source spaces found";
309 for(
int k = 0; k < spaces.size(); ++k)
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" );
316 p_Hemisphere->complete_source_space_info();
318 p_SourceSpace.m_sourceSpaces.push_back(p_Hemisphere);
323 qInfo(
"\t%lld source spaces read\n", spaces.size());
342 for(
size_t k = 0; k < this->m_sourceSpaces.size(); ++k)
344 auto* hemi =
dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[k].get());
346 if(!hemi->transform_hemisphere_to(dest,trans))
348 qWarning(
"Could not transform source space.");
360 p_Hemisphere.
clear();
368 p_Hemisphere.
id = *t_pTag->toInt();
376 throw std::runtime_error(
"error: Number of vertices not found.");
379 p_Hemisphere.
np = *t_pTag->toInt();
385 p_Hemisphere.
ntri = 0;
387 p_Hemisphere.
ntri = *t_pTag->toInt();
391 p_Hemisphere.
ntri = *t_pTag->toInt();
399 throw std::runtime_error(
"Coordinate frame information not found.");
411 throw std::runtime_error(
"Vertex data not found.");
414 p_Hemisphere.
rr = t_pTag->toFloatMatrix().transpose();
415 qint32 rows_rr = p_Hemisphere.
rr.rows();
418 if (rows_rr != p_Hemisphere.
np)
421 throw std::runtime_error(
"Vertex information is incorrect.");
429 throw std::runtime_error(
"Vertex normals not found.");
432 p_Hemisphere.
nn = t_pTag->toFloatMatrix().transpose();
433 qint32 rows_nn = p_Hemisphere.
nn.rows();
435 if (rows_nn != p_Hemisphere.
np)
438 throw std::runtime_error(
"Vertex normal information is incorrect.");
443 if (p_Hemisphere.
ntri > 0)
450 throw std::runtime_error(
"Triangulation not found.");
454 p_Hemisphere.
itris = t_pTag->toIntMatrix().transpose();
455 p_Hemisphere.
itris.array() -= 1;
460 p_Hemisphere.
itris = t_pTag->toIntMatrix().transpose();
461 p_Hemisphere.
itris.array() -= 1;
463 if (p_Hemisphere.
itris.rows() != p_Hemisphere.
ntri)
466 throw std::runtime_error(
"Triangulation information is incorrect.");
471 p_Hemisphere.
itris.resize(0, 3);
480 p_Hemisphere.
nuse = 0;
481 p_Hemisphere.
inuse = VectorXi::Zero(p_Hemisphere.
nuse);
482 VectorXi p_defaultVector;
483 p_Hemisphere.
vertno = p_defaultVector;
487 p_Hemisphere.
nuse = *t_pTag->toInt();
491 throw std::runtime_error(
"Source selection information missing.");
493 p_Hemisphere.
inuse = VectorXi(Map<VectorXi>(t_pTag->toInt(), t_pTag->size()/4, 1));
495 p_Hemisphere.
vertno = VectorXi::Zero(p_Hemisphere.
nuse);
496 if (p_Hemisphere.
inuse.rows() != p_Hemisphere.
np)
499 throw std::runtime_error(
"Incorrect number of entries in source space selection.");
502 for (
int p = 0; p < p_Hemisphere.
np; ++p)
504 if(p_Hemisphere.
inuse(p) == 1)
506 p_Hemisphere.
vertno(pp) = p;
520 MatrixX3i p_defaultMatrix;
522 p_Hemisphere.
use_itris = p_defaultMatrix;
526 p_Hemisphere.
nuse_tri = *t_pTag1->toInt();
527 p_Hemisphere.
use_itris = t_pTag2->toIntMatrix().transpose();
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>());
549 qInfo(
"\tPatch information added...");
555 p_Hemisphere.
dist = FiffSparseMatrix();
562 auto dist_full = dist_lower->mne_add_upper_triangle_rcs();
564 p_Hemisphere.
dist = std::move(*dist_full);
567 p_Hemisphere.
dist_limit = *t_pTag2->toFloat();
582bool MNESourceSpaces::complete_source_space_info(
MNEHemisphere& p_Hemisphere)
591 for(
size_t h = 0; h < m_sourceSpaces.size(); ++h)
593 qInfo(
"\tWrite a source space... ");
595 auto* hemi =
dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[h].get());
601 qInfo(
"\t%zu source spaces written\n", m_sourceSpaces.size());
608 if(
static_cast<qint32
>(m_sourceSpaces.size()) > idx)
609 return *m_sourceSpaces[idx];
612 qWarning(
"Warning: Index out of bound! Returning last element.");
613 return *m_sourceSpaces.back();
621 if(
static_cast<qint32
>(m_sourceSpaces.size()) > idx)
622 return *m_sourceSpaces[idx];
625 qWarning(
"Warning: Index out of bound! Returning last element.");
626 return *m_sourceSpaces.back();
634 if(idt.compare(
"lh") == 0)
635 return *m_sourceSpaces[0];
636 else if(idt.compare(
"rh") == 0)
637 return *m_sourceSpaces[1];
640 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
641 return *m_sourceSpaces[0];
649 if(idt.compare(
"lh") == 0)
650 return *m_sourceSpaces[0];
651 else if(idt.compare(
"rh") == 0)
652 return *m_sourceSpaces[1];
655 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
656 return *m_sourceSpaces[0];
664 if(idx >= 0 && idx <
static_cast<qint32
>(m_sourceSpaces.size()))
665 return dynamic_cast<MNEHemisphere*
>(m_sourceSpaces[idx].get());
673 if(idx >= 0 && idx <
static_cast<qint32
>(m_sourceSpaces.size()))
674 return dynamic_cast<const MNEHemisphere*
>(m_sourceSpaces[idx].get());
682 return m_sourceSpaces.at(idx);
689 return m_sourceSpaces.at(idx);
Linalg class declaration.
#define FIFF_BEM_SURF_TRIANGLES
#define FIFF_BEM_SURF_NTRI
#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).
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