2#include <fwd/fwd_types.h>
6#include "../c/mne_meas_data.h"
7#include "../c/mne_meas_data_set.h"
21#include <QCoreApplication>
24#define _USE_MATH_DEFINES
28using namespace FIFFLIB;
29using namespace MNELIB;
30using namespace FWDLIB;
31using namespace INVERSELIB;
35#ifndef FIFFV_COIL_CTF_GRAD
36#define FIFFV_COIL_CTF_GRAD 5001
39#ifndef FIFFV_COIL_CTF_REF_MAG
40#define FIFFV_COIL_CTF_REF_MAG 5002
43#ifndef FIFFV_COIL_CTF_REF_GRAD
44#define FIFFV_COIL_CTF_REF_GRAD 5003
47#ifndef FIFFV_COIL_CTF_OFFDIAG_REF_GRAD
48#define FIFFV_COIL_CTF_OFFDIAG_REF_GRAD 5004
71#define MALLOC_3(x,t) (t *)malloc((x)*sizeof(t))
72#define REALLOC_3(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
73#define FREE_3(x) if ((char *)(x) != NULL) free((char *)(x))
78#define ALLOC_FLOAT_3(x) MALLOC_3(x,float)
80#define ALLOC_DCMATRIX_3(x,y) mne_dmatrix_3((x),(y))
81#define ALLOC_CMATRIX_3(x,y) mne_cmatrix_3((x),(y))
82#define FREE_CMATRIX_3(m) mne_free_cmatrix_3((m))
83#define FREE_DCMATRIX_3(m) mne_free_dcmatrix_3((m))
85static void matrix_error_3(
int kind,
int nr,
int nc)
89 printf(
"Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
91 printf(
"Failed to allocate memory for a %d x %d matrix\n",nr,nc);
93 printf(
"Allocation error for a %d x %d matrix\n",nr,nc);
94 if (
sizeof(
void *) == 4) {
95 printf(
"This is probably because you seem to be using a computer with 32-bit architecture.\n");
96 printf(
"Please consider moving to a 64-bit platform.");
98 printf(
"Cannot continue. Sorry.\n");
102float **mne_cmatrix_3 (
int nr,
int nc)
109 m = MALLOC_3(nr,
float *);
110 if (!m) matrix_error_3(1,nr,nc);
111 whole = MALLOC_3(nr*nc,
float);
112 if (!whole) matrix_error_3(2,nr,nc);
119double **mne_dmatrix_3(
int nr,
int nc)
126 m = MALLOC_3(nr,
double *);
127 if (!m) matrix_error_3(1,nr,nc);
128 whole = MALLOC_3(nr*nc,
double);
129 if (!whole) matrix_error_3(2,nr,nc);
136void mne_free_dcmatrix_3 (
double **m)
148#define VEC_DOT_3(x,y) ((x)[X_3]*(y)[X_3] + (x)[Y_3]*(y)[Y_3] + (x)[Z_3]*(y)[Z_3])
149#define VEC_LEN_3(x) sqrt(VEC_DOT_3(x,x))
155#define VEC_DIFF_3(from,to,diff) {\
156 (diff)[X_3] = (to)[X_3] - (from)[X_3];\
157 (diff)[Y_3] = (to)[Y_3] - (from)[Y_3];\
158 (diff)[Z_3] = (to)[Z_3] - (from)[Z_3];\
161#define VEC_COPY_3(to,from) {\
162 (to)[X_3] = (from)[X_3];\
163 (to)[Y_3] = (from)[Y_3];\
164 (to)[Z_3] = (from)[Z_3];\
167#define CROSS_PRODUCT_3(x,y,xy) {\
168 (xy)[X_3] = (x)[Y_3]*(y)[Z_3]-(y)[Y_3]*(x)[Z_3];\
169 (xy)[Y_3] = -((x)[X_3]*(y)[Z_3]-(y)[X_3]*(x)[Z_3]);\
170 (xy)[Z_3] = (x)[X_3]*(y)[Y_3]-(y)[X_3]*(x)[Y_3];\
175#define MIN_3(a,b) ((a) < (b) ? (a) : (b))
177void mne_transpose_square_3(
float **mat,
int n)
185 for (j = 1; j < n; j++)
186 for (
k = 0;
k < j;
k++) {
188 mat[j][
k] = mat[
k][j];
194float mne_dot_vectors_3(
float *v1,
201 float res = sdot(&nn,v1,&one,v2,&one);
207 for (
k = 0;
k < nn;
k++)
208 res = res + v1[
k]*v2[
k];
213void mne_add_scaled_vector_to_3(
float *v1,
float scale,
float *v2,
int nn)
217 float fscale = scale;
219 saxpy(&nn,&fscale,v1,&one,v2,&one);
222 for (
k = 0;
k < nn;
k++)
223 v2[
k] = v2[
k] + scale*v1[
k];
228double **mne_dmatt_dmat_mult2_3 (
double **m1,
double **m2,
int d1,
int d2,
int d3)
233 double **result = ALLOC_DCMATRIX_3(d1,d3);
240 dgemm (transa,transb,&d3,&d1,&d2,
241 &one,m2[0],&d3,m1[0],&d1,&zero,result[0],&d3);
248 for (j = 0; j < d1; j++)
249 for (
k = 0;
k < d3;
k++) {
251 for (p = 0; p < d2; p++)
252 sum = sum + m1[p][j]*m2[p][
k];
259float **mne_mat_mat_mult_3 (
float **m1,
float **m2,
int d1,
int d2,
int d3)
265 float **result = ALLOC_CMATRIX_3(d1,d3);
270 sgemm (transa,transb,&d3,&d1,&d2,
271 &one,m2[0],&d3,m1[0],&d2,&zero,result[0],&d3);
274 float **result = ALLOC_CMATRIX_3(d1,d3);
278 for (j = 0; j < d1; j++)
279 for (
k = 0;
k < d3;
k++) {
281 for (p = 0; p < d2; p++)
282 sum = sum + m1[j][p]*m2[p][
k];
289void mne_mat_vec_mult2_3(
float **m,
float *v,
float *result,
int d1,
int d2)
298 for (j = 0; j < d1; j++)
299 result[j] = mne_dot_vectors_3(m[j],v,d2);
305QString mne_name_list_to_string_3(
const QStringList& list)
310 int nlist = list.size();
312 if (nlist == 0 || list.isEmpty())
315 for (
int k = 0;
k < nlist-1;
k++) {
319 res += list[nlist-1];
323QString mne_channel_names_to_string_3(
const QList<FiffChInfo>& chs,
int nch)
334 for (
k = 0;
k < nch;
k++)
335 names.append(chs[
k].ch_name);
336 res = mne_name_list_to_string_3(names);
341void mne_string_to_name_list_3(
const QString& s, QStringList& listp,
int &nlistp)
348 if (!s.isEmpty() && s.size() > 0) {
353 nlistp = list.size();
380 for (j = 0; j < nrow; j++)
381 for (
k = 0;
k < ncol;
k++) {
382 val = std::fabs(dense[j][
k]);
387 small = maxval * std::fabs(small);
389 small = std::fabs(small);
391 for (j = 0, nz = 0; j < nrow; j++)
392 for (
k = 0;
k < ncol;
k++) {
393 if (std::fabs(dense[j][
k]) > small)
398 printf(
"No nonzero elements found.");
401 if (stor_type == FIFFTS_MC_CCS) {
402 size = nz*(
sizeof(fiff_float_t) +
sizeof(fiff_int_t)) +
403 (ncol+1)*(
sizeof(fiff_int_t));
405 else if (stor_type == FIFFTS_MC_RCS) {
406 size = nz*(
sizeof(fiff_float_t) +
sizeof(fiff_int_t)) +
407 (nrow+1)*(
sizeof(fiff_int_t));
410 printf(
"Unknown sparse matrix storage type: %d",stor_type);
414 sparse->
coding = stor_type;
418 sparse->
data = (
float *)malloc(size);
419 sparse->
inds = (
int *)(sparse->
data+nz);
422 if (stor_type == FIFFTS_MC_RCS) {
423 for (j = 0, nz = 0; j < nrow; j++) {
425 for (
k = 0;
k < ncol;
k++)
426 if (std::fabs(dense[j][
k]) > small) {
427 sparse->
data[nz] = dense[j][
k];
430 sparse->
inds[nz++] =
k;
432 sparse->
ptrs[j] = ptr;
434 sparse->
ptrs[nrow] = nz;
435 for (j = nrow - 1; j >= 0; j--)
436 if (sparse->
ptrs[j] < 0)
437 sparse->
ptrs[j] = sparse->
ptrs[j+1];
439 else if (stor_type == FIFFTS_MC_CCS) {
440 for (
k = 0, nz = 0;
k < ncol;
k++) {
442 for (j = 0; j < nrow; j++)
443 if (std::fabs(dense[j][
k]) > small) {
444 sparse->
data[nz] = dense[j][
k];
447 sparse->
inds[nz++] = j;
449 sparse->
ptrs[
k] = ptr;
451 sparse->
ptrs[ncol] = nz;
452 for (
k = ncol-1;
k >= 0;
k--)
453 if (sparse->
ptrs[
k] < 0)
475 return c->cov_diag != NULL;
478void mne_scale_vector_3 (
double scale,
float *v,
int nn)
482 float fscale = scale;
484 sscal(&nn,&fscale,v,&one);
487 for (
k = 0;
k < nn;
k++)
493Eigen::MatrixXf toFloatEigenMatrix_3(
float **mat,
const int m,
const int n)
495 Eigen::MatrixXf eigen_mat(m,n);
497 for (
int i = 0; i < m; ++i)
498 for (
int j = 0; j < n; ++j)
499 eigen_mat(i,j) = mat[i][j];
504void fromFloatEigenMatrix_3(
const Eigen::MatrixXf& from_mat,
float **& to_mat,
const int m,
const int n)
506 for (
int i = 0; i < m; ++i)
507 for (
int j = 0; j < n; ++j)
508 to_mat[i][j] = from_mat(i,j);
511void fromFloatEigenMatrix_3(
const Eigen::MatrixXf& from_mat,
float **& to_mat)
513 fromFloatEigenMatrix_3(from_mat, to_mat, from_mat.rows(), from_mat.cols());
516void fromFloatEigenVector_3(
const Eigen::VectorXf& from_vec,
float *to_vec,
const int n)
518 for (
int i = 0; i < n; ++i)
519 to_vec[i] = from_vec[i];
522float **mne_lu_invert_3(
float **mat,
int dim)
528 Eigen::MatrixXf eigen_mat = toFloatEigenMatrix_3(mat, dim, dim);
529 Eigen::MatrixXf eigen_mat_inv = eigen_mat.inverse();
530 fromFloatEigenMatrix_3(eigen_mat_inv, mat);
534void mne_free_cmatrix_3 (
float **m)
542int mne_svd_3(
float **mat,
567 int udim = MIN_3(m,n);
569 Eigen::MatrixXf eigen_mat = toFloatEigenMatrix_3(mat, m, n);
572 Eigen::JacobiSVD< Eigen::MatrixXf > svd(eigen_mat ,Eigen::ComputeFullU | Eigen::ComputeFullV);
574 fromFloatEigenVector_3(svd.singularValues(), sing, svd.singularValues().size());
577 fromFloatEigenMatrix_3(svd.matrixU().transpose(), uu, udim, m);
580 fromFloatEigenMatrix_3(svd.matrixV().transpose(), vv, m, n);
596 delete c->cov_sparse;
598 FREE_CMATRIX_3(c->eigen);
600 FREE_3(c->inv_lambda);
614int mne_get_values_from_data_3 (
float time,
634 for (ch = 0; ch < nch; ch++) {
638 if (std::fabs(sfreq*integ) < EPS_3) {
639 s1 = sfreq*(time - tmin);
642 if (n1 < 0 || n1 > nsamp-1) {
643 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
650 if (std::fabs(f1 - 1.0) < 1e-3)
653 if (f1 < 1.0 && n1 > nsamp-2) {
654 printf(
"Sample value out of range %d (0..%d) %.4f",n1,nsamp-1,f1);
659 sum = f1*std::fabs(data[n1][ch]) + (1.0-f1)*std::fabs(data[n1+1][ch]);
661 sum = f1*data[n1][ch] + (1.0-f1)*data[n1+1][ch];
665 sum = std::fabs(data[n1][ch]);
671 s1 = sfreq*(time - 0.5*integ - tmin);
672 s2 = sfreq*(time + 0.5*integ - tmin);
673 n1 = ceil(s1); n2 = floor(s2);
676 if (n1 < 0 || n1 > nsamp-2)
681 sum = 0.5*((f1+f2)*std::fabs(data[n1+1][ch]) + (2.0-f1-f2)*std::fabs(data[n1][ch]));
683 sum = 0.5*((f1+f2)*data[n1+1][ch] + (2.0-f1-f2)*data[n1][ch]);
688 if (n1 < 0 || n1 > nsamp-1) {
689 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
692 if (n2 < 0 || n2 > nsamp-1) {
693 printf(
"Sample value out of range %d (0..%d)",n2,nsamp-1);
696 if (f1 != 0.0 && n1 < 1)
698 if (f2 != 0.0 && n2 > nsamp-2)
704 sum = 0.5 * std::fabs(data[n1][ch]);
705 for (
k = n1+1;
k < n2;
k++)
706 sum = sum + std::fabs(data[
k][ch]);
707 sum = sum + 0.5 * std::fabs(data[n2][ch]);
710 sum = 0.5*data[n1][ch];
711 for (
k = n1+1;
k < n2;
k++)
712 sum = sum + data[
k][ch];
713 sum = sum + 0.5*data[n2][ch];
722 sum = sum + 0.5*f1*(f1*std::fabs(data[n1-1][ch]) + (2.0-f1)*std::fabs(data[n1][ch]));
724 sum = sum + 0.5*f2*(f2*std::fabs(data[n2+1][ch]) + (2.0-f2)*std::fabs(data[n2][ch]));
728 sum = sum + 0.5*f1*(f1*data[n1-1][ch] + (2.0-f1)*data[n1][ch]);
730 sum = sum + 0.5*f2*(f2*data[n2+1][ch] + (2.0-f2)*data[n2][ch]);
732 width = width + f1 + f2;
743int mne_decompose_eigen_3(
double *mat,
754 int np = dim*(dim+1)/2;
755 double *w = MALLOC_3(dim,
double);
756 double *z = MALLOC_3(dim*dim,
double);
757 double *work = MALLOC_3(3*dim,
double);
758 double *dmat = MALLOC_3(np,
double);
759 float *vecp = vectors[0];
768 for(
int i = 0; i < np; ++i)
769 if (std::fabs(mat[i]) > std::fabs(mat[maxi]))
773 scale = 1.0/mat[maxi];
775 for (
k = 0;
k < np;
k++)
776 dmat[
k] = mat[
k]*scale;
780 MatrixXd dmat_tmp = MatrixXd::Zero(dim,dim);
782 for (
int i = 0; i < dim; ++i) {
783 for(
int j = 0; j <= i; ++j) {
784 dmat_tmp(i,j) = dmat[idx];
785 dmat_tmp(j,i) = dmat[idx];
789 SelfAdjointEigenSolver<MatrixXd> es;
790 es.compute(dmat_tmp);
791 for (
int i = 0; i < dim; ++i )
792 w[i] = es.eigenvalues()[i];
795 for (
int j = 0; j < dim; ++j ) {
796 for(
int i = 0; i < dim; ++i ) {
797 z[idx] = es.eigenvectors()(i,j);
805 qDebug() <<
"!!!DEBUG ToDo: dspev(compz,uplo,&dim,dmat,w,z,&dim,work,&info);";
809 printf(
"Eigenvalue decomposition failed (LAPACK info = %d)",info);
812 for (
k = 0;
k < dim;
k++)
813 lambda[
k] = scale*w[
k];
814 for (
k = 0;
k < dim*dim;
k++)
831static int mne_lt_packed_index_3(
int j,
int k)
835 return k + j*(j+1)/2;
837 return j +
k*(
k+1)/2;
849 double *src = c->lambda ? c->lambda : c->cov_diag;
853 qCritical(
"Covariance matrix is not diagonal or not decomposed.");
856 c->inv_lambda = REALLOC_3(c->inv_lambda,c->ncov,
double);
857 for (
k = 0;
k < c->ncov;
k++) {
859 c->inv_lambda[
k] = 0.0;
861 c->inv_lambda[
k] = 1.0/sqrt(src[
k]);
866static int condition_cov_3(
MneCovMatrix* c,
float rank_threshold,
int use_rank)
869 double *scale = NULL;
871 double *lambda = NULL;
872 float **eigen = NULL;
873 double **data1 = NULL;
874 double **data2 = NULL;
875 double magscale,gradscale,eegscale;
876 int nmag,ngrad,neeg,nok;
883 qCritical(
"Channels not classified. Rank cannot be determined.");
886 magscale = gradscale = eegscale = 0.0;
887 nmag = ngrad = neeg = 0;
888 for (
k = 0;
k < c->ncov;
k++) {
889 if (c->ch_class[
k] == MNE_COV_CH_MEG_MAG) {
890 magscale += c->cov[mne_lt_packed_index_3(
k,
k)]; nmag++;
892 else if (c->ch_class[
k] == MNE_COV_CH_MEG_GRAD) {
893 gradscale += c->cov[mne_lt_packed_index_3(
k,
k)]; ngrad++;
895 else if (c->ch_class[
k] == MNE_COV_CH_EEG) {
896 eegscale += c->cov[mne_lt_packed_index_3(
k,
k)]; neeg++;
899 fprintf(stdout,
"%d ",c->ch_class[
k]);
903 fprintf(stdout,
"\n");
906 magscale = magscale > 0.0 ? sqrt(nmag/magscale) : 0.0;
908 gradscale = gradscale > 0.0 ? sqrt(ngrad/gradscale) : 0.0;
910 eegscale = eegscale > 0.0 ? sqrt(neeg/eegscale) : 0.0;
912 fprintf(stdout,
"%d %g\n",nmag,magscale);
913 fprintf(stdout,
"%d %g\n",ngrad,gradscale);
914 fprintf(stdout,
"%d %g\n",neeg,eegscale);
916 scale = MALLOC_3(c->ncov,
double);
917 for (
k = 0;
k < c->ncov;
k++) {
918 if (c->ch_class[
k] == MNE_COV_CH_MEG_MAG)
920 else if (c->ch_class[
k] == MNE_COV_CH_MEG_GRAD)
921 scale[
k] = gradscale;
922 else if (c->ch_class[
k] == MNE_COV_CH_EEG)
927 cov = MALLOC_3(c->ncov*(c->ncov+1)/2.0,
double);
928 lambda = MALLOC_3(c->ncov,
double);
929 eigen = ALLOC_CMATRIX_3(c->ncov,c->ncov);
930 for (j = 0; j < c->ncov; j++)
931 for (
k = 0;
k <= j;
k++)
932 cov[mne_lt_packed_index_3(j,
k)] = c->cov[mne_lt_packed_index_3(j,
k)]*scale[j]*scale[
k];
933 if (mne_decompose_eigen_3(cov,lambda,eigen,c->ncov) == 0) {
935 for (
k = 0;
k < c->ncov;
k++)
936 fprintf(stdout,
"%g ",lambda[
k]/lambda[c->ncov-1]);
937 fprintf(stdout,
"\n");
940 for (
k = c->ncov-1;
k >= 0;
k--) {
941 if (lambda[
k] >= rank_threshold*lambda[c->ncov-1])
946 printf(
"\n\tEstimated covariance matrix rank = %d (%g)\n",nok,lambda[c->ncov-nok]/lambda[c->ncov-1]);
947 if (use_rank > 0 && use_rank < nok) {
949 printf(
"\tUser-selected covariance matrix rank = %d (%g)\n",nok,lambda[c->ncov-nok]/lambda[c->ncov-1]);
954 for (j = 0; j < c->ncov-nok; j++)
956 data1 = ALLOC_DCMATRIX_3(c->ncov,c->ncov);
957 for (j = 0; j < c->ncov; j++) {
959 mne_print_vector(stdout,NULL,eigen[j],c->ncov);
961 for (
k = 0;
k < c->ncov;
k++)
962 data1[j][
k] = sqrt(lambda[j])*eigen[j][
k];
964 data2 = mne_dmatt_dmat_mult2_3(data1,data1,c->ncov,c->ncov,c->ncov);
967 for (j = 0; j < c->ncov; j++)
968 mne_print_dvector(stdout,NULL,data2[j],c->ncov);
974 for (
k = 0;
k < c->ncov;
k++)
976 scale[
k] = 1.0/scale[
k];
977 for (j = 0; j < c->ncov; j++)
978 for (
k = 0;
k <= j;
k++)
979 if (c->cov[mne_lt_packed_index_3(j,
k)] != 0.0)
980 c->cov[mne_lt_packed_index_3(j,
k)] = scale[j]*scale[
k]*data2[j][
k];
986 FREE_CMATRIX_3(eigen);
987 FREE_DCMATRIX_3(data1);
988 FREE_DCMATRIX_3(data2);
992static int check_cov_data(
double *vals,
int nval)
998 for (
k = 0, sum = 0.0;
k < nval;
k++)
1001 qCritical(
"Sum of covariance matrix elements is zero!");
1008 const QList<FiffChInfo>& chs,
1017 if (chs.isEmpty()) {
1018 qCritical(
"Channel information not available in mne_classify_channels_cov");
1021 cov->ch_class = REALLOC_3(cov->ch_class,cov->ncov,
int);
1022 for (
k = 0;
k < cov->ncov;
k++) {
1023 cov->ch_class[
k] = MNE_COV_CH_UNKNOWN;
1024 for (p = 0; p < nchan; p++) {
1025 if (QString::compare(chs[p].ch_name,cov->names[
k]) == 0) {
1027 if (ch.
kind == FIFFV_MEG_CH) {
1028 if (ch.
unit == FIFF_UNIT_T)
1029 cov->ch_class[
k] = MNE_COV_CH_MEG_MAG;
1031 cov->ch_class[
k] = MNE_COV_CH_MEG_GRAD;
1033 else if (ch.
kind == FIFFV_EEG_CH)
1034 cov->ch_class[
k] = MNE_COV_CH_EEG;
1046 FREE_3(cov->ch_class);
1047 cov->ch_class = NULL;
1052static int mne_decompose_eigen_cov_small_3(
MneCovMatrix* c,
float small,
int use_rank)
1058 float rank_threshold = 1e-6;
1066 return mne_add_inv_cov_3(c);
1067 if (c->lambda && c->eigen) {
1068 printf(
"\n\tEigenvalue decomposition had been precomputed.\n");
1070 for (
k = 0;
k < c->ncov;
k++, c->nzero++)
1071 if (c->lambda[
k] > 0)
1075 FREE_3(c->lambda); c->lambda = NULL;
1076 FREE_CMATRIX_3(c->eigen); c->eigen = NULL;
1078 if ((rank = condition_cov_3(c,rank_threshold,use_rank)) < 0)
1081 np = c->ncov*(c->ncov+1)/2;
1082 c->lambda = MALLOC_3(c->ncov,
double);
1083 c->eigen = ALLOC_CMATRIX_3(c->ncov,c->ncov);
1084 if (mne_decompose_eigen_3(c->cov,c->lambda,c->eigen,c->ncov) != 0)
1086 c->nzero = c->ncov - rank;
1087 for (
k = 0;
k < c->nzero;
k++)
1093 float meglike,eeglike;
1097 for (
k = c->nzero;
k < c->ncov;
k++) {
1098 meglike = eeglike = 0.0;
1099 for (p = 0; p < c->ncov; p++) {
1100 if (c->ch_class[p] == MNE_COV_CH_EEG)
1101 eeglike += std::fabs(c->eigen[
k][p]);
1102 else if (c->ch_class[p] == MNE_COV_CH_MEG_MAG || c->ch_class[p] == MNE_COV_CH_MEG_GRAD)
1103 meglike += std::fabs(c->eigen[
k][p]);
1105 if (meglike > eeglike)
1110 printf(
"\t%d MEG and %d EEG-like channels remain in the whitened data\n",nmeg,neeg);
1113 return mne_add_inv_cov_3(c);
1116 FREE_3(c->lambda); c->lambda = NULL;
1117 FREE_CMATRIX_3(c->eigen); c->eigen = NULL;
1125 return mne_decompose_eigen_cov_small_3(c,-1.0,-1);
1130int mne_whiten_data(
float **data,
float **whitened_data,
int np,
int nchan,
MneCovMatrix* C)
1136 float *one = NULL,*orig,*white;
1139 if (data == NULL || np <= 0)
1142 if (C->ncov != nchan) {
1143 printf(
"Incompatible covariance matrix. Cannot whiten the data.");
1146 inv = C->inv_lambda;
1147 if (mne_is_diag_cov_3(C)) {
1149 for (j = 0; j < np; j++) {
1151 white = whitened_data[j];
1152 for (
k = 0;
k < nchan;
k++)
1153 white[
k] = orig[
k]*inv[
k];
1160 one = MALLOC_3(nchan,
float);
1161 for (j = 0; j < np; j++) {
1163 white = whitened_data[j];
1164 for (
k = C->nzero;
k < nchan;
k++)
1165 one[
k] = mne_dot_vectors_3(C->eigen[
k],orig,nchan);
1166 for (
k = 0;
k < C->nzero;
k++)
1168 for (
k = C->nzero;
k < nchan;
k++)
1169 white[
k] = one[
k]*inv[
k];
1176int mne_whiten_one_data(
float *data,
float *whitened_data,
int nchan,
MneCovMatrix* C)
1180 float *whitened_datap[1];
1183 whitened_datap[0] = whitened_data;
1185 return mne_whiten_data(datap,whitened_datap,1,nchan,C);
1196 if (f->meg_client_free && f->meg_client)
1197 f->meg_client_free(f->meg_client);
1198 if (f->eeg_client_free && f->eeg_client)
1199 f->eeg_client_free(f->eeg_client);
1267 float sums[3],nn[3];
1270 if (!c->cov || !c->ch_class)
1273 for (j = 0; j < nkind; j++) {
1280 for (j = 0; j < c->ncov; j++) {
1281 if (c->ch_class[j] >= 0) {
1282 sums[c->ch_class[j]] += c->cov[mne_lt_packed_index_3(j,j)];
1283 nn[c->ch_class[j]]++;
1286 printf(
"Average noise-covariance matrix diagonals:\n");
1287 for (j = 0; j < nkind; j++) {
1289 sums[j] = sums[j]/nn[j];
1290 if (j == MNE_COV_CH_MEG_MAG)
1291 printf(
"\tMagnetometers : %-7.2f fT reg = %-6.2f\n",1e15*sqrt(sums[j]),regs[j]);
1292 else if (j == MNE_COV_CH_MEG_GRAD)
1293 printf(
"\tPlanar gradiometers : %-7.2f fT/cm reg = %-6.2f\n",1e13*sqrt(sums[j]),regs[j]);
1295 printf(
"\tEEG : %-7.2f uV reg = %-6.2f\n",1e6*sqrt(sums[j]),regs[j]);
1296 sums[j] = regs[j]*sums[j];
1302 for (j = 0; j < c->ncov; j++)
1303 if (c->ch_class[j] >= 0)
1304 c->cov[mne_lt_packed_index_3(j,j)] += sums[c->ch_class[j]];
1306 printf(
"Noise-covariance regularized as requested.\n");
1317 f->meg_field = NULL;
1319 f->meg_vec_field = NULL;
1320 f->eeg_vec_pot = NULL;
1321 f->meg_client = NULL;
1322 f->meg_client_free = NULL;
1323 f->eeg_client = NULL;
1324 f->eeg_client_free = NULL;
1339static float tryit (
float **p,
1343 float (*func)(
float *x,
int npar,
void *user_data),
1351 float fac1,fac2,ytry,*ptry;
1353 ptry = ALLOC_FLOAT_3(ndim);
1354 fac1 = (1.0-fac)/ndim;
1356 for (j = 0; j < ndim; j++)
1357 ptry[j] = psum[j]*fac1-p[ihi][j]*fac2;
1358 ytry = (*func)(ptry,ndim,user_data);
1360 if (ytry < y[ihi]) {
1362 for (j = 0; j < ndim; j++) {
1363 psum[j] += ptry[j]-p[ihi][j];
1364 p[ihi][j] = ptry[j];
1371int mne_simplex_minimize(
float **p,
1375 float (*func)(
float *x,
int npar,
void *user_data),
1380 int (*report_func)(
int loop,
1381 float *fitpar,
int npar,
1390 int i,j,ilo,ihi,inhi;
1392 float ytry,ysave,sum,rtol,*psum;
1397 psum = ALLOC_FLOAT_3(ndim);
1399 for (j = 0; j < ndim; j++) {
1400 for (i = 0,sum = 0.0; i<mpts; i++)
1404 if (report_func != NULL && report > 0)
1405 (void)report_func (0,p[0],ndim,-1.0);
1407 for (;;count++,loop++) {
1409 ihi = y[1]>y[2] ? (inhi = 2,1) : (inhi = 1,2);
1410 for (i = 0; i < mpts; i++) {
1411 if (y[i] < y[ilo]) ilo = i;
1412 if (y[i] > y[ihi]) {
1415 }
else if (y[i] > y[inhi])
1416 if (i != ihi) inhi = i;
1418 rtol = 2.0*std::fabs(y[ihi]-y[ilo])/(std::fabs(y[ihi])+std::fabs(y[ilo]));
1422 if (count == report && report_func != NULL) {
1423 if (report_func (loop,p[ilo],ndim,y[ilo])) {
1424 qWarning(
"Interation interrupted.");
1430 if (rtol < ftol)
break;
1431 if (*neval >= max_eval) {
1432 qWarning(
"Maximum number of evaluations exceeded.");
1436 ytry = tryit(p,y,psum,ndim,func,user_data,ihi,neval,-ALPHA);
1438 ytry = tryit(p,y,psum,ndim,func,user_data,ihi,neval,GAMMA);
1439 else if (ytry >= y[inhi]) {
1441 ytry = tryit(p,y,psum,ndim,func,user_data,ihi,neval,BETA);
1442 if (ytry >= ysave) {
1443 for (i = 0; i < mpts; i++) {
1445 for (j = 0; j < ndim; j++) {
1446 psum[j] = 0.5*(p[i][j]+p[ilo][j]);
1449 y[i] = (*func)(psum,ndim,user_data);
1453 for (j = 0; j < ndim; j++) {
1454 for (i = 0,sum = 0.0; i < mpts; i++)
1482static int report_func(
int loop,
1493 printf(
"loop %d r0 %7.1f %7.1f %7.1f fval %g\n",
1494 loop,1000*r0[0],1000*r0[1],1000*r0[2],fval);
1499static float fit_sphere_eval(
float *fitpar,
1511 float sum,sum2,one,F;
1514 for (
k = 0, sum = sum2 = 0.0;
k < user->np;
k++) {
1515 VEC_DIFF_3(r0,user->rr[
k],diff);
1516 one = VEC_LEN_3(diff);
1520 F = sum2 - sum*sum/user->np;
1523 printf(
"r0 %7.1f %7.1f %7.1f R %7.1f fval %g\n",
1524 1000*r0[0],1000*r0[1],1000*r0[2],1000*sum/user->np,F);
1532 float sum, diff[3], one;
1535 for (
k = 0, sum = 0.0;
k < user->np;
k++) {
1536 VEC_DIFF_3(r0,user->rr[
k],diff);
1537 one = VEC_LEN_3(diff);
1540 return sum/user->np;
1543static void calculate_cm_ave_dist(
float **rr,
int np,
float *cm,
float *avep)
1549 for (q = 0; q < 3; q++)
1552 for (
k = 0;
k < np;
k++)
1553 for (q = 0; q < 3; q++)
1557 for (q = 0; q < 3; q++)
1560 for (
k = 0, ave = 0.0;
k < np;
k++) {
1561 for (q = 0; q < 3; q++)
1562 diff[q] = rr[
k][q] - cm[q];
1563 ave += VEC_LEN_3(diff);
1570static float **make_initial_simplex(
float *pars,
1577 float **simplex = ALLOC_CMATRIX_3(npar+1,npar);
1580 for (
k = 0;
k < npar+1;
k++)
1581 memcpy (simplex[
k],pars,npar*
sizeof(
float));
1583 for (
k = 1;
k < npar+1;
k++)
1584 simplex[
k][
k-1] = simplex[
k][
k-1] + size;
1588int fit_sphere_to_points(
float **rr,
1600 int report_interval = -1;
1602 float **init_simplex = NULL;
1603 float *init_vals = NULL;
1613 calculate_cm_ave_dist(rr,np,cm,&R0);
1616 printf(
"cm %7.1f %7.1f %7.1f R %7.1f\n",
1617 1000*cm[0],1000*cm[1],1000*cm[2],1000*R0);
1620 init_simplex = make_initial_simplex(cm,3,simplex_size);
1622 init_vals = MALLOC_3(4,
float);
1627 user.report = FALSE;
1630 for (
k = 0;
k < 4;
k++)
1631 init_vals[
k] = fit_sphere_eval(init_simplex[
k],3,&user);
1633 if (mne_simplex_minimize(init_simplex,
1645 r0[X_3] = init_simplex[0][X_3];
1646 r0[Y_3] = init_simplex[0][Y_3];
1647 r0[Z_3] = init_simplex[0][Z_3];
1648 *R = opt_rad(r0,&user);
1655 FREE_CMATRIX_3(init_simplex);
1662void mne_proj_op_report_data_3(FILE *out,
const char *tag,
MneProjOp* op,
int list_data,
1663 char **exclude,
int nexclude)
1677 if (op->nitems <= 0) {
1678 fprintf(out,
"Empty operator\n");
1682 for (
k = 0;
k < op->nitems;
k++) {
1684 if (list_data && tag)
1685 fprintf(out,
"%s\n",tag);
1687 fprintf(out,
"%s",tag);
1688 fprintf(out,
"# %d : %s : %d vecs : %d chs %s %s\n",
1691 it->active ?
"active" :
"idle");
1692 if (list_data && tag)
1693 fprintf(out,
"%s\n",tag);
1695 vecs = op->items[
k]->vecs;
1697 for (q = 0; q < vecs->ncol; q++) {
1698 fprintf(out,
"%-10s",vecs->collist[q].toUtf8().constData());
1699 fprintf(out,q < vecs->ncol-1 ?
" " :
"\n");
1701 for (p = 0; p < vecs->nrow; p++)
1702 for (q = 0; q < vecs->ncol; q++) {
1703 for (j = 0, found = 0; j < nexclude; j++) {
1704 if (QString::compare(exclude[j],vecs->collist[q]) == 0) {
1709 fprintf(out,
"%10.5g ",found ? 0.0 : vecs->data[p][q]);
1710 fprintf(out,q < vecs->ncol-1 ?
" " :
"\n");
1712 if (list_data && tag)
1713 fprintf(out,
"%s\n",tag);
1719void mne_proj_op_report_3(FILE *out,
const char *tag,
MneProjOp* op)
1721 mne_proj_op_report_data_3(out,tag,op, FALSE, NULL, 0);
1726int mne_pick_from_named_vector_3(
mneNamedVector vec,
const QStringList& names,
int nnames,
int require_all,
float *res)
1734 if (vec->names.size() == 0) {
1735 qCritical(
"No names present in vector. Cannot pick.");
1739 for (
k = 0;
k < nnames;
k++)
1742 for (
k = 0;
k < nnames;
k++) {
1744 for (p = 0; p < vec->nvec; p++) {
1745 if (QString::compare(vec->names[p],names[
k]) == 0) {
1746 res[
k] = vec->data[p];
1751 if (!found && require_all) {
1752 qCritical(
"All required elements not found in named vector.");
1769 QList<FiffDirNode::SPtr> proj;
1771 QList<FiffDirNode::SPtr> items;
1774 QString item_desc, desc_tag;
1775 int global_nchan,item_nchan,nlist;
1776 QStringList item_names;
1778 float **item_vectors = NULL;
1783 QStringList emptyList;
1787 qCritical(
"File not open mne_read_proj_op_from_node");
1791 if (!start || start->isEmpty())
1792 start_node = stream->dirtree();
1797 proj = start_node->dir_tree_find(FIFFB_PROJ);
1798 if (proj.size() == 0 || proj[0]->isEmpty())
1803 items = proj[0]->dir_tree_find(FIFFB_PROJ_ITEM);
1804 if (items.size() == 0 || items[0]->isEmpty())
1810 if(!node->find_tag(stream,
FIFF_NCHAN, t_pTag))
1813 global_nchan = *t_pTag->toInt();
1819 for (
k = 0;
k < items.size();
k++) {
1826 if (node->find_tag(stream,
FIFF_NAME, t_pTag)) {
1827 item_desc += t_pTag->toString();
1834 desc_tag = t_pTag->toString();
1835 if((pos = desc_tag.indexOf(
"\n")) >= 0)
1836 desc_tag.truncate(pos);
1837 if (!item_desc.isEmpty())
1839 item_desc += desc_tag;
1844 if (!node->find_tag(stream,
FIFF_NCHAN, t_pTag)) {
1845 item_nchan = global_nchan;
1848 item_nchan = *t_pTag->toInt();
1850 if (item_nchan <= 0) {
1851 qCritical(
"Number of channels incorrectly specified for one of the projection items.");
1857 if (!node->find_tag(stream, FIFF_PROJ_ITEM_CH_NAME_LIST, t_pTag))
1860 mne_string_to_name_list_3(t_pTag->toString(),item_names,nlist);
1861 if (nlist != item_nchan) {
1862 printf(
"Channel name list incorrectly specified for proj item # %d",
k+1);
1869 if (!node->find_tag(stream, FIFF_PROJ_ITEM_KIND, t_pTag))
1871 item_kind = *t_pTag->toInt();
1875 if (!node->find_tag(stream,FIFF_PROJ_ITEM_NVEC, t_pTag))
1877 item_nvec = *t_pTag->toInt();
1881 if (!node->find_tag(stream,FIFF_PROJ_ITEM_VECTORS, t_pTag))
1884 MatrixXf tmp_item_vectors = t_pTag->toFloatMatrix().transpose();
1885 item_vectors = ALLOC_CMATRIX_3(tmp_item_vectors.rows(),tmp_item_vectors.cols());
1886 fromFloatEigenMatrix_3(tmp_item_vectors, item_vectors);
1892 item_active = *t_pTag->toInt();
1895 item_active = FALSE;
1900 MneProjOp::mne_proj_op_add_item_act(op,item,item_kind,item_desc,item_active);
1902 op->items[op->nitems-1]->active_file = item_active;
1915MneProjOp* mne_read_proj_op_3(
const QString& name)
1927 res = mne_read_proj_op_from_node_3(stream,t_default);
1934int mne_proj_op_chs_3(
MneProjOp* op,
const QStringList& list,
int nlist)
1951static void clear_these(
float *data,
const QStringList& names,
int nnames,
const QString& start)
1955 for (
k = 0;
k < nnames;
k++)
1956 if (names[
k].contains(start))
1960#define USE_LIMIT 1e-5
1961#define SMALL_VALUE 1e-4
1963int mne_proj_op_make_proj_bad(
MneProjOp* op,
char **bad,
int nbad)
1972 float **vv_meg = NULL;
1973 float *sing_meg = NULL;
1974 float **vv_eeg = NULL;
1975 float *sing_eeg = NULL;
1976 float **mat_meg = NULL;
1977 float **mat_eeg = NULL;
1987 FREE_CMATRIX_3(op->proj_data);
1988 op->proj_data = NULL;
1993 if (op->nitems <= 0)
1996 nvec = MneProjOp::mne_proj_op_affect(op,op->names,op->nch);
2000 mat_meg = ALLOC_CMATRIX_3(nvec, op->nch);
2001 mat_eeg = ALLOC_CMATRIX_3(nvec, op->nch);
2004 fprintf(stdout,
"mne_proj_op_make_proj_bad\n");
2006 for (
k = 0, nvec_meg = nvec_eeg = 0;
k < op->nitems;
k++) {
2007 if (op->items[
k]->active && MneProjItem::mne_proj_item_affect(op->items[
k],op->names,op->nch)) {
2008 vec.nvec = op->items[
k]->vecs->ncol;
2009 vec.names = op->items[
k]->vecs->collist;
2010 if (op->items[
k]->has_meg) {
2011 for (p = 0; p < op->items[
k]->nvec; p++, nvec_meg++) {
2012 vec.data = op->items[
k]->vecs->data[p];
2013 if (mne_pick_from_named_vector_3(&vec,op->names,op->nch,FALSE,mat_meg[nvec_meg]) == FAIL)
2016 fprintf(stdout,
"Original MEG:\n");
2017 mne_print_vector(stdout,op->items[
k]->desc,mat_meg[nvec_meg],op->nch);
2022 else if (op->items[
k]->has_eeg) {
2023 for (p = 0; p < op->items[
k]->nvec; p++, nvec_eeg++) {
2024 vec.data = op->items[
k]->vecs->data[p];
2025 if (mne_pick_from_named_vector_3(&vec,op->names,op->nch,FALSE,mat_eeg[nvec_eeg]) == FAIL)
2028 fprintf (stdout,
"Original EEG:\n");
2029 mne_print_vector(stdout,op->items[
k]->desc,mat_eeg[nvec_eeg],op->nch);
2039 for (q = 0; q < nbad; q++)
2040 for (r = 0; r < op->nch; r++)
2041 if (QString::compare(op->names[r],bad[q]) == 0) {
2042 for (p = 0; p < nvec_meg; p++)
2043 mat_meg[p][r] = 0.0;
2044 for (p = 0; p < nvec_eeg; p++)
2045 mat_eeg[p][r] = 0.0;
2050 for (p = 0, nzero = 0; p < nvec_meg; p++) {
2051 size = sqrt(mne_dot_vectors_3(mat_meg[p],mat_meg[p],op->nch));
2053 for (
k = 0;
k < op->nch;
k++)
2054 mat_meg[p][
k] = mat_meg[p][
k]/size;
2059 if (nzero == nvec_meg) {
2060 FREE_CMATRIX_3(mat_meg); mat_meg = NULL; nvec_meg = 0;
2062 for (p = 0, nzero = 0; p < nvec_eeg; p++) {
2063 size = sqrt(mne_dot_vectors_3(mat_eeg[p],mat_eeg[p],op->nch));
2065 for (
k = 0;
k < op->nch;
k++)
2066 mat_eeg[p][
k] = mat_eeg[p][
k]/size;
2071 if (nzero == nvec_eeg) {
2072 FREE_CMATRIX_3(mat_eeg); mat_eeg = NULL; nvec_eeg = 0;
2074 if (nvec_meg + nvec_eeg == 0) {
2075 printf(
"No projection remains after excluding bad channels. Omitting projection.\n");
2082 fprintf(stdout,
"Before SVD:\n");
2086 fprintf(stdout,
"---->>\n");
2087 for (p = 0; p < nvec_meg; p++) {
2088 sprintf(name,
"MEG %02d",p+1);
2089 mne_print_vector(stdout,name,mat_meg[p],op->nch);
2091 fprintf(stdout,
"---->>\n");
2093 sing_meg = MALLOC_3(nvec_meg+1,
float);
2094 vv_meg = ALLOC_CMATRIX_3(nvec_meg,op->nch);
2095 if (mne_svd_3(mat_meg,nvec_meg,op->nch,sing_meg,NULL,vv_meg) != OK)
2100 fprintf(stdout,
"---->>\n");
2101 for (p = 0; p < nvec_eeg; p++) {
2102 sprintf(name,
"EEG %02d",p+1);
2103 mne_print_vector(stdout,name,mat_eeg[p],op->nch);
2105 fprintf(stdout,
"---->>\n");
2107 sing_eeg = MALLOC_3(nvec_eeg+1,
float);
2108 vv_eeg = ALLOC_CMATRIX_3(nvec_eeg,op->nch);
2109 if (mne_svd_3(mat_eeg,nvec_eeg,op->nch,sing_eeg,NULL,vv_eeg) != OK)
2115 for (p = 0, op->nvec = 0; p < nvec_meg; p++, op->nvec++)
2116 if (sing_meg[p]/sing_meg[0] < USE_LIMIT)
2118 for (p = 0; p < nvec_eeg; p++, op->nvec++)
2119 if (sing_eeg[p]/sing_eeg[0] < USE_LIMIT)
2122 printf(
"Number of linearly independent vectors = %d\n",op->nvec);
2124 op->proj_data = ALLOC_CMATRIX_3(op->nvec,op->nch);
2126 fprintf(stdout,
"Final projection data:\n");
2128 for (p = 0, op->nvec = 0; p < nvec_meg; p++, op->nvec++) {
2129 if (sing_meg[p]/sing_meg[0] < USE_LIMIT)
2131 for (
k = 0;
k < op->nch;
k++) {
2135 if (std::fabs(vv_meg[p][
k]) < SMALL_VALUE)
2136 op->proj_data[op->nvec][
k] = 0.0;
2138 op->proj_data[op->nvec][
k] = vv_meg[p][
k];
2143 clear_these(op->proj_data[op->nvec],op->names,op->nch,
"EEG");
2146 sprintf(name,
"MEG %02d",p+1);
2147 mne_print_vector(stdout,name,op->proj_data[op->nvec],op->nch);
2150 for (p = 0; p < nvec_eeg; p++, op->nvec++) {
2151 if (sing_eeg[p]/sing_eeg[0] < USE_LIMIT)
2153 for (
k = 0;
k < op->nch;
k++) {
2157 if (std::fabs(vv_eeg[p][
k]) < SMALL_VALUE)
2158 op->proj_data[op->nvec][
k] = 0.0;
2160 op->proj_data[op->nvec][
k] = vv_eeg[p][
k];
2164 clear_these(op->proj_data[op->nvec],op->names,op->nch,
"MEG");
2167 sprintf(name,
"EEG %02d",p+1);
2168 mne_print_vector(stdout,name,op->proj_data[op->nvec],op->nch);
2173 FREE_CMATRIX_3(vv_meg);
2174 FREE_CMATRIX_3(mat_meg);
2176 FREE_CMATRIX_3(vv_eeg);
2177 FREE_CMATRIX_3(mat_eeg);
2181 for (
k = 0;
k < op->nch;
k++)
2182 if (op->names[
k].contains(
"STI")){
2183 for (p = 0; p < op->nvec; p++)
2184 op->proj_data[p][
k] = 0.0;
2191 FREE_CMATRIX_3(vv_meg);
2192 FREE_CMATRIX_3(mat_meg);
2194 FREE_CMATRIX_3(vv_eeg);
2195 FREE_CMATRIX_3(mat_eeg);
2205 return mne_proj_op_make_proj_bad(op,NULL,0);
2210int mne_read_meg_comp_eeg_ch_info_3(
const QString& name,
2211 QList<FiffChInfo>& megp,
2213 QList<FiffChInfo>& meg_compp,
2215 QList<FiffChInfo>& eegp,
2227 QList<FiffChInfo> chs;
2229 QList<FiffChInfo> meg;
2231 QList<FiffChInfo> meg_comp;
2233 QList<FiffChInfo> eeg;
2236 QList<FiffDirNode::SPtr> nodes;
2241 fiff_int_t kind, pos;
2247 nodes = stream->dirtree()->dir_tree_find(FIFFB_MNE_PARENT_MEAS_FILE);
2249 if (nodes.size() == 0) {
2250 nodes = stream->dirtree()->dir_tree_find(FIFFB_MEAS_INFO);
2251 if (nodes.size() == 0) {
2252 qCritical (
"Could not find the channel information.");
2258 for (
k = 0;
k < info->nent();
k++) {
2259 kind = info->dir[
k]->kind;
2260 pos = info->dir[
k]->pos;
2263 if (!stream->read_tag(t_pTag,pos))
2265 nchan = *t_pTag->toInt();
2267 for (j = 0; j < nchan; j++)
2273 case FIFF_PARENT_BLOCK_ID :
2274 if(!stream->read_tag(t_pTag, pos))
2276 *
id = *(
fiffId)t_pTag->data();
2280 if(!stream->read_tag(t_pTag, pos))
2282 t = FiffCoordTransOld::read_helper( t_pTag );
2283 if (t && (t->
from != FIFFV_COORD_DEVICE || t->
to != FIFFV_COORD_HEAD))
2291 if(!stream->read_tag(t_pTag, pos))
2293 this_ch = t_pTag->toChInfo();
2295 printf (
"FIFF_CH_INFO : scan # out of range %d (%d)!",this_ch.
scanNo,nchan);
2299 chs[this_ch.
scanNo-1] = this_ch;
2305 qCritical(
"Some of the channel information was missing.");
2308 if (t == NULL && meg_head_t != NULL) {
2312 if ((t = FiffCoordTransOld::mne_read_meas_transform(name)) == NULL) {
2313 qCritical(
"MEG -> head coordinate transformation not found.");
2320 for (
k = 0;
k < nchan;
k++) {
2321 if (chs[
k].kind == FIFFV_MEG_CH) {
2325 meg_comp.append(chs[
k]);
2327 }
else if (chs[
k].kind == FIFFV_EEG_CH) {
2340 meg_compp = meg_comp;
2341 *nmeg_compp = nmeg_comp;
2351 if (meg_head_t == NULL) {
2371#if defined(_WIN32) || defined(_WIN64)
2372#define snprintf _snprintf
2373#define vsnprintf _vsnprintf
2374#define strcasecmp _stricmp
2375#define strncasecmp _strnicmp
2378int is_selected_in_data(
mshMegEegData d,
const QString& ch_name)
2386 for (
k = 0;
k < d->meas->nchan;
k++)
2387 if (QString::compare(ch_name,d->meas->chs[
k].ch_name,Qt::CaseInsensitive) == 0) {
2396static int whitespace_3(
char *text)
2399 if (text == NULL || strlen(text) == 0)
2401 if (strspn(text,
" \t\n\r") == strlen(text))
2406static char *next_line_3(
char *line,
int n, FILE *in)
2410 for (res = fgets(line,n,in); res != NULL; res = fgets(line,n,in))
2411 if (!whitespace_3(res))
2419int mne_read_bad_channels_3(
const QString& name, QStringList& listp,
int& nlistp)
2426 char line[MAXLINE+1];
2432 if ((in = fopen(name.toUtf8().data(),
"r")) == NULL) {
2433 qCritical() << name;
2436 while ((next = next_line_3(line,MAXLINE,in)) != NULL) {
2437 if (strlen(next) > 0) {
2438 if (next[strlen(next)-1] ==
'\n')
2439 next[strlen(next)-1] =
'\0';
2447 nlistp = list.size();
2465 QList<FiffDirNode::SPtr> temp;
2471 if (pNode->isEmpty())
2472 node = stream->dirtree();
2476 temp = node->dir_tree_find(FIFFB_MNE_BAD_CHANNELS);
2477 if (temp.size() > 0) {
2480 bad->find_tag(stream, FIFF_MNE_CH_NAME_LIST, t_pTag);
2482 names = t_pTag->toString();
2483 mne_string_to_name_list_3(names,list,nlist);
2487 nlistp = list.size();
2491int mne_read_bad_channel_list_3(
const QString& name, QStringList& listp,
int& nlistp)
2502 res = mne_read_bad_channel_list_from_node_3(stream,stream->dirtree(),listp,nlistp);
2509MneCovMatrix* mne_read_cov(
const QString& name,
int kind)
2518 QList<FiffDirNode::SPtr> nodes;
2524 double *cov_diag = NULL;
2526 double *lambda = NULL;
2527 float **eigen = NULL;
2544 nodes = stream->dirtree()->dir_tree_find(FIFFB_MNE_COV);
2546 if (nodes.size() == 0) {
2547 printf(
"No covariance matrix available in %s",name.toUtf8().data());
2553 for (
k = 0 ;
k < nodes.size(); ++
k) {
2557 if (*t_pTag->toInt() == kind) {
2562 if (covnode->isEmpty()) {
2563 printf(
"Desired covariance matrix not found from %s",name.toUtf8().data());
2571 ncov = *t_pTag->toInt();
2574 nfree = *t_pTag->toInt();
2576 if (covnode->find_tag(stream, FIFF_MNE_ROW_NAMES, t_pTag)) {
2577 mne_string_to_name_list_3(t_pTag->toString(),names,nnames);
2578 if (nnames != ncov) {
2579 qCritical(
"Incorrect number of channel names for a covariance matrix");
2587 if (t_pTag->getType() == FIFFT_DOUBLE) {
2588 cov_diag = MALLOC_3(ncov,
double);
2589 qDebug() <<
"ToDo: Check whether cov_diag contains the right stuff!!! - use VectorXd instead";
2590 d = t_pTag->toDouble();
2591 for (p = 0; p < ncov; p++)
2593 if (check_cov_data(cov_diag,ncov) != OK)
2596 else if (t_pTag->getType() == FIFFT_FLOAT) {
2597 cov_diag = MALLOC_3(ncov,
double);
2598 qDebug() <<
"ToDo: Check whether f contains the right stuff!!! - use VectorXf instead";
2599 f = t_pTag->toFloat();
2600 for (p = 0; p < ncov; p++)
2604 printf(
"Illegal data type for covariance matrix");
2610 nn = ncov*(ncov+1)/2;
2611 if (t_pTag->getType() == FIFFT_DOUBLE) {
2612 qDebug() <<
"ToDo: Check whether cov contains the right stuff!!! - use VectorXd instead";
2614 cov = MALLOC_3(nn,
double);
2615 d = t_pTag->toDouble();
2616 for (p = 0; p < nn; p++)
2618 if (check_cov_data(cov,nn) != OK)
2621 else if (t_pTag->getType() == FIFFT_FLOAT) {
2622 cov = MALLOC_3(nn,
double);
2623 f = t_pTag->toFloat();
2624 for (p = 0; p < nn; p++)
2627 else if ((cov_sparse = FiffSparseMatrix::fiff_get_float_sparse_matrix(t_pTag)) == NULL) {
2632 lambda = (
double *)t_pTag->toDouble();
2633 if (nodes[
k]->find_tag(stream, FIFF_MNE_COV_EIGENVECTORS, t_pTag))
2636 tmp_eigen = t_pTag->toFloatMatrix().transpose();
2637 eigen = ALLOC_CMATRIX_3(tmp_eigen.rows(),tmp_eigen.cols());
2638 fromFloatEigenMatrix_3(tmp_eigen, eigen);
2643 if ((op = mne_read_proj_op_from_node_3(stream,nodes[
k])) == NULL)
2653 if (mne_read_bad_channel_list_from_node_3(stream,nodes[
k],bads,nbad) == FAIL)
2657 res = MneCovMatrix::mne_new_cov_sparse(kind,ncov,names,cov_sparse);
2659 res = MneCovMatrix::mne_new_cov_dense(kind,ncov,names,cov);
2661 res = MneCovMatrix::mne_new_cov_diag(kind,ncov,names,cov_diag);
2663 qCritical(
"mne_read_cov : covariance matrix data is not defined. How come?");
2670 res->lambda = lambda;
2679 for (
k = 0;
k < res->ncov;
k++, res->nzero++)
2680 if (res->lambda[
k] > 0)
2684 if (op && op->nitems > 0) {
2724const char *mne_coord_frame_name_3(
int frame)
2728 {FIFFV_COORD_UNKNOWN,
"unknown"},
2729 {FIFFV_COORD_DEVICE,
"MEG device"},
2730 {FIFFV_COORD_ISOTRAK,
"isotrak"},
2731 {FIFFV_COORD_HPI,
"hpi"},
2732 {FIFFV_COORD_HEAD,
"head"},
2733 {FIFFV_COORD_MRI,
"MRI (surface RAS)"},
2735 {FIFFV_COORD_MRI_SLICE,
"MRI slice"},
2736 {FIFFV_COORD_MRI_DISPLAY,
"MRI display"},
2746 for (
k = 0; frames[
k].frame != -1;
k++) {
2747 if (frame == frames[
k].frame)
2748 return frames[
k].name;
2750 return frames[
k].name;
2755void mne_merge_channels(
const QList<FiffChInfo>& chs1,
2757 const QList<FiffChInfo>& chs2,
2759 QList<FiffChInfo>& resp,
2764 resp.reserve(nch1+nch2);
2767 for (
k = 0;
k < nch1;
k++) {
2768 resp.append(chs1.at(
k));
2770 for (
k = 0;
k < nch2;
k++) {
2771 resp.append(chs2.at(
k));
2788 while (tmp_node->type != FIFFB_MEAS) {
2789 if (tmp_node->parent == NULL)
2791 tmp_node = tmp_node->parent;
2805 while (tmp_node->type != FIFFB_MEAS) {
2806 if (tmp_node->parent == NULL)
2808 tmp_node = tmp_node->parent;
2810 for (
k = 0;
k < tmp_node->nchild();
k++)
2811 if (tmp_node->children[
k]->type == FIFFB_MEAS_INFO)
2812 return (tmp_node->children[
k]);
2816static int get_all_chs (
2820 QList<FiffChInfo>& chp,
2828 QList<FiffChInfo> ch;
2835 fiff_int_t kind, pos;
2842 if (!(meas = find_meas_3(p_node))) {
2843 qCritical(
"Meas. block not found!");
2847 if (!(meas_info = find_meas_info_3(p_node))) {
2848 qCritical (
"Meas. info not found!");
2854 if (!meas->id.isEmpty()) {
2856 (*id)->version = meas->id.version;
2857 (*id)->machid[0] = meas->id.machid[0];
2858 (*id)->machid[1] = meas->id.machid[1];
2859 (*id)->time = meas->id.time;
2864 for (
k = 0;
k < meas_info->nent();
k++) {
2865 kind = meas_info->dir[
k]->kind;
2866 pos = meas_info->dir[
k]->pos;
2869 if (!stream->read_tag(t_pTag,pos))
2871 nchan = *t_pTag->toInt();
2874 for (j = 0; j < nchan; j++) {
2879 to_find += nchan - 1;
2883 if (!stream->read_tag(t_pTag,pos))
2885 this_ch = t_pTag->toChInfo();
2887 qCritical (
"FIFF_CH_INFO : scan # out of range!");
2891 ch[this_ch.
scanNo-1] = this_ch;
2905static int read_ch_info(
const QString& name,
2906 QList<FiffChInfo>& chsp,
2916 QList<FiffChInfo> chs;
2920 QList<FiffDirNode::SPtr> meas;
2926 meas = stream->dirtree()->dir_tree_find(FIFFB_MEAS);
2927 if (meas.size() == 0) {
2928 qCritical (
"%s : no MEG data available here",name.toUtf8().data());
2932 if (get_all_chs(stream,
2936 &nchan) == FIFF_FAIL)
2951#define TOO_CLOSE 1e-4
2953static int at_origin (
const Eigen::Vector3f& rr)
2955 return (rr.norm() < TOO_CLOSE);
2958static int is_valid_eeg_ch(
const FiffChInfo& ch)
2963 if (ch.
kind == FIFFV_EEG_CH) {
2974 const QStringList& bads,
2979 for (
k = 0;
k < nbad;
k++)
2980 if (QString::compare(ch.
ch_name,bads[
k]) == 0)
2985int read_meg_eeg_ch_info(
const QString& name,
2988 const QStringList& bads,
2990 QList<FiffChInfo>& chsp,
2998 QList<FiffChInfo> chs;
3000 QList<FiffChInfo> meg;
3002 QList<FiffChInfo> eeg;
3009 if (read_ch_info(name,
3017 for (
k = 0;
k < nchan;
k++) {
3018 if (accept_ch(chs[
k],bads,nbad)) {
3019 if (do_meg && chs[
k].kind == FIFFV_MEG_CH) {
3022 }
else if (do_eeg && chs[
k].kind == FIFFV_EEG_CH && is_valid_eeg_ch(chs[
k])) {
3029 mne_merge_channels(meg,
3059#define REALLY_REVERT
3061 c->cov_diag = REALLOC_3(c->cov_diag,c->ncov,
double);
3063 for (
k = p = 0;
k < c->ncov;
k++) {
3064 c->cov_diag[
k] = c->cov[p];
3067 FREE_3(c->cov); c->cov = NULL;
3069 for (j = 0, p = 0; j < c->ncov; j++)
3070 for (
k = 0;
k <= j;
k++, p++)
3075 FREE_3(c->lambda); c->lambda = NULL;
3076 FREE_CMATRIX_3(c->eigen); c->eigen = NULL;
3081 const QStringList& new_names,
3084 const QList<FiffChInfo>& chs)
3092 double *cov_diag = NULL;
3099 qCritical(
"No channels specified for picking in mne_pick_chs_cov_omit");
3102 if (c->names.isEmpty()) {
3103 qCritical(
"No names in covariance matrix. Cannot do picking.");
3106 pick = MALLOC_3(ncov,
int);
3107 for (j = 0; j < ncov; j++)
3109 for (j = 0; j < ncov; j++)
3110 for (
k = 0;
k < c->ncov;
k++)
3111 if (QString::compare(c->names[
k],new_names[j]) == 0) {
3115 for (j = 0; j < ncov; j++) {
3117 printf(
"All desired channels not found in the covariance matrix (at least missing %s).", new_names[j].toUtf8().constData());
3123 is_meg = MALLOC_3(ncov,
int);
3124 if (!chs.isEmpty()) {
3125 for (j = 0; j < ncov; j++)
3126 if (chs[j].kind == FIFFV_MEG_CH)
3132 for (j = 0; j < ncov; j++)
3133 if (new_names[j].startsWith(
"MEG"))
3140 cov_diag = MALLOC_3(ncov,
double);
3141 for (j = 0; j < ncov; j++) {
3142 cov_diag[j] = c->cov_diag[pick[j]];
3143 names.append(c->names[pick[j]]);
3147 cov = MALLOC_3(ncov*(ncov+1)/2,
double);
3148 for (j = 0; j < ncov; j++) {
3149 names.append(c->names[pick[j]]);
3150 for (
k = 0;
k <= j;
k++) {
3151 from = mne_lt_packed_index_3(pick[j],pick[
k]);
3152 to = mne_lt_packed_index_3(j,
k);
3153 if (to < 0 || to > ncov*(ncov+1)/2-1) {
3154 printf(
"Wrong destination index in mne_pick_chs_cov : %d %d %d\n",j,
k,to);
3157 if (from < 0 || from > c->ncov*(c->ncov+1)/2-1) {
3158 printf(
"Wrong source index in mne_pick_chs_cov : %d %d %d\n",pick[j],pick[
k],from);
3161 cov[to] = c->cov[from];
3163 if (is_meg[j] != is_meg[
k])
3169 res = MneCovMatrix::mne_new_cov(c->kind,ncov,names,cov,cov_diag);
3171 res->bads = c->bads;
3172 res->nbad = c->nbad;
3173 res->proj = MneProjOp::mne_dup_proj_op(c->proj);
3174 res->sss = c->sss ?
new MneSssData(*(c->sss)) : NULL;
3177 res->ch_class = MALLOC_3(res->ncov,
int);
3178 for (
k = 0;
k < res->ncov;
k++)
3179 res->ch_class[
k] = c->ch_class[pick[
k]];
3186int mne_proj_op_proj_dvector(
MneProjOp* op,
double *vec,
int nch,
int do_complement)
3199 if (op->nch != nch) {
3200 qCritical(
"Data vector size does not match projection operator");
3204 Eigen::VectorXd res = Eigen::VectorXd::Zero(op->nch);
3206 for (p = 0; p < op->nvec; p++) {
3207 pvec = op->proj_data[p];
3209 for (
k = 0;
k < op->nch;
k++)
3210 w += vec[
k]*pvec[
k];
3211 for (
k = 0;
k < op->nch;
k++)
3212 res[
k] = res[
k] + w*pvec[
k];
3215 if (do_complement) {
3216 for (
k = 0;
k < op->nch;
k++)
3217 vec[
k] = vec[
k] - res[
k];
3220 for (
k = 0;
k < op->nch;
k++)
3227int mne_name_list_match(
const QStringList& list1,
int nlist1,
3228 const QStringList& list2,
int nlist2)
3234 if (list1.isEmpty() && list2.isEmpty())
3236 if (list1.isEmpty() || list2.isEmpty())
3238 if (nlist1 != nlist2)
3240 for (
k = 0;
k < nlist1;
k++)
3241 if (QString::compare(list1[
k],list2[
k]) != 0)
3246void mne_transpose_dsquare(
double **mat,
int n)
3254 for (j = 1; j < n; j++)
3255 for (
k = 0;
k < j;
k++) {
3257 mat[j][
k] = mat[
k][j];
3268 double **dcov = NULL;
3270 int do_complement = TRUE;
3272 if (op == NULL || op->nitems == 0)
3275 if (mne_name_list_match(op->names,op->nch,c->names,c->ncov) != OK) {
3276 qCritical(
"Incompatible data in mne_proj_op_apply_cov");
3280 dcov = ALLOC_DCMATRIX_3(c->ncov,c->ncov);
3285 for (j = 0, p = 0; j < c->ncov; j++)
3286 for (
k = 0;
k < c->ncov;
k++)
3287 dcov[j][
k] = (j ==
k) ? c->cov_diag[j] : 0;
3290 for (j = 0, p = 0; j < c->ncov; j++)
3291 for (
k = 0;
k <= j;
k++)
3292 dcov[j][
k] = c->cov[p++];
3293 for (j = 0; j < c->ncov; j++)
3294 for (
k = j+1;
k < c->ncov;
k++)
3295 dcov[j][
k] = dcov[
k][j];
3301 for (
k = 0;
k < c->ncov;
k++) {
3302 if (mne_proj_op_proj_dvector(op,dcov[
k],c->ncov,do_complement) != OK)
3306 mne_transpose_dsquare(dcov,c->ncov);
3308 for (
k = 0;
k < c->ncov;
k++)
3309 if (mne_proj_op_proj_dvector(op,dcov[
k],c->ncov,do_complement) != OK)
3316 for (j = 0; j < c->ncov; j++) {
3317 c->cov_diag[j] = dcov[j][j];
3319 FREE_3(c->cov); c->cov = NULL;
3322 for (j = 0, p = 0; j < c->ncov; j++)
3323 for (
k = 0;
k <= j;
k++)
3324 c->cov[p++] = dcov[j][
k];
3327 FREE_DCMATRIX_3(dcov);
3329 c->nproj = MneProjOp::mne_proj_op_affect(op,c->names,c->ncov);
3340, coord_frame(FIFFV_COORD_UNKNOWN)
3349, sphere_funcs (NULL)
3352, mag_dipole_funcs (NULL)
3353, fixed_noise (FALSE)
3358, column_norm (COLUMN_NORM_NONE)
3359, fit_mag_dipoles (FALSE)
3384 mne_free_cov_3(
noise);
3415 int fit_sphere_to_bem = TRUE;
3424 printf(
"\nSetting up the BEM model using %s...\n",d->
bemname.toUtf8().constData());
3425 printf(
"\nLoading surfaces...\n");
3428 printf(
"Three-layer model surfaces loaded.\n");
3434 printf(
"Homogeneous model surface loaded.\n");
3437 qCritical(
"Cannot use a homogeneous model in EEG calculations.");
3440 printf(
"\nLoading the solution matrix...\n");
3441 if (FwdBemModel::fwd_bem_load_recompute_solution(d->
bemname,FWD_BEM_UNKNOWN,FALSE,d->
bem_model) == FAIL)
3443 printf(
"Employing the head->MRI coordinate transform with the BEM model.\n");
3446 printf(
"BEM model %s is now set up\n",d->
bem_model->sol_name.toUtf8().constData());
3450 if (fit_sphere_to_bem) {
3452 float simplex_size = 2e-2;
3455 if ((inner_skull = d->
bem_model->fwd_bem_find_surface(FIFFV_BEM_SURF_ID_BRAIN)) == NULL)
3458 if (fit_sphere_to_points(inner_skull->rr,inner_skull->np,simplex_size,d->
r0,&R) == FAIL)
3461 FiffCoordTransOld::fiff_coord_trans(d->
r0,d->
mri_head_t,TRUE);
3462 printf(
"Fitted sphere model origin : %6.1f %6.1f %6.1f mm rad = %6.1f mm.\n",
3463 1000*d->
r0[X_3],1000*d->
r0[Y_3],1000*d->
r0[Z_3],1000*R);
3465 d->
bem_funcs = f = new_dipole_fit_funcs();
3471 comp = FwdCompData::fwd_make_comp_data(comp_data,d->
meg_coils,comp_coils,
3472 FwdBemModel::fwd_bem_field,NULL,NULL,d->
bem_model,NULL);
3475 printf(
"Compensation setup done.\n");
3477 printf(
"MEG solution matrix...");
3480 if (FwdBemModel::fwd_bem_specify_coils(d->
bem_model,comp->comp_coils) == FAIL)
3484 f->meg_field = FwdCompData::fwd_comp_field;
3485 f->meg_vec_field = NULL;
3486 f->meg_client = comp;
3487 f->meg_client_free = FwdCompData::fwd_free_comp_data;
3490 printf(
"\tEEG solution matrix...");
3494 f->eeg_pot = FwdBemModel::fwd_bem_pot_els;
3495 f->eeg_vec_pot = NULL;
3500 qCritical(
"EEG sphere model not defined.");
3515 comp = FwdCompData::fwd_make_comp_data(comp_data,d->
meg_coils,comp_coils,
3516 FwdBemModel::fwd_sphere_field,
3517 FwdBemModel::fwd_sphere_field_vec,
3522 f->meg_field = FwdCompData::fwd_comp_field;
3523 f->meg_vec_field = FwdCompData::fwd_comp_field_vec;
3524 f->meg_client = comp;
3525 f->meg_client_free = FwdCompData::fwd_free_comp_data;
3527 printf(
"Sphere model origin : %6.1f %6.1f %6.1f mm.\n",
3528 1000*d->
r0[X_3],1000*d->
r0[Y_3],1000*d->
r0[Z_3]);
3538 comp = FwdCompData::fwd_make_comp_data(comp_data,d->
meg_coils,comp_coils,
3539 FwdBemModel::fwd_mag_dipole_field,
3540 FwdBemModel::fwd_mag_dipole_field_vec,
3545 f->meg_field = FwdCompData::fwd_comp_field;
3546 f->meg_vec_field = FwdCompData::fwd_comp_field_vec;
3547 f->meg_client = comp;
3548 f->meg_client_free = FwdCompData::fwd_free_comp_data;
3550 f->eeg_pot = FwdBemModel::fwd_mag_dipole_field;
3551 f->eeg_vec_pot = FwdBemModel::fwd_mag_dipole_field_vec;
3557 fprintf (stderr,
"\n");
3576 printf(
"Using standard noise values "
3577 "(MEG grad : %6.1f fT/cm MEG mag : %6.1f fT EEG : %6.1f uV)\n",
3578 1e13*grad_std,1e15*mag_std,1e6*eeg_std);
3582 nchan = nchan + meg->ncoil;
3584 nchan = nchan + eeg->ncoil;
3586 stds = MALLOC_3(nchan,
double);
3590 for (
k = 0;
k < meg->ncoil;
k++, n++) {
3592 stds[n] = mag_std*mag_std;
3596 meg->coils[
k]->
type == FIFFV_COIL_CTF_OFFDIAG_REF_GRAD)
3597 stds[n] = 1e6*stds[n];
3601 stds[n] = grad_std*grad_std;
3606 for (
k = 0;
k < eeg->ncoil;
k++, n++) {
3607 stds[n] = eeg_std*eeg_std;
3617int DipoleFitData::make_projection(
const QList<QString> &projnames,
3618 const QList<FiffChInfo>& chs,
3630 for (
k = 0,
neeg = 0;
k < nch;
k++)
3631 if (
chs[
k].kind == FIFFV_EEG_CH)
3634 if (projnames.size() == 0 &&
neeg == 0)
3637 for (
k = 0;
k < projnames.size();
k++) {
3638 if ((one = mne_read_proj_op_3(projnames[
k])) == NULL)
3640 if (one->nitems == 0) {
3641 printf(
"No linear projection information in %s.\n",projnames[
k].toUtf8().data());
3647 printf(
"Loaded projection from %s:\n",projnames[
k].toUtf8().data());
3648 mne_proj_op_report_3(stderr,
"\t",one);
3649 all = MneProjOp::mne_proj_op_combine(all,one);
3659 for (
k = 0;
k < all->nitems;
k++)
3660 if (all->items[
k]->kind == FIFFV_MNE_PROJ_ITEM_EEG_AVREF) {
3666 if ((one = MneProjOp::mne_proj_op_average_eeg_ref(
chs,nch)) != NULL) {
3667 printf(
"Average EEG reference projection added:\n");
3668 mne_proj_op_report_3(stderr,
"\t",one);
3669 all = MneProjOp::mne_proj_op_combine(all,one);
3676 if (all && MneProjOp::mne_proj_op_affect_chs(all,
chs,nch) == 0) {
3677 printf(
"Projection will not have any effect on selected channels. Projection omitted.\n");
3694int DipoleFitData::scale_noise_cov(
DipoleFitData *f,
int nave)
3696 float nave_ratio = ((float)f->
nave)/(float)
nave;
3702 if (f->
noise->cov != NULL) {
3703 printf(
"Decomposing the sensor noise covariance matrix...\n");
3704 if (mne_decompose_eigen_cov_3(f->
noise) == FAIL)
3709 for (
k = 0;
k < f->
noise->ncov;
k++) {
3711 if (f->
noise->lambda[
k] < 0.0)
3712 f->
noise->lambda[
k] = 0.0;
3714 if (mne_add_inv_cov_3(f->
noise) == FAIL)
3718 for (
k = 0;
k < f->
noise->ncov;
k++)
3719 f->
noise->cov_diag[
k] = nave_ratio*f->
noise->cov_diag[
k];
3720 printf(
"Decomposition not needed for a diagonal noise covariance matrix.\n");
3721 if (mne_add_inv_cov_3(f->
noise) == FAIL)
3724 printf(
"Effective nave is now %d\n",
nave);
3734int DipoleFitData::scale_dipole_fit_noise_cov(
DipoleFitData *f,
int nave)
3736 float nave_ratio = ((float)f->
nave)/(float)
nave;
3744 if (f->
noise->cov) {
3748 printf(
"Decomposing the noise covariance...");
3749 if (f->
noise->cov) {
3750 if (mne_decompose_eigen_cov_3(f->
noise) == FAIL)
3752 for (
k = 0;
k < f->
noise->ncov;
k++) {
3753 if (f->
noise->lambda[
k] < 0.0)
3754 f->
noise->lambda[
k] = 0.0;
3759 for (
k = 0;
k < f->
noise->ncov;
k++) {
3761 if (f->
noise->lambda[
k] < 0.0)
3762 f->
noise->lambda[
k] = 0.0;
3764 if (mne_add_inv_cov_3(f->
noise) == FAIL)
3768 for (
k = 0;
k < f->
noise->ncov;
k++)
3769 f->
noise->cov_diag[
k] = nave_ratio*f->
noise->cov_diag[
k];
3770 printf(
"Decomposition not needed for a diagonal noise covariance matrix.\n");
3771 if (mne_add_inv_cov_3(f->
noise) == FAIL)
3774 printf(
"Effective nave is now %d\n",
nave);
3790 float nonsel_w = 30;
3799 nave = d->meas->current->nave;
3807 float *w = MALLOC_3(f->
noise_orig->ncov,
float);
3812 nomit_meg = nomit_eeg = 0;
3818 if (is_selected_in_data(d,f->
noise_orig->names[
k]))
3829 if (
nmeg > 0 &&
nmeg-nomit_meg > 0 &&
nmeg-nomit_meg < min_nchan) {
3830 qCritical(
"Too few MEG channels remaining");
3834 if (
neeg > 0 &&
neeg-nomit_eeg > 0 &&
neeg-nomit_eeg < min_nchan) {
3835 qCritical(
"Too few EEG channels remaining");
3840 if (nomit_meg+nomit_eeg > 0) {
3841 if (f->
noise->cov) {
3842 for (j = 0; j < f->
noise->ncov; j++)
3843 for (
k = 0;
k <= j;
k++) {
3844 val = f->
noise->cov+mne_lt_packed_index_3(j,
k);
3845 *val = w[j]*w[
k]*(*val);
3849 for (j = 0; j < f->
noise->ncov; j++) {
3850 val = f->
noise->cov_diag+j;
3851 *val = w[j]*w[j]*(*val);
3863 return scale_dipole_fit_noise_cov(f,
nave);
3869 const QString &measname,
3870 const QString& bemname,
3874 const QString &badname,
3875 const QString &noisename,
3883 const QList<QString> &projnames,
3892 QStringList badlist;
3894 QStringList file_bads;
3905 if (!mriname.isEmpty()) {
3906 if ((res->
mri_head_t = FiffCoordTransOld::mne_read_mri_transform(mriname)) == NULL)
3909 else if (!
bemname.isEmpty()) {
3910 qWarning(
"Source of MRI / head transform required for the BEM model is missing");
3914 float move[] = { 0.0, 0.0, 0.0 };
3915 float rot[3][3] = { { 1.0, 0.0, 0.0 },
3917 { 0.0, 0.0, 1.0 } };
3921 FiffCoordTransOld::mne_print_coord_transform(stdout,res->
mri_head_t);
3922 if ((res->
meg_head_t = FiffCoordTransOld::mne_read_meas_transform(measname)) == NULL)
3924 FiffCoordTransOld::mne_print_coord_transform(stdout,res->
meg_head_t);
3928 if (!badname.isEmpty()) {
3929 if (mne_read_bad_channels_3(badname,badlist,nbad) != OK)
3931 printf(
"%d bad channels read from %s.\n",nbad,badname.toUtf8().data());
3933 if (mne_read_bad_channel_list_3(measname,file_bads,file_nbad) == OK && file_nbad > 0) {
3934 if (badlist.isEmpty())
3936 for (
k = 0;
k < file_nbad;
k++) {
3937 badlist.append(file_bads[
k]);
3941 printf(
"%d bad channels read from the data file.\n",file_nbad);
3943 printf(
"%d bad channels total.\n",nbad);
3947 if (read_meg_eeg_ch_info(measname,
3958 printf(
"Will use %3d MEG channels from %s\n",res->
nmeg,measname.toUtf8().data());
3960 printf(
"Will use %3d EEG channels from %s\n",res->
neeg,measname.toUtf8().data());
3962 QString s = mne_channel_names_to_string_3(res->
chs,
3965 mne_string_to_name_list_3(s,res->
ch_names,n);
3981 QString qPath = QString(QCoreApplication::applicationDirPath() +
"/../resources/general/coilDefinitions/coil_def.dat");
3983 if ( !QCoreApplication::startingUp() )
3984 qPath = QCoreApplication::applicationDirPath() + QString(
"/../resources/general/coilDefinitions/coil_def.dat");
3985 else if (!file.exists())
3986 qPath =
"../resources/general/coilDefinitions/coil_def.dat";
3988 char *coilfile = MALLOC_3(strlen(qPath.toUtf8().data())+1,
char);
3989 strcpy(coilfile,qPath.toUtf8().data());
4001 accurate_coils ? FWD_COIL_ACCURACY_ACCURATE : FWD_COIL_ACCURACY_NORMAL,
4008 printf(
"Head coordinate coil definitions created.\n");
4011 qWarning(
"Cannot handle computations in %s coordinates",mne_coord_frame_name_3(
coord_frame));
4019 res->
r0[0] = (*r0)[0];
4020 res->
r0[1] = (*r0)[1];
4021 res->
r0[2] = (*r0)[2];
4027 if ((comp_data = MneCTFCompDataSet::mne_read_ctf_comp_data(measname)) == NULL)
4029 if (comp_data->ncomp > 0) {
4030 QList<FiffChInfo> comp_chs;
4033 printf(
"%d compensation data sets in %s\n",comp_data->ncomp,measname.toUtf8().data());
4034 QList<FiffChInfo> temp;
4035 if (mne_read_meg_comp_eeg_ch_info_3(measname,
4048 FWD_COIL_ACCURACY_NORMAL,
4052 printf(
"%d compensation channels in %s\n",comp_coils->ncoil,measname.toUtf8().data());
4063 if (setup_forward_model(res,comp_data,comp_coils) == FAIL)
4069 if (make_projection(projnames,
4072 &res->
proj) == FAIL)
4074 if (res->
proj && res->
proj->nitems > 0) {
4075 printf(
"Final projection operator is:\n");
4076 mne_proj_op_report_3(stderr,
"\t",res->
proj);
4080 if (mne_proj_op_make_proj(res->
proj) == FAIL)
4084 printf(
"No projection will be applied to the data.\n");
4089 if (!noisename.isEmpty()) {
4090 if ((cov = mne_read_cov(noisename,FIFFV_MNE_SENSOR_COV)) == NULL)
4092 printf(
"Read a %s noise-covariance matrix from %s\n",
4093 cov->cov_diag ?
"diagonal" :
"full", noisename.toUtf8().data());
4096 if ((cov = ad_hoc_noise(res->
meg_coils,res->
eeg_els,grad_std,mag_std,eeg_std)) == NULL)
4099 res->
noise = mne_pick_chs_cov_omit(cov,
4104 if (res->
noise == NULL) {
4105 mne_free_cov_3(cov);
4109 printf(
"Picked appropriate channels from the noise-covariance matrix.\n");
4110 mne_free_cov_3(cov);
4115 if (res->
proj && res->
proj->nitems > 0 && res->
proj->nvec > 0) {
4116 if (mne_proj_op_apply_cov(res->
proj,res->
noise) == FAIL)
4118 printf(
"Projection applied to the covariance matrix.\n");
4125 mne_revert_to_diag_cov(res->
noise);
4126 printf(
"Using only the main diagonal of the noise-covariance matrix.\n");
4132 if (res->
noise->cov) {
4136 regs[MNE_COV_CH_MEG_MAG] = mag_reg;
4137 regs[MNE_COV_CH_MEG_GRAD] = grad_reg;
4138 regs[MNE_COV_CH_EEG] = eeg_reg;
4142 if (mne_classify_channels_cov(res->
noise,
4149 for (
k = 0, do_it = 0;
k < res->
noise->ncov;
k++) {
4150 if (res->
noise->ch_class[
k] != MNE_COV_CH_UNKNOWN &&
4151 regs[res->
noise->ch_class[
k]] > 0.0)
4158 mne_regularize_cov(res->
noise,regs);
4160 printf(
"No regularization applied to the noise-covariance matrix\n");
4166 printf(
"Decomposing the noise covariance...\n");
4167 if (res->
noise->cov) {
4168 if (mne_decompose_eigen_cov_3(res->
noise) == FAIL)
4170 printf(
"Eigenvalue decomposition done.\n");
4171 for (
k = 0;
k < res->
noise->ncov;
k++) {
4172 if (res->
noise->lambda[
k] < 0.0)
4173 res->
noise->lambda[
k] = 0.0;
4177 printf(
"Decomposition not needed for a diagonal covariance matrix.\n");
4178 if (mne_add_inv_cov_3(res->
noise) == FAIL)
4205void print_fields(
float *rd,
4213 float *one = MALLOC_3(data->nchan,
float);
4217 if (mne_get_values_from_data_3(time,integ,data->current->data,data->current->np,data->nchan,data->current->tmin,
4218 1.0/data->current->tstep,FALSE,one) == FAIL) {
4219 printf(
"Cannot pick time: %7.1f ms\n",1000*time);
4222 for (
k = 0;
k < data->nchan;
k++)
4224 data->chs[
k].chpos.coil_type == FIFFV_COIL_CTF_OFFDIAG_REF_GRAD) {
4225 printf(
"%g ",1e15*one[
k]);
4229 fwd = ALLOC_CMATRIX_3(3,fit->
nmeg+fit->
neeg);
4230 if (DipoleFitData::compute_dipole_field(fit,rd,FALSE,fwd) == FAIL)
4233 for (
k = 0;
k < data->nchan;
k++)
4235 data->chs[
k].chpos.coil_type == FIFFV_COIL_CTF_OFFDIAG_REF_GRAD) {
4236 printf(
"%g ",1e15*(Q[X_3]*fwd[X_3][
k]+Q[Y_3]*fwd[Y_3][
k]+Q[Z_3]*fwd[Z_3][
k]));
4242 FREE_CMATRIX_3(fwd);
4268 delete old; old = NULL;
4270 res->
fwd = ALLOC_CMATRIX_3(3*ndip,d->
nmeg+d->
neeg);
4271 res->
uu = ALLOC_CMATRIX_3(3*ndip,d->
nmeg+d->
neeg);
4272 res->
vv = ALLOC_CMATRIX_3(3*ndip,3);
4273 res->
sing = MALLOC_3(3*ndip,
float);
4275 res->
rd = ALLOC_CMATRIX_3(ndip,3);
4276 res->
scales = MALLOC_3(3*ndip,
float);
4280 for (
k = 0;
k < ndip;
k++) {
4281 VEC_COPY_3(res->
rd[
k],rd[
k]);
4282 this_fwd = res->
fwd + 3*
k;
4286 if ((DipoleFitData::compute_dipole_field(d,rd[
k],TRUE,this_fwd)) == FAIL)
4293 for (p = 0; p < 3; p++)
4294 S[p] = mne_dot_vectors_3(res->
fwd[3*
k+p],res->
fwd[3*
k+p],res->
nch);
4296 for (p = 0; p < 3; p++)
4297 res->
scales[3*
k+p] = sqrt(S[p]);
4305 for (p = 0; p < 3; p++) {
4306 if (res->
scales[3*
k+p] > 0.0) {
4347 return dipole_forward(d,rds,1,old);
4352static float fit_eval(
float *rd,
int npar,
void *user)
4364 fwd = fuser->fwd = DipoleFitData::dipole_forward_one(fit,rd,fuser->fwd);
4365 ncomp = fwd->sing[2]/fwd->sing[0] > fuser->limit ? 3 : 2;
4366 if (fuser->report_dim)
4367 printf(
"ncomp = %d\n",ncomp);
4369 for (c = 0, Bm2 = 0.0; c < ncomp; c++) {
4370 one = mne_dot_vectors_3(fwd->uu[c],fuser->B,fwd->nch);
4371 Bm2 = Bm2 + one*one;
4373 return fuser->B2-Bm2;
4376static int find_best_guess(
float *B,
4387 double B2,Bm2,this_good,one;
4393 B2 = mne_dot_vectors_3(B,B,nch);
4396 if (fwd->
nch == nch) {
4397 ncomp = fwd->
sing[2]/fwd->
sing[0] > limit ? 3 : 2;
4398 for (c = 0, Bm2 = 0.0; c < ncomp; c++) {
4399 one = mne_dot_vectors_3(fwd->
uu[c],B,nch);
4400 Bm2 = Bm2 + one*one;
4402 this_good = 1.0 - (B2 - Bm2)/B2;
4403 if (this_good > good) {
4410 printf(
"No reasonable initial guess found.");
4418static float **make_initial_dipole_simplex(
float *r0,
4430 float x = sqrt(3.0)/3.0;
4431 float r = sqrt(6.0)/12.0;
4434 float rr[][3] = { { x , 0.0, -r },
4439 float **simplex = ALLOC_CMATRIX_3(4,3);
4442 for (j = 0; j < 4; j++) {
4443 VEC_COPY_3(simplex[j],rr[j]);
4444 for (
k = 0;
k < 3;
k++)
4445 simplex[j][
k] = size*simplex[j][
k] + r0[
k];
4450static int report_func(
int loop,
4462 fprintf(stdout,
"loop %d rd %7.2f %7.2f %7.2f fval %g %g par diff %g\n",
4463 loop,1000*r0[0],1000*r0[1],1000*r0[2],fval_lo,fval_hi,1000*par_diff);
4480 DipoleForward* fwd = DipoleFitData::dipole_forward_one(fit,rd,NULL);
4486 *ncomp = fwd->
sing[2]/fwd->
sing[0] > limit ? 3 : 2;
4488 Q[0] = Q[1] = Q[2] = 0.0;
4489 for (c = 0, Bm2 = 0.0; c < *ncomp; c++) {
4490 one = mne_dot_vectors_3(fwd->
uu[c],B,fwd->
nch);
4491 mne_add_scaled_vector_to_3(fwd->
vv[c],one/fwd->
sing[c],Q,3);
4492 Bm2 = Bm2 + one*one;
4497 for (c = 0; c < 3; c++)
4498 Q[c] = fwd->
scales[c]*Q[c];
4499 *res = mne_dot_vectors_3(B,B,fwd->
nch) - Bm2;
4506static float rtol(
float *vals,
int nval)
4512 minv = maxv = vals[0];
4513 for (
k = 1;
k < nval;
k++) {
4519 return 2.0*(maxv-minv)/(maxv+minv);
4529#define MIN_STOL_LOOP 5
4531static float tryf (
float **p,
4535 float (*func)(
float *x,
int npar,
void *user_data),
4543 float fac1,fac2,ytry,*ptry;
4545 ptry = ALLOC_FLOAT_3(ndim);
4546 fac1 = (1.0-fac)/ndim;
4548 for (j = 0; j < ndim; j++)
4549 ptry[j] = psum[j]*fac1-p[ihi][j]*fac2;
4550 ytry = (*func)(ptry,ndim,user_data);
4552 if (ytry < y[ihi]) {
4554 for (j = 0; j < ndim; j++) {
4555 psum[j] += ptry[j]-p[ihi][j];
4556 p[ihi][j] = ptry[j];
4563int simplex_minimize(
float **p,
4568 float (*func)(
float *x,
int npar,
void *user_data),
4573 int (*report_func)(
int loop,
4574 float *fitpar,
int npar,
4584 int i,j,ilo,ihi,inhi;
4586 float ytry,ysave,sum,rtol,*psum;
4592 psum = ALLOC_FLOAT_3(ndim);
4594 for (j = 0; j < ndim; j++) {
4595 for (i = 0,sum = 0.0; i<mpts; i++)
4599 if (report_func != NULL && report > 0)
4600 (void)report_func (0,p[0],ndim,-1.0,-1.0,0.0);
4603 for (;;count++,loop++) {
4605 ihi = y[1]>y[2] ? (inhi = 2,1) : (inhi = 1,2);
4606 for (i = 0; i < mpts; i++) {
4607 if (y[i] < y[ilo]) ilo = i;
4608 if (y[i] > y[ihi]) {
4611 }
else if (y[i] > y[inhi])
4612 if (i != ihi) inhi = i;
4614 rtol = 2.0*std::fabs(y[ihi]-y[ilo])/(std::fabs(y[ihi])+std::fabs(y[ilo]));
4618 if (count == report && report_func != NULL) {
4619 if (report_func (loop,p[ilo],ndim,y[ilo],y[ihi],sqrt(dsum))) {
4620 printf(
"Interation interrupted.");
4626 if (rtol < ftol)
break;
4627 if (*neval >= max_eval) {
4628 printf(
"Maximum number of evaluations exceeded.");
4633 for (dsum = 0.0, j = 0; j < ndim; j++) {
4634 diff = p[ilo][j] - p[ihi][j];
4637 if (loop > MIN_STOL_LOOP && sqrt(dsum) < stol)
4640 ytry = tryf(p,y,psum,ndim,func,user_data,ihi,neval,-ALPHA);
4642 ytry = tryf(p,y,psum,ndim,func,user_data,ihi,neval,GAMMA);
4643 else if (ytry >= y[inhi]) {
4645 ytry = tryf(p,y,psum,ndim,func,user_data,ihi,neval,BETA);
4646 if (ytry >= ysave) {
4647 for (i = 0; i < mpts; i++) {
4649 for (j = 0; j < ndim; j++) {
4650 psum[j] = 0.5*(p[i][j]+p[ilo][j]);
4653 y[i] = (*func)(psum,ndim,user_data);
4657 for (j = 0; j < ndim; j++) {
4658 for (i = 0,sum = 0.0; i < mpts; i++)
4679 float **simplex = NULL;
4683 float ftol[] = { 1e-2, 1e-2 };
4684 float atol[] = { 0.2e-3, 0.2e-3 };
4687 int max_eval = 1000;
4688 int report_interval = verbose ? 1 : -1;
4691 float good,rd_guess[3],rd_final[3],Q[3],final_val;
4693 int k,p,neval,neval_tot,nchan,ncomp;
4699 if (MneProjOp::mne_proj_op_proj_vector(fit->
proj,B,nchan,TRUE) == FAIL)
4702 if (mne_whiten_one_data(B,B,nchan,fit->
noise) == FAIL)
4707 if (find_best_guess(B,nchan,guess,limit,&best,&good) < 0)
4712 user.B2 = mne_dot_vectors_3(B,B,nchan);
4714 user.report_dim = FALSE;
4717 VEC_COPY_3(rd_guess,guess->
rr[best]);
4718 VEC_COPY_3(rd_final,guess->
rr[best]);
4722 for (
k = 0;
k < ntol;
k++) {
4731 simplex = make_initial_dipole_simplex(rd_guess,size);
4732 for (p = 0; p < 4; p++)
4733 vals[p] = fit_eval(simplex[p],3,fit);
4734 if (simplex_minimize(simplex,
4744 report_func) != OK) {
4748 printf(
"\nWarning (t = %8.1f ms) : g = %6.1f %% final val = %7.3f rtol = %f\n",
4749 1000*time,100*(1 - vals[0]/
user.B2),vals[0],rtol(vals,4));
4753 VEC_COPY_3(rd_final,simplex[0]);
4754 VEC_COPY_3(rd_guess,simplex[0]);
4755 FREE_CMATRIX_3(simplex); simplex = NULL;
4758 final_val = vals[0];
4766 if (fit_Q(fit,
user.B,rd_final,
user.limit,Q,&ncomp,&final_val) == OK) {
4769 for(
int i = 0; i < 3; ++i)
4770 res.
rd[i] = rd_final[i];
4771 for(
int i = 0; i < 3; ++i)
4773 res.
good = 1.0 - final_val/
user.B2;
4776 res.
khi2 = final_val;
4778 res.
nfree = nchan-3-ncomp-fit->
proj->nvec;
4780 res.
nfree = nchan-3-ncomp;
4781 res.
neval = neval_tot;
4786 FREE_CMATRIX_3(simplex);
4792 FREE_CMATRIX_3(simplex);
4799int DipoleFitData::compute_dipole_field(
DipoleFitData* d,
float *rd,
int whiten,
float **fwd)
4805 static float Qx[] = {1.0,0.0,0.0};
4806 static float Qy[] = {0.0,1.0,0.0};
4807 static float Qz[] = {0.0,0.0,1.0};
4813 if (d->
funcs->meg_vec_field) {
4828 if (d->
funcs->eeg_vec_pot) {
4829 eeg_fwd[0] = fwd[0]+d->
nmeg;
4830 eeg_fwd[1] = fwd[1]+d->
nmeg;
4831 eeg_fwd[2] = fwd[2]+d->
nmeg;
4849 fprintf(stdout,
"orig : ");
4850 for (
k = 0;
k < 3;
k++)
4851 fprintf(stdout,
"%g ",sqrt(mne_dot_vectors_3(fwd[
k],fwd[
k],d->
nmeg+d->
neeg)));
4852 fprintf(stdout,
"\n");
4855 for (
k = 0;
k < 3;
k++)
4856 if (MneProjOp::mne_proj_op_proj_vector(d->
proj,fwd[
k],d->
nmeg+d->
neeg,TRUE) == FAIL)
4860 fprintf(stdout,
"proj : ");
4861 for (
k = 0;
k < 3;
k++)
4862 fprintf(stdout,
"%g ",sqrt(mne_dot_vectors_3(fwd[
k],fwd[
k],d->
nmeg+d->
neeg)));
4863 fprintf(stdout,
"\n");
4869 if (d->
noise && whiten) {
4870 if (mne_whiten_data(fwd,fwd,3,d->
nmeg+d->
neeg,d->
noise) == FAIL)
4875 fprintf(stdout,
"white : ");
4876 for (
k = 0;
k < 3;
k++)
4877 fprintf(stdout,
"%g ",sqrt(mne_dot_vectors_3(fwd[
k],fwd[
k],d->
nmeg+d->
neeg)));
4878 fprintf(stdout,
"\n");
#define FIFF_MNE_COV_KIND
#define FIFFV_MNE_COORD_MNI_TAL
#define FIFFV_MNE_COORD_FS_TAL_LTZ
#define FIFFV_MNE_COORD_CTF_DEVICE
#define FIFF_MNE_COV_DIAG
#define FIFFV_COIL_CTF_REF_GRAD
#define FIFFV_MNE_COORD_MRI_VOXEL
#define FIFFV_MNE_NOISE_COV
#define FIFF_MNE_COV_EIGENVALUES
#define FIFF_MNE_PROJ_ITEM_ACTIVE
#define FIFFV_MNE_COORD_CTF_HEAD
#define FIFFV_COIL_CTF_REF_MAG
#define FIFF_MNE_COV_NFREE
#define FIFFV_MNE_COORD_FS_TAL_GTZ
#define FIFFV_MNE_COORD_RAS
FiffStream class declaration.
#define FIFFV_SSS_JOB_NOTHING
MneCovMatrix class declaration.
MNEProjItem class declaration.
MneSurfaceOld class declaration.
FwdCompData class declaration.
FwdBemModel class declaration.
GuessData class declaration.
Electric Current Dipole (ECD) class declaration.
Dipole Fit Data class declaration.
Coordinate transformation descriptor.
Data associated with MNE computations for each mneMeasDataSet.
FIFFLIB::fiff_int_t * inds
FIFFLIB::fiff_int_t * ptrs
FIFFLIB::fiff_float_t * data
FIFFLIB::fiff_int_t coding
ToDo Old implementation use new fiff_id.h instead.
QSharedPointer< FiffDirNode > SPtr
static QStringList split_name_list(QString p_sNameList)
QSharedPointer< FiffStream > SPtr
QSharedPointer< FiffTag > SPtr
static QString fwd_bem_make_bem_sol_name(const QString &name)
bool is_axial_coil() const
FwdCoilSet * create_meg_coils(const QList< FIFFLIB::FiffChInfo > &chs, int nch, int acc, const FIFFLIB::FiffCoordTransOld *t)
static FwdCoilSet * create_eeg_els(const QList< FIFFLIB::FiffChInfo > &chs, int nch, const FIFFLIB::FiffCoordTransOld *t)
static FwdCoilSet * read_coil_defs(const QString &name)
This structure is used in the compensated field calculations.
Electric Current Dipole description.
static int fwd_eeg_spherepot_coil_vec(float *rd, FwdCoilSet *els, float **Vval_vec, void *client)
static int fwd_eeg_spherepot_coil(float *rd, float *Q, FwdCoilSet *els, float *Vval, void *client)
easurement data representation in MNE calculations
Dipole Fit Data implementation.
static DipoleFitData * setup_dipole_fit_data(const QString &mriname, const QString &measname, const QString &bemname, Eigen::Vector3f *r0, FWDLIB::FwdEegSphereModel *eeg_model, int accurate_coils, const QString &badname, const QString &noisename, float grad_std, float mag_std, float eeg_std, float mag_reg, float grad_reg, float eeg_reg, int diagnoise, const QList< QString > &projnames, int include_meg, int include_eeg)
FWDLIB::FwdCoilSet * meg_coils
dipoleFitFuncs mag_dipole_funcs
FIFFLIB::FiffSparseMatrix * pick
static bool fit_one(DipoleFitData *fit, GuessData *guess, float time, float *B, int verbose, ECD &res)
QList< FIFFLIB::FiffChInfo > chs
dipoleFitFuncs sphere_funcs
FWDLIB::FwdBemModel * bem_model
FIFFLIB::FiffCoordTransOld * mri_head_t
fitUserFreeFunc user_free
MNELIB::MneCovMatrix * noise_orig
FWDLIB::FwdEegSphereModel * eeg_model
FWDLIB::FwdCoilSet * eeg_els
MNELIB::MneCovMatrix * noise
FIFFLIB::FiffCoordTransOld * meg_head_t
DipoleForward description.
Electric Current Dipole description.
DipoleForward ** guess_fwd
Covariance matrix storage.
One MNE CTF Compensation Data Set description.
Matrix specification with a channel list.
static MneNamedMatrix * build_named_matrix(int nrow, int ncol, const QStringList &rowlist, const QStringList &collist, float **data)
One linear projection item.
One linear projection item.
static void mne_free_proj_op_proj(MneProjOp *op)
MNE SSS Data description.
static MneSssData * read_sss_data_from_node(QSharedPointer< FIFFLIB::FiffStream > &stream, const QSharedPointer< FIFFLIB::FiffDirNode > &start)