23#include <QCoreApplication>
26#define _USE_MATH_DEFINES
37#ifndef FIFFV_COIL_CTF_GRAD
38#define FIFFV_COIL_CTF_GRAD 5001
41#ifndef FIFFV_COIL_CTF_REF_MAG
42#define FIFFV_COIL_CTF_REF_MAG 5002
45#ifndef FIFFV_COIL_CTF_REF_GRAD
46#define FIFFV_COIL_CTF_REF_GRAD 5003
49#ifndef FIFFV_COIL_CTF_OFFDIAG_REF_GRAD
50#define FIFFV_COIL_CTF_OFFDIAG_REF_GRAD 5004
73#define MALLOC_3(x,t) (t *)malloc((x)*sizeof(t))
74#define REALLOC_3(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
75#define FREE_3(x) if ((char *)(x) != NULL) free((char *)(x))
80#define ALLOC_FLOAT_3(x) MALLOC_3(x,float)
82#define ALLOC_DCMATRIX_3(x,y) mne_dmatrix_3((x),(y))
83#define ALLOC_CMATRIX_3(x,y) mne_cmatrix_3((x),(y))
84#define FREE_CMATRIX_3(m) mne_free_cmatrix_3((m))
85#define FREE_DCMATRIX_3(m) mne_free_dcmatrix_3((m))
87static void matrix_error_3(
int kind,
int nr,
int nc)
91 printf(
"Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
93 printf(
"Failed to allocate memory for a %d x %d matrix\n",nr,nc);
95 printf(
"Allocation error for a %d x %d matrix\n",nr,nc);
96 if (
sizeof(
void *) == 4) {
97 printf(
"This is probably because you seem to be using a computer with 32-bit architecture.\n");
98 printf(
"Please consider moving to a 64-bit platform.");
100 printf(
"Cannot continue. Sorry.\n");
112 if (!m) matrix_error_3(1,nr,nc);
114 if (!whole) matrix_error_3(2,nr,nc);
129 if (!m) matrix_error_3(1,nr,nc);
131 if (!whole) matrix_error_3(2,nr,nc);
150#define VEC_DOT_3(x,y) ((x)[X_3]*(y)[X_3] + (x)[Y_3]*(y)[Y_3] + (x)[Z_3]*(y)[Z_3])
151#define VEC_LEN_3(x) sqrt(VEC_DOT_3(x,x))
157#define VEC_DIFF_3(from,to,diff) {\
158 (diff)[X_3] = (to)[X_3] - (from)[X_3];\
159 (diff)[Y_3] = (to)[Y_3] - (from)[Y_3];\
160 (diff)[Z_3] = (to)[Z_3] - (from)[Z_3];\
163#define VEC_COPY_3(to,from) {\
164 (to)[X_3] = (from)[X_3];\
165 (to)[Y_3] = (from)[Y_3];\
166 (to)[Z_3] = (from)[Z_3];\
169#define CROSS_PRODUCT_3(x,y,xy) {\
170 (xy)[X_3] = (x)[Y_3]*(y)[Z_3]-(y)[Y_3]*(x)[Z_3];\
171 (xy)[Y_3] = -((x)[X_3]*(y)[Z_3]-(y)[X_3]*(x)[Z_3]);\
172 (xy)[Z_3] = (x)[X_3]*(y)[Y_3]-(y)[X_3]*(x)[Y_3];\
177#define MIN_3(a,b) ((a) < (b) ? (a) : (b))
187 for (j = 1; j < n; j++)
188 for (k = 0; k < j; k++) {
190 mat[j][k] = mat[k][j];
203 float res = sdot(&nn,v1,&one,v2,&one);
209 for (k = 0; k < nn; k++)
210 res = res + v1[k]*v2[k];
219 float fscale = scale;
221 saxpy(&nn,&fscale,v1,&one,v2,&one);
224 for (k = 0; k < nn; k++)
225 v2[k] = v2[k] + scale*v1[k];
242 dgemm (transa,transb,&d3,&d1,&d2,
243 &one,m2[0],&d3,m1[0],&d1,&zero,result[0],&d3);
250 for (j = 0; j < d1; j++)
251 for (k = 0; k < d3; k++) {
253 for (p = 0; p < d2; p++)
254 sum = sum + m1[p][j]*m2[p][k];
272 sgemm (transa,transb,&d3,&d1,&d2,
273 &one,m2[0],&d3,m1[0],&d2,&zero,result[0],&d3);
280 for (j = 0; j < d1; j++)
281 for (k = 0; k < d3; k++) {
283 for (p = 0; p < d2; p++)
284 sum = sum + m1[j][p]*m2[p][k];
300 for (j = 0; j < d1; j++)
312 int nlist = list.size();
314 if (nlist == 0 || list.isEmpty())
317 for (
int k = 0; k < nlist-1; k++) {
321 res += list[nlist-1];
336 for (k = 0; k < nch; k++)
337 names.append(chs[k].ch_name);
350 if (!s.isEmpty() && s.size() > 0) {
355 nlistp = list.size();
381 for (j = 0; j < nrow; j++)
382 for (k = 0; k < ncol; k++) {
383 val = std::fabs(dense[j][k]);
388 small = maxval * std::fabs(small);
390 small = std::fabs(small);
392 for (j = 0, nz = 0; j < nrow; j++)
393 for (k = 0; k < ncol; k++) {
394 if (std::fabs(dense[j][k]) > small)
399 qWarning(
"No nonzero elements found.");
403 qWarning(
"Unknown sparse matrix storage type: %d",stor_type);
407 sparse->
coding = stor_type;
411 sparse->
data.resize(nz);
412 sparse->
inds.resize(nz);
415 sparse->
ptrs.resize(nrow + 1);
416 for (j = 0, nz = 0; j < nrow; j++) {
418 for (k = 0; k < ncol; k++)
419 if (std::fabs(dense[j][k]) > small) {
420 sparse->
data[nz] = dense[j][k];
423 sparse->
inds[nz++] = k;
425 sparse->
ptrs[j] = ptr;
427 sparse->
ptrs[nrow] = nz;
428 for (j = nrow - 1; j >= 0; j--)
429 if (sparse->
ptrs[j] < 0)
430 sparse->
ptrs[j] = sparse->
ptrs[j+1];
433 sparse->
ptrs.resize(ncol + 1);
434 for (k = 0, nz = 0; k < ncol; k++) {
436 for (j = 0; j < nrow; j++)
437 if (std::fabs(dense[j][k]) > small) {
438 sparse->
data[nz] = dense[j][k];
441 sparse->
inds[nz++] = j;
443 sparse->
ptrs[k] = ptr;
445 sparse->
ptrs[ncol] = nz;
446 for (k = ncol-1; k >= 0; k--)
447 if (sparse->
ptrs[k] < 0)
448 sparse->
ptrs[k] = sparse->
ptrs[k+1];
468 float fscale = scale;
470 sscal(&nn,&fscale,v,&one);
473 for (k = 0; k < nn; k++)
481 Eigen::MatrixXf eigen_mat(m,n);
483 for (
int i = 0; i < m; ++i)
484 for (
int j = 0; j < n; ++j)
485 eigen_mat(i,j) = mat[i][j];
492 for (
int i = 0; i < m; ++i)
493 for (
int j = 0; j < n; ++j)
494 to_mat[i][j] = from_mat(i,j);
504 for (
int i = 0; i < n; ++i)
505 to_vec[i] = from_vec[i];
515 Eigen::MatrixXf eigen_mat_inv = eigen_mat.inverse();
553 int udim =
MIN_3(m,n);
558 Eigen::JacobiSVD< Eigen::MatrixXf > svd(eigen_mat ,Eigen::ComputeFullU | Eigen::ComputeFullV);
605 for (ch = 0; ch < nch; ch++) {
609 if (std::fabs(sfreq*integ) <
EPS_3) {
610 s1 = sfreq*(time - tmin);
613 if (n1 < 0 || n1 > nsamp-1) {
614 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
621 if (std::fabs(f1 - 1.0) < 1e-3)
624 if (f1 < 1.0 && n1 > nsamp-2) {
625 printf(
"Sample value out of range %d (0..%d) %.4f",n1,nsamp-1,f1);
630 sum = f1*std::fabs(data[n1][ch]) + (1.0-f1)*std::fabs(data[n1+1][ch]);
632 sum = f1*data[n1][ch] + (1.0-f1)*data[n1+1][ch];
636 sum = std::fabs(data[n1][ch]);
642 s1 = sfreq*(time - 0.5*integ - tmin);
643 s2 = sfreq*(time + 0.5*integ - tmin);
644 n1 = ceil(s1); n2 = floor(s2);
647 if (n1 < 0 || n1 > nsamp-2)
652 sum = 0.5*((f1+f2)*std::fabs(data[n1+1][ch]) + (2.0-f1-f2)*std::fabs(data[n1][ch]));
654 sum = 0.5*((f1+f2)*data[n1+1][ch] + (2.0-f1-f2)*data[n1][ch]);
659 if (n1 < 0 || n1 > nsamp-1) {
660 printf(
"Sample value out of range %d (0..%d)",n1,nsamp-1);
663 if (n2 < 0 || n2 > nsamp-1) {
664 printf(
"Sample value out of range %d (0..%d)",n2,nsamp-1);
667 if (f1 != 0.0 && n1 < 1)
669 if (f2 != 0.0 && n2 > nsamp-2)
675 sum = 0.5 * std::fabs(data[n1][ch]);
676 for (k = n1+1; k < n2; k++)
677 sum = sum + std::fabs(data[k][ch]);
678 sum = sum + 0.5 * std::fabs(data[n2][ch]);
681 sum = 0.5*data[n1][ch];
682 for (k = n1+1; k < n2; k++)
683 sum = sum + data[k][ch];
684 sum = sum + 0.5*data[n2][ch];
693 sum = sum + 0.5*f1*(f1*std::fabs(data[n1-1][ch]) + (2.0-f1)*std::fabs(data[n1][ch]));
695 sum = sum + 0.5*f2*(f2*std::fabs(data[n2+1][ch]) + (2.0-f2)*std::fabs(data[n2][ch]));
699 sum = sum + 0.5*f1*(f1*data[n1-1][ch] + (2.0-f1)*data[n1][ch]);
701 sum = sum + 0.5*f2*(f2*data[n2+1][ch] + (2.0-f2)*data[n2][ch]);
703 width = width + f1 + f2;
716 Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>& vectors,
725 int np = dim*(dim+1)/2;
729 float *vecp = vectors.data();
737 for(
int i = 0; i < np; ++i)
738 if (std::fabs(mat[i]) > std::fabs(mat[maxi]))
742 scale = 1.0/mat[maxi];
744 for (k = 0; k < np; k++)
745 dmat[k] = mat[k]*scale;
748 MatrixXd dmat_tmp = MatrixXd::Zero(dim,dim);
750 for (
int i = 0; i < dim; ++i) {
751 for(
int j = 0; j <= i; ++j) {
752 dmat_tmp(i,j) = dmat[idx];
753 dmat_tmp(j,i) = dmat[idx];
757 SelfAdjointEigenSolver<MatrixXd> es;
758 es.compute(dmat_tmp);
759 for (
int i = 0; i < dim; ++i )
760 w[i] = es.eigenvalues()[i];
763 for (
int j = 0; j < dim; ++j ) {
764 for(
int i = 0; i < dim; ++i ) {
765 z[idx] = es.eigenvectors()(i,j);
774 printf(
"Eigenvalue decomposition failed (LAPACK info = %d)",info);
777 for (k = 0; k < dim; k++)
778 lambda[k] = scale*w[k];
779 for (k = 0; k < dim*dim; k++)
794static int mne_lt_packed_index_3(
int j,
int k)
798 return k + j*(j+1)/2;
800 return j + k*(k+1)/2;
815 if (src.size() == 0) {
816 qCritical(
"Covariance matrix is not diagonal or not decomposed.");
820 for (k = 0; k < c->
ncov; k++) {
829static int condition_cov_3(
MNECovMatrix* c,
float rank_threshold,
int use_rank)
832 double *scale = NULL;
834 double *lambda = NULL;
835 Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> local_eigen;
836 double **data1 = NULL;
837 double **data2 = NULL;
838 double magscale,gradscale,eegscale;
839 int nmag,ngrad,neeg,nok;
846 qCritical(
"Channels not classified. Rank cannot be determined.");
849 magscale = gradscale = eegscale = 0.0;
850 nmag = ngrad = neeg = 0;
851 for (k = 0; k < c->
ncov; k++) {
853 magscale += c->
cov[mne_lt_packed_index_3(k,k)]; nmag++;
856 gradscale += c->
cov[mne_lt_packed_index_3(k,k)]; ngrad++;
859 eegscale += c->
cov[mne_lt_packed_index_3(k,k)]; neeg++;
862 fprintf(stdout,
"%d ",c->
ch_class[k]);
866 fprintf(stdout,
"\n");
869 magscale = magscale > 0.0 ? sqrt(nmag/magscale) : 0.0;
871 gradscale = gradscale > 0.0 ? sqrt(ngrad/gradscale) : 0.0;
873 eegscale = eegscale > 0.0 ? sqrt(neeg/eegscale) : 0.0;
875 fprintf(stdout,
"%d %g\n",nmag,magscale);
876 fprintf(stdout,
"%d %g\n",ngrad,gradscale);
877 fprintf(stdout,
"%d %g\n",neeg,eegscale);
880 for (k = 0; k < c->
ncov; k++) {
884 scale[k] = gradscale;
892 local_eigen.resize(c->
ncov,c->
ncov);
893 for (j = 0; j < c->
ncov; j++)
894 for (k = 0; k <= j; k++)
895 cov[mne_lt_packed_index_3(j,k)] = c->
cov[mne_lt_packed_index_3(j,k)]*scale[j]*scale[k];
898 for (k = 0; k < c->
ncov; k++)
899 fprintf(stdout,
"%g ",lambda[k]/lambda[c->
ncov-1]);
900 fprintf(stdout,
"\n");
903 for (k = c->
ncov-1; k >= 0; k--) {
904 if (lambda[k] >= rank_threshold*lambda[c->
ncov-1])
909 printf(
"\n\tEstimated covariance matrix rank = %d (%g)\n",nok,lambda[c->
ncov-nok]/lambda[c->
ncov-1]);
910 if (use_rank > 0 && use_rank < nok) {
912 printf(
"\tUser-selected covariance matrix rank = %d (%g)\n",nok,lambda[c->
ncov-nok]/lambda[c->
ncov-1]);
917 for (j = 0; j < c->
ncov-nok; j++)
920 for (j = 0; j < c->
ncov; j++) {
922 mne_print_vector(stdout,NULL,local_eigen.row(j).data(),c->
ncov);
924 for (k = 0; k < c->
ncov; k++)
925 data1[j][k] = sqrt(lambda[j])*local_eigen(j,k);
930 for (j = 0; j < c->
ncov; j++)
931 mne_print_dvector(stdout,NULL,data2[j],c->
ncov);
937 for (k = 0; k < c->
ncov; k++)
939 scale[k] = 1.0/scale[k];
940 for (j = 0; j < c->
ncov; j++)
941 for (k = 0; k <= j; k++)
942 if (c->
cov[mne_lt_packed_index_3(j,k)] != 0.0)
943 c->
cov[mne_lt_packed_index_3(j,k)] = scale[j]*scale[k]*data2[j][k];
954static int check_cov_data(
double *vals,
int nval)
960 for (k = 0, sum = 0.0; k < nval; k++)
963 qCritical(
"Sum of covariance matrix elements is zero!");
970 const QList<FiffChInfo>& chs,
980 qCritical(
"Channel information not available in mne_classify_channels_cov");
984 for (k = 0; k < cov->
ncov; k++) {
986 for (p = 0; p < nchan; p++) {
987 if (QString::compare(chs[p].ch_name,cov->
names[k]) == 0) {
1013static int mne_decompose_eigen_cov_small_3(
MNECovMatrix* c,
float small,
int use_rank)
1019 float rank_threshold = 1e-6;
1028 if (c->
lambda.size() > 0 && c->
eigen.size() > 0) {
1029 printf(
"\n\tEigenvalue decomposition had been precomputed.\n");
1031 for (k = 0; k < c->
ncov; k++, c->
nzero++)
1037 c->
eigen.resize(0,0);
1039 if ((rank = condition_cov_3(c,rank_threshold,use_rank)) < 0)
1048 for (k = 0; k < c->
nzero; k++)
1054 float meglike,eeglike;
1058 for (k = c->
nzero; k < c->ncov; k++) {
1059 meglike = eeglike = 0.0;
1060 for (p = 0; p < c->
ncov; p++) {
1062 eeglike += std::fabs(c->
eigen(k,p));
1064 meglike += std::fabs(c->
eigen(k,p));
1066 if (meglike > eeglike)
1071 printf(
"\t%d MEG and %d EEG-like channels remain in the whitened data\n",nmeg,neeg);
1078 c->
eigen.resize(0,0);
1086 return mne_decompose_eigen_cov_small_3(c,-1.0,-1);
1097 float *one = NULL,*orig,*white;
1100 if (data == NULL || np <= 0)
1103 if (C->
ncov != nchan) {
1104 printf(
"Incompatible covariance matrix. Cannot whiten the data.");
1110 for (j = 0; j < np; j++) {
1112 white = whitened_data[j];
1113 for (k = 0; k < nchan; k++)
1114 white[k] = orig[k]*inv[k];
1122 for (j = 0; j < np; j++) {
1124 white = whitened_data[j];
1125 for (k = C->
nzero; k < nchan; k++)
1127 for (k = 0; k < C->
nzero; k++)
1129 for (k = C->
nzero; k < nchan; k++)
1130 white[k] = one[k]*inv[k];
1141 float *whitened_datap[1];
1144 whitened_datap[0] = whitened_data;
1228 float sums[3],nn[3];
1231 if (c->
cov.size() == 0 || c->
ch_class.size() == 0)
1234 for (j = 0; j < nkind; j++) {
1241 for (j = 0; j < c->
ncov; j++) {
1243 sums[c->
ch_class[j]] += c->
cov[mne_lt_packed_index_3(j,j)];
1247 printf(
"Average noise-covariance matrix diagonals:\n");
1248 for (j = 0; j < nkind; j++) {
1250 sums[j] = sums[j]/nn[j];
1252 printf(
"\tMagnetometers : %-7.2f fT reg = %-6.2f\n",1e15*sqrt(sums[j]),regs[j]);
1254 printf(
"\tPlanar gradiometers : %-7.2f fT/cm reg = %-6.2f\n",1e13*sqrt(sums[j]),regs[j]);
1256 printf(
"\tEEG : %-7.2f uV reg = %-6.2f\n",1e6*sqrt(sums[j]),regs[j]);
1257 sums[j] = regs[j]*sums[j];
1263 for (j = 0; j < c->
ncov; j++)
1265 c->
cov[mne_lt_packed_index_3(j,j)] += sums[c->
ch_class[j]];
1267 printf(
"Noise-covariance regularized as requested.\n");
1300static float tryit (
float **p,
1304 float (*func)(
float *x,
int npar,
void *user_data),
1312 float fac1,fac2,ytry,*ptry;
1315 fac1 = (1.0-fac)/ndim;
1317 for (j = 0; j < ndim; j++)
1318 ptry[j] = psum[j]*fac1-p[ihi][j]*fac2;
1319 ytry = (*func)(ptry,ndim,user_data);
1321 if (ytry < y[ihi]) {
1323 for (j = 0; j < ndim; j++) {
1324 psum[j] += ptry[j]-p[ihi][j];
1325 p[ihi][j] = ptry[j];
1336 float (*func)(
float *x,
int npar,
void *user_data),
1341 int (*report_func)(
int loop,
1342 float *fitpar,
int npar,
1351 int i,j,ilo,ihi,inhi;
1353 float ytry,ysave,sum,rtol,*psum;
1360 for (j = 0; j < ndim; j++) {
1361 for (i = 0,sum = 0.0; i<mpts; i++)
1365 if (report_func != NULL && report > 0)
1366 (void)report_func (0,p[0],ndim,-1.0);
1368 for (;;count++,loop++) {
1370 ihi = y[1]>y[2] ? (inhi = 2,1) : (inhi = 1,2);
1371 for (i = 0; i < mpts; i++) {
1372 if (y[i] < y[ilo]) ilo = i;
1373 if (y[i] > y[ihi]) {
1376 }
else if (y[i] > y[inhi])
1377 if (i != ihi) inhi = i;
1379 rtol = 2.0*std::fabs(y[ihi]-y[ilo])/(std::fabs(y[ihi])+std::fabs(y[ilo]));
1383 if (count == report && report_func != NULL) {
1384 if (report_func (loop,p[ilo],ndim,y[ilo])) {
1385 qWarning(
"Interation interrupted.");
1391 if (rtol < ftol)
break;
1392 if (*neval >= max_eval) {
1393 qWarning(
"Maximum number of evaluations exceeded.");
1397 ytry = tryit(p,y,psum,ndim,func,user_data,ihi,neval,-
ALPHA);
1399 ytry = tryit(p,y,psum,ndim,func,user_data,ihi,neval,
GAMMA);
1400 else if (ytry >= y[inhi]) {
1402 ytry = tryit(p,y,psum,ndim,func,user_data,ihi,neval,
BETA);
1403 if (ytry >= ysave) {
1404 for (i = 0; i < mpts; i++) {
1406 for (j = 0; j < ndim; j++) {
1407 psum[j] = 0.5*(p[i][j]+p[ilo][j]);
1410 y[i] = (*func)(psum,ndim,user_data);
1414 for (j = 0; j < ndim; j++) {
1415 for (i = 0,sum = 0.0; i < mpts; i++)
1446static int report_func(
int loop,
1457 printf(
"loop %d r0 %7.1f %7.1f %7.1f fval %g\n",
1458 loop,1000*r0[0],1000*r0[1],1000*r0[2],fval);
1463static float fit_sphere_eval(
float *fitpar,
1475 float sum,sum2,one,F;
1478 for (k = 0, sum = sum2 = 0.0; k < user->
np; k++) {
1484 F = sum2 - sum*sum/user->
np;
1487 printf(
"r0 %7.1f %7.1f %7.1f R %7.1f fval %g\n",
1488 1000*r0[0],1000*r0[1],1000*r0[2],1000*sum/user->
np,F);
1496 float sum, diff[3], one;
1499 for (k = 0, sum = 0.0; k < user->
np; k++) {
1504 return sum/user->
np;
1513 for (q = 0; q < 3; q++)
1516 for (k = 0; k < np; k++)
1517 for (q = 0; q < 3; q++)
1521 for (q = 0; q < 3; q++)
1524 for (k = 0, ave = 0.0; k < np; k++) {
1525 for (q = 0; q < 3; q++)
1526 diff[q] = rr(k,q) - cm[q];
1534static float **make_initial_simplex(
float *pars,
1544 for (k = 0; k < npar+1; k++)
1545 memcpy (simplex[k],pars,npar*
sizeof(
float));
1547 for (k = 1; k < npar+1; k++)
1548 simplex[k][k-1] = simplex[k][k-1] + size;
1564 int report_interval = -1;
1566 float **init_simplex = NULL;
1567 float *init_vals = NULL;
1577 calculate_cm_ave_dist(rr,np,cm,&R0);
1580 printf(
"cm %7.1f %7.1f %7.1f R %7.1f\n",
1581 1000*cm[0],1000*cm[1],1000*cm[2],1000*R0);
1584 init_simplex = make_initial_simplex(cm,3,simplex_size);
1594 for (k = 0; k < 4; k++)
1595 init_vals[k] = fit_sphere_eval(init_simplex[k],3,&user);
1609 r0[
X_3] = init_simplex[0][
X_3];
1610 r0[
Y_3] = init_simplex[0][
Y_3];
1611 r0[
Z_3] = init_simplex[0][
Z_3];
1612 *R = opt_rad(r0,&user);
1627 char **exclude,
int nexclude)
1640 out <<
"Empty operator\n";
1644 for (k = 0; k < op->
nitems; k++) {
1646 if (list_data && tag)
1650 out <<
"# " << (k+1) <<
" : " << it->
desc <<
" : " << it->
nvec <<
" vecs : " << it->
vecs->ncol <<
" chs "
1651 << (it->
has_meg ?
"MEG" :
"EEG") <<
" "
1652 << (it->
active ?
"active" :
"idle") <<
"\n";
1653 if (list_data && tag)
1656 vecs = op->
items[k].vecs.get();
1658 for (q = 0; q < vecs->
ncol; q++) {
1659 out << qSetFieldWidth(10) << Qt::left << vecs->
collist[q] << qSetFieldWidth(0);
1660 out << (q < vecs->
ncol-1 ?
" " :
"\n");
1662 for (p = 0; p < vecs->
nrow; p++)
1663 for (q = 0; q < vecs->
ncol; q++) {
1664 for (j = 0, found = 0; j < nexclude; j++) {
1665 if (QString::compare(exclude[j],vecs->
collist[q]) == 0) {
1670 out << qSetFieldWidth(10) << qSetRealNumberPrecision(5) << Qt::forcepoint
1671 << (found ? 0.0 : vecs->
data(p, q)) << qSetFieldWidth(0) <<
" ";
1672 out << (q < vecs->
ncol-1 ?
" " :
"\n");
1674 if (list_data && tag)
1696 if (vec->
names.size() == 0) {
1697 qCritical(
"No names present in vector. Cannot pick.");
1701 for (k = 0; k < nnames; k++)
1704 for (k = 0; k < nnames; k++) {
1706 for (p = 0; p < vec->
nvec; p++) {
1707 if (QString::compare(vec->
names[p],names[k]) == 0) {
1708 res[k] = vec->
data[p];
1713 if (!found && require_all) {
1714 qCritical(
"All required elements not found in named vector.");
1731 QList<FiffDirNode::SPtr> proj;
1733 QList<FiffDirNode::SPtr> items;
1736 QString item_desc, desc_tag;
1737 int global_nchan,item_nchan,nlist;
1738 QStringList item_names;
1743 QStringList emptyList;
1747 qCritical(
"File not open mne_read_proj_op_from_node");
1751 if (!start || start->isEmpty())
1752 start_node = stream->dirtree();
1757 proj = start_node->dir_tree_find(
FIFFB_PROJ);
1758 if (proj.size() == 0 || proj[0]->isEmpty())
1764 if (items.size() == 0 || items[0]->isEmpty())
1770 if(!node->find_tag(stream,
FIFF_NCHAN, t_pTag))
1773 global_nchan = *t_pTag->toInt();
1779 for (k = 0; k < items.size(); k++) {
1786 if (node->find_tag(stream,
FIFF_NAME, t_pTag)) {
1787 item_desc += t_pTag->toString();
1794 desc_tag = t_pTag->toString();
1795 if((pos = desc_tag.indexOf(
"\n")) >= 0)
1796 desc_tag.truncate(pos);
1797 if (!item_desc.isEmpty())
1799 item_desc += desc_tag;
1804 if (!node->find_tag(stream,
FIFF_NCHAN, t_pTag)) {
1805 item_nchan = global_nchan;
1808 item_nchan = *t_pTag->toInt();
1810 if (item_nchan <= 0) {
1811 qCritical(
"Number of channels incorrectly specified for one of the projection items.");
1821 if (nlist != item_nchan) {
1822 printf(
"Channel name list incorrectly specified for proj item # %d",k+1);
1831 item_kind = *t_pTag->toInt();
1837 item_nvec = *t_pTag->toInt();
1844 MatrixXf item_vectors = t_pTag->toFloatMatrix().transpose();
1850 item_active = *t_pTag->toInt();
1853 item_active =
FALSE;
1859 op->
items[op->
nitems-1].active_file = item_active;
1908static void clear_these(
float *data,
const QStringList& names,
int nnames,
const QString& start)
1912 for (k = 0; k < nnames; k++)
1913 if (names[k].contains(start))
1917#define USE_LIMIT 1e-5
1918#define SMALL_VALUE 1e-4
1929 float **vv_meg = NULL;
1930 float *sing_meg = NULL;
1931 float **vv_eeg = NULL;
1932 float *sing_eeg = NULL;
1933 float **mat_meg = NULL;
1934 float **mat_eeg = NULL;
1960 fprintf(stdout,
"mne_proj_op_make_proj_bad\n");
1962 for (k = 0, nvec_meg = nvec_eeg = 0; k < op->
nitems; k++) {
1966 if (op->
items[k].has_meg) {
1967 for (p = 0; p < op->
items[k].nvec; p++, nvec_meg++) {
1968 vec.
data = op->
items[k].vecs->data.row(p);
1972 fprintf(stdout,
"Original MEG:\n");
1973 mne_print_vector(stdout,op->
items[k].desc,mat_meg[nvec_meg],op->
nch);
1978 else if (op->
items[k].has_eeg) {
1979 for (p = 0; p < op->
items[k].nvec; p++, nvec_eeg++) {
1980 vec.
data = op->
items[k].vecs->data.row(p);
1984 fprintf (stdout,
"Original EEG:\n");
1985 mne_print_vector(stdout,op->
items[k].desc,mat_eeg[nvec_eeg],op->
nch);
1995 for (q = 0; q < nbad; q++)
1996 for (r = 0; r < op->
nch; r++)
1997 if (QString::compare(op->
names[r],bad[q]) == 0) {
1998 for (p = 0; p < nvec_meg; p++)
1999 mat_meg[p][r] = 0.0;
2000 for (p = 0; p < nvec_eeg; p++)
2001 mat_eeg[p][r] = 0.0;
2006 for (p = 0, nzero = 0; p < nvec_meg; p++) {
2009 for (k = 0; k < op->
nch; k++)
2010 mat_meg[p][k] = mat_meg[p][k]/size;
2015 if (nzero == nvec_meg) {
2018 for (p = 0, nzero = 0; p < nvec_eeg; p++) {
2021 for (k = 0; k < op->
nch; k++)
2022 mat_eeg[p][k] = mat_eeg[p][k]/size;
2027 if (nzero == nvec_eeg) {
2030 if (nvec_meg + nvec_eeg == 0) {
2031 printf(
"No projection remains after excluding bad channels. Omitting projection.\n");
2038 fprintf(stdout,
"Before SVD:\n");
2042 fprintf(stdout,
"---->>\n");
2043 for (p = 0; p < nvec_meg; p++) {
2044 sprintf(
name,
"MEG %02d",p+1);
2045 mne_print_vector(stdout,
name,mat_meg[p],op->
nch);
2047 fprintf(stdout,
"---->>\n");
2049 sing_meg =
MALLOC_3(nvec_meg+1,
float);
2051 if (
mne_svd_3(mat_meg,nvec_meg,op->
nch,sing_meg,NULL,vv_meg) !=
OK)
2056 fprintf(stdout,
"---->>\n");
2057 for (p = 0; p < nvec_eeg; p++) {
2058 sprintf(
name,
"EEG %02d",p+1);
2059 mne_print_vector(stdout,
name,mat_eeg[p],op->
nch);
2061 fprintf(stdout,
"---->>\n");
2063 sing_eeg =
MALLOC_3(nvec_eeg+1,
float);
2065 if (
mne_svd_3(mat_eeg,nvec_eeg,op->
nch,sing_eeg,NULL,vv_eeg) !=
OK)
2071 for (p = 0, op->
nvec = 0; p < nvec_meg; p++, op->nvec++)
2072 if (sing_meg[p]/sing_meg[0] <
USE_LIMIT)
2074 for (p = 0; p < nvec_eeg; p++, op->
nvec++)
2075 if (sing_eeg[p]/sing_eeg[0] <
USE_LIMIT)
2078 printf(
"Number of linearly independent vectors = %d\n",op->
nvec);
2082 fprintf(stdout,
"Final projection data:\n");
2084 for (p = 0, op->
nvec = 0; p < nvec_meg; p++, op->nvec++) {
2085 if (sing_meg[p]/sing_meg[0] <
USE_LIMIT)
2087 for (k = 0; k < op->
nch; k++) {
2102 sprintf(
name,
"MEG %02d",p+1);
2106 for (p = 0; p < nvec_eeg; p++, op->
nvec++) {
2107 if (sing_eeg[p]/sing_eeg[0] <
USE_LIMIT)
2109 for (k = 0; k < op->
nch; k++) {
2123 sprintf(
name,
"EEG %02d",p+1);
2137 for (k = 0; k < op->
nch; k++)
2138 if (op->
names[k].contains(
"STI")){
2139 for (p = 0; p < op->
nvec; p++)
2167 QList<FiffChInfo>& megp,
2169 QList<FiffChInfo>& meg_compp,
2171 QList<FiffChInfo>& eegp,
2183 QList<FiffChInfo> chs;
2185 QList<FiffChInfo> meg;
2187 QList<FiffChInfo> meg_comp;
2189 QList<FiffChInfo> eeg;
2192 QList<FiffDirNode::SPtr> nodes;
2205 if (nodes.size() == 0) {
2207 if (nodes.size() == 0) {
2208 qCritical (
"Could not find the channel information.");
2214 for (k = 0; k < info->nent(); k++) {
2215 kind = info->dir[k]->kind;
2216 pos = info->dir[k]->pos;
2219 if (!stream->read_tag(t_pTag,pos))
2221 nchan = *t_pTag->toInt();
2223 for (j = 0; j < nchan; j++)
2230 if(!stream->read_tag(t_pTag, pos))
2232 *
id = *(
fiffId)t_pTag->data();
2236 if(!stream->read_tag(t_pTag, pos))
2246 if(!stream->read_tag(t_pTag, pos))
2248 this_ch = t_pTag->toChInfo();
2250 printf (
"FIFF_CH_INFO : scan # out of range %d (%d)!",this_ch.
scanNo,nchan);
2254 chs[this_ch.
scanNo-1] = this_ch;
2260 qCritical(
"Some of the channel information was missing.");
2263 if (t.
isEmpty() && meg_head_t != NULL) {
2269 qCritical(
"MEG -> head coordinate transformation not found.");
2276 for (k = 0; k < nchan; k++) {
2281 meg_comp.append(chs[k]);
2296 meg_compp = meg_comp;
2297 *nmeg_compp = nmeg_comp;
2307 if (meg_head_t == NULL) {
2311 *meg_head_t = std::move(t);
2326#if defined(_WIN32) || defined(_WIN64)
2327#define snprintf _snprintf
2328#define vsnprintf _vsnprintf
2329#define strcasecmp _stricmp
2330#define strncasecmp _strnicmp
2342 if (QString::compare(ch_name,d->
meas->
chs[k].ch_name,Qt::CaseInsensitive) == 0) {
2351static int whitespace_3(
char *text)
2354 if (text == NULL || strlen(text) == 0)
2356 if (strspn(text,
" \t\n\r") == strlen(text))
2361static char *next_line_3(
char *line,
int n, FILE *in)
2365 for (res = fgets(line,n,in); res != NULL; res = fgets(line,n,in))
2366 if (!whitespace_3(res))
2387 if ((in = fopen(
name.toUtf8().data(),
"r")) == NULL) {
2388 qCritical() <<
name;
2391 while ((next = next_line_3(line,
MAXLINE,in)) != NULL) {
2392 if (strlen(next) > 0) {
2393 if (next[strlen(next)-1] ==
'\n')
2394 next[strlen(next)-1] =
'\0';
2402 nlistp = list.size();
2420 QList<FiffDirNode::SPtr> temp;
2426 if (pNode->isEmpty())
2427 node = stream->dirtree();
2432 if (temp.size() > 0) {
2437 names = t_pTag->toString();
2442 nlistp = list.size();
2473 QList<FiffDirNode::SPtr> nodes;
2478 Eigen::VectorXd cov;
2479 Eigen::VectorXd cov_diag;
2481 Eigen::VectorXd lambda;
2482 Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> eigen;
2488 std::unique_ptr<MNECovMatrix> res;
2501 if (nodes.size() == 0) {
2502 printf(
"No covariance matrix available in %s",
name.toUtf8().data());
2508 for (k = 0 ; k < nodes.size(); ++k) {
2512 if (*t_pTag->toInt() ==
kind) {
2517 if (covnode->isEmpty()) {
2518 printf(
"Desired covariance matrix not found from %s",
name.toUtf8().data());
2526 ncov = *t_pTag->toInt();
2529 nfree = *t_pTag->toInt();
2533 if (nnames != ncov) {
2534 qCritical(
"Incorrect number of channel names for a covariance matrix");
2538 if (!nodes[k]->find_tag(stream,
FIFF_MNE_COV, t_pTag)) {
2543 cov_diag.resize(ncov);
2544 qDebug() <<
"ToDo: Check whether cov_diag contains the right stuff!!! - use VectorXd instead";
2545 d = t_pTag->toDouble();
2546 for (p = 0; p < ncov; p++)
2548 if (check_cov_data(cov_diag.data(),ncov) !=
OK)
2552 cov_diag.resize(ncov);
2553 qDebug() <<
"ToDo: Check whether f contains the right stuff!!! - use VectorXf instead";
2554 f = t_pTag->toFloat();
2555 for (p = 0; p < ncov; p++)
2559 printf(
"Illegal data type for covariance matrix");
2565 nn = ncov*(ncov+1)/2;
2567 qDebug() <<
"ToDo: Check whether cov contains the right stuff!!! - use VectorXd instead";
2570 d = t_pTag->toDouble();
2571 for (p = 0; p < nn; p++)
2573 if (check_cov_data(cov.data(),nn) !=
OK)
2578 f = t_pTag->toFloat();
2579 for (p = 0; p < nn; p++)
2584 if (!cov_sparse_uptr)
2586 cov_sparse = cov_sparse_uptr.release();
2590 const double *lambda_data = (
const double *)t_pTag->toDouble();
2591 lambda = Eigen::Map<const Eigen::VectorXd>(lambda_data, ncov);
2595 tmp_eigen = t_pTag->toFloatMatrix().transpose();
2596 eigen.resize(tmp_eigen.rows(),tmp_eigen.cols());
2597 for (
int r = 0; r < tmp_eigen.rows(); ++r)
2598 for (
int c = 0; c < tmp_eigen.cols(); ++c)
2599 eigen(r,c) = tmp_eigen(r,c);
2619 else if (cov.size() > 0)
2621 else if (cov_diag.size() > 0)
2624 qCritical(
"mne_read_cov : covariance matrix data is not defined. How come?");
2628 res->eigen = std::move(eigen);
2629 res->lambda = std::move(lambda);
2636 if (res->lambda.size() > 0) {
2638 for (k = 0; k < res->ncov; k++, res->nzero++)
2639 if (res->lambda[k] > 0)
2643 if (op && op->
nitems > 0) {
2644 res->proj.reset(op);
2648 res->sss.reset(sss);
2706 for (k = 0; frames[k].
frame != -1; k++) {
2707 if (frame == frames[k].frame)
2708 return frames[k].
name;
2710 return frames[k].
name;
2717 const QList<FiffChInfo>& chs2,
2719 QList<FiffChInfo>& resp,
2724 resp.reserve(nch1+nch2);
2727 for (k = 0; k < nch1; k++) {
2728 resp.append(chs1.at(k));
2730 for (k = 0; k < nch2; k++) {
2731 resp.append(chs2.at(k));
2749 if (tmp_node->parent == NULL)
2751 tmp_node = tmp_node->parent;
2766 if (tmp_node->parent == NULL)
2768 tmp_node = tmp_node->parent;
2770 for (k = 0; k < tmp_node->nchild(); k++)
2772 return (tmp_node->children[k]);
2776static int get_all_chs (
2780 QList<FiffChInfo>& chp,
2788 QList<FiffChInfo> ch;
2802 if (!(meas = find_meas_3(p_node))) {
2803 qCritical(
"Meas. block not found!");
2807 if (!(meas_info = find_meas_info_3(p_node))) {
2808 qCritical (
"Meas. info not found!");
2814 if (!meas->id.isEmpty()) {
2816 (*id)->version = meas->id.version;
2817 (*id)->machid[0] = meas->id.machid[0];
2818 (*id)->machid[1] = meas->id.machid[1];
2819 (*id)->time = meas->id.time;
2824 for (k = 0; k < meas_info->nent(); k++) {
2825 kind = meas_info->dir[k]->kind;
2826 pos = meas_info->dir[k]->pos;
2829 if (!stream->read_tag(t_pTag,pos))
2831 nchan = *t_pTag->toInt();
2834 for (j = 0; j < nchan; j++) {
2839 to_find += nchan - 1;
2843 if (!stream->read_tag(t_pTag,pos))
2845 this_ch = t_pTag->toChInfo();
2847 qCritical (
"FIFF_CH_INFO : scan # out of range!");
2851 ch[this_ch.
scanNo-1] = this_ch;
2865static int read_ch_info(
const QString&
name,
2866 QList<FiffChInfo>& chsp,
2876 QList<FiffChInfo> chs;
2880 QList<FiffDirNode::SPtr> meas;
2886 meas = stream->dirtree()->dir_tree_find(
FIFFB_MEAS);
2887 if (meas.size() == 0) {
2888 qCritical (
"%s : no MEG data available here",
name.toUtf8().data());
2892 if (get_all_chs(stream,
2911#define TOO_CLOSE 1e-4
2913static int at_origin (
const Eigen::Vector3f& rr)
2918static int is_valid_eeg_ch(
const FiffChInfo& ch)
2934 const QStringList& bads,
2939 for (k = 0; k < nbad; k++)
2940 if (QString::compare(ch.
ch_name,bads[k]) == 0)
2948 const QStringList& bads,
2950 QList<FiffChInfo>& chsp,
2958 QList<FiffChInfo> chs;
2960 QList<FiffChInfo> meg;
2962 QList<FiffChInfo> eeg;
2969 if (read_ch_info(
name,
2977 for (k = 0; k < nchan; k++) {
2978 if (accept_ch(chs[k],bads,nbad)) {
2982 }
else if (do_eeg && chs[k].
kind ==
FIFFV_EEG_CH && is_valid_eeg_ch(chs[k])) {
3017 if (c->
cov.size() == 0)
3019#define REALLY_REVERT
3023 for (k = p = 0; k < c->
ncov; k++) {
3029 for (j = 0, p = 0; j < c->
ncov; j++)
3030 for (k = 0; k <= j; k++, p++)
3036 c->
eigen.resize(0,0);
3041 const QStringList& new_names,
3044 const QList<FiffChInfo>& chs)
3051 Eigen::VectorXd cov_local;
3052 Eigen::VectorXd cov_diag_local;
3056 std::unique_ptr<MNECovMatrix> res;
3059 qCritical(
"No channels specified for picking in mne_pick_chs_cov_omit");
3062 if (c->
names.isEmpty()) {
3063 qCritical(
"No names in covariance matrix. Cannot do picking.");
3067 for (j = 0; j < ncov; j++)
3069 for (j = 0; j < ncov; j++)
3070 for (k = 0; k < c->
ncov; k++)
3071 if (QString::compare(c->
names[k],new_names[j]) == 0) {
3075 for (j = 0; j < ncov; j++) {
3077 printf(
"All desired channels not found in the covariance matrix (at least missing %s).", new_names[j].toUtf8().constData());
3084 if (!chs.isEmpty()) {
3085 for (j = 0; j < ncov; j++)
3092 for (j = 0; j < ncov; j++)
3093 if (new_names[j].startsWith(
"MEG"))
3100 cov_diag_local.resize(ncov);
3101 for (j = 0; j < ncov; j++) {
3102 cov_diag_local[j] = c->
cov_diag[pick[j]];
3103 names.append(c->
names[pick[j]]);
3107 cov_local.resize(ncov*(ncov+1)/2);
3108 for (j = 0; j < ncov; j++) {
3109 names.append(c->
names[pick[j]]);
3110 for (k = 0; k <= j; k++) {
3111 from = mne_lt_packed_index_3(pick[j],pick[k]);
3112 to = mne_lt_packed_index_3(j,k);
3113 if (to < 0 || to > ncov*(ncov+1)/2-1) {
3114 printf(
"Wrong destination index in mne_pick_chs_cov : %d %d %d\n",j,k,to);
3117 if (from < 0 || from > c->
ncov*(c->
ncov+1)/2-1) {
3118 printf(
"Wrong source index in mne_pick_chs_cov : %d %d %d\n",pick[j],pick[k],from);
3121 cov_local[to] = c->
cov[from];
3123 if (is_meg[j] != is_meg[k])
3124 cov_local[to] = 0.0;
3131 res->bads = c->
bads;
3132 res->nbad = c->
nbad;
3133 res->proj.reset(c->
proj ? c->
proj->dup() :
nullptr);
3137 res->ch_class.resize(res->ncov);
3138 for (k = 0; k < res->ncov; k++)
3139 res->ch_class[k] = c->
ch_class[pick[k]];
3159 if (op->
nch != nch) {
3160 qCritical(
"Data vector size does not match projection operator");
3164 Eigen::VectorXd res = Eigen::VectorXd::Zero(op->
nch);
3166 for (p = 0; p < op->
nvec; p++) {
3169 for (k = 0; k < op->
nch; k++)
3170 w += vec[k]*pvec[k];
3171 for (k = 0; k < op->
nch; k++)
3172 res[k] = res[k] + w*pvec[k];
3175 if (do_complement) {
3176 for (k = 0; k < op->
nch; k++)
3177 vec[k] = vec[k] - res[k];
3180 for (k = 0; k < op->
nch; k++)
3188 const QStringList& list2,
int nlist2)
3194 if (list1.isEmpty() && list2.isEmpty())
3196 if (list1.isEmpty() || list2.isEmpty())
3198 if (nlist1 != nlist2)
3200 for (k = 0; k < nlist1; k++)
3201 if (QString::compare(list1[k],list2[k]) != 0)
3214 for (j = 1; j < n; j++)
3215 for (k = 0; k < j; k++) {
3217 mat[j][k] = mat[k][j];
3228 double **dcov = NULL;
3230 int do_complement =
TRUE;
3232 if (op == NULL || op->
nitems == 0)
3236 qCritical(
"Incompatible data in mne_proj_op_apply_cov");
3245 for (j = 0, p = 0; j < c->
ncov; j++)
3246 for (k = 0; k < c->
ncov; k++)
3247 dcov[j][k] = (j == k) ? c->
cov_diag[j] : 0;
3250 for (j = 0, p = 0; j < c->
ncov; j++)
3251 for (k = 0; k <= j; k++)
3252 dcov[j][k] = c->
cov[p++];
3253 for (j = 0; j < c->
ncov; j++)
3254 for (k = j+1; k < c->
ncov; k++)
3255 dcov[j][k] = dcov[k][j];
3261 for (k = 0; k < c->
ncov; k++) {
3268 for (k = 0; k < c->
ncov; k++)
3276 for (j = 0; j < c->
ncov; j++) {
3282 for (j = 0, p = 0; j < c->
ncov; j++)
3283 for (k = 0; k <= j; k++)
3284 c->
cov[p++] = dcov[j][k];
3336 int fit_sphere_to_bem =
TRUE;
3345 printf(
"\nSetting up the BEM model using %s...\n",d->
bemname.toUtf8().constData());
3346 printf(
"\nLoading surfaces...\n");
3349 printf(
"Three-layer model surfaces loaded.\n");
3355 printf(
"Homogeneous model surface loaded.\n");
3358 qCritical(
"Cannot use a homogeneous model in EEG calculations.");
3361 printf(
"\nLoading the solution matrix...\n");
3364 printf(
"Employing the head->MRI coordinate transform with the BEM model.\n");
3368 printf(
"BEM model %s is now set up\n",d->
bem_model->sol_name.toUtf8().constData());
3372 if (fit_sphere_to_bem) {
3374 float simplex_size = 2e-2;
3384 printf(
"Fitted sphere model origin : %6.1f %6.1f %6.1f mm rad = %6.1f mm.\n",
3387 d->
bem_funcs = f = new_dipole_fit_funcs();
3397 printf(
"Compensation setup done.\n");
3399 printf(
"MEG solution matrix...");
3412 printf(
"\tEEG solution matrix...");
3422 qCritical(
"EEG sphere model not defined.");
3449 printf(
"Sphere model origin : %6.1f %6.1f %6.1f mm.\n",
3479 fprintf (stderr,
"\n");
3494 Eigen::VectorXd stds;
3498 printf(
"Using standard noise values "
3499 "(MEG grad : %6.1f fT/cm MEG mag : %6.1f fT EEG : %6.1f uV)\n",
3500 1e13*grad_std,1e15*mag_std,1e6*eeg_std);
3504 nchan = nchan + meg->
ncoil;
3506 nchan = nchan + eeg->
ncoil;
3512 for (k = 0; k < meg->
ncoil; k++, n++) {
3514 stds[n] = mag_std*mag_std;
3519 stds[n] = 1e6*stds[n];
3523 stds[n] = grad_std*grad_std;
3528 for (k = 0; k < eeg->
ncoil; k++, n++) {
3529 stds[n] = eeg_std*eeg_std;
3540 const QList<FiffChInfo>&
chs,
3552 for (k = 0,
neeg = 0; k < nch; k++)
3556 if (projnames.size() == 0 &&
neeg == 0)
3559 for (k = 0; k < projnames.size(); k++) {
3563 printf(
"No linear projection information in %s.\n",projnames[k].toUtf8().data());
3569 printf(
"Loaded projection from %s:\n",projnames[k].toUtf8().data());
3581 for (k = 0; k < all->
nitems; k++)
3589 printf(
"Average EEG reference projection added:\n");
3599 printf(
"Projection will not have any effect on selected channels. Projection omitted.\n");
3618 float nave_ratio = ((float)f->
nave)/(
float)
nave;
3624 if (f->
noise->cov.size() > 0) {
3625 printf(
"Decomposing the sensor noise covariance matrix...\n");
3629 for (k = 0; k < f->
noise->ncov*(f->
noise->ncov+1)/2; k++)
3630 f->
noise->cov[k] = nave_ratio*f->
noise->cov[k];
3631 for (k = 0; k < f->
noise->ncov; k++) {
3632 f->
noise->lambda[k] = nave_ratio*f->
noise->lambda[k];
3633 if (f->
noise->lambda[k] < 0.0)
3634 f->
noise->lambda[k] = 0.0;
3640 for (k = 0; k < f->
noise->ncov; k++)
3641 f->
noise->cov_diag[k] = nave_ratio*f->
noise->cov_diag[k];
3642 printf(
"Decomposition not needed for a diagonal noise covariance matrix.\n");
3646 printf(
"Effective nave is now %d\n",
nave);
3658 float nave_ratio = ((float)f->
nave)/(
float)
nave;
3666 if (f->
noise->cov.size() > 0) {
3670 printf(
"Decomposing the noise covariance...");
3671 if (f->
noise->cov.size() > 0) {
3674 for (k = 0; k < f->
noise->ncov; k++) {
3675 if (f->
noise->lambda[k] < 0.0)
3676 f->
noise->lambda[k] = 0.0;
3679 for (k = 0; k < f->
noise->ncov*(f->
noise->ncov+1)/2; k++)
3680 f->
noise->cov[k] = nave_ratio*f->
noise->cov[k];
3681 for (k = 0; k < f->
noise->ncov; k++) {
3682 f->
noise->lambda[k] = nave_ratio*f->
noise->lambda[k];
3683 if (f->
noise->lambda[k] < 0.0)
3684 f->
noise->lambda[k] = 0.0;
3690 for (k = 0; k < f->
noise->ncov; k++)
3691 f->
noise->cov_diag[k] = nave_ratio*f->
noise->cov_diag[k];
3692 printf(
"Decomposition not needed for a diagonal noise covariance matrix.\n");
3696 printf(
"Effective nave is now %d\n",
nave);
3712 float nonsel_w = 30;
3733 nomit_meg = nomit_eeg = 0;
3750 if (
nmeg > 0 &&
nmeg-nomit_meg > 0 &&
nmeg-nomit_meg < min_nchan) {
3751 qCritical(
"Too few MEG channels remaining");
3755 if (
neeg > 0 &&
neeg-nomit_eeg > 0 &&
neeg-nomit_eeg < min_nchan) {
3756 qCritical(
"Too few EEG channels remaining");
3761 if (nomit_meg+nomit_eeg > 0) {
3762 if (f->
noise->cov.size() > 0) {
3763 for (j = 0; j < f->
noise->ncov; j++)
3764 for (k = 0; k <= j; k++) {
3765 f->
noise->cov[mne_lt_packed_index_3(j,k)] *= w[j]*w[k];
3769 for (j = 0; j < f->
noise->ncov; j++) {
3770 f->
noise->cov_diag[j] *= w[j]*w[j];
3788 const QString &measname,
3793 const QString &badname,
3794 const QString &noisename,
3802 const QList<QString> &projnames,
3811 QStringList badlist;
3813 QStringList file_bads;
3816 std::unique_ptr<MNECovMatrix> cov;
3818 std::unique_ptr<MNECTFCompDataSet> comp_data;
3824 if (!mriname.isEmpty()) {
3829 else if (!
bemname.isEmpty()) {
3830 qWarning(
"Source of MRI / head transform required for the BEM model is missing");
3834 float move[] = { 0.0, 0.0, 0.0 };
3835 float rot[3][3] = { { 1.0, 0.0, 0.0 },
3837 { 0.0, 0.0, 1.0 } };
3838 Eigen::Matrix3f rotMat;
3839 rotMat << rot[0][0], rot[0][1], rot[0][2],
3840 rot[1][0], rot[1][1], rot[1][2],
3841 rot[2][0], rot[2][1], rot[2][2];
3842 Eigen::Vector3f moveVec = Eigen::Map<Eigen::Vector3f>(move);
3854 if (!badname.isEmpty()) {
3857 printf(
"%d bad channels read from %s.\n",nbad,badname.toUtf8().data());
3860 if (badlist.isEmpty())
3862 for (k = 0; k < file_nbad; k++) {
3863 badlist.append(file_bads[k]);
3867 printf(
"%d bad channels read from the data file.\n",file_nbad);
3869 printf(
"%d bad channels total.\n",nbad);
3884 printf(
"Will use %3d MEG channels from %s\n",res->
nmeg,measname.toUtf8().data());
3886 printf(
"Will use %3d EEG channels from %s\n",res->
neeg,measname.toUtf8().data());
3907 QString qPath = QString(QCoreApplication::applicationDirPath() +
"/../resources/general/coilDefinitions/coil_def.dat");
3909 if ( !QCoreApplication::startingUp() )
3910 qPath = QCoreApplication::applicationDirPath() + QString(
"/../resources/general/coilDefinitions/coil_def.dat");
3911 else if (!file.exists())
3912 qPath =
"../resources/general/coilDefinitions/coil_def.dat";
3914 char *coilfile =
MALLOC_3(strlen(qPath.toUtf8().data())+1,
char);
3915 strcpy(coilfile,qPath.toUtf8().data());
3936 printf(
"Head coordinate coil definitions created.\n");
3947 res->
r0[0] = (*r0)[0];
3948 res->
r0[1] = (*r0)[1];
3949 res->
r0[2] = (*r0)[2];
3958 if (comp_data->ncomp > 0) {
3959 QList<FiffChInfo> comp_chs;
3962 printf(
"%d compensation data sets in %s\n",comp_data->ncomp,measname.toUtf8().data());
3963 QList<FiffChInfo> temp;
3981 printf(
"%d compensation channels in %s\n",comp_coils->
ncoil,measname.toUtf8().data());
4003 res->
proj.reset(proj_raw);
4005 if (res->
proj && res->
proj->nitems > 0) {
4006 printf(
"Final projection operator is:\n");
4015 printf(
"No projection will be applied to the data.\n");
4020 if (!noisename.isEmpty()) {
4023 printf(
"Read a %s noise-covariance matrix from %s\n",
4024 cov->cov_diag.size() > 0 ?
"diagonal" :
"full", noisename.toUtf8().data());
4039 printf(
"Picked appropriate channels from the noise-covariance matrix.\n");
4045 if (res->
proj && res->
proj->nitems > 0 && res->
proj->nvec > 0) {
4048 printf(
"Projection applied to the covariance matrix.\n");
4056 printf(
"Using only the main diagonal of the noise-covariance matrix.\n");
4062 if (res->
noise->cov.size() > 0) {
4079 for (k = 0, do_it = 0; k < res->
noise->ncov; k++) {
4081 regs[res->
noise->ch_class[k]] > 0.0)
4090 printf(
"No regularization applied to the noise-covariance matrix\n");
4096 printf(
"Decomposing the noise covariance...\n");
4097 if (res->
noise->cov.size() > 0) {
4100 printf(
"Eigenvalue decomposition done.\n");
4101 for (k = 0; k < res->
noise->ncov; k++) {
4102 if (res->
noise->lambda[k] < 0.0)
4103 res->
noise->lambda[k] = 0.0;
4107 printf(
"Decomposition not needed for a diagonal covariance matrix.\n");
4145 printf(
"Cannot pick time: %7.1f ms\n",1000*time);
4148 for (k = 0; k < data->
nchan; k++)
4151 printf(
"%g ",1e15*one[k]);
4159 for (k = 0; k < data->
nchan; k++)
4194 delete old; old = NULL;
4206 for (k = 0; k < ndip; k++) {
4208 this_fwd = res->
fwd + 3*k;
4219 for (p = 0; p < 3; p++)
4222 for (p = 0; p < 3; p++)
4223 res->
scales[3*k+p] = sqrt(S[p]);
4229 res->
scales[3*k+0] = res->
scales[3*k+1] = res->
scales[3*k+2] = sqrt(S[0]+S[1]+S[2])/3.0;
4231 for (p = 0; p < 3; p++) {
4232 if (res->
scales[3*k+p] > 0.0) {
4237 res->
scales[3*k+p] = 1.0;
4242 res->
scales[3*k+1] = 1.0;
4243 res->
scales[3*k+2] = 1.0;
4278static float fit_eval(
float *rd,
int npar,
void *user)
4293 printf(
"ncomp = %d\n",ncomp);
4295 for (c = 0, Bm2 = 0.0; c < ncomp; c++) {
4297 Bm2 = Bm2 + one*one;
4299 return fuser->
B2-Bm2;
4302static int find_best_guess(
float *B,
4313 double B2,Bm2,this_good,one;
4320 for (k = 0; k < guess->
nguess; k++) {
4322 if (fwd->
nch == nch) {
4323 ncomp = fwd->
sing[2]/fwd->
sing[0] > limit ? 3 : 2;
4324 for (c = 0, Bm2 = 0.0; c < ncomp; c++) {
4326 Bm2 = Bm2 + one*one;
4328 this_good = 1.0 - (B2 - Bm2)/B2;
4329 if (this_good > good) {
4336 printf(
"No reasonable initial guess found.");
4344static float **make_initial_dipole_simplex(
float *r0,
4356 float x = sqrt(3.0)/3.0;
4357 float r = sqrt(6.0)/12.0;
4360 float rr[][3] = { { x , 0.0, -r },
4368 for (j = 0; j < 4; j++) {
4370 for (k = 0; k < 3; k++)
4371 simplex[j][k] = size*simplex[j][k] + r0[k];
4376static int report_func(
int loop,
4388 fprintf(stdout,
"loop %d rd %7.2f %7.2f %7.2f fval %g %g par diff %g\n",
4389 loop,1000*r0[0],1000*r0[1],1000*r0[2],fval_lo,fval_hi,1000*par_diff);
4412 *ncomp = fwd->
sing[2]/fwd->
sing[0] > limit ? 3 : 2;
4414 Q[0] = Q[1] = Q[2] = 0.0;
4415 for (c = 0, Bm2 = 0.0; c < *ncomp; c++) {
4418 Bm2 = Bm2 + one*one;
4423 for (c = 0; c < 3; c++)
4424 Q[c] = fwd->
scales[c]*Q[c];
4432static float rtol(
float *vals,
int nval)
4438 minv = maxv = vals[0];
4439 for (k = 1; k < nval; k++) {
4445 return 2.0*(maxv-minv)/(maxv+minv);
4455#define MIN_STOL_LOOP 5
4457static float tryf (
float **p,
4461 float (*func)(
float *x,
int npar,
void *user_data),
4469 float fac1,fac2,ytry,*ptry;
4472 fac1 = (1.0-fac)/ndim;
4474 for (j = 0; j < ndim; j++)
4475 ptry[j] = psum[j]*fac1-p[ihi][j]*fac2;
4476 ytry = (*func)(ptry,ndim,user_data);
4478 if (ytry < y[ihi]) {
4480 for (j = 0; j < ndim; j++) {
4481 psum[j] += ptry[j]-p[ihi][j];
4482 p[ihi][j] = ptry[j];
4494 float (*func)(
float *x,
int npar,
void *user_data),
4499 int (*report_func)(
int loop,
4500 float *fitpar,
int npar,
4510 int i,j,ilo,ihi,inhi;
4512 float ytry,ysave,sum,rtol,*psum;
4520 for (j = 0; j < ndim; j++) {
4521 for (i = 0,sum = 0.0; i<mpts; i++)
4525 if (report_func != NULL && report > 0)
4526 (void)report_func (0,p[0],ndim,-1.0,-1.0,0.0);
4529 for (;;count++,loop++) {
4531 ihi = y[1]>y[2] ? (inhi = 2,1) : (inhi = 1,2);
4532 for (i = 0; i < mpts; i++) {
4533 if (y[i] < y[ilo]) ilo = i;
4534 if (y[i] > y[ihi]) {
4537 }
else if (y[i] > y[inhi])
4538 if (i != ihi) inhi = i;
4540 rtol = 2.0*std::fabs(y[ihi]-y[ilo])/(std::fabs(y[ihi])+std::fabs(y[ilo]));
4544 if (count == report && report_func != NULL) {
4545 if (report_func (loop,p[ilo],ndim,y[ilo],y[ihi],sqrt(dsum))) {
4546 printf(
"Interation interrupted.");
4552 if (rtol < ftol)
break;
4553 if (*neval >= max_eval) {
4554 printf(
"Maximum number of evaluations exceeded.");
4559 for (dsum = 0.0, j = 0; j < ndim; j++) {
4560 diff = p[ilo][j] - p[ihi][j];
4566 ytry = tryf(p,y,psum,ndim,func,user_data,ihi,neval,-
ALPHA);
4568 ytry = tryf(p,y,psum,ndim,func,user_data,ihi,neval,
GAMMA);
4569 else if (ytry >= y[inhi]) {
4571 ytry = tryf(p,y,psum,ndim,func,user_data,ihi,neval,
BETA);
4572 if (ytry >= ysave) {
4573 for (i = 0; i < mpts; i++) {
4575 for (j = 0; j < ndim; j++) {
4576 psum[j] = 0.5*(p[i][j]+p[ilo][j]);
4579 y[i] = (*func)(psum,ndim,user_data);
4583 for (j = 0; j < ndim; j++) {
4584 for (i = 0,sum = 0.0; i < mpts; i++)
4605 float **simplex = NULL;
4609 float ftol[] = { 1e-2, 1e-2 };
4610 float atol[] = { 0.2e-3, 0.2e-3 };
4613 int max_eval = 1000;
4614 int report_interval = verbose ? 1 : -1;
4617 float good,rd_guess[3],rd_final[3],Q[3],final_val;
4619 int k,p,neval,neval_tot,nchan,ncomp;
4633 if (find_best_guess(B,nchan,guess,limit,&best,&good) < 0)
4648 for (k = 0; k < ntol; k++) {
4657 simplex = make_initial_dipole_simplex(rd_guess,size);
4658 for (p = 0; p < 4; p++)
4659 vals[p] = fit_eval(simplex[p],3,fit);
4670 report_func) !=
OK) {
4674 printf(
"\nWarning (t = %8.1f ms) : g = %6.1f %% final val = %7.3f rtol = %f\n",
4675 1000*time,100*(1 - vals[0]/
user.B2),vals[0],rtol(vals,4));
4684 final_val = vals[0];
4692 if (fit_Q(fit,
user.B,rd_final,
user.limit,Q,&ncomp,&final_val) ==
OK) {
4695 for(
int i = 0; i < 3; ++i)
4696 res.
rd[i] = rd_final[i];
4697 for(
int i = 0; i < 3; ++i)
4699 res.
good = 1.0 - final_val/
user.B2;
4702 res.
khi2 = final_val;
4704 res.
nfree = nchan-3-ncomp-fit->
proj->nvec;
4706 res.
nfree = nchan-3-ncomp;
4707 res.
neval = neval_tot;
4731 static float Qx[] = {1.0,0.0,0.0};
4732 static float Qy[] = {0.0,1.0,0.0};
4733 static float Qz[] = {0.0,0.0,1.0};
4755 eeg_fwd[0] = fwd[0]+d->
nmeg;
4756 eeg_fwd[1] = fwd[1]+d->
nmeg;
4757 eeg_fwd[2] = fwd[2]+d->
nmeg;
4775 fprintf(stdout,
"orig : ");
4776 for (k = 0; k < 3; k++)
4778 fprintf(stdout,
"\n");
4781 for (k = 0; k < 3; k++)
4786 fprintf(stdout,
"proj : ");
4787 for (k = 0; k < 3; k++)
4789 fprintf(stdout,
"\n");
4795 if (d->
noise && whiten) {
4801 fprintf(stdout,
"white : ");
4802 for (k = 0; k < 3; k++)
4804 fprintf(stdout,
"\n");
#define FIFFV_MNE_SENSOR_COV
#define FIFF_MNE_COV_KIND
#define FIFFV_MNE_COORD_MNI_TAL
#define FIFFV_MNE_COORD_FS_TAL_LTZ
#define FIFFV_COORD_MRI_SLICE
#define FIFFV_MNE_COORD_CTF_DEVICE
#define FIFFV_COORD_DEVICE
#define FIFF_MNE_COV_DIAG
#define FIFFV_COORD_MRI_DISPLAY
#define FIFFV_COIL_CTF_REF_GRAD
#define FIFFV_MNE_COORD_MRI_VOXEL
#define FIFF_MNE_ROW_NAMES
#define FIFFV_MNE_NOISE_COV
#define FIFF_MNE_COV_EIGENVALUES
#define FIFF_MNE_PROJ_ITEM_ACTIVE
#define FIFFV_MNE_COORD_CTF_HEAD
#define FIFFV_MNE_PROJ_ITEM_EEG_AVREF
#define FIFFV_COIL_CTF_REF_MAG
#define FIFF_MNE_CH_NAME_LIST
#define FIFFV_COORD_ISOTRAK
#define FIFF_MNE_COV_NFREE
#define FIFFB_MNE_PARENT_MEAS_FILE
#define FIFF_MNE_COV_EIGENVECTORS
#define FIFFV_COORD_UNKNOWN
#define FIFFV_MNE_COORD_FS_TAL_GTZ
#define FIFFV_MNE_COORD_RAS
#define FIFFB_MNE_BAD_CHANNELS
FiffStream class declaration.
#define FIFF_PARENT_BLOCK_ID
#define FIFF_PROJ_ITEM_VECTORS
#define FIFF_PROJ_ITEM_KIND
#define FIFFV_SSS_JOB_NOTHING
#define FIFFV_BEM_SURF_ID_BRAIN
#define FIFF_PROJ_ITEM_CH_NAME_LIST
#define FIFF_PROJ_ITEM_NVEC
FiffCoordTrans class declaration.
MNECovMatrix class declaration.
#define MNE_COV_CH_MEG_MAG
#define MNE_COV_CH_MEG_GRAD
#define MNE_COV_CH_UNKNOWN
MNEProjItem class declaration.
MNESurface class declaration.
FwdCompData class declaration.
#define FWD_COIL_ACCURACY_ACCURATE
#define FWD_COIL_ACCURACY_NORMAL
FwdBemModel class declaration.
MNE Meas Data Set (MNEMeasDataSet) class declaration.
MNE Meas Data (MNEMeasData) class declaration.
GuessData class declaration.
void mne_string_to_name_list_3(const QString &s, QStringList &listp, int &nlistp)
int read_meg_eeg_ch_info(const QString &name, int do_meg, int do_eeg, const QStringList &bads, int nbad, QList< FiffChInfo > &chsp, int *nmegp, int *neegp)
void mne_free_cmatrix_3(float **m)
Eigen::MatrixXf toFloatEigenMatrix_3(float **mat, const int m, const int n)
void mne_free_cov_3(MNECovMatrix *c)
int mne_read_bad_channels_3(const QString &name, QStringList &listp, int &nlistp)
int mne_read_bad_channel_list_3(const QString &name, QStringList &listp, int &nlistp)
void mne_transpose_dsquare(double **mat, int n)
int mne_decompose_eigen_3(double *mat, double *lambda, Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > &vectors, int dim)
double ** mne_dmatrix_3(int nr, int nc)
int fit_sphere_to_points(const MNESurfaceOrVolume::PointsT &rr, int np, float simplex_size, float *r0, float *R)
float ** mne_cmatrix_3(int nr, int nc)
int is_selected_in_data(mshMegEegData d, const QString &ch_name)
#define FREE_CMATRIX_3(m)
int mne_whiten_one_data(float *data, float *whitened_data, int nchan, MNECovMatrix *C)
MNEProjOp * mne_read_proj_op_3(const QString &name)
DipoleForward * dipole_forward(DipoleFitData *d, float **rd, int ndip, DipoleForward *old)
#define FIFFV_COIL_CTF_OFFDIAG_REF_GRAD
void mne_proj_op_report_data_3(QTextStream &out, const char *tag, MNEProjOp *op, int list_data, char **exclude, int nexclude)
int mne_svd_3(float **mat, int m, int n, float *sing, float **uu, float **vv)
void fromFloatEigenMatrix_3(const Eigen::MatrixXf &from_mat, float **&to_mat, const int m, const int n)
#define ALLOC_CMATRIX_3(x, y)
#define FREE_DCMATRIX_3(m)
void mne_transpose_square_3(float **mat, int n)
const char * mne_coord_frame_name_3(int frame)
#define VEC_COPY_3(to, from)
float mne_dot_vectors_3(float *v1, float *v2, int nn)
int mne_get_values_from_data_3(float time, float integ, float **data, int nsamp, int nch, float tmin, float sfreq, int use_abs, float *value)
void mne_free_dcmatrix_3(double **m)
int mne_proj_op_make_proj(MNEProjOp *op)
FiffSparseMatrix * mne_convert_to_sparse_3(float **dense, int nrow, int ncol, int stor_type, float small)
int mne_classify_channels_cov(MNECovMatrix *cov, const QList< FiffChInfo > &chs, int nchan)
double ** mne_dmatt_dmat_mult2_3(double **m1, double **m2, int d1, int d2, int d3)
#define ALLOC_DCMATRIX_3(x, y)
float ** mne_mat_mat_mult_3(float **m1, float **m2, int d1, int d2, int d3)
std::unique_ptr< MNECovMatrix > mne_pick_chs_cov_omit(MNECovMatrix *c, const QStringList &new_names, int ncov, int omit_meg_eeg, const QList< FiffChInfo > &chs)
void mne_proj_op_report_3(QTextStream &out, const char *tag, MNEProjOp *op)
int mne_proj_op_chs_3(MNEProjOp *op, const QStringList &list, int nlist)
#define VEC_DIFF_3(from, to, diff)
int mne_is_diag_cov_3(MNECovMatrix *c)
QString mne_name_list_to_string_3(const QStringList &list)
std::unique_ptr< MNECovMatrix > mne_read_cov(const QString &name, int kind)
MNEProjOp * mne_read_proj_op_from_node_3(FiffStream::SPtr &stream, const FiffDirNode::SPtr &start)
int mne_proj_op_make_proj_bad(MNEProjOp *op, char **bad, int nbad)
int simplex_minimize(float **p, float *y, int ndim, float ftol, float stol, float(*func)(float *x, int npar, void *user_data), void *user_data, int max_eval, int *neval, int report, int(*report_func)(int loop, float *fitpar, int npar, double fval_lo, double fval_hi, double par_diff))
int mne_whiten_data(float **data, float **whitened_data, int np, int nchan, MNECovMatrix *C)
void print_fields(float *rd, float *Q, float time, float integ, DipoleFitData *fit, MNEMeasData *data)
void mne_merge_channels(const QList< FiffChInfo > &chs1, int nch1, const QList< FiffChInfo > &chs2, int nch2, QList< FiffChInfo > &resp, int *nresp)
int mne_decompose_eigen_cov_3(MNECovMatrix *c)
float ** mne_lu_invert_3(float **mat, int dim)
int mne_add_inv_cov_3(MNECovMatrix *c)
void mne_scale_vector_3(double scale, float *v, int nn)
int mne_proj_op_proj_dvector(MNEProjOp *op, double *vec, int nch, int do_complement)
int mne_name_list_match(const QStringList &list1, int nlist1, const QStringList &list2, int nlist2)
int mne_read_bad_channel_list_from_node_3(FiffStream::SPtr &stream, const FiffDirNode::SPtr &pNode, QStringList &listp, int &nlistp)
int mne_proj_op_apply_cov(MNEProjOp *op, MNECovMatrix *c)
void mne_mat_vec_mult2_3(float **m, float *v, float *result, int d1, int d2)
int mne_simplex_minimize(float **p, float *y, int ndim, float ftol, float(*func)(float *x, int npar, void *user_data), void *user_data, int max_eval, int *neval, int report, int(*report_func)(int loop, float *fitpar, int npar, double fval))
void mne_revert_to_diag_cov(MNECovMatrix *c)
int mne_pick_from_named_vector_3(MNENamedVector *vec, const QStringList &names, int nnames, int require_all, float *res)
int mne_read_meg_comp_eeg_ch_info_3(const QString &name, QList< FiffChInfo > &megp, int *nmegp, QList< FiffChInfo > &meg_compp, int *nmeg_compp, QList< FiffChInfo > &eegp, int *neegp, FiffCoordTrans *meg_head_t, fiffId *idp)
QString mne_channel_names_to_string_3(const QList< FiffChInfo > &chs, int nch)
void mne_regularize_cov(MNECovMatrix *c, float *regs)
void mne_add_scaled_vector_to_3(float *v1, float scale, float *v2, int nn)
void fromFloatEigenVector_3(const Eigen::VectorXf &from_vec, float *to_vec, const int n)
Electric Current Dipole (ECD) class declaration.
Dipole Fit Data class declaration.
Core MNE data structures (source spaces, source estimates, hemispheres).
struct MNELIB::fitSphereUser fitSphereUserRec
FIFF file I/O and data structures (raw, epochs, evoked, covariance, forward).
FiffId * fiffId
Backward-compatible pointer typedef for the old fiffId pointer.
FiffId fiffIdRec
Backward-compatible typedef for the old fiffIdRec struct.
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
struct INVERSELIB::dipoleFitFuncs dipoleFitFuncsRec
Forward modelling (BEM, MEG/EEG lead fields).
Coordinate transformation description.
QSharedPointer< FiffDirNode > SPtr
FIFF sparse matrix storage.
static FiffSparseMatrix::UPtr fiff_get_float_sparse_matrix(FIFFLIB::FiffTag::SPtr &tag)
FIFFLIB::fiff_int_t coding
static QStringList split_name_list(QString p_sNameList)
QSharedPointer< FiffStream > SPtr
QSharedPointer< FiffTag > SPtr
static int fwd_mag_dipole_field_vec(float *rm, FwdCoilSet *coils, float **Bval, void *client)
static FwdBemModel * fwd_bem_load_homog_surface(const QString &name)
static int fwd_sphere_field_vec(float *rd, FwdCoilSet *coils, float **Bval, void *client)
static int fwd_bem_set_head_mri_t(FwdBemModel *m, const FIFFLIB::FiffCoordTrans &t)
static int fwd_bem_field(float *rd, float *Q, FwdCoilSet *coils, float *B, void *client)
static QString fwd_bem_make_bem_sol_name(const QString &name)
static int fwd_bem_load_recompute_solution(const QString &name, int bem_method, int force_recompute, FwdBemModel *m)
static int fwd_bem_specify_coils(FwdBemModel *m, FwdCoilSet *coils)
static int fwd_sphere_field(float *rd, float Q[], FwdCoilSet *coils, float Bval[], void *client)
static int fwd_bem_specify_els(FwdBemModel *m, FwdCoilSet *els)
static FwdBemModel * fwd_bem_load_three_layer_surfaces(const QString &name)
static int fwd_bem_pot_els(float *rd, float *Q, FwdCoilSet *els, float *pot, void *client)
static int fwd_mag_dipole_field(float *rm, float M[], FwdCoilSet *coils, float Bval[], void *client)
bool is_axial_coil() const
Collection of FwdCoil objects representing a full MEG or EEG sensor array.
static FwdCoilSet * create_eeg_els(const QList< FIFFLIB::FiffChInfo > &chs, int nch, const FIFFLIB::FiffCoordTrans &t=FIFFLIB::FiffCoordTrans())
static FwdCoilSet * read_coil_defs(const QString &name)
FwdCoilSet * create_meg_coils(const QList< FIFFLIB::FiffChInfo > &chs, int nch, int acc, const FIFFLIB::FiffCoordTrans &t=FIFFLIB::FiffCoordTrans())
This structure is used in the compensated field calculations.
static void fwd_free_comp_data(void *d)
static FwdCompData * fwd_make_comp_data(MNELIB::MNECTFCompDataSet *set, FwdCoilSet *coils, FwdCoilSet *comp_coils, fwdFieldFunc field, fwdVecFieldFunc vec_field, fwdFieldGradFunc field_grad, void *client, fwdUserFreeFunc client_free)
static int fwd_comp_field_vec(float *rd, FwdCoilSet *coils, float **res, void *client)
static int fwd_comp_field(float *rd, float *Q, FwdCoilSet *coils, float *res, void *client)
Multi-layer spherical head model for EEG forward computation.
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)
Measurement data container holding multiple data sets for MNE inverse computations.
QList< FIFFLIB::FiffChInfo > chs
Combined MEG/EEG measurement data with inverse operator, field mapping, dipole fitting,...
INVERSELIB::MNEMeasData * meas
Workspace for sphere-fitting optimization, holding digitizer point coordinates and count.
const MNESurfaceOrVolume::PointsT * rr
Lookup record mapping a FIFF coordinate frame integer ID to its human-readable name string.
Forward field computation function pointers and client data for MEG and EEG dipole fitting.
MNELIB::mneUserFreeFunc eeg_client_free
fwdVecFieldFunc eeg_vec_pot
MNELIB::mneUserFreeFunc meg_client_free
fwdVecFieldFunc meg_vec_field
Workspace for the dipole fitting objective function, holding forward model, measured field,...
Dipole Fit Data implementation.
static int scale_dipole_fit_noise_cov(DipoleFitData *f, int nave)
static int compute_dipole_field(DipoleFitData *d, float *rd, int whiten, float **fwd)
std::unique_ptr< FIFFLIB::FiffCoordTrans > meg_head_t
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)
static int select_dipole_fit_noise_cov(DipoleFitData *f, mshMegEegData d)
static std::unique_ptr< MNELIB::MNECovMatrix > ad_hoc_noise(FWDLIB::FwdCoilSet *meg, FWDLIB::FwdCoilSet *eeg, float grad_std, float mag_std, float eeg_std)
std::unique_ptr< MNELIB::MNECovMatrix > noise_orig
std::unique_ptr< FWDLIB::FwdBemModel > bem_model
static int make_projection(const QList< QString > &projnames, const QList< FIFFLIB::FiffChInfo > &chs, int nch, MNELIB::MNEProjOp **res)
dipoleFitFuncs mag_dipole_funcs
std::unique_ptr< MNELIB::MNECovMatrix > noise
static int setup_forward_model(DipoleFitData *d, MNELIB::MNECTFCompDataSet *comp_data, FWDLIB::FwdCoilSet *comp_coils)
static bool fit_one(DipoleFitData *fit, GuessData *guess, float time, float *B, int verbose, ECD &res)
std::unique_ptr< FWDLIB::FwdCoilSet > meg_coils
QList< FIFFLIB::FiffChInfo > chs
dipoleFitFuncs sphere_funcs
static int scale_noise_cov(DipoleFitData *f, int nave)
std::unique_ptr< FWDLIB::FwdEegSphereModel > eeg_model
std::unique_ptr< FIFFLIB::FiffCoordTrans > mri_head_t
static DipoleForward * dipole_forward_one(DipoleFitData *d, float *rd, DipoleForward *old)
std::unique_ptr< FWDLIB::FwdCoilSet > eeg_els
std::unique_ptr< MNELIB::MNEProjOp > proj
Stores forward field matrices and source space data for magnetic dipole fitting.
Single equivalent current dipole with position, orientation, amplitude, and goodness-of-fit.
Precomputed guess point grid with forward fields for initial dipole position candidates.
DipoleForward ** guess_fwd
Covariance matrix storage.
Eigen::VectorXd inv_lambda
static std::unique_ptr< MNECovMatrix > create_sparse(int kind, int ncov, const QStringList &names, FIFFLIB::FiffSparseMatrix *cov_sparse)
std::unique_ptr< MNEProjOp > proj
static std::unique_ptr< MNECovMatrix > create_diag(int kind, int ncov, const QStringList &names, const Eigen::VectorXd &cov_diag)
static std::unique_ptr< MNECovMatrix > create_dense(int kind, int ncov, const QStringList &names, const Eigen::VectorXd &cov)
std::unique_ptr< MNESssData > sss
static std::unique_ptr< MNECovMatrix > create(int kind, int ncov, const QStringList &names, const Eigen::VectorXd &cov, const Eigen::VectorXd &cov_diag)
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > eigen
Collection of CTF third-order gradient compensation operators.
static std::unique_ptr< MNECTFCompDataSet > read(const QString &name)
A dense matrix with named rows and columns.
static std::unique_ptr< MNENamedMatrix > build(int nrow, int ncol, const QStringList &rowlist, const QStringList &collist, const Eigen::MatrixXf &data)
Factory: build a named matrix from its constituent parts.
A single SSP (Signal-Space Projection) item.
std::unique_ptr< MNENamedMatrix > vecs
Projection operator managing a set of linear projection items and the final compiled projector matrix...
void free_proj()
Release the compiled projector data.
RowMajorMatrixXf proj_data
static MNEProjOp * create_average_eeg_ref(const QList< FIFFLIB::FiffChInfo > &chs, int nch)
Create an average EEG reference projector.
int affect(const QStringList &list, int nlist)
MNEProjOp * combine(MNEProjOp *from)
Append all projection items from another operator.
int affect_chs(const QList< FIFFLIB::FiffChInfo > &chs, int nch)
QList< MNELIB::MNEProjItem > items
void add_item_active(const MNENamedMatrix *vecs, int kind, const QString &desc, int is_active)
Add a projection item with an explicit active/inactive state.
Container for Signal Space Separation (SSS/Maxwell filtering) expansion coefficients and metadata.
Eigen::VectorXi comp_info
static MNESssData * read_from_node(QSharedPointer< FIFFLIB::FiffStream > &stream, const QSharedPointer< FIFFLIB::FiffDirNode > &start)
Eigen::Matrix< float, Eigen::Dynamic, 3, Eigen::RowMajor > PointsT
static FiffCoordTrans readMriTransform(const QString &name)
static FiffCoordTrans readMeasTransform(const QString &name)
Eigen::MatrixX3f apply_trans(const Eigen::MatrixX3f &rr, bool do_move=true) const
static FiffCoordTrans readFromTag(const QSharedPointer< FiffTag > &tag)