7 #include "../fwd_coil_set.h"
8 #include "../fwd_comp_data.h"
10 #include "../fwd_eeg_sphere_model_set.h"
11 #include "../fwd_bem_model.h"
24 #include <Eigen/Dense>
26 #include <QCoreApplication>
30 using namespace Eigen;
31 using namespace FWDLIB;
32 using namespace FIFFLIB;
33 using namespace MNELIB;
55 #define ALLOC_ICMATRIX_41(x,y) mne_imatrix_41((x),(y))
57 #define MALLOC_41(x,t) (t *)malloc((x)*sizeof(t))
58 #define REALLOC_41(x,y,t) (t *)((x == Q_NULLPTR) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
60 #define FREE_41(x) if ((char *)(x) != Q_NULLPTR) free((char *)(x))
62 #define VEC_COPY_41(to,from) {\
63 (to)[X_41] = (from)[X_41];\
64 (to)[Y_41] = (from)[Y_41];\
65 (to)[Z_41] = (from)[Z_41];\
68 #define VEC_DOT_41(x,y) ((x)[X_41]*(y)[X_41] + (x)[Y_41]*(y)[Y_41] + (x)[Z_41]*(y)[Z_41])
70 #define VEC_LEN_41(x) sqrt(VEC_DOT_41(x,x))
72 #define ALLOC_CMATRIX_41(x,y) mne_cmatrix_41((x),(y))
73 #define FREE_CMATRIX_41(m) mne_free_cmatrix_41((m))
74 #define FREE_ICMATRIX_41(m) mne_free_icmatrix_41((m))
76 static void matrix_error_41(
int kind,
int nr,
int nc)
80 printf(
"Failed to allocate memory pointers for a %d x %d matrix\n",nr,nc);
82 printf(
"Failed to allocate memory for a %d x %d matrix\n",nr,nc);
84 printf(
"Allocation error for a %d x %d matrix\n",nr,nc);
85 if (
sizeof(
void *) == 4) {
86 printf(
"This is probably because you seem to be using a computer with 32-bit architecture.\n");
87 printf(
"Please consider moving to a 64-bit platform.");
89 printf(
"Cannot continue. Sorry.\n");
93 float **mne_cmatrix_41(
int nr,
int nc)
100 m = MALLOC_41(nr,
float *);
101 if (!m) matrix_error_41(1,nr,nc);
102 whole = MALLOC_41(nr*nc,
float);
103 if (!whole) matrix_error_41(2,nr,nc);
110 int **mne_imatrix_41(
int nr,
int nc)
116 m = MALLOC_41(nr,
int *);
117 if (!m) matrix_error_41(1,nr,nc);
118 whole = MALLOC_41(nr*nc,
int);
119 if (!whole) matrix_error_41(2,nr,nc);
125 void mne_free_cmatrix_41 (
float **m)
133 void mne_free_icmatrix_41 (
int **m)
142 fiffId get_file_id(
const QString& name)
147 if(!stream->open()) {
153 id->version = stream->id().version;
154 id->machid[0] = stream->id().machid[0];
155 id->machid[1] = stream->id().machid[1];
156 id->time = stream->id().time;
331 QList<FiffChInfo>& listMegCh,
333 QList<FiffChInfo>& listMegComp,
335 QList<FiffChInfo>& listEegCh,
340 int iNumCh = pFiffInfoBase->nchan;
341 for (
int k = 0;
k < iNumCh;
k++) {
342 if (pFiffInfoBase->chs[
k].kind == FIFFV_MEG_CH) {
343 listMegCh.append(pFiffInfoBase->chs[
k]);
346 listMegComp.append(pFiffInfoBase->chs[
k]);
348 }
else if (pFiffInfoBase->chs[
k].kind == FIFFV_EEG_CH) {
349 listEegCh.append(pFiffInfoBase->chs[
k]);
354 if(!m_pSettings->meg_head_t) {
357 *transDevHeadOld = m_pSettings->meg_head_t;
360 qCritical(
"MEG -> head coordinate transformation not found.");
363 id = pFiffInfoBase->meas_id;
367 int mne_check_chinfo(
const QList<FiffChInfo>& chs,
377 for (
k = 0;
k < nch;
k++) {
378 if (chs.at(
k).kind == FIFFV_EEG_CH) {
379 if (chs.at(
k).chpos.r0.norm() < close) {
380 qCritical(
"Some EEG channels do not have locations assigned.");
399 srand ( time(Q_NULLPTR) );
400 double rand_1 = (double)(rand() % 100);rand_1 /= 100;
401 double rand_2 = (double)(rand() % 100);rand_2 /= 100;
404 seconds = time (Q_NULLPTR);
408 t_id->
machid[0] = 65536*rand_1;
409 t_id->
machid[1] = 65536*rand_2;
416 fiff_int_t datasize = 5*4;
418 *t_pStream << (qint32)kind;
419 *t_pStream << (qint32)FIFFT_ID_STRUCT;
420 *t_pStream << (qint32)datasize;
421 *t_pStream << (qint32)FIFFV_NEXT_SEQ;
427 data[1] = t_id->
machid[0];
428 data[2] = t_id->
machid[1];
432 for(qint32 i = 0; i < 5; ++i)
433 *t_pStream << data[i];
448 fiff_int_t datasize = 4*2*12 + 4*2;
451 *t_pStream << (qint32)FIFFT_COORD_TRANS_STRUCT;
452 *t_pStream << (qint32)datasize;
453 *t_pStream << (qint32)FIFFV_NEXT_SEQ;
458 *t_pStream << (qint32)trans->
from;
459 *t_pStream << (qint32)trans->
to;
465 for (r = 0; r < 3; ++r)
466 for (c = 0; c < 3; ++c)
467 *t_pStream << (
float)trans->
rot(r,c);
468 for (r = 0; r < 3; ++r)
469 *t_pStream << (
float)trans->
move[r];
474 for (r = 0; r < 3; ++r)
475 for (c = 0; c < 3; ++c)
476 *t_pStream << (
float)trans->
invrot(r,c);
477 for (r = 0; r < 3; ++r)
478 *t_pStream << (
float)trans->
invmove[r];
481 static int **make_file_triangle_list_41(
int **tris,
int ntri)
486 int **res = ALLOC_ICMATRIX_41(ntri,3);
489 for (j = 0; j < ntri; j++)
490 for (
k = 0;
k < 3;
k++)
491 res[j][
k] = tris[j][
k]+1;
495 void mne_write_bad_channel_list_new(
FiffStream::SPtr& t_pStream,
const QStringList& t_badList)
498 t_pStream->start_block(FIFFB_MNE_BAD_CHANNELS);
499 t_pStream->write_name_list(FIFF_MNE_CH_NAME_LIST,t_badList);
500 t_pStream->end_block(FIFFB_MNE_BAD_CHANNELS);
544 MatrixXf mat(rows,cols);
546 for (
int i = 0; i < rows; ++i) {
547 for(
int j = 0; j < cols; ++j) {
548 mat(i,j) = data[i][j];
552 t_pStream->write_float_matrix(kind, mat);
618 MatrixXi mat(rows,cols);
620 for (
int i = 0; i < rows; ++i) {
621 for(
int j = 0; j < cols; ++j) {
622 mat(i,j) = data[i][j];
626 t_pStream->write_int_matrix(kind, mat);
691 int datasize,idxsize,ptrsize;
694 datasize = mat->
nz *
sizeof(fiff_float_t);
695 idxsize = mat->
nz *
sizeof(fiff_int_t);
696 if (mat->
coding == FIFFTS_MC_CCS)
697 ptrsize = (mat->
n+1) *
sizeof(fiff_int_t);
698 else if (mat->
coding == FIFFTS_MC_RCS)
699 ptrsize = (mat->
m+1) *
sizeof(fiff_int_t);
701 qCritical(
"Incomprehensible sparse matrix coding");
705 if (datasize <= 0 || idxsize <= 0 || ptrsize <= 0) {
706 qCritical(
"fiff_write_float_ccs_matrix: negative vector size(s) in sparse matrix!\n");
711 if (mat->
coding == FIFFTS_MC_CCS)
712 type = FIFFT_FLOAT | FIFFT_CCS_MATRIX;
713 else if (mat->
coding == FIFFTS_MC_RCS)
714 type = FIFFT_FLOAT | FIFFT_RCS_MATRIX;
716 qCritical(
"Incomprehensible sparse matrix coding");
725 *t_pStream << (qint32)kind;
726 *t_pStream << (qint32)type;
727 *t_pStream << (qint32)(datasize+idxsize+ptrsize+4*
sizeof(fiff_int_t));
728 *t_pStream << (qint32)FIFFV_NEXT_SEQ;
735 for(
k = 0;
k < mat->
nz; ++
k)
736 *t_pStream << mat->
data[
k];
756 for(
k = 0; k < mat->nz; ++
k)
757 *t_pStream << mat->
inds[
k];
774 if (mat->
coding == FIFFTS_MC_CCS) {
776 for(
k = 0;
k < mat->
n+1; ++
k)
777 *t_pStream << mat->
ptrs[
k];
793 for(
k = 0;
k < mat->
m+1; ++
k)
794 *t_pStream << mat->
ptrs[
k];
811 *t_pStream << (qint32)mat->
nz;
816 *t_pStream << (qint32)mat->
m;
821 *t_pStream << (qint32)mat->
n;
826 *t_pStream << (qint32)two;
841 static int comp_points2(
const void *vp1,
const void *vp2)
847 if (v1->vert > v2->vert)
849 else if (v1->vert == v2->vert)
855 void mne_sort_nearest_by_vertex(
MneNearest* points,
int npoint)
858 if (npoint > 1 && points != Q_NULLPTR)
859 qsort(points,npoint,
sizeof(
MneNearest),comp_points2);
872 int j,
k,nz,ptr,size,ind;
873 int stor_type = FIFFTS_MC_RCS;
875 for (j = 0, nz = 0; j < nrow; j++)
879 qCritical(
"No nonzero elements specified.");
882 size = nz*(
sizeof(fiff_float_t) +
sizeof(fiff_int_t)) +
883 (nrow+1)*(
sizeof(fiff_int_t));
886 sparse->
coding = stor_type;
890 sparse->
data = (
float *)malloc(size);
891 sparse->
inds = (
int *)(sparse->
data+nz);
894 for (j = 0, nz = 0; j < nrow; j++) {
896 for (
k = 0;
k < nnz[j];
k++) {
899 ind = sparse->
inds[nz] = colindex[j][
k];
900 if (ind < 0 || ind >= ncol) {
901 qCritical(
"Column index out of range in mne_create_sparse_rcs");
905 sparse->
data[nz] = vals[j][
k];
907 sparse->
data[nz] = 0.0;
910 sparse->
ptrs[j] = ptr;
912 sparse->
ptrs[nrow] = nz;
913 for (j = nrow-1; j >= 0; j--)
914 if (sparse->
ptrs[j] < 0)
915 sparse->
ptrs[j] = sparse->
ptrs[j+1];
930 int *nnz = Q_NULLPTR;
931 int **colindex = Q_NULLPTR;
932 float **vals = Q_NULLPTR;
936 if (mat->
coding != FIFFTS_MC_RCS) {
937 qCritical(
"The input matrix to mne_add_upper_triangle_rcs must be in RCS format");
940 if (mat->
m != mat->
n) {
941 qCritical(
"The input matrix to mne_pick_lower_triangle_rcs must be square");
947 nnz = MALLOC_41(mat->
m,
int);
948 colindex = MALLOC_41(mat->
m,
int *);
949 vals = MALLOC_41(mat->
m,
float *);
950 for (i = 0; i < mat->
m; i++) {
951 nnz[i] = mat->
ptrs[i+1] - mat->
ptrs[i];
953 colindex[i] = MALLOC_41(nnz[i],
int);
954 vals[i] = MALLOC_41(nnz[i],
float);
955 for (j = mat->
ptrs[i],
k = 0; j < mat->ptrs[i+1]; j++) {
956 if (mat->
inds[j] <= i) {
957 vals[i][
k] = mat->
data[j];
958 colindex[i][
k] = mat->
inds[j];
965 colindex[i] = Q_NULLPTR;
972 res = mne_create_sparse_rcs(mat->
m,mat->
n,nnz,colindex,vals);
975 for (i = 0; i < mat->
m; i++) {
976 FREE_41(colindex[i]);
992 int *nneighbors = Q_NULLPTR;
993 int *neighbors = Q_NULLPTR;
994 int *inuse_map = Q_NULLPTR;
999 if (ss->type != FIFFV_MNE_SPACE_VOLUME)
1001 if (!ss->neighbor_vert || !ss->nneighbor_vert)
1003 if (selected_only) {
1004 inuse_map = MALLOC_41(ss->np,
int);
1005 for (
k = 0,p = 0, ntot = 0;
k < ss->np;
k++) {
1007 ntot += ss->nneighbor_vert[
k];
1013 nneighbors = MALLOC_41(ss->nuse,
int);
1014 neighbors = MALLOC_41(ntot,
int);
1019 for (
k = 0, nvert = 0, ntot = 0;
k < ss->np;
k++) {
1021 neigh = ss->neighbor_vert[
k];
1022 nneigh = ss->nneighbor_vert[
k];
1023 nneighbors[nvert++] = nneigh;
1024 for (p = 0; p < nneigh; p++)
1025 neighbors[ntot++] = neigh[p] < 0 ? -1 : inuse_map[neigh[p]];
1030 for (
k = 0, ntot = 0;
k < ss->np;
k++)
1031 ntot += ss->nneighbor_vert[
k];
1032 nneighbors = MALLOC_41(ss->np,
int);
1033 neighbors = MALLOC_41(ntot,
int);
1035 for (
k = 0, ntot = 0;
k < ss->np;
k++) {
1036 neigh = ss->neighbor_vert[
k];
1037 nneigh = ss->nneighbor_vert[
k];
1038 nneighbors[
k] = nneigh;
1039 for (p = 0; p < nneigh; p++)
1040 neighbors[ntot++] = neigh[p];
1044 t_pStream->write_int(FIFF_MNE_SOURCE_SPACE_NNEIGHBORS,nneighbors,nvert);
1053 t_pStream->write_int(FIFF_MNE_SOURCE_SPACE_NEIGHBORS,neighbors,ntot);
1065 if (!selected_only) {
1066 if (ss->voxel_surf_RAS_t) {
1067 write_coord_trans_old(t_pStream, ss->voxel_surf_RAS_t);
1078 if (ss->interpolator && !ss->MRI_volume.isEmpty()) {
1079 t_pStream->start_block(FIFFB_MNE_PARENT_MRI_FILE);
1080 if (ss->MRI_surf_RAS_RAS_t)
1081 write_coord_trans_old(t_pStream, ss->MRI_surf_RAS_RAS_t);
1082 if (ss->MRI_voxel_surf_RAS_t)
1083 write_coord_trans_old(t_pStream, ss->MRI_voxel_surf_RAS_t);
1085 if (ss->interpolator)
1087 if (ss->MRI_vol_dims[0] > 0 && ss->MRI_vol_dims[1] > 0 && ss->MRI_vol_dims[2] > 0) {
1088 t_pStream->write_int(FIFF_MRI_WIDTH,&ss->MRI_vol_dims[0]);
1089 t_pStream->write_int(FIFF_MRI_HEIGHT,&ss->MRI_vol_dims[1]);
1090 t_pStream->write_int(FIFF_MRI_DEPTH,&ss->MRI_vol_dims[2]);
1092 t_pStream->end_block(FIFFB_MNE_PARENT_MRI_FILE);
1096 if (ss->interpolator && !ss->MRI_volume.isEmpty()) {
1098 qCritical(
"Cannot write the interpolator for selection yet");
1107 FREE_41(nneighbors);
1115 float **sel = Q_NULLPTR;
1116 int **tris = Q_NULLPTR;
1117 int *nearest = Q_NULLPTR;
1118 float *nearest_dist = Q_NULLPTR;
1122 qCritical(
"No points in the source space being saved");
1126 t_pStream->start_block(FIFFB_MNE_SOURCE_SPACE);
1131 if (ss->type != FIFFV_MNE_SPACE_UNKNOWN)
1133 if (ss->id != FIFFV_MNE_SURF_UNKNOWN)
1135 if (!ss->subject.isEmpty() && ss->subject.size() > 0) {
1136 QString subj(ss->subject);
1142 if (selected_only) {
1143 if (ss->nuse == 0) {
1144 qCritical(
"No vertices in use. Cannot write active-only vertices from this source space");
1147 sel = ALLOC_CMATRIX_41(ss->nuse,3);
1149 for (p = 0, pp = 0; p < ss->np; p++) {
1151 sel[pp][X_41] = ss->rr[p][X_41];
1152 sel[pp][Y_41] = ss->rr[p][Y_41];
1153 sel[pp][Z_41] = ss->rr[p][Z_41];
1159 for (p = 0, pp = 0; p < ss->np; p++) {
1161 sel[pp][X_41] = ss->nn[p][X_41];
1162 sel[pp][Y_41] = ss->nn[p][Y_41];
1163 sel[pp][Z_41] = ss->nn[p][Z_41];
1168 FREE_CMATRIX_41(sel); sel = Q_NULLPTR;
1173 if (ss->nuse_tri > 0) {
1179 tris = make_file_triangle_list(ss->use_itris,ss->nuse_tri);
1181 ss->nuse_tri,3) == FIFF_FAIL)
1187 ss->nuse_tri,3) == FIFF_FAIL)
1189 FREE_ICMATRIX(tris); tris = Q_NULLPTR;
1201 if (ss->nuse > 0 && ss->inuse) {
1218 tris = make_file_triangle_list_41(ss->itris,ss->ntri);
1224 FREE_ICMATRIX_41(tris); tris = Q_NULLPTR;
1226 if (ss->nuse_tri > 0) {
1230 tris = make_file_triangle_list_41(ss->use_itris,ss->nuse_tri);
1236 FREE_ICMATRIX_41(tris); tris = Q_NULLPTR;
1239 nearest = MALLOC_41(ss->np,
int);
1240 nearest_dist = MALLOC_41(ss->np,
float);
1242 mne_sort_nearest_by_vertex(ss->nearest,ss->np);
1243 for (p = 0; p < ss->np; p++) {
1244 nearest[p] = ss->nearest[p].nearest;
1245 nearest_dist[p] = ss->nearest[p].dist;
1266 FREE_41(nearest); nearest = Q_NULLPTR;
1267 FREE_41(nearest_dist); nearest_dist = Q_NULLPTR;
1290 t_pStream->end_block(FIFFB_MNE_SOURCE_SPACE);
1294 FREE_ICMATRIX_41(tris);
1295 FREE_CMATRIX_41(sel);
1297 FREE_41(nearest_dist);
1302 QString mne_name_list_to_string_41(
const QStringList& list)
1307 int nlist = list.size();
1309 if (nlist == 0 || list.isEmpty())
1312 for (
int k = 0;
k < nlist-1;
k++) {
1316 res += list[nlist-1];
1329 t_pStream->start_block(FIFFB_MNE_NAMED_MATRIX);
1331 t_pStream->write_int(FIFF_MNE_NROW,&mat->nrow);
1332 t_pStream->write_int(FIFF_MNE_NCOL,&mat->ncol);
1333 if (!mat->rowlist.isEmpty()) {
1334 names = mne_name_list_to_string_41(mat->rowlist);
1335 t_pStream->write_string(FIFF_MNE_ROW_NAMES,names);
1337 if (!mat->collist.isEmpty()) {
1338 names = mne_name_list_to_string_41(mat->collist);
1339 t_pStream->write_string(FIFF_MNE_COL_NAMES,names);
1341 fiff_write_float_matrix_old (t_pStream,kind,mat->data,mat->nrow,mat->ncol);
1343 t_pStream->end_block(FIFFB_MNE_NAMED_MATRIX);
1348 bool fiff_put_dir (
FiffStream::SPtr& t_pStream,
const QList<FiffDirEntry::SPtr>& dir)
1353 int nent = dir.size();
1358 for (
k = 0;
k < nent;
k++) {
1359 if (dir[
k]->kind == FIFF_DIR_POINTER) {
1363 if (!t_pStream->read_tag(t_pTag,dir[
k]->pos)) {
1364 fprintf (stderr,
"Could not read FIFF_DIR_POINTER!\n");
1370 dirpos = *t_pTag->toInt();
1376 dirpos = (fiff_int_t)t_pStream->write_dir_entries(dir);
1378 printf (
"Could not update directory!\n");
1380 t_pTag->setNum(dirpos);
1383 t_pStream->write_dir_pointer(dirpos, dir[
k]->pos);
1400 printf (
"Could not find place for directory!\n");
1406 bool write_solution(
const QString& name,
1409 const QString& mri_file,
1412 const QString& meas_file,
1415 QList<FiffChInfo> meg_chs,
1417 QList<FiffChInfo> eeg_chs,
1443 t_pStream->start_block(FIFFB_MNE);
1449 t_pStream->start_block(FIFFB_MNE_PARENT_MRI_FILE);
1452 if (mri_id != Q_NULLPTR)
1453 write_id_old(t_pStream, FIFF_PARENT_FILE_ID, mri_id);
1454 write_coord_trans_old(t_pStream, mri_head_t);
1456 t_pStream->end_block(FIFFB_MNE_PARENT_MRI_FILE);
1463 QStringList file_bads;
1465 t_pStream->start_block(FIFFB_MNE_PARENT_MEAS_FILE);
1469 t_pStream->write_id(FIFF_PARENT_BLOCK_ID, meas_id);
1471 write_coord_trans_old(t_pStream, meg_head_t);
1473 int nchan = nmeg+neeg;
1478 for (
k = 0, p = 0;
k < nmeg;
k++) {
1502 t_pStream->write_ch_info(meg_chs[
k]);
1505 for (
k = 0;
k < neeg;
k++) {
1529 t_pStream->write_ch_info(eeg_chs[
k]);
1538 QFile fileBad(meas_file);
1540 if(!t_pStreamBads->open())
1542 file_bads = t_pStreamBads->read_bad_channels(t_pStreamBads->dirtree());
1547 mne_write_bad_channel_list_new(t_pStream,file_bads);
1549 t_pStream->end_block(FIFFB_MNE_PARENT_MEAS_FILE);
1555 for (
k = 0, nvert = 0;
k < nspace;
k++) {
1556 if (mne_write_one_source_space(t_pStream,spaces[
k],FALSE) == FIFF_FAIL)
1558 nvert += spaces[
k]->nuse;
1565 t_pStream->start_block(FIFFB_MNE_FORWARD_SOLUTION);
1567 int val = FIFFV_MNE_MEG;
1568 t_pStream->write_int(FIFF_MNE_INCLUDED_METHODS,&val);
1570 val = fixed_ori ? FIFFV_MNE_FIXED_ORI : FIFFV_MNE_FREE_ORI;
1576 t_pStream->write_named_matrix(FIFF_MNE_FORWARD_SOLUTION,meg_solution);
1582 t_pStream->write_named_matrix(FIFF_MNE_FORWARD_SOLUTION_GRAD,meg_solution_grad);
1588 t_pStream->end_block(FIFFB_MNE_FORWARD_SOLUTION);
1594 t_pStream->start_block(FIFFB_MNE_FORWARD_SOLUTION);
1596 int val = FIFFV_MNE_EEG;
1597 t_pStream->write_int(FIFF_MNE_INCLUDED_METHODS,&val);
1599 val = fixed_ori ? FIFFV_MNE_FIXED_ORI : FIFFV_MNE_FREE_ORI;
1605 t_pStream->write_named_matrix(FIFF_MNE_FORWARD_SOLUTION,eeg_solution);
1611 t_pStream->write_named_matrix(FIFF_MNE_FORWARD_SOLUTION_GRAD,eeg_solution_grad);
1617 t_pStream->end_block(FIFFB_MNE_FORWARD_SOLUTION);
1620 t_pStream->end_block(FIFFB_MNE);
1621 t_pStream->end_file();
1628 t_pStreamIn = FiffStream::open_update(fileIn);
1630 if (!fiff_put_dir(t_pStreamIn,t_pStreamIn->dir()))
1633 t_pStreamIn->close();
1641 t_pStreamIn->close();
1650 bool mne_attach_env(
const QString& name,
const QString& command)
1656 QString cwd = QDir::currentPath();
1661 QFile fileInOut(name);
1666 FiffId id(FiffId::new_file_id());
1675 if (!fileInOut.exists()) {
1676 qCritical(
"File %s does not exist. Cannot attach env info.",name.toUtf8().constData());
1686 if (!(t_pStreamInOut = FiffStream::open_update(fileInOut)))
1691 for (insert = -1, b = 0; insert_blocks[b] >= 0; b++) {
1692 for (
k = 0;
k < t_pStreamInOut->nent();
k++) {
1693 if (t_pStreamInOut->dir()[
k]->kind == FIFF_BLOCK_START) {
1694 if (!t_pStreamInOut->read_tag(t_pTag, t_pStreamInOut->dir()[
k]->pos))
1696 if (*(t_pTag->toInt()) == insert_blocks[b]) {
1706 qCritical(
"Suitable place for environment insertion not found.");
1720 if (where < 0 || where >= t_pStreamInOut->nent()-1) {
1721 qCritical(
"illegal insertion point in fiff_insert_after!");
1726 QList<FiffDirEntry::SPtr> old_dir = t_pStreamInOut->dir();
1727 QList<FiffDirEntry::SPtr> this_ent = old_dir.mid(where);
1729 if (!t_pStreamInOut->read_tag(t_pTagNext, this_ent[0]->pos))
1734 qint64 next_tmp = t_pStreamInOut->device()->pos();
1738 t_pStreamInOut->device()->seek(fileInOut.size());
1743 QList<FiffDirEntry::SPtr> new_dir = old_dir.mid(0,where+1);
1748 qint64 old_end = t_pStreamInOut->device()->pos();
1757 new_this->kind = FIFF_BLOCK_START;
1758 new_this->type = FIFFT_INT;
1759 new_this->size = 1 * 4;
1760 new_this->pos = t_pStreamInOut->start_block(FIFFB_MNE_ENV);
1761 new_dir.append(new_this);
1764 new_this->kind = FIFF_BLOCK_ID;
1765 new_this->type = FIFFT_ID_STRUCT;
1766 new_this->size = 5 * 4;
1767 new_this->pos = t_pStreamInOut->write_id(FIFF_BLOCK_ID,
id);
1768 new_dir.append(new_this);
1772 new_this->type = FIFFT_STRING;
1773 new_this->size = cwd.size();
1775 new_dir.append(new_this);
1779 new_this->type = FIFFT_STRING;
1780 new_this->size = command.size();
1782 new_dir.append(new_this);
1785 new_this->kind = FIFF_BLOCK_END;
1786 new_this->type = FIFFT_INT;
1787 new_this->size = 1 * 4;
1789 new_this->pos = t_pStreamInOut->end_block(FIFFB_MNE_ENV,next_tmp);
1790 new_dir.append(new_this);
1795 new_dir.append(old_dir.mid(where+1));
1801 t_pTagNext->next = (qint32)old_end;
1802 t_pStreamInOut->write_tag(t_pTagNext,this_ent[0]->pos);
1807 t_pStreamInOut->dir() = new_dir;
1829 , m_pSettings(pSettings)
1839 for (
int k = 0;
k < m_iNSpace;
k++)
1843 delete m_mri_head_t;
1845 delete m_meg_head_t;
1856 void ComputeFwd::initFwd()
1859 m_spaces = Q_NULLPTR;
1863 m_mri_head_t = Q_NULLPTR;
1864 m_meg_head_t = Q_NULLPTR;
1866 m_listMegChs = QList<FiffChInfo>();
1867 m_listEegChs = QList<FiffChInfo>();
1868 m_listCompChs = QList<FiffChInfo>();
1870 if(!m_pSettings->compute_grad) {
1879 m_templates = Q_NULLPTR;
1880 m_megcoils = Q_NULLPTR;
1881 m_compcoils = Q_NULLPTR;
1882 m_compData = Q_NULLPTR;
1883 m_eegels = Q_NULLPTR;
1884 m_eegModels = Q_NULLPTR;
1888 m_mri_id = Q_NULLPTR;
1891 FILE* out = Q_NULLPTR;
1893 m_eegModel = Q_NULLPTR;
1894 m_bemModel = Q_NULLPTR;
1901 printf(
"Source space : %s\n",m_pSettings->srcname.toUtf8().constData());
1902 if (!(m_pSettings->transname.isEmpty()) || !(m_pSettings->mriname.isEmpty())) {
1903 printf(
"MRI -> head transform source : %s\n",!(m_pSettings->mriname.isEmpty()) ? m_pSettings->mriname.toUtf8().constData() : m_pSettings->transname.toUtf8().constData());
1905 printf(
"MRI and head coordinates are assumed to be identical.\n");
1907 printf(
"Measurement data : %s\n",m_pSettings->measname.toUtf8().constData());
1908 if (!m_pSettings->bemname.isEmpty()) {
1909 printf(
"BEM model : %s\n",m_pSettings->bemname.toUtf8().constData());
1911 printf(
"Sphere model : origin at (% 7.2f % 7.2f % 7.2f) mm\n",
1912 1000.0f*m_pSettings->r0[X_41],1000.0f*m_pSettings->r0[Y_41],1000.0f*m_pSettings->r0[Z_41]);
1913 if (m_pSettings->include_eeg) {
1916 if (m_pSettings->eeg_model_file.isEmpty()) {
1917 qCritical(
"!!!!!!!!!!TODO: default_eeg_model_file();");
1923 if (m_pSettings->eeg_model_name.isEmpty()) {
1924 m_pSettings->eeg_model_name = QString(
"Default");
1934 printf(
"Using EEG sphere model \"%s\" with scalp radius %7.1f mm\n",
1935 m_pSettings->eeg_model_name.toUtf8().constData(),1000*m_pSettings->eeg_sphere_rad);
1936 printf(
"%s the electrode locations to scalp\n",m_pSettings->scale_eeg_pos ?
"Scale" :
"Do not scale");
1938 m_eegModel->
scale_pos = m_pSettings->scale_eeg_pos;
1939 VEC_COPY_41(m_eegModel->
r0,m_pSettings->r0);
1944 printf(
"%s field computations\n",m_pSettings->accurate ?
"Accurate" :
"Standard");
1945 printf(
"Do computations in %s coordinates.\n",FiffCoordTransOld::mne_coord_frame_name(m_pSettings->coord_frame));
1946 printf(
"%s source orientations\n",m_pSettings->fixed_ori ?
"Fixed" :
"Free");
1947 if (m_pSettings->compute_grad) {
1948 printf(
"Compute derivatives with respect to source location coordinates\n");
1950 printf(
"Destination for the solution : %s\n",m_pSettings->solname.toUtf8().constData());
1951 if (m_pSettings->do_all) {
1952 printf(
"Calculate solution for all source locations.\n");
1954 if (m_pSettings->nlabel > 0) {
1955 printf(
"Source space will be restricted to sources in %d labels\n",m_pSettings->nlabel);
1961 printf(
"Reading %s...\n",m_pSettings->srcname.toUtf8().constData());
1962 if (MneSurfaceOrVolume::mne_read_source_spaces(m_pSettings->srcname,&m_spaces,&m_iNSpace) != OK) {
1965 for (
k = 0, m_iNSource = 0;
k < m_iNSpace;
k++) {
1966 if (m_pSettings->do_all) {
1967 MneSurfaceOrVolume::enable_all_sources(m_spaces[
k]);
1969 m_iNSource += m_spaces[
k]->nuse;
1971 if (m_iNSource == 0) {
1972 qCritical(
"No sources are active in these source spaces. --all option should be used.");
1975 printf(
"Read %d source spaces a total of %d active source locations\n", m_iNSpace,m_iNSource);
1976 if (MneSurfaceOrVolume::restrict_sources_to_labels(m_spaces,m_iNSpace,m_pSettings->labels,m_pSettings->nlabel) == FAIL) {
1982 if (!m_pSettings->mriname.isEmpty()) {
1983 if ((m_mri_head_t = FiffCoordTransOld::mne_read_mri_transform(m_pSettings->mriname)) == Q_NULLPTR) {
1986 if ((m_mri_id = get_file_id(m_pSettings->mriname)) == Q_NULLPTR) {
1987 qCritical(
"Couln't read MRI file id (How come?)");
1991 else if (!m_pSettings->transname.isEmpty()) {
1993 if ((t = FiffCoordTransOld::mne_read_FShead2mri_transform(m_pSettings->transname.toUtf8().data())) == Q_NULLPTR) {
1996 m_mri_head_t = t->fiff_invert_transform();
2001 m_mri_head_t = FiffCoordTransOld::mne_identity_transform(FIFFV_COORD_MRI,FIFFV_COORD_HEAD);
2003 FiffCoordTransOld::mne_print_coord_transform(stdout,m_mri_head_t);
2008 if(!m_pSettings->pFiffInfo) {
2010 QFile measname(m_pSettings->measname);
2014 if(!pStream->open()) {
2015 qCritical() <<
"Could not open Stream.";
2020 if(!pStream->read_meas_info(pStream->dirtree(), fiffInfo, DirNode)){
2021 qCritical() <<
"Could not find the channel information.";
2025 m_pInfoBase = QSharedPointer<FIFFLIB::FiffInfo>(
new FiffInfo(fiffInfo));
2027 m_pInfoBase = m_pSettings->pFiffInfo;
2030 qCritical (
"ComputeFwd::initFwd(): no FiffInfo");
2033 if (mne_read_meg_comp_eeg_ch_info_41(m_pInfoBase,
2045 m_iNChan = iNMeg + iNEeg;
2049 printf(
"Read %3d MEG channels from %s\n",iNMeg,m_pSettings->measname.toUtf8().constData());
2052 printf(
"Read %3d MEG compensation channels from %s\n",iNComp,m_pSettings->measname.toUtf8().constData());
2055 printf(
"Read %3d EEG channels from %s\n",iNEeg,m_pSettings->measname.toUtf8().constData());
2057 if (!m_pSettings->include_meg) {
2058 printf(
"MEG not requested. MEG channels omitted.\n");
2059 m_listMegChs.clear();
2060 m_listCompChs.clear();
2065 FiffCoordTransOld::mne_print_coord_transform(stdout,m_meg_head_t);
2066 if (!m_pSettings->include_eeg) {
2067 printf(
"EEG not requested. EEG channels omitted.\n");
2068 m_listEegChs.clear();
2071 if (mne_check_chinfo(m_listEegChs,iNEeg) != OK) {
2078 if (m_pSettings->include_meg) {
2079 qPath = QString(QCoreApplication::applicationDirPath() +
"/../resources/general/coilDefinitions/coil_def.dat");
2080 file.setFileName(qPath);
2081 if ( !QCoreApplication::startingUp() ) {
2082 qPath = QCoreApplication::applicationDirPath() + QString(
"/../resources/general/coilDefinitions/coil_def.dat");
2083 }
else if (!file.exists()) {
2084 qPath =
"../resources/general/coilDefinitions/coil_def.dat";
2094 if ((m_compData = MneCTFCompDataSet::mne_read_ctf_comp_data(m_pSettings->measname)) == Q_NULLPTR) {
2098 if (m_compData->ncomp > 0) {
2099 printf(
"%d compensation data sets in %s\n",m_compData->ncomp,m_pSettings->measname.toUtf8().constData());
2101 m_listCompChs.clear();
2107 m_compData = Q_NULLPTR;
2110 if (m_pSettings->coord_frame == FIFFV_COORD_MRI) {
2112 FiffCoordTransOld* meg_mri_t = FiffCoordTransOld::fiff_combine_transforms(FIFFV_COORD_DEVICE,FIFFV_COORD_MRI,m_meg_head_t,head_mri_t);
2113 if (meg_mri_t == Q_NULLPTR) {
2118 m_pSettings->accurate ? FWD_COIL_ACCURACY_ACCURATE : FWD_COIL_ACCURACY_NORMAL,
2119 meg_mri_t)) == Q_NULLPTR) {
2125 FWD_COIL_ACCURACY_NORMAL,
2126 meg_mri_t)) == Q_NULLPTR) {
2132 head_mri_t)) == Q_NULLPTR) {
2136 FREE_41(head_mri_t);
2137 printf(
"MRI coordinate coil definitions created.\n");
2141 m_pSettings->accurate ? FWD_COIL_ACCURACY_ACCURATE : FWD_COIL_ACCURACY_NORMAL,
2142 m_meg_head_t)) == Q_NULLPTR) {
2149 FWD_COIL_ACCURACY_NORMAL,m_meg_head_t)) == Q_NULLPTR) {
2155 Q_NULLPTR)) == Q_NULLPTR) {
2158 printf(
"Head coordinate coil definitions created.\n");
2163 if (MneSurfaceOrVolume::mne_transform_source_spaces_to(m_pSettings->coord_frame,m_mri_head_t,m_spaces,m_iNSpace) != OK) {
2166 printf(
"Source spaces are now in %s coordinates.\n",FiffCoordTransOld::mne_coord_frame_name(m_pSettings->coord_frame));
2170 if (!m_pSettings->bemname.isEmpty()) {
2173 m_pSettings->bemname = bemsolname;
2175 printf(
"\nSetting up the BEM model using %s...\n",m_pSettings->bemname.toUtf8().constData());
2176 printf(
"\nLoading surfaces...\n");
2177 m_bemModel = FwdBemModel::fwd_bem_load_three_layer_surfaces(m_pSettings->bemname);
2180 printf(
"Three-layer model surfaces loaded.\n");
2183 m_bemModel = FwdBemModel::fwd_bem_load_homog_surface(m_pSettings->bemname);
2187 printf(
"Homogeneous model surface loaded.\n");
2189 if (iNEeg > 0 && m_bemModel->nsurf == 1) {
2190 qCritical(
"Cannot use a homogeneous model in EEG calculations.");
2193 printf(
"\nLoading the solution matrix...\n");
2194 if (FwdBemModel::fwd_bem_load_recompute_solution(m_pSettings->bemname.toUtf8().data(),FWD_BEM_UNKNOWN,FALSE,m_bemModel) == FAIL) {
2197 if (m_pSettings->coord_frame == FIFFV_COORD_HEAD) {
2198 printf(
"Employing the head->MRI coordinate transform with the BEM model.\n");
2199 if (FwdBemModel::fwd_bem_set_head_mri_t(m_bemModel,m_mri_head_t) == FAIL) {
2203 printf(
"BEM model %s is now set up\n",m_bemModel->sol_name.toUtf8().constData());
2205 printf(
"Using the sphere model.\n");
2211 if (m_pSettings->filter_spaces) {
2212 if (!m_pSettings->mindistoutname.isEmpty()) {
2213 out = fopen(m_pSettings->mindistoutname.toUtf8().constData(),
"w");
2214 if (out == Q_NULLPTR) {
2215 qCritical() << m_pSettings->mindistoutname;
2218 printf(
"Omitted source space points will be output to : %s\n",m_pSettings->mindistoutname.toUtf8().constData());
2220 MneSurfaceOrVolume::filter_source_spaces(m_pSettings->mindist,
2221 m_pSettings->bemname.toUtf8().data(),
2224 m_iNSpace,out,m_pSettings->use_threads);
2225 if(out != Q_NULLPTR)
2238 iNMeg = m_megcoils->ncoil;
2241 iNEeg = m_eegels->ncoil;
2244 m_pSettings->use_threads =
false;
2248 if(m_spaces[0]->coord_frame != FIFFV_COORD_HEAD) {
2249 if (MneSurfaceOrVolume::mne_transform_source_spaces_to(m_pSettings->coord_frame,m_mri_head_t,m_spaces,m_iNSpace) != OK) {
2261 m_pSettings->fixed_ori,
2264 m_pSettings->use_threads,
2267 m_pSettings->compute_grad)) == FAIL) {
2275 m_pSettings->fixed_ori,
2278 m_pSettings->use_threads,
2281 m_pSettings->compute_grad))== FAIL) {
2285 if(iNMeg > 0 && iNEeg > 0) {
2287 qWarning() <<
"The MEG and EEG forward solutions do not match";
2296 }
else if (iNMeg > 0) {
2302 if(m_pSettings->compute_grad) {
2303 if(iNMeg > 0 && iNEeg > 0) {
2305 qWarning() <<
"The MEG and EEG forward solutions do not match";
2314 }
else if (iNMeg > 0) {
2329 iNMeg = m_megcoils->ncoil;
2334 iNComp = m_compcoils->ncoil;
2377 if (m_pSettings->coord_frame == FIFFV_COORD_MRI) {
2379 FiffCoordTransOld* meg_mri_t = FiffCoordTransOld::fiff_combine_transforms(FIFFV_COORD_DEVICE,FIFFV_COORD_MRI,transDevHeadOld,head_mri_t);
2380 if (meg_mri_t == Q_NULLPTR) {
2385 m_pSettings->accurate ? FWD_COIL_ACCURACY_ACCURATE : FWD_COIL_ACCURACY_NORMAL,
2386 meg_mri_t)) == Q_NULLPTR) {
2392 FWD_COIL_ACCURACY_NORMAL,
2393 meg_mri_t)) == Q_NULLPTR) {
2400 m_pSettings->accurate ? FWD_COIL_ACCURACY_ACCURATE : FWD_COIL_ACCURACY_NORMAL,
2401 transDevHeadOld)) == Q_NULLPTR) {
2408 FWD_COIL_ACCURACY_NORMAL,transDevHeadOld)) == Q_NULLPTR) {
2415 if(m_spaces[0]->coord_frame != FIFFV_COORD_HEAD) {
2416 if (MneSurfaceOrVolume::mne_transform_source_spaces_to(m_pSettings->coord_frame,m_mri_head_t,m_spaces,m_iNSpace) != OK) {
2427 m_pSettings->fixed_ori,
2430 m_pSettings->use_threads,
2433 m_pSettings->compute_grad)) == FAIL) {
2441 if(m_pSettings->compute_grad) {
2452 if (MneSourceSpaceOld::mne_transform_source_spaces_to(FIFFV_COORD_MRI,m_mri_head_t,m_spaces,m_iNSpace) != OK) {
2456 int iNMeg = m_megcoils->ncoil;
2457 int iNEeg = m_eegels->ncoil;
2461 if(sSolName ==
"default") {
2462 sName = m_pSettings->solname;
2467 printf(
"\nwriting %s...",sSolName.toUtf8().constData());
2469 if (!write_solution(sName,
2472 m_pSettings->mriname,m_mri_id,
2474 m_pSettings->measname,m_meas_id,
2480 m_pSettings->fixed_ori,
2481 m_pSettings->coord_frame,
2486 m_pSettings->compute_grad)) {
2490 if (!mne_attach_env(m_pSettings->solname,m_pSettings->command)) {
2494 printf(
"\nFinished.\n");