39#include <QtConcurrent>
78 qRegisterMetaType<QSharedPointer<MNELIB::MNEInverseOperator> >(
"QSharedPointer<MNELIB::MNEInverseOperator>");
79 qRegisterMetaType<MNELIB::MNEInverseOperator>(
"MNELIB::MNEInverseOperator");
87 qRegisterMetaType<QSharedPointer<MNELIB::MNEInverseOperator> >(
"QSharedPointer<MNELIB::MNEInverseOperator>");
88 qRegisterMetaType<MNELIB::MNEInverseOperator>(
"MNELIB::MNEInverseOperator");
102 qRegisterMetaType<QSharedPointer<MNELIB::MNEInverseOperator> >(
"QSharedPointer<MNELIB::MNEInverseOperator>");
103 qRegisterMetaType<MNELIB::MNEInverseOperator>(
"MNELIB::MNEInverseOperator");
134 qRegisterMetaType<QSharedPointer<MNELIB::MNEInverseOperator> >(
"QSharedPointer<MNELIB::MNEInverseOperator>");
135 qRegisterMetaType<MNELIB::MNEInverseOperator>(
"MNELIB::MNEInverseOperator");
145 const QString &method,
148 SparseMatrix<double> &noise_norm,
149 QList<VectorXi> &vertno)
153 if(method.compare(QLatin1String(
"MNE")) != 0)
156 vertno =
src.get_vertno();
158 typedef Eigen::Triplet<double> T;
159 std::vector<T> tripletList;
163 qWarning(
"Label selection needs further debugging.");
165 vertno =
src.label_src_vertno_sel(label, src_sel);
167 if(method.compare(QLatin1String(
"MNE")) != 0)
170 tripletList.reserve(noise_norm.nonZeros());
172 for (qint32 k = 0; k < noise_norm.outerSize(); ++k)
174 for (SparseMatrix<double>::InnerIterator it(noise_norm,k); it; ++it)
177 for(qint32 i = 0; i < src_sel.size(); ++i)
179 if(src_sel[i] == it.row())
186 tripletList.push_back(T(it.row(), it.col(), it.value()));
190 noise_norm = SparseMatrix<double>(src_sel.size(),noise_norm.cols());
191 noise_norm.setFromTriplets(tripletList.begin(), tripletList.end());
196 VectorXi src_sel_new(src_sel.size()*3);
198 for(qint32 i = 0; i < src_sel.size(); ++i)
200 src_sel_new[i*3] = src_sel[i]*3;
201 src_sel_new[i*3+1] = src_sel[i]*3+1;
202 src_sel_new[i*3+2] = src_sel[i]*3+2;
204 src_sel = src_sel_new;
207 for(qint32 i = 0; i < src_sel.size(); ++i)
209 t_eigen_leads.row(i) = t_eigen_leads.row(src_sel[i]);
210 t_source_cov = t_source_cov.row(src_sel[i]);
212 t_eigen_leads.conservativeResize(src_sel.size(), t_eigen_leads.cols());
213 t_source_cov.conservativeResize(src_sel.size(), t_source_cov.cols());
220 qWarning(
"Warning: Pick normal can only be used with a free orientation inverse operator.\n");
227 qWarning(
"The pick_normal parameter is only valid when working with loose orientations.\n");
233 for(qint32 i = 2; i < t_eigen_leads.rows(); i+=3)
235 t_eigen_leads.row(count) = t_eigen_leads.row(i);
238 t_eigen_leads.conservativeResize(count, t_eigen_leads.cols());
241 for(qint32 i = 2; i < t_source_cov.rows(); i+=3)
243 t_source_cov.row(count) = t_source_cov.row(i);
246 t_source_cov.conservativeResize(count, t_source_cov.cols());
250 tripletList.reserve(
reginv.rows());
251 for(qint32 i = 0; i <
reginv.rows(); ++i)
252 tripletList.push_back(T(i, i,
reginv(i,0)));
253 SparseMatrix<double> t_reginv(
reginv.rows(),
reginv.rows());
254 t_reginv.setFromTriplets(tripletList.begin(), tripletList.end());
266 qInfo(
"(eigenleads already weighted)...\n");
267 K = t_eigen_leads*trans;
274 qInfo(
"(eigenleads need to be weighted)...\n");
276 std::vector<T> tripletList2;
277 tripletList2.reserve(t_source_cov.rows());
278 for(qint32 i = 0; i < t_source_cov.rows(); ++i)
279 tripletList2.push_back(T(i, i, sqrt(t_source_cov(i,0))));
280 SparseMatrix<double> t_sourceCov(t_source_cov.rows(),t_source_cov.rows());
281 t_sourceCov.setFromTriplets(tripletList2.begin(), tripletList2.end());
283 K = t_sourceCov*t_eigen_leads*trans;
286 if(method.compare(QLatin1String(
"MNE")) == 0)
287 noise_norm = SparseMatrix<double>();
299 QStringList inv_ch_names = this->
eigen_fields->col_names;
301 bool t_bContains =
true;
302 if(this->
eigen_fields->col_names.size() != this->noise_cov->names.size())
306 for(qint32 i = 0; i < this->
noise_cov->names.size(); ++i)
308 if(inv_ch_names[i] != this->
noise_cov->names[i])
318 qCritical(
"Channels in inverse operator eigen fields do not match noise covariance channels.");
322 QStringList data_ch_names =
info.ch_names;
324 QStringList missing_ch_names;
325 for(qint32 i = 0; i < inv_ch_names.size(); ++i)
326 if(!data_ch_names.contains(inv_ch_names[i]))
327 missing_ch_names.append(inv_ch_names[i]);
329 qint32 n_missing = missing_ch_names.size();
333 qCritical() << n_missing <<
"channels in inverse operator are not present in the data (" << missing_ch_names <<
")";
344 qInfo(
"Cluster kernel using %s.\n", p_sMethod.toUtf8().constData());
346 MatrixXd p_outMT = m_K.transpose();
348 QList<MNEClusterInfo> t_qListMNEClusterInfo;
350 t_qListMNEClusterInfo.append(t_MNEClusterInfo);
351 t_qListMNEClusterInfo.append(t_MNEClusterInfo);
358 qCritical(
"Error: Fixed orientation not implemented yet!\n");
370 for(qint32 h = 0; h < this->
src.size(); ++h )
377 for(qint32 j = 0; j < h; ++j)
378 offset += this->
src[j].nuse;
381 qInfo(
"Cluster Left Hemisphere\n");
383 qInfo(
"Cluster Right Hemisphere\n");
385 FsColortable t_CurrentColorTable = p_AnnotationSet[h].getColortable();
386 VectorXi label_ids = t_CurrentColorTable.
getLabelIds();
389 VectorXi vertno_labeled = VectorXi::Zero(this->
src[h].vertno.rows());
391 for(qint32 i = 0; i < vertno_labeled.rows(); ++i)
392 vertno_labeled[i] = p_AnnotationSet[h].getLabelIds()[this->
src[h].vertno[i]];
395 QList<RegionMT> m_qListRegionMTIn;
400 for (qint32 i = 0; i < label_ids.rows(); ++i)
402 if (label_ids[i] != 0)
404 QString curr_name = t_CurrentColorTable.
struct_names[i];
405 qInfo(
"\tCluster %d / %ld %s...", i+1, label_ids.rows(), curr_name.toUtf8().constData());
410 VectorXi idcs = VectorXi::Zero(vertno_labeled.rows());
414 for(qint32 j = 0; j < vertno_labeled.rows(); ++j)
416 if(vertno_labeled[j] == label_ids[i])
422 idcs.conservativeResize(c);
425 MatrixXd t_MT(p_outMT.rows(), idcs.rows()*3);
427 for(qint32 j = 0; j < idcs.rows(); ++j)
428 t_MT.block(0, j*3, t_MT.rows(), 3) = p_outMT.block(0, (idcs[j]+offset)*3, t_MT.rows(), 3);
430 qint32 nSens = t_MT.rows();
431 qint32 nSources = t_MT.cols()/3;
437 t_sensMT.
idcs = idcs;
439 t_sensMT.
nClusters = ceil(
static_cast<double>(nSources)/
static_cast<double>(p_iClusterSize));
443 qInfo(
"%d Cluster(s)... ", t_sensMT.
nClusters);
446 t_sensMT.
matRoiMT = MatrixXd(t_MT.cols()/3, 3*nSens);
448 for(qint32 j = 0; j < nSens; ++j)
449 for(qint32 k = 0; k < t_sensMT.
matRoiMT.rows(); ++k)
450 t_sensMT.
matRoiMT.block(k,j*3,1,3) = t_MT.block(j,k*3,1,3);
454 m_qListRegionMTIn.append(t_sensMT);
460 qInfo(
"failed! FsLabel contains no sources.\n");
468 qInfo(
"Clustering... ");
469 QFuture< RegionMTOut > res;
471 res.waitForFinished();
476 MatrixXd t_MT_partial;
480 QList<RegionMT>::const_iterator itIn;
481 itIn = m_qListRegionMTIn.begin();
482 QFuture<RegionMTOut>::const_iterator itOut;
483 for (itOut = res.constBegin(); itOut != res.constEnd(); ++itOut)
485 nClusters = itOut->ctrs.rows();
486 nSens = itOut->ctrs.cols()/3;
487 t_MT_partial = MatrixXd::Zero(nSens, nClusters*3);
492 for(qint32 j = 0; j < nSens; ++j)
493 for(qint32 k = 0; k < nClusters; ++k)
494 t_MT_partial.block(j, k*3, 1, 3) = itOut->ctrs.block(k,j*3,1,3);
499 for(qint32 j = 0; j < nClusters; ++j)
501 VectorXi clusterIdcs = VectorXi::Zero(itOut->roiIdx.rows());
502 VectorXd clusterDistance = VectorXd::Zero(itOut->roiIdx.rows());
503 qint32 nClusterIdcs = 0;
504 for(qint32 k = 0; k < itOut->roiIdx.rows(); ++k)
506 if(itOut->roiIdx[k] == j)
508 clusterIdcs[nClusterIdcs] = itIn->idcs[k];
509 clusterDistance[nClusterIdcs] = itOut->D(k,j);
513 clusterIdcs.conservativeResize(nClusterIdcs);
514 clusterDistance.conservativeResize(nClusterIdcs);
516 VectorXi clusterVertnos = VectorXi::Zero(clusterIdcs.size());
517 for(qint32 k = 0; k < clusterVertnos.size(); ++k)
518 clusterVertnos(k) = this->
src[h].vertno[clusterIdcs(k)];
520 t_qListMNEClusterInfo[h].clusterVertnos.append(clusterVertnos);
527 if(t_MT_partial.rows() > 0 && t_MT_partial.cols() > 0)
529 t_MT_new.conservativeResize(t_MT_partial.rows(), t_MT_new.cols() + t_MT_partial.cols());
530 t_MT_new.block(0, t_MT_new.cols() - t_MT_partial.cols(), t_MT_new.rows(), t_MT_partial.cols()) = t_MT_partial;
533 for(qint32 k = 0; k < nClusters; ++k)
537 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());
538 double sqec_min = sqec;
540 for(qint32 j = 1; j < itIn->idcs.rows(); ++j)
542 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());
565 qint32 totalNumOfClust = 0;
566 for (qint32 h = 0; h < 2; ++h)
567 totalNumOfClust += t_qListMNEClusterInfo[h].clusterVertnos.size();
570 p_D = MatrixXd::Zero(p_outMT.cols(), totalNumOfClust);
572 p_D = MatrixXd::Zero(p_outMT.cols(), totalNumOfClust*3);
574 QList<VectorXi> t_vertnos =
src.get_vertno();
576 qint32 currentCluster = 0;
577 for (qint32 h = 0; h < 2; ++h)
579 int hemiOffset = h == 0 ? 0 : t_vertnos[0].size();
580 for(qint32 i = 0; i < t_qListMNEClusterInfo[h].clusterVertnos.size(); ++i)
583 Linalg::intersect(t_vertnos[h], t_qListMNEClusterInfo[h].clusterVertnos[i], idx_sel);
585 idx_sel.array() += hemiOffset;
587 double selectWeight = 1.0/idx_sel.size();
590 for(qint32 j = 0; j < idx_sel.size(); ++j)
591 p_D.col(currentCluster)[idx_sel(j)] = selectWeight;
595 qint32 clustOffset = currentCluster*3;
596 for(qint32 j = 0; j < idx_sel.size(); ++j)
598 qint32 idx_sel_Offset = idx_sel(j)*3;
600 p_D(idx_sel_Offset,clustOffset) = selectWeight;
602 p_D(idx_sel_Offset+1, clustOffset+1) = selectWeight;
604 p_D(idx_sel_Offset+2, clustOffset+2) = selectWeight;
627 bool limit_depth_chs)
637 qWarning(
"Warning: Forward solution is not surface-oriented. A surface-oriented solution is recommended for fixed-orientation inverse operators.");
641 if(fixed && loose > 0)
643 qWarning(
"Warning: When invoking make_inverse_operator with fixed = true, the loose parameter is ignored.\n");
647 if(is_fixed_ori && !fixed)
649 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");
655 qCritical(
"Forward solution is not oriented in surface coordinates. loose parameter should be 0 not %f.", loose);
659 if(loose < 0 || loose > 1)
661 qWarning(
"Warning: Loose value should be in interval [0,1] not %f.\n", loose);
662 loose = loose > 1 ? 1 : 0;
663 qInfo(
"Setting loose to %f.\n", loose);
666 if(depth < 0 || depth > 1)
668 qWarning(
"Warning: Depth value should be in interval [0,1] not %f.\n", depth);
669 depth = depth > 1 ? 1 : 0;
670 qInfo(
"Setting depth to %f.\n", depth);
690 MatrixXd patch_areas;
698 p_depth_prior->data = MatrixXd::Ones(gain.cols(), gain.cols());
700 p_depth_prior->diag =
true;
701 p_depth_prior->dim = gain.cols();
702 p_depth_prior->nfree = 1;
708 if(depth < 0 || depth > 1)
711 qInfo(
"\tPicking elements from free-orientation depth prior into fixed-orientation one.\n");
717 qWarning(
"Warning: For a fixed-orientation inverse, the forward solution must be surface-oriented. Skipping fixed conversion.\n");
723 for(qint32 i = 2; i < p_depth_prior->data.rows(); i+=3)
725 p_depth_prior->data.row(count) = p_depth_prior->data.row(i);
728 p_depth_prior->data.conservativeResize(count, 1);
736 qInfo(
"\tComputing inverse operator with %lld channels.\n", gain_info.
ch_names.size());
741 qInfo(
"\tCreating the source covariance matrix\n");
749 p_source_cov->data.array() *= p_orient_prior->data.array();
758 qInfo(
"\tWhitening the forward solution.\n");
769 qInfo(
"\tAdjusting source covariance matrix.\n");
770 RowVectorXd source_std = p_source_cov->data.array().sqrt().transpose();
772 for(qint32 i = 0; i < gain.rows(); ++i)
773 gain.row(i) = gain.row(i).array() * source_std.array();
775 double trace_GRGT = (gain * gain.transpose()).trace();
776 double scaling_source_cov =
static_cast<double>(n_nzero) / trace_GRGT;
778 p_source_cov->data.array() *= scaling_source_cov;
780 gain.array() *= sqrt(scaling_source_cov);
785 qInfo(
"Computing SVD of whitened and weighted lead field matrix.\n");
786 JacobiSVD<MatrixXd>
svd(gain, ComputeThinU | ComputeThinV);
788 VectorXd p_sing =
svd.singularValues();
789 MatrixXd t_U =
svd.matrixU();
792 svd.matrixU().rows(),
797 p_sing =
svd.singularValues();
798 MatrixXd t_V =
svd.matrixV();
801 svd.matrixV().cols(),
805 qInfo(
"\tlargest singular value = %f\n", p_sing.maxCoeff());
806 qInfo(
"\tscaling factor to adjust the trace = %f\n", trace_GRGT);
811 bool has_meg =
false;
812 bool has_eeg =
false;
814 RowVectorXd ch_idx(
info.chs.size());
816 for(qint32 i = 0; i <
info.chs.size(); ++i)
824 ch_idx.conservativeResize(count);
826 for(qint32 i = 0; i < ch_idx.size(); ++i)
828 QString ch_type =
info.channel_type(ch_idx[i]);
829 if (ch_type ==
"eeg")
831 if ((ch_type ==
"mag") || (ch_type ==
"grad"))
837 if(has_eeg && has_meg)
851 inv.
nchan = p_sing.rows();
880 qCritical(
"The number of averages should be positive\n");
883 qInfo(
"Preparing the inverse operator for use...\n");
888 float scale =
static_cast<float>(inv.
nave)/
static_cast<float>(
nave);
896 qInfo(
"\tScaled noise and source covariance from nave = %d to nave = %d\n",inv.
nave,
nave);
901 VectorXd tmp = inv.
sing.cwiseProduct(inv.
sing) + VectorXd::Constant(inv.
sing.size(), lambda2);
902 inv.
reginv = VectorXd(inv.
sing.cwiseQuotient(tmp));
903 qInfo(
"\tCreated the regularized inverter\n");
910 qInfo(
"\tCreated an SSP operator (subspace dimension = %d)\n",ncomp);
925 for (k = ncomp; k < inv.
noise_cov->dim; ++k)
937 qInfo(
"\tCreated the whitener using a full noise covariance matrix (%d small eigenvalues omitted)\n", inv.
noise_cov->dim - nnzero);
947 qInfo(
"\tCreated the whitener using a diagonal noise covariance matrix (%d small eigenvalues discarded)\n",ncomp);
954 VectorXd noise_norm = VectorXd::Zero(inv.
eigen_leads->nrow);
955 VectorXd noise_weight;
958 qInfo(
"\tComputing noise-normalization factors (dSPM)...");
959 noise_weight = VectorXd(inv.
reginv);
963 qInfo(
"\tComputing noise-normalization factors (sLORETA)...");
964 VectorXd tmp = (VectorXd::Constant(inv.
sing.size(), 1) + inv.
sing.cwiseProduct(inv.
sing)/lambda2);
965 noise_weight = inv.
reginv.cwiseProduct(tmp.cwiseSqrt());
973 noise_norm[k] = sqrt(one.dot(one));
982 one = c*(inv.
eigen_leads->data.row(k).transpose()).cwiseProduct(noise_weight);
983 noise_norm[k] = sqrt(one.dot(one));
990 VectorXd noise_norm_new;
996 noise_norm_new = t.cwiseSqrt();
998 VectorXd vOnes = VectorXd::Ones(noise_norm_new.size());
999 VectorXd tmp = vOnes.cwiseQuotient(noise_norm_new.cwiseAbs());
1001 typedef Eigen::Triplet<double> T;
1002 std::vector<T> tripletList;
1003 tripletList.reserve(noise_norm_new.size());
1004 for(qint32 i = 0; i < noise_norm_new.size(); ++i)
1005 tripletList.push_back(T(i, i, tmp[i]));
1007 inv.
noisenorm = SparseMatrix<double>(noise_norm_new.size(),noise_norm_new.size());
1008 inv.
noisenorm.setFromTriplets(tripletList.begin(), tripletList.end());
1028 qInfo(
"Reading inverse operator decomposition from %s...\n",t_pStream->streamName().toUtf8().constData());
1030 if(!t_pStream->open())
1036 if ( invs_list.size()== 0)
1038 qCritical(
"No inverse solutions in %s\n", t_pStream->streamName().toUtf8().constData());
1046 if (parent_mri.size() == 0)
1048 qCritical(
"No parent MRI information in %s", t_pStream->streamName().toUtf8().constData());
1051 qInfo(
"\tReading inverse operator info...");
1058 qCritical(
"Modalities not found\n");
1063 inv.
methods = *t_pTag->toInt();
1067 qCritical(
"Source orientation constraints not found\n");
1074 qCritical(
"Number of sources not found\n");
1077 inv.
nsource = *t_pTag->toInt();
1084 qCritical(
"Coordinate frame tag not found\n");
1093 qCritical(
"Source orientation information not found\n");
1097 inv.
source_nn = t_pTag->toFloatMatrix();
1104 qInfo(
"\tReading inverse operator decomposition...");
1107 qCritical(
"Singular values not found\n");
1111 inv.
sing = Map<const VectorXf>(t_pTag->toFloat(), t_pTag->size()/4).cast<
double>();
1122 qCritical(
"Error reading eigenleads named matrix.\n");
1133 qCritical(
"Error reading eigenfields named matrix.\n");
1142 qInfo(
"\tNoise covariance matrix read.\n");
1146 qCritical(
"\tError: Not able to read noise covariance matrix.\n");
1152 qInfo(
"\tSource covariance matrix read.\n");
1156 qCritical(
"\tError: Not able to read source covariance matrix.\n");
1164 qInfo(
"\tOrientation priors read.\n");
1171 qInfo(
"\tDepth priors read.\n");
1179 qInfo(
"\tfMRI priors read.\n");
1190 qCritical(
"\tError: Could not read the source spaces.\n");
1193 for (qint32 k = 0; k < inv.
src.
size(); ++k)
1201 qCritical(
"MRI/head coordinate transformation not found\n");
1212 qCritical(
"MRI/head coordinate transformation not found");
1222 t_pStream->read_meas_info_base(t_pStream->dirtree(), inv.
info);
1229 qCritical(
"Only inverse solutions computed in MRI or head coordinates are acceptable");
1237 inv.
projs = t_pStream->read_proj(t_pStream->dirtree());
1243 qCritical(
"Could not transform source space.\n");
1245 qInfo(
"\tSource spaces transformed to the inverse solution coordinate frame\n");
1263 qInfo(
"Write inverse operator decomposition in %s...", t_pStream->streamName().toUtf8().constData());
1265 t_pStream->end_file();
1274 qInfo(
"\tWriting inverse operator info...\n");
1281 VectorXf tmp_sing = this->
sing.cast<
float>();
1301 qInfo(
"\t[done]\n");
1305 qInfo(
"\tWriting noise covariance matrix.");
1308 qInfo(
"\tWriting source covariance matrix.\n");
1313 qInfo(
"\tWriting orientation priors.\n");
1338 this->
src.writeToStream(p_pStream);
Reader and in-memory representation of a FreeSurfer/MNE surface label (.label).
Pre-computed inverse operator (whitened SVD of the forward model) for MNE/dSPM/sLORETA.
Eigen::JacobiSVD< Eigen::Matrix3f > svd(S, Eigen::ComputeFullU|Eigen::ComputeFullV)
#define FIFF_MNE_INVERSE_FIELDS
#define FIFF_MNE_INVERSE_LEADS
#define FIFF_MNE_INVERSE_SOURCE_ORIENTATIONS
#define FIFF_MNE_COORD_FRAME
#define FIFF_MNE_SOURCE_ORIENTATION
#define FIFFV_MNE_NOISE_COV
#define FIFFV_MNE_FMRI_PRIOR_COV
#define FIFF_MNE_INVERSE_LEADS_WEIGHTED
#define FIFF_MNE_INCLUDED_METHODS
#define FIFFB_MNE_INVERSE_SOLUTION
#define FIFF_MNE_SOURCE_SPACE_NPOINTS
#define FIFF_MNE_INVERSE_SING
#define FIFFV_MNE_MEG_EEG
#define FIFFV_MNE_SOURCE_COV
#define FIFFV_MNE_ORIENT_PRIOR_COV
#define FIFFB_MNE_PARENT_MRI_FILE
#define FIFFV_MNE_DEPTH_PRIOR_COV
#define FIFFV_MNE_FREE_ORI
Static linear-algebra helpers: SVD-based conditioning, block-diagonal assembly, sorted index pairs.
Core MNE data structures (source spaces, source estimates, hemispheres).
FreeSurfer surface, annotation and parcellation I/O for mne-cpp.
FIFF file I/O, in-memory data structures and high-level readers/writers.
Shared utilities (I/O helpers, spectral analysis, layout management, warp algorithms).
Labelled 4x4 FIFF affine: source frame, destination frame, rotation, translation and cached inverse.
FIFF noise / data covariance: matrix, channel names, kind, applied projectors, bads,...
QSharedDataPointer< FiffCov > SDPtr
QSharedPointer< FiffDirNode > SPtr
Full FIFF measurement info: per-channel descriptors, sampling and filter setup, projectors,...
FIFF named matrix: dense / sparse Eigen matrix plus row-name and column-name string lists.
QSharedDataPointer< FiffNamedMatrix > SDPtr
void transpose_named_matrix()
static fiff_int_t make_projector(const QList< FiffProj > &projs, const QStringList &ch_names, Eigen::MatrixXd &proj, const QStringList &bads=defaultQStringList, Eigen::MatrixXd &U=defaultMatrixXd)
FIFF tag-stream reader/writer: wraps a QIODevice and exposes typed read_* / write_* methods for every...
fiff_long_t write_cov(const FiffCov &p_FiffCov)
fiff_long_t start_block(fiff_int_t kind)
fiff_long_t write_float_matrix(fiff_int_t kind, const Eigen::MatrixXf &mat)
fiff_long_t write_proj(const QList< FiffProj > &projs)
QSharedPointer< FiffStream > SPtr
fiff_long_t write_int(fiff_int_t kind, const fiff_int_t *data, fiff_int_t nel=1, fiff_int_t next=FIFFV_NEXT_SEQ)
fiff_long_t write_float(fiff_int_t kind, const float *data, fiff_int_t nel=1)
fiff_long_t write_coord_trans(const FiffCoordTrans &trans)
fiff_long_t write_named_matrix(fiff_int_t kind, const FiffNamedMatrix &mat)
static FiffStream::SPtr start_file(QIODevice &p_IODevice)
fiff_long_t write_info_base(const FiffInfoBase &p_FiffInfoBase)
fiff_long_t end_block(fiff_int_t kind, fiff_int_t next=FIFFV_NEXT_SEQ)
std::unique_ptr< FiffTag > UPtr
Container holding the lh and/or rh FsAnnotation for one parcellation atlas.
FreeSurfer colour lookup table: region name + RGBA + packed label, indexed by entry.
Eigen::VectorXi getLabelIds() const
A FreeSurfer/MNE surface label: per-vertex indices, Tk-RAS positions and scalar values for one hemisp...
static Eigen::VectorXd combine_xyz(const Eigen::VectorXd &vec)
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)
Cluster table used to compress and reconstruct a clustered leadfield.
In-memory representation of an -fwd.fif forward solution.
FIFFLIB::fiff_int_t nsource
FIFFLIB::FiffInfoBase info
static FIFFLIB::FiffCov compute_depth_prior(const Eigen::MatrixXd &Gain, const FIFFLIB::FiffInfo &gain_info, bool is_fixed_ori, double exp=0.8, double limit=10.0, const Eigen::MatrixXd &patch_areas=FIFFLIB::defaultConstMatrixXd, bool limit_depth_chs=false)
MNELIB::MNESourceSpaces src
FIFFLIB::fiff_int_t source_ori
void prepare_forward(const FIFFLIB::FiffInfo &p_info, const FIFFLIB::FiffCov &p_noise_cov, bool p_pca, FIFFLIB::FiffInfo &p_outFwdInfo, Eigen::MatrixXd &gain, FIFFLIB::FiffCov &p_outNoiseCov, Eigen::MatrixXd &p_outWhitener, qint32 &p_outNumNonZero) const
FIFFLIB::FiffCoordTrans mri_head_t
bool isFixedOrient() const
Eigen::MatrixX3f source_nn
FIFFLIB::FiffCov compute_orient_prior(float loose=0.2)
FIFFLIB::fiff_int_t coord_frame
Input parameters for multi-threaded KMeans clustering on a single cortical region.
Eigen::MatrixXd matRoiMTOrig
RegionMTOut cluster() const
Run KMeans clustering on this region.
MNEInverseOperator()
Constructs an empty inverse operator with invalid sentinel values.
FIFFLIB::FiffCov::SDPtr fmri_prior
Eigen::MatrixXd cluster_kernel(const FSLIB::FsAnnotationSet &annotationSet, qint32 clusterSize, Eigen::MatrixXd &D, const QString &method=QStringLiteral("cityblock")) const
Cluster the inverse kernel by cortical parcellation.
FIFFLIB::fiff_int_t coord_frame
QList< FIFFLIB::FiffProj > projs
Eigen::SparseMatrix< double > noisenorm
FIFFLIB::FiffCov::SDPtr orient_prior
static MNEInverseOperator make_inverse_operator(const FIFFLIB::FiffInfo &info, MNEForwardSolution forward, const FIFFLIB::FiffCov &noiseCov, float loose=0.2f, float depth=0.8f, bool fixed=false, bool limit_depth_chs=true)
Assemble an inverse operator from a forward solution and noise covariance.
FIFFLIB::fiff_int_t nchan
bool eigen_leads_weighted
FIFFLIB::fiff_int_t methods
FIFFLIB::FiffNamedMatrix::SDPtr eigen_leads
bool check_ch_names(const FIFFLIB::FiffInfo &info) const
Verify that inverse-operator channels are present in the measurement info.
FIFFLIB::FiffCoordTrans mri_head_t
FIFFLIB::fiff_int_t nsource
MNEInverseOperator prepare_inverse_operator(qint32 nave, float lambda2, bool dSPM, bool sLORETA=false) const
Prepare the inverse operator for source estimation.
Eigen::MatrixXf source_nn
FIFFLIB::FiffCov::SDPtr depth_prior
void write(QIODevice &p_IODevice)
Write the inverse operator to a FIFF file.
FIFFLIB::fiff_int_t source_ori
bool assemble_kernel(const FSLIB::FsLabel &label, const QString &method, bool pick_normal, Eigen::MatrixXd &K, Eigen::SparseMatrix< double > &noise_norm, QList< Eigen::VectorXi > &vertno)
Assemble the inverse kernel matrix.
void writeToStream(FIFFLIB::FiffStream *p_pStream)
Write the inverse operator into an already-open FIFF stream.
FIFFLIB::FiffInfoBase info
~MNEInverseOperator()
Destructor.
FIFFLIB::FiffCov::SDPtr noise_cov
FIFFLIB::FiffCov::SDPtr source_cov
static bool read_inverse_operator(QIODevice &p_IODevice, MNEInverseOperator &inv)
Read an inverse operator from a FIFF file.
bool isFixedOrient() const
Check whether the inverse operator uses fixed source orientations.
FIFFLIB::FiffNamedMatrix::SDPtr eigen_fields
bool transform_source_space_to(FIFFLIB::fiff_int_t dest, FIFFLIB::FiffCoordTrans &trans)
static qint32 find_source_space_hemi(MNESourceSpace &p_SourceSpace)
static bool readFromStream(FIFFLIB::FiffStream::SPtr &p_pStream, bool add_geom, MNESourceSpaces &p_SourceSpace)