58 using namespace UTILSLIB;
59 using namespace FSLIB;
60 using namespace MNELIB;
61 using namespace Eigen;
62 using namespace FIFFLIB;
68 MNESourceSpace::MNESourceSpace()
75 : m_qListHemispheres(p_MNESourceSpace.m_qListHemispheres)
89 m_qListHemispheres.clear();
96 QList<VectorXi> p_vertices;
97 for(qint32 i = 0; i < m_qListHemispheres.size(); ++i)
98 p_vertices.push_back(m_qListHemispheres[i].vertno);
109 QList<VectorXi> vertno;
110 vertno << this->m_qListHemispheres[0].vertno << this->m_qListHemispheres[1].vertno;
112 if (p_label.
hemi == 0)
114 VectorXi vertno_sel = MNEMath::intersect(vertno[0], p_label.
vertices, src_sel);
115 vertno[0] = vertno_sel;
116 vertno[1] = VectorXi();
118 else if (p_label.
hemi == 1)
120 VectorXi vertno_sel = MNEMath::intersect(vertno[1], p_label.
vertices, src_sel);
121 src_sel.array() += p_label.
vertices.size();
122 vertno[0] = VectorXi();
123 vertno[1] = vertno_sel;
152 qWarning(
"Unknown hemisphere type\n");
153 vertno[0] = VectorXi::Zero(0);
154 vertno[1] = VectorXi::Zero(0);
164 Q_UNUSED(p_qListLabels);
168 for(qint32 h = 0; h < 2; ++h)
170 VectorXi selVertices;
174 for(qint32 i = 0; i < p_qListLabels.size(); ++i)
176 if(p_qListLabels[i].hemi == h)
178 VectorXi currentSelection;
180 MNEMath::intersect(m_qListHemispheres[h].vertno, p_qListLabels[i].vertices, currentSelection);
182 selVertices.conservativeResize(iSize+currentSelection.size());
183 selVertices.block(iSize,0,currentSelection.size(),1) = currentSelection;
184 iSize = selVertices.size();
188 MNEMath::sort(selVertices,
false);
190 VectorXi newVertno(selVertices.size());
192 selectedSrc.m_qListHemispheres[h].inuse = VectorXi::Zero(selectedSrc.m_qListHemispheres[h].np);
194 for(qint32 i = 0; i < selVertices.size(); ++i)
196 selectedSrc.m_qListHemispheres[h].inuse[selVertices[i]] = 1;
197 newVertno[i] = this->m_qListHemispheres[h].vertno[selVertices[i]];
200 selectedSrc.m_qListHemispheres[h].nuse = selVertices.size();
201 selectedSrc.m_qListHemispheres[h].vertno = newVertno;
206 VectorXi idx_select = VectorXi::Zero(this->m_qListHemispheres[h].use_tris.rows());
207 for(qint32 i = 0; i < 3; ++i)
209 VectorXi tri_dim = this->m_qListHemispheres[h].use_tris.col(i);
211 MNEMath::intersect(tri_dim, newVertno, idx_dim);
213 for(qint32 j = 0; j < idx_dim.size(); ++j)
214 idx_select[idx_dim[j]] = 1;
218 for(qint32 i = 0; i < idx_select.size(); ++i)
219 if(idx_select[i] == 1)
222 selectedSrc.m_qListHemispheres[h].nuse_tri = countSel;
224 MatrixX3i use_tris_new(countSel,3);
225 MatrixX3d use_tri_cent_new(countSel,3);
226 MatrixX3d use_tri_nn_new(countSel,3);
227 VectorXd use_tri_area_new(countSel);
230 for(qint32 i = 0; i < idx_select.size(); ++i)
232 if(idx_select[i] == 1)
234 use_tris_new.row(countSel) = this->m_qListHemispheres[h].use_tris.row(i);
235 use_tri_cent_new.row(countSel) = this->m_qListHemispheres[h].use_tri_cent.row(i);
236 use_tri_nn_new.row(countSel) = this->m_qListHemispheres[h].use_tri_nn.row(i);
237 use_tri_area_new[countSel] = this->m_qListHemispheres[h].use_tri_area[i];
242 selectedSrc.m_qListHemispheres[h].use_tris = use_tris_new;
243 selectedSrc.m_qListHemispheres[h].use_tri_cent = use_tri_cent_new;
244 selectedSrc.m_qListHemispheres[h].use_tri_nn = use_tri_nn_new;
245 selectedSrc.m_qListHemispheres[h].use_tri_area = use_tri_area_new;
264 bool open_here =
false;
267 if (!p_pStream->device()->isOpen())
269 QString t_sFileName = p_pStream->streamName();
271 t_file.setFileName(t_sFileName);
273 if(!p_pStream->open())
282 QList<FiffDirNode::SPtr> spaces = p_pStream->dirtree()->dir_tree_find(FIFFB_MNE_SOURCE_SPACE);
283 if (spaces.size() == 0)
287 std::cout <<
"No source spaces found";
291 for(
int k = 0;
k < spaces.size(); ++
k)
294 printf(
"\tReading a source space...");
295 MNESourceSpace::read_source_space(p_pStream, spaces[
k], p_Hemisphere);
296 printf(
"\t[done]\n" );
298 complete_source_space_info(p_Hemisphere);
300 p_SourceSpace.m_qListHemispheres.append(p_Hemisphere);
305 printf(
"\t%lld source spaces read\n", spaces.size());
317 double xave = p_Hemisphere.
rr.col(0).sum();
321 hemi = FIFFV_MNE_SURF_LEFT_HEMI;
323 hemi = FIFFV_MNE_SURF_RIGHT_HEMI;
332 for(
int k = 0;
k < this->m_qListHemispheres.size(); ++
k)
334 if(!this->m_qListHemispheres[
k].transform_hemisphere_to(dest,trans))
336 printf(
"Could not transform source space.\n");
347 p_Hemisphere.
clear();
353 p_Hemisphere.
id = FIFFV_MNE_SURF_UNKNOWN;
355 p_Hemisphere.
id = *t_pTag->toInt();
363 std::cout <<
"error: Number of vertices not found.";
367 p_Hemisphere.
np = *t_pTag->toInt();
373 p_Hemisphere.
ntri = 0;
375 p_Hemisphere.
ntri = *t_pTag->toInt();
379 p_Hemisphere.
ntri = *t_pTag->toInt();
387 std::cout <<
"Coordinate frame information not found.";
400 std::cout <<
"Vertex data not found.";
404 p_Hemisphere.
rr = t_pTag->toFloatMatrix().transpose();
405 qint32 rows_rr = p_Hemisphere.
rr.rows();
408 if (rows_rr != p_Hemisphere.
np)
411 std::cout <<
"Vertex information is incorrect.";
420 std::cout <<
"Vertex normals not found.";
424 p_Hemisphere.
nn = t_pTag->toFloatMatrix().transpose();
425 qint32 rows_nn = p_Hemisphere.
nn.rows();
427 if (rows_nn != p_Hemisphere.
np)
430 std::cout <<
"Vertex normal information is incorrect.";
436 if (p_Hemisphere.
ntri > 0)
443 std::cout <<
"Triangulation not found.";
448 p_Hemisphere.
tris = t_pTag->toIntMatrix().transpose();
449 p_Hemisphere.
tris -= MatrixXi::Constant(p_Hemisphere.
tris.rows(),3,1);
454 p_Hemisphere.
tris = t_pTag->toIntMatrix().transpose();
455 p_Hemisphere.
tris -= MatrixXi::Constant(p_Hemisphere.
tris.rows(),3,1);
457 if (p_Hemisphere.
tris.rows() != p_Hemisphere.
ntri)
460 std::cout <<
"Triangulation information is incorrect.";
466 MatrixXi p_defaultMatrix(0, 0);
467 p_Hemisphere.
tris = p_defaultMatrix;
476 p_Hemisphere.
nuse = 0;
477 p_Hemisphere.
inuse = VectorXi::Zero(p_Hemisphere.
nuse);
478 VectorXi p_defaultVector;
479 p_Hemisphere.
vertno = p_defaultVector;
483 p_Hemisphere.
nuse = *t_pTag->toInt();
487 std::cout <<
"Source selection information missing.";
490 p_Hemisphere.
inuse = VectorXi(Map<VectorXi>(t_pTag->toInt(), t_pTag->size()/4, 1));
492 p_Hemisphere.
vertno = VectorXi::Zero(p_Hemisphere.
nuse);
493 if (p_Hemisphere.
inuse.rows() != p_Hemisphere.
np)
496 std::cout <<
"Incorrect number of entries in source space selection.";
500 for (
int p = 0; p < p_Hemisphere.
np; ++p)
502 if(p_Hemisphere.
inuse(p) == 1)
504 p_Hemisphere.
vertno(pp) = p;
518 MatrixX3i p_defaultMatrix;
520 p_Hemisphere.
use_tris = p_defaultMatrix;
524 p_Hemisphere.
nuse_tri = *t_pTag1->toInt();
525 p_Hemisphere.
use_tris = t_pTag2->toIntMatrix().transpose();
526 p_Hemisphere.
use_tris -= MatrixXi::Constant(p_Hemisphere.
use_tris.rows(),3,1);
535 VectorXi p_defaultVector;
536 p_Hemisphere.
nearest = p_defaultVector;
537 VectorXd p_defaultFloatVector;
543 p_Hemisphere.
nearest = VectorXi(Map<VectorXi>(t_pTag1->toInt(), t_pTag1->size()/4, 1));
544 p_Hemisphere.
nearest_dist = VectorXd((Map<VectorXf>(t_pTag2->toFloat(), t_pTag1->size()/4, 1)).cast<
double>());
549 printf(
"\tPatch information added...");
558 p_Hemisphere.
dist = SparseMatrix<double>();
563 p_Hemisphere.
dist = t_pTag1->toSparseFloatMatrix();
564 p_Hemisphere.
dist_limit = *t_pTag2->toFloat();
568 SparseMatrix<double> distT = p_Hemisphere.
dist.transpose();
569 p_Hemisphere.
dist += distT;
579 if (p_Hemisphere.
nearest.rows() == 0)
581 p_Hemisphere.
pinfo.clear();
586 printf(
"\tComputing patch statistics...");
588 std::vector< std::pair<int,int> > t_vIndn;
590 for(qint32 i = 0; i < p_Hemisphere.
nearest.rows(); ++i)
592 std::pair<int,int> t_pair(i, p_Hemisphere.
nearest(i));
593 t_vIndn.push_back(t_pair);
595 std::sort(t_vIndn.begin(),t_vIndn.end(), MNEMath::compareIdxValuePairSmallerThan<int> );
597 VectorXi nearest_sorted(t_vIndn.size());
600 std::vector<qint32> t_vfirsti;
601 t_vfirsti.push_back(current);
602 std::vector<qint32> t_vlasti;
604 for(quint32 i = 0; i < t_vIndn.size(); ++i)
606 nearest_sorted[i] = t_vIndn[i].second;
607 if (t_vIndn[current].second != t_vIndn[i].second)
610 t_vlasti.push_back(i-1);
611 t_vfirsti.push_back(current);
614 t_vlasti.push_back(
static_cast<int>(t_vIndn.size()-1));
616 for(quint32
k = 0;
k < t_vfirsti.size(); ++
k)
618 std::vector<int> t_vIndex;
620 for(
int l = t_vfirsti[
k]; l <= t_vlasti[
k]; ++l)
621 t_vIndex.push_back(t_vIndn[l].first);
623 std::sort(t_vIndex.begin(),t_vIndex.end());
625 int* t_pV = &t_vIndex[0];
626 Eigen::Map<Eigen::VectorXi> t_vPInfo(t_pV, t_vIndex.size());
628 p_Hemisphere.
pinfo.append(t_vPInfo);
632 std::vector<qint32> patch_verts;
633 patch_verts.reserve(t_vlasti.size());
634 for(quint32 i = 0; i < t_vlasti.size(); ++i)
635 patch_verts.push_back(nearest_sorted[t_vlasti[i]]);
638 std::vector<qint32>::iterator it;
639 for(qint32 i = 0; i < p_Hemisphere.
vertno.size(); ++i)
641 it = std::find(patch_verts.begin(), patch_verts.end(), p_Hemisphere.
vertno[i]);
642 p_Hemisphere.
patch_inds[i] = it-patch_verts.begin();
650 bool MNESourceSpace::complete_source_space_info(
MNEHemisphere& p_Hemisphere)
655 printf(
"\tCompleting triangulation info...");
656 p_Hemisphere.
tri_cent = MatrixX3d::Zero(p_Hemisphere.
ntri,3);
657 p_Hemisphere.
tri_nn = MatrixX3d::Zero(p_Hemisphere.
ntri,3);
658 p_Hemisphere.
tri_area = VectorXd::Zero(p_Hemisphere.
ntri);
664 for (qint32 i = 0; i < p_Hemisphere.
ntri; ++i)
666 for ( qint32 j = 0; j < 3; ++j)
668 k = p_Hemisphere.
tris(i, j);
670 r(j,0) = p_Hemisphere.
rr(
k, 0);
671 r(j,1) = p_Hemisphere.
rr(
k, 1);
672 r(j,2) = p_Hemisphere.
rr(
k, 2);
674 p_Hemisphere.
tri_cent(i, 0) += p_Hemisphere.
rr(
k, 0);
675 p_Hemisphere.
tri_cent(i, 1) += p_Hemisphere.
rr(
k, 1);
676 p_Hemisphere.
tri_cent(i, 2) += p_Hemisphere.
rr(
k, 2);
678 p_Hemisphere.
tri_cent.row(i) /= 3.0f;
681 a = r.row(1) - r.row(0 );
682 b = r.row(2) - r.row(0);
683 p_Hemisphere.
tri_nn(i,0) = a(1)*
b(2)-a(2)*
b(1);
684 p_Hemisphere.
tri_nn(i,1) = a(2)*
b(0)-a(0)*
b(2);
685 p_Hemisphere.
tri_nn(i,2) = a(0)*
b(1)-a(1)*
b(0);
706 printf(
"\tCompleting selection triangulation info...");
713 for (qint32 i = 0; i < p_Hemisphere.
nuse_tri; ++i)
715 for ( qint32 j = 0; j < 3; ++j)
719 r(j,0) = p_Hemisphere.
rr(
k, 0);
720 r(j,1) = p_Hemisphere.
rr(
k, 1);
721 r(j,2) = p_Hemisphere.
rr(
k, 2);
730 a = r.row(1) - r.row(0 );
731 b = r.row(2) - r.row(0);
752 printf(
"\tCompleting triangle and vertex neighboring info...");
763 for(qint32 h = 0; h < m_qListHemispheres.size(); ++h)
765 printf(
"\tWrite a source space... ");
767 m_qListHemispheres[h].writeToStream(p_pStream);
768 p_pStream->
end_block(FIFFB_MNE_SOURCE_SPACE);
771 printf(
"\t%lld source spaces written\n", m_qListHemispheres.size());
778 if(m_qListHemispheres.size() > idx)
779 return m_qListHemispheres[idx];
782 qWarning(
"Warning: Index out of bound! Returning last element.");
783 return m_qListHemispheres[m_qListHemispheres.size()-1];
791 if(m_qListHemispheres.size() > idx)
792 return m_qListHemispheres[idx];
795 qWarning(
"Warning: Index out of bound! Returning last element.");
796 return m_qListHemispheres[m_qListHemispheres.size()-1];
804 if(idt.compare(
"lh") == 0)
805 return m_qListHemispheres[0];
806 else if(idt.compare(
"rh") == 0)
807 return m_qListHemispheres[1];
810 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
811 return m_qListHemispheres[0];
819 if(idt.compare(
"lh") == 0)
820 return m_qListHemispheres[0];
821 else if(idt.compare(
"rh") == 0)
822 return m_qListHemispheres[1];
825 qWarning(
"Warning: Identifier is not 'lh' or 'rh'! Returning 'lh'.");
826 return m_qListHemispheres[0];