44 #include <QtConcurrent>
61 MNEInverseOperator::MNEInverseOperator()
67 , eigen_leads_weighted(false)
99 : info(p_MNEInverseOperator.info)
100 , methods(p_MNEInverseOperator.methods)
101 , source_ori(p_MNEInverseOperator.source_ori)
102 , nsource(p_MNEInverseOperator.nsource)
103 , nchan(p_MNEInverseOperator.nchan)
104 , coord_frame(p_MNEInverseOperator.coord_frame)
105 , source_nn(p_MNEInverseOperator.source_nn)
106 , sing(p_MNEInverseOperator.sing)
107 , eigen_leads_weighted(p_MNEInverseOperator.eigen_leads_weighted)
108 , eigen_leads(p_MNEInverseOperator.eigen_leads)
109 , eigen_fields(p_MNEInverseOperator.eigen_fields)
110 , noise_cov(p_MNEInverseOperator.noise_cov)
111 , source_cov(p_MNEInverseOperator.source_cov)
112 , orient_prior(p_MNEInverseOperator.orient_prior)
113 , depth_prior(p_MNEInverseOperator.depth_prior)
114 , fmri_prior(p_MNEInverseOperator.fmri_prior)
115 , src(p_MNEInverseOperator.src)
116 , mri_head_t(p_MNEInverseOperator.mri_head_t)
117 , nave(p_MNEInverseOperator.nave)
118 , projs(p_MNEInverseOperator.projs)
119 , proj(p_MNEInverseOperator.proj)
120 , whitener(p_MNEInverseOperator.whitener)
121 , reginv(p_MNEInverseOperator.reginv)
122 , noisenorm(p_MNEInverseOperator.noisenorm)
141 MatrixXd t_source_cov = this->
source_cov->data;
142 if(method.compare(
"MNE") != 0)
147 typedef Eigen::Triplet<double> T;
148 std::vector<T> tripletList;
152 qDebug() <<
"ToDo: Label selection needs to be debugged - not done jet!";
156 if(method.compare(
"MNE") != 0)
159 tripletList.reserve(noise_norm.nonZeros());
161 for (qint32 k = 0; k < noise_norm.outerSize(); ++k)
163 for (SparseMatrix<double>::InnerIterator it(noise_norm,k); it; ++it)
167 for(qint32 i = 0; i < src_sel.size(); ++i)
168 if(src_sel[i] == it.row())
171 tripletList.push_back(T(it.row(), it.col(), it.value()));
175 noise_norm = SparseMatrix<double>(src_sel.size(),noise_norm.cols());
176 noise_norm.setFromTriplets(tripletList.begin(), tripletList.end());
181 VectorXi src_sel_new(src_sel.size()*3);
183 for(qint32 i = 0; i < src_sel.size(); ++i)
185 src_sel_new[i*3] = src_sel[i]*3;
186 src_sel_new[i*3+1] = src_sel[i]*3+1;
187 src_sel_new[i*3+2] = src_sel[i]*3+2;
189 src_sel = src_sel_new;
193 for(qint32 i = 0; i < src_sel.size(); ++i)
195 t_eigen_leads.row(i) = t_eigen_leads.row(src_sel[i]);
196 t_source_cov = t_source_cov.row(src_sel[i]);
198 t_eigen_leads.conservativeResize(src_sel.size(), t_eigen_leads.cols());
199 t_source_cov.conservativeResize(src_sel.size(), t_source_cov.cols());
206 qWarning(
"Warning: Pick normal can only be used with a free orientation inverse operator.\n");
213 qWarning(
"The pick_normal parameter is only valid when working with loose orientations.\n");
219 for(qint32 i = 2; i < t_eigen_leads.rows(); i+=3)
221 t_eigen_leads.row(count) = t_eigen_leads.row(i);
224 t_eigen_leads.conservativeResize(count, t_eigen_leads.cols());
227 for(qint32 i = 2; i < t_source_cov.rows(); i+=3)
229 t_source_cov.row(count) = t_source_cov.row(i);
232 t_source_cov.conservativeResize(count, t_source_cov.cols());
236 tripletList.reserve(
reginv.rows());
237 for(qint32 i = 0; i <
reginv.rows(); ++i)
238 tripletList.push_back(T(i, i,
reginv(i,0)));
239 SparseMatrix<double> t_reginv(
reginv.rows(),
reginv.rows());
240 t_reginv.setFromTriplets(tripletList.begin(), tripletList.end());
252 printf(
"(eigenleads already weighted)...");
253 K = t_eigen_leads*trans;
260 printf(
"(eigenleads need to be weighted)...");
262 std::vector<T> tripletList2;
263 tripletList2.reserve(t_source_cov.rows());
264 for(qint32 i = 0; i < t_source_cov.rows(); ++i)
265 tripletList2.push_back(T(i, i, sqrt(t_source_cov(i,0))));
266 SparseMatrix<double> t_sourceCov(t_source_cov.rows(),t_source_cov.rows());
267 t_sourceCov.setFromTriplets(tripletList2.begin(), tripletList2.end());
269 K = t_sourceCov*t_eigen_leads*trans;
272 if(method.compare(
"MNE") == 0)
273 noise_norm = SparseMatrix<double>();
286 QStringList inv_ch_names = this->
eigen_fields->col_names;
288 bool t_bContains =
true;
293 for(qint32 i = 0; i < this->
noise_cov->names.size(); ++i)
295 if(inv_ch_names[i] != this->
noise_cov->names[i])
305 qCritical(
"Channels in inverse operator eigen fields do not match noise covariance channels.");
309 QStringList data_ch_names = info.
ch_names;
311 QStringList missing_ch_names;
312 for(qint32 i = 0; i < inv_ch_names.size(); ++i)
313 if(!data_ch_names.contains(inv_ch_names[i]))
314 missing_ch_names.append(inv_ch_names[i]);
316 qint32 n_missing = missing_ch_names.size();
320 qCritical() << n_missing <<
"channels in inverse operator are not present in the data (" << missing_ch_names <<
")";
332 printf(
"Cluster kernel using %s.\n", p_sMethod.toUtf8().constData());
334 MatrixXd p_outMT = this->m_K.transpose();
336 QList<MNEClusterInfo> t_qListMNEClusterInfo;
338 t_qListMNEClusterInfo.append(t_MNEClusterInfo);
339 t_qListMNEClusterInfo.append(t_MNEClusterInfo);
346 printf(
"Error: Fixed orientation not implemented jet!\n");
381 for(qint32 h = 0; h < this->
src.
size(); ++h )
389 for(qint32 j = 0; j < h; ++j)
390 offset += this->
src[j].nuse;
393 printf(
"Cluster Left Hemisphere\n");
395 printf(
"Cluster Right Hemisphere\n");
397 Colortable t_CurrentColorTable = p_AnnotationSet[h].getColortable();
398 VectorXi label_ids = t_CurrentColorTable.
getLabelIds();
401 VectorXi vertno_labeled = VectorXi::Zero(this->
src[h].vertno.rows());
404 for(qint32 i = 0; i < vertno_labeled.rows(); ++i)
405 vertno_labeled[i] = p_AnnotationSet[h].getLabelIds()[this->
src[h].vertno[i]];
408 QList<RegionMT> m_qListRegionMTIn;
413 for (qint32 i = 0; i < label_ids.rows(); ++i)
415 if (label_ids[i] != 0)
417 QString curr_name = t_CurrentColorTable.
struct_names[i];
418 printf(
"\tCluster %d / %li %s...", i+1, label_ids.rows(), curr_name.toUtf8().constData());
423 VectorXi idcs = VectorXi::Zero(vertno_labeled.rows());
427 for(qint32 j = 0; j < vertno_labeled.rows(); ++j)
429 if(vertno_labeled[j] == label_ids[i])
435 idcs.conservativeResize(c);
438 MatrixXd t_MT(p_outMT.rows(), idcs.rows()*3);
440 for(qint32 j = 0; j < idcs.rows(); ++j)
441 t_MT.block(0, j*3, t_MT.rows(), 3) = p_outMT.block(0, (idcs[j]+offset)*3, t_MT.rows(), 3);
443 qint32 nSens = t_MT.rows();
444 qint32 nSources = t_MT.cols()/3;
450 t_sensMT.
idcs = idcs;
452 t_sensMT.
nClusters = ceil((
double)nSources/(
double)p_iClusterSize);
456 printf(
"%d Cluster(s)... ", t_sensMT.
nClusters);
459 t_sensMT.
matRoiMT = MatrixXd(t_MT.cols()/3, 3*nSens);
461 for(qint32 j = 0; j < nSens; ++j)
462 for(qint32 k = 0; k < t_sensMT.
matRoiMT.rows(); ++k)
463 t_sensMT.
matRoiMT.block(k,j*3,1,3) = t_MT.block(j,k*3,1,3);
467 m_qListRegionMTIn.append(t_sensMT);
473 printf(
"failed! Label contains no sources.\n");
482 printf(
"Clustering... ");
483 QFuture< RegionMTOut > res;
484 res = QtConcurrent::mapped(m_qListRegionMTIn, &RegionMT::cluster);
485 res.waitForFinished();
490 MatrixXd t_MT_partial;
494 QList<RegionMT>::const_iterator itIn;
495 itIn = m_qListRegionMTIn.begin();
496 QFuture<RegionMTOut>::const_iterator itOut;
497 for (itOut = res.constBegin(); itOut != res.constEnd(); ++itOut)
499 nClusters = itOut->ctrs.rows();
500 nSens = itOut->ctrs.cols()/3;
501 t_MT_partial = MatrixXd::Zero(nSens, nClusters*3);
509 for(qint32 j = 0; j < nSens; ++j)
510 for(qint32 k = 0; k < nClusters; ++k)
511 t_MT_partial.block(j, k*3, 1, 3) = itOut->ctrs.block(k,j*3,1,3);
516 for(qint32 j = 0; j < nClusters; ++j)
518 VectorXi clusterIdcs = VectorXi::Zero(itOut->roiIdx.rows());
519 VectorXd clusterDistance = VectorXd::Zero(itOut->roiIdx.rows());
520 qint32 nClusterIdcs = 0;
521 for(qint32 k = 0; k < itOut->roiIdx.rows(); ++k)
523 if(itOut->roiIdx[k] == j)
525 clusterIdcs[nClusterIdcs] = itIn->idcs[k];
528 clusterDistance[nClusterIdcs] = itOut->D(k,j);
532 clusterIdcs.conservativeResize(nClusterIdcs);
533 clusterDistance.conservativeResize(nClusterIdcs);
535 VectorXi clusterVertnos = VectorXi::Zero(clusterIdcs.size());
536 for(qint32 k = 0; k < clusterVertnos.size(); ++k)
537 clusterVertnos(k) = this->
src[h].vertno[clusterIdcs(k)];
539 t_qListMNEClusterInfo[h].clusterVertnos.append(clusterVertnos);
547 if(t_MT_partial.rows() > 0 && t_MT_partial.cols() > 0)
549 t_MT_new.conservativeResize(t_MT_partial.rows(), t_MT_new.cols() + t_MT_partial.cols());
550 t_MT_new.block(0, t_MT_new.cols() - t_MT_partial.cols(), t_MT_new.rows(), t_MT_partial.cols()) = t_MT_partial;
553 for(qint32 k = 0; k < nClusters; ++k)
557 double sqec = sqrt((itIn->matRoiMTOrig.block(0, j*3, itIn->matRoiMTOrig.rows(), 3) - t_MT_partial.block(0, k*3, t_MT_partial.rows(), 3)).array().pow(2).sum());
558 double sqec_min = sqec;
561 for(qint32 j = 1; j < itIn->idcs.rows(); ++j)
563 sqec = sqrt((itIn->matRoiMTOrig.block(0, j*3, itIn->matRoiMTOrig.rows(), 3) - t_MT_partial.block(0, k*3, t_MT_partial.rows(), 3)).array().pow(2).sum());
596 qint32 totalNumOfClust = 0;
597 for (qint32 h = 0; h < 2; ++h)
598 totalNumOfClust += t_qListMNEClusterInfo[h].clusterVertnos.size();
601 p_D = MatrixXd::Zero(p_outMT.cols(), totalNumOfClust);
603 p_D = MatrixXd::Zero(p_outMT.cols(), totalNumOfClust*3);
610 qint32 currentCluster = 0;
611 for (qint32 h = 0; h < 2; ++h)
613 int hemiOffset = h == 0 ? 0 : t_vertnos[0].size();
614 for(qint32 i = 0; i < t_qListMNEClusterInfo[h].clusterVertnos.size(); ++i)
617 MNEMath::intersect(t_vertnos[h], t_qListMNEClusterInfo[h].clusterVertnos[i], idx_sel);
623 idx_sel.array() += hemiOffset;
629 double selectWeight = 1.0/idx_sel.size();
632 for(qint32 j = 0; j < idx_sel.size(); ++j)
633 p_D.col(currentCluster)[idx_sel(j)] = selectWeight;
637 qint32 clustOffset = currentCluster*3;
638 for(qint32 j = 0; j < idx_sel.size(); ++j)
640 qint32 idx_sel_Offset = idx_sel(j)*3;
642 p_D(idx_sel_Offset,clustOffset) = selectWeight;
644 p_D(idx_sel_Offset+1, clustOffset+1) = selectWeight;
646 p_D(idx_sel_Offset+2, clustOffset+2) = selectWeight;
671 std::cout <<
"ToDo MNEInverseOperator::make_inverse_operator: do surf_ori check" << std::endl;
674 if(fixed && loose > 0)
676 qWarning(
"Warning: When invoking make_inverse_operator with fixed = true, the loose parameter is ignored.\n");
680 if(is_fixed_ori && !fixed)
682 qWarning(
"Warning: Setting fixed parameter = true. Because the given forward operator has fixed orientation and can only be used to make a fixed-orientation inverse operator.\n");
688 qCritical(
"Error: Forward solution is not oriented in surface coordinates. loose parameter should be 0 not %f.\n", loose);
689 return p_MNEInverseOperator;
692 if(loose < 0 || loose > 1)
694 qWarning(
"Warning: Loose value should be in interval [0,1] not %f.\n", loose);
695 loose = loose > 1 ? 1 : 0;
696 printf(
"Setting loose to %f.\n", loose);
699 if(depth < 0 || depth > 1)
701 qWarning(
"Warning: Depth value should be in interval [0,1] not %f.\n", depth);
702 depth = depth > 1 ? 1 : 0;
703 printf(
"Setting depth to %f.\n", depth);
717 forward.
prepare_forward(info, p_noise_cov,
false, gain_info, gain, p_outNoiseCov, whitener, n_nzero);
723 MatrixXd patch_areas;
726 std::cout <<
"ToDo: patch_areas" << std::endl;
732 p_depth_prior->data = MatrixXd::Ones(gain.cols(), gain.cols());
734 p_depth_prior->diag =
true;
735 p_depth_prior->dim = gain.cols();
736 p_depth_prior->nfree = 1;
742 if(depth < 0 || depth > 1)
745 printf(
"\tToDo: Picked elements from a free-orientation depth-weighting prior into the fixed-orientation one.\n");
751 for(qint32 i = 2; i < p_depth_prior->data.rows(); i+=3)
753 p_depth_prior->data.row(count) = p_depth_prior->data.row(i);
756 p_depth_prior->data.conservativeResize(count, 1);
761 forward.
prepare_forward(info, p_outNoiseCov,
false, gain_info, gain, p_outNoiseCov, whitener, n_nzero);
764 printf(
"\tComputing inverse operator with %d channels.\n", gain_info.
ch_names.size());
769 printf(
"\tCreating the source covariance matrix\n");
777 p_source_cov->data.array() *= p_orient_prior->data.array();
786 printf(
"\tWhitening the forward solution.\n");
787 gain = whitener*gain;
797 printf(
"\tAdjusting source covariance matrix.\n");
798 RowVectorXd source_std = p_source_cov->data.array().sqrt().transpose();
800 for(qint32 i = 0; i < gain.rows(); ++i)
801 gain.row(i) = gain.row(i).array() * source_std.array();
803 double trace_GRGT = (gain * gain.transpose()).trace();
804 double scaling_source_cov = (double)n_nzero / trace_GRGT;
806 p_source_cov->data.array() *= scaling_source_cov;
808 gain.array() *= sqrt(scaling_source_cov);
816 printf(
"Computing SVD of whitened and weighted lead field matrix.\n");
817 JacobiSVD<MatrixXd> svd(gain, ComputeThinU | ComputeThinV);
818 std::cout <<
"ToDo Sorting Necessary?" << std::endl;
819 VectorXd p_sing = svd.singularValues();
820 MatrixXd t_U = svd.matrixU();
821 MNEMath::sort<double>(p_sing, t_U);
823 svd.matrixU().rows(),
828 p_sing = svd.singularValues();
829 MatrixXd t_V = svd.matrixV();
830 MNEMath::sort<double>(p_sing, t_V);
832 svd.matrixV().cols(),
836 printf(
"\tlargest singular value = %f\n", p_sing.maxCoeff());
837 printf(
"\tscaling factor to adjust the trace = %f\n", trace_GRGT);
842 bool has_meg =
false;
843 bool has_eeg =
false;
845 RowVectorXd ch_idx(info.
chs.size());
847 for(qint32 i = 0; i < info.
chs.size(); ++i)
849 if(gain_info.
ch_names.contains(info.
chs[i].ch_name))
855 ch_idx.conservativeResize(count);
857 for(qint32 i = 0; i < ch_idx.size(); ++i)
860 if (ch_type ==
"eeg")
862 if ((ch_type ==
"mag") || (ch_type ==
"grad"))
868 if(has_eeg && has_meg)
869 p_iMethods = FIFFV_MNE_MEG_EEG;
871 p_iMethods = FIFFV_MNE_MEG;
873 p_iMethods = FIFFV_MNE_EEG;
881 p_MNEInverseOperator.
sing = p_sing;
882 p_MNEInverseOperator.
nave = p_nave;
884 p_MNEInverseOperator.
source_cov = p_source_cov;
891 p_MNEInverseOperator.
methods = p_iMethods;
895 p_MNEInverseOperator.
src = forward.
src;
896 p_MNEInverseOperator.
info = forward.
info;
899 return p_MNEInverseOperator;
909 printf(
"The number of averages should be positive\n");
912 printf(
"Preparing the inverse operator for use...\n");
917 float scale = ((float)inv.
nave)/((float)nave);
925 printf(
"\tScaled noise and source covariance from nave = %d to nave = %d\n",inv.
nave,nave);
930 VectorXd tmp = inv.
sing.cwiseProduct(inv.
sing) + VectorXd::Constant(inv.
sing.size(), lambda2);
933 inv.
reginv = VectorXd(inv.
sing.cwiseQuotient(tmp));
934 printf(
"\tCreated the regularized inverter\n");
941 printf(
"\tCreated an SSP operator (subspace dimension = %d)\n",ncomp);
958 for (k = ncomp; k < inv.
noise_cov->dim; ++k)
970 printf(
"\tCreated the whitener using a full noise covariance matrix (%d small eigenvalues omitted)\n", inv.
noise_cov->dim - nnzero);
980 printf(
"\tCreated the whitener using a diagonal noise covariance matrix (%d small eigenvalues discarded)\n",ncomp);
987 VectorXd noise_norm = VectorXd::Zero(inv.
eigen_leads->nrow);
988 VectorXd noise_weight;
991 printf(
"\tComputing noise-normalization factors (dSPM)...");
992 noise_weight = VectorXd(inv.
reginv);
996 printf(
"\tComputing noise-normalization factors (sLORETA)...");
997 VectorXd tmp = (VectorXd::Constant(inv.
sing.size(), 1) + inv.
sing.cwiseProduct(inv.
sing)/lambda2);
998 noise_weight = inv.
reginv.cwiseProduct(tmp.cwiseSqrt());
1006 noise_norm[k] = sqrt(one.dot(one));
1020 one = c*(inv.
eigen_leads->data.row(k).transpose()).cwiseProduct(noise_weight);
1021 noise_norm[k] = sqrt(one.dot(one));
1031 VectorXd noise_norm_new;
1043 noise_norm_new = t->cwiseSqrt();
1051 VectorXd vOnes = VectorXd::Ones(noise_norm_new.size());
1052 VectorXd tmp = vOnes.cwiseQuotient(noise_norm_new.cwiseAbs());
1056 typedef Eigen::Triplet<double> T;
1057 std::vector<T> tripletList;
1058 tripletList.reserve(noise_norm_new.size());
1059 for(qint32 i = 0; i < noise_norm_new.size(); ++i)
1060 tripletList.push_back(T(i, i, tmp[i]));
1062 inv.
noisenorm = SparseMatrix<double>(noise_norm_new.size(),noise_norm_new.size());
1063 inv.
noisenorm.setFromTriplets(tripletList.begin(), tripletList.end());
1086 printf(
"Reading inverse operator decomposition from %s...\n",t_pStream->streamName().toUtf8().constData());
1088 QList<FiffDirEntry> t_Dir;
1090 if(!t_pStream->open(t_Tree, t_Dir))
1095 QList <FiffDirTree> invs_list = t_Tree.
dir_tree_find(FIFFB_MNE_INVERSE_SOLUTION);
1096 if ( invs_list.size()== 0)
1098 printf(
"No inverse solutions in %s\n", t_pStream->streamName().toUtf8().constData());
1105 QList <FiffDirTree> parent_mri = t_Tree.
dir_tree_find(FIFFB_MNE_PARENT_MRI_FILE);
1106 if (parent_mri.size() == 0)
1108 printf(
"No parent MRI information in %s", t_pStream->streamName().toUtf8().constData());
1111 printf(
"\tReading inverse operator info...");
1116 if (!invs->
find_tag(t_pStream.data(), FIFF_MNE_INCLUDED_METHODS, t_pTag))
1118 printf(
"Modalities not found\n");
1123 inv.
methods = *t_pTag->toInt();
1127 printf(
"Source orientation constraints not found\n");
1134 printf(
"Number of sources not found\n");
1137 inv.
nsource = *t_pTag->toInt();
1144 printf(
"Coordinate frame tag not found\n");
1153 printf(
"Source orientation information not found\n");
1159 inv.
source_nn = t_pTag->toFloatMatrix();
1166 printf(
"\tReading inverse operator decomposition...");
1169 printf(
"Singular values not found\n");
1175 inv.
sing = Map<VectorXf>(t_pTag->toFloat(), t_pTag->size()/4).cast<double>();
1186 printf(
"Error reading eigenleads named matrix.\n");
1197 printf(
"Error reading eigenfields named matrix.\n");
1206 printf(
"\tNoise covariance matrix read.\n");
1210 printf(
"\tError: Not able to read noise covariance matrix.\n");
1214 if(t_pStream->read_cov(*invs, FIFFV_MNE_SOURCE_COV, *inv.
source_cov.data()))
1216 printf(
"\tSource covariance matrix read.\n");
1220 printf(
"\tError: Not able to read source covariance matrix.\n");
1228 printf(
"\tOrientation priors read.\n");
1235 printf(
"\tDepth priors read.\n");
1241 if(t_pStream->read_cov(*invs, FIFFV_MNE_FMRI_PRIOR_COV, *inv.
fmri_prior.data()))
1243 printf(
"\tfMRI priors read.\n");
1254 printf(
"\tError: Could not read the source spaces.\n");
1257 for (qint32 k = 0; k < inv.
src.
size(); ++k)
1263 if (!parent_mri[0].find_tag(t_pStream.data(), FIFF_COORD_TRANS, t_pTag))
1265 printf(
"MRI/head coordinate transformation not found\n");
1270 mri_head_t = t_pTag->toCoordTrans();
1271 if (mri_head_t.
from != FIFFV_COORD_MRI || mri_head_t.
to != FIFFV_COORD_HEAD)
1274 if (mri_head_t.
from != FIFFV_COORD_MRI || mri_head_t.
to != FIFFV_COORD_HEAD)
1276 printf(
"MRI/head coordinate transformation not found");
1288 t_pStream->read_meas_info_base(t_Tree, inv.
info);
1295 printf(
"Only inverse solutions computed in MRI or head coordinates are acceptable");
1303 inv.
projs = t_pStream->read_proj(t_Tree);
1315 printf(
"Could not transform source space.\n");
1317 printf(
"\tSource spaces transformed to the inverse solution coordinate frame\n");
1336 printf(
"Write inverse operator decomposition in %s...", t_pStream->streamName().toUtf8().constData());
1345 p_pStream->
start_block(FIFFB_MNE_INVERSE_SOLUTION);
1347 printf(
"\tWriting inverse operator info...\n");
1354 VectorXf tmp_sing = this->
sing.cast<
float>();
1374 printf(
"\t[done]\n");
1378 printf(
"\tWriting noise covariance matrix.");
1381 printf(
"\tWriting source covariance matrix.\n");
1386 printf(
"\tWriting orientation priors.\n");
1388 p_pStream->
write_cov(*this->orient_prior.data());
1390 p_pStream->
write_cov(*this->depth_prior.data());
1392 p_pStream->
write_cov(*this->fmri_prior.data());
1397 p_pStream->
start_block(FIFFB_MNE_PARENT_MRI_FILE);
1400 p_pStream->
end_block(FIFFB_MNE_PARENT_MRI_FILE);
1420 p_pStream->
end_block(FIFFB_MNE_INVERSE_SOLUTION);
static qint32 find_source_space_hemi(MNEHemisphere &p_Hemisphere)
#define FIFF_MNE_SOURCE_SPACE_NPOINTS
QSharedDataPointer< FiffCov > SDPtr
#define FIFFV_MNE_NOISE_COV
bool eigen_leads_weighted
#define FIFF_MNE_SOURCE_ORIENTATION
FIFF measurement file information.
void writeToStream(FiffStream *p_pStream)
bool isFixedOrient() const
FiffNamedMatrix::SDPtr eigen_fields
void write_cov(const FiffCov &p_FiffCov)
bool assemble_kernel(const Label &label, QString method, bool pick_normal, MatrixXd &K, SparseMatrix< double > &noise_norm, QList< VectorXi > &vertno)
bool transform_source_space_to(fiff_int_t dest, FiffCoordTrans &trans)
bool find_tag(FiffStream *p_pStream, fiff_int_t findkind, QSharedPointer< FiffTag > &p_pTag) const
static FiffStream::SPtr start_file(QIODevice &p_IODevice)
QList< FiffDirTree > dir_tree_find(fiff_int_t p_kind) const
void write_named_matrix(fiff_int_t kind, const FiffNamedMatrix &mat)
QSharedDataPointer< FiffNamedMatrix > SDPtr
VectorXi getLabelIds() const
FiffCoordTrans mri_head_t
static MNEInverseOperator make_inverse_operator(const FiffInfo &info, MNEForwardSolution forward, const FiffCov &p_noise_cov, float loose=0.2f, float depth=0.8f, bool fixed=false, bool limit_depth_chs=true)
QSharedPointer< FiffTag > SPtr
#define FIFF_MNE_INVERSE_SING
#define FIFF_MNE_INVERSE_LEADS
#define FIFF_MNE_INVERSE_LEADS_WEIGHTED
FiffCov::SDPtr depth_prior
static VectorXd * combine_xyz(const VectorXd &vec)
static bool readFromStream(FiffStream::SPtr &p_pStream, bool add_geom, FiffDirTree &p_Tree, MNESourceSpace &p_SourceSpace)
MatrixXd cluster_kernel(const AnnotationSet &p_AnnotationSet, qint32 p_iClusterSize, MatrixXd &p_D, QString p_sMethod="cityblock") const
FiffCov::SDPtr source_cov
static bool read_inverse_operator(QIODevice &p_IODevice, MNEInverseOperator &inv)
SparseMatrix< double > noisenorm
QSharedPointer< FiffStream > SPtr
FiffNamedMatrix::SDPtr eigen_leads
void write_float(fiff_int_t kind, const float *data, fiff_int_t nel=1)
static FiffCov compute_depth_prior(const MatrixXd &Gain, const FiffInfo &gain_info, bool is_fixed_ori, double exp=0.8, double limit=10.0, const MatrixXd &patch_areas=defaultConstMatrixXd, bool limit_depth_chs=false)
void transpose_named_matrix()
void write_int(fiff_int_t kind, const fiff_int_t *data, fiff_int_t nel=1)
FiffCoordTrans mri_head_t
static VectorXi intersect(const VectorXi &v1, const VectorXi &v2, VectorXi &idx_sel)
void start_block(fiff_int_t kind)
void write_info_base(const FiffInfoBase &p_FiffInfoBase)
#define FIFF_MNE_INVERSE_FIELDS
Directory tree structure.
MNEInverseOperator prepare_inverse_operator(qint32 nave, float lambda2, bool dSPM, bool sLORETA=false) const
bool check_ch_names(const FiffInfo &info) const
#define FIFFV_MNE_ORIENT_PRIOR_COV
MNEInverseOperator class declaration.
static fiff_int_t make_projector(const QList< FiffProj > &projs, const QStringList &ch_names, MatrixXd &proj, const QStringList &bads=defaultQStringList, MatrixXd &U=defaultMatrixXd, bool include_active=true)
#define FIFF_MNE_COORD_FRAME
Vertices label based lookup table.
void write_proj(const QList< FiffProj > &projs)
void write_coord_trans(const FiffCoordTrans &trans)
QList< VectorXi > get_vertno() const
QString channel_type(qint32 idx) const
bool isFixedOrient() const
void write_float_matrix(fiff_int_t kind, const MatrixXf &mat)
void prepare_forward(const FiffInfo &p_info, const FiffCov &p_noise_cov, bool p_pca, FiffInfo &p_outFwdInfo, MatrixXd &gain, FiffCov &p_outNoiseCov, MatrixXd &p_outWhitener, qint32 &p_outNumNonZero) const
Coordinate transformation description.
FiffCov compute_orient_prior(float loose=0.2)
void writeToStream(FiffStream *p_pStream)
void write(QIODevice &p_IODevice)
#define FIFF_MNE_INVERSE_SOURCE_ORIENTATIONS
void end_block(fiff_int_t kind)
#define FIFFV_MNE_DEPTH_PRIOR_COV
FiffCov::SDPtr orient_prior
QList< VectorXi > label_src_vertno_sel(const Label &p_label, VectorXi &src_sel) const
FiffCov::SDPtr fmri_prior