56 using namespace Eigen;
57 using namespace FIFFLIB;
58 using namespace FWDLIB;
79 #define MALLOC_6(x,t) (t *)malloc((x)*sizeof(t))
80 #define REALLOC_6(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
81 #define FREE_6(x) if ((char *)(x) != NULL) free((char *)(x))
83 #define FIFFV_COORD_UNKNOWN 0
89 #define VEC_DOT_6(x,y) ((x)[X_6]*(y)[X_6] + (x)[Y_6]*(y)[Y_6] + (x)[Z_6]*(y)[Z_6])
90 #define VEC_LEN_6(x) sqrt(VEC_DOT_6(x,x))
92 #define VEC_COPY_6(to,from) {\
93 (to)[X_6] = (from)[X_6];\
94 (to)[Y_6] = (from)[Y_6];\
95 (to)[Z_6] = (from)[Z_6];\
98 static void skip_comments(FILE *in)
106 for (c = fgetc(in); c != EOF && c !=
'\n'; c = fgetc(in))
116 static int whitespace(
int c)
119 if (c ==
'\t' || c ==
'\n' || c ==
' ')
125 static int whitespace_quote(
int c,
int inquote)
131 return (c ==
'\t' || c ==
'\n' || c ==
' ');
134 static char *next_word(FILE *in)
137 char *next = MALLOC_6(MAXWORD,
char);
145 for (
k = 0, p = 0, c = fgetc(in); c != EOF && !whitespace_quote(c,inquote) ; c = fgetc(in),
k++) {
146 if (
k == 0 && c ==
'"')
151 if (c == EOF &&
k == 0) {
158 for (
k = 0, c = fgetc(in); whitespace(c) ; c = fgetc(in),
k++)
165 printf(
"<%s>\n",next);
170 static int get_ival(FILE *in,
int *ival)
173 char *next = next_word(in);
175 qWarning(
"missing integer");
178 else if (sscanf(next,
"%d",ival) != 1) {
179 qWarning(
"bad integer : %s",next);
187 static int get_fval(FILE *in,
float *fval)
190 char *next = next_word(in);
191 setlocale(LC_NUMERIC,
"C");
193 qWarning(
"bad integer");
196 else if (sscanf(next,
"%g",fval) != 1) {
197 qWarning(
"bad floating point number : %s",next);
205 static void normalize(
float *rr)
210 float ll = VEC_LEN_6(rr);
213 for (
k = 0;
k < 3;
k++)
220 int type,
int coil_class,
int acc,
int np,
float size,
float base,
const QString& desc)
226 qWarning (
"No coil definition set to augment.");
230 qWarning(
"Number of integration points should be positive (type = %d acc = %d)",type,acc);
233 if (! (acc == FWD_COIL_ACCURACY_POINT ||
234 acc == FWD_COIL_ACCURACY_NORMAL ||
235 acc == FWD_COIL_ACCURACY_ACCURATE) ) {
236 qWarning(
"Illegal accuracy (type = %d acc = %d)",type,acc);
239 if (! (coil_class == FWD_COILC_MAG ||
240 coil_class == FWD_COILC_AXIAL_GRAD ||
241 coil_class == FWD_COILC_PLANAR_GRAD ||
242 coil_class == FWD_COILC_AXIAL_GRAD2) ) {
243 qWarning(
"Illegal coil class (type = %d acc = %d class = %d)",type,acc,coil_class);
247 set->coils = REALLOC_6(set->coils,set->ncoil+1,
FwdCoil*);
248 def = set->coils[set->ncoil++] =
new FwdCoil(np);
265 FwdCoilSet::FwdCoilSet()
269 coord_frame = FIFFV_COORD_UNKNOWN;
271 user_data_free = NULL;
282 FwdCoilSet::~FwdCoilSet()
284 for (
int k = 0;
k < ncoil;
k++)
288 this->fwd_free_coil_set_user_data();
300 qWarning() << ch.
ch_name <<
"is not a MEG channel. Cannot create a coil definition.";
306 for (
k = 0, def = NULL;
k < this->ncoil;
k++) {
308 this->coils[
k]->accuracy == acc) {
309 def = this->coils[
k];
313 printf(
"Desired coil definition not found (type = %d acc = %d)",ch.
chpos.
coil_type,acc);
322 if (!def->
desc.isEmpty())
338 FiffCoordTransOld::fiff_coord_trans(res->
r0,t,FIFFV_MOVE);
339 FiffCoordTransOld::fiff_coord_trans(res->
ex,t,FIFFV_NO_MOVE);
340 FiffCoordTransOld::fiff_coord_trans(res->
ey,t,FIFFV_NO_MOVE);
341 FiffCoordTransOld::fiff_coord_trans(res->
ez,t,FIFFV_NO_MOVE);
347 for (p = 0; p < res->
np; p++) {
348 res->
w[p] = def->
w[p];
349 for (c = 0; c < 3; c++) {
350 res->
rmag[p][c] = res->
r0[c] + def->
rmag[p][X_6]*res->
ex[c] + def->
rmag[p][Y_6]*res->
ey[c] + def->
rmag[p][Z_6]*res->
ez[c];
363 FwdCoilSet *FwdCoilSet::create_meg_coils(
const QList<FIFFLIB::FiffChInfo>& chs,
372 for (
k = 0;
k < nch;
k++) {
373 if ((next = this->create_meg_coil(chs.at(
k),acc,t)) == Q_NULLPTR)
375 res->coils = REALLOC_6(res->coils,res->ncoil+1,
FwdCoil*);
376 res->coils[res->ncoil++] = next;
379 res->coord_frame = t->
to;
390 FwdCoilSet *FwdCoilSet::create_eeg_els(
const QList<FIFFLIB::FiffChInfo>& chs,
398 for (
k = 0;
k < nch;
k++) {
399 if ((next = FwdCoil::create_eeg_el(chs.at(
k),t)) == Q_NULLPTR)
401 res->coils = REALLOC_6(res->coils,res->ncoil+1,
FwdCoil*);
402 res->coils[res->ncoil++] = next;
405 res->coord_frame = t->
to;
421 FILE *in = fopen(name.toUtf8().constData(),
"r");
423 int type,coil_class,acc,np;
430 qWarning() <<
"FwdCoilSet::read_coil_defs - File is NULL" << name;
439 if (get_ival(in,&coil_class) != OK)
441 if (get_ival(in,&type) != OK)
443 if (get_ival(in,&acc) != OK)
445 if (get_ival(in,&np) != OK)
447 if (get_fval(in,&size) != OK)
449 if (get_fval(in,&base) != OK)
451 desc = next_word(in);
455 def = fwd_add_coil_to_set(res,type,coil_class,acc,np,size,base,desc);
458 FREE_6(desc); desc = NULL;
460 for (p = 0; p < def->
np; p++) {
464 if (get_fval(in,def->
w+p) != OK)
466 if (get_fval(in,def->
rmag[p]+X_6) != OK)
468 if (get_fval(in,def->
rmag[p]+Y_6) != OK)
470 if (get_fval(in,def->
rmag[p]+Z_6) != OK)
472 if (get_fval(in,def->
cosmag[p]+X_6) != OK)
474 if (get_fval(in,def->
cosmag[p]+Y_6) != OK)
476 if (get_fval(in,def->
cosmag[p]+Z_6) != OK)
479 if (VEC_LEN_6(def->
rmag[p]) > BIG) {
480 qWarning(
"Unreasonable integration point: %f %f %f mm (coil type = %d acc = %d)", 1000*def->
rmag[p][X_6],1000*def->
rmag[p][Y_6],1000*def->
rmag[p][Z_6], def->
type,def->
accuracy);
483 size = VEC_LEN_6(def->
cosmag[p]);
485 qWarning(
"Unreasonable normal: %f %f %f (coil type = %d acc = %d)", def->
cosmag[p][X_6],def->
cosmag[p][Y_6],def->
cosmag[p][Z_6], def->
type,def->
accuracy);
488 normalize(def->
cosmag[p]);
494 printf(
"%d coil definitions read\n",res->ncoil);
512 if (this->coord_frame != t->
from) {
513 qWarning(
"Coordinate frame of the transformation does not match the coil set in fwd_dup_coil_set");
519 res->coord_frame = t->
to;
521 res->coord_frame = this->coord_frame;
523 res->coils = MALLOC_6(this->ncoil,
FwdCoil*);
524 res->ncoil = this->ncoil;
526 for (
int k = 0;
k < this->ncoil;
k++) {
527 coil = res->coils[
k] =
new FwdCoil(*(this->coils[
k]));
532 FiffCoordTransOld::fiff_coord_trans(coil->
r0,t,FIFFV_MOVE);
533 FiffCoordTransOld::fiff_coord_trans(coil->
ex,t,FIFFV_NO_MOVE);
534 FiffCoordTransOld::fiff_coord_trans(coil->
ey,t,FIFFV_NO_MOVE);
535 FiffCoordTransOld::fiff_coord_trans(coil->
ez,t,FIFFV_NO_MOVE);
537 for (
int p = 0; p < coil->
np; p++) {
538 FiffCoordTransOld::fiff_coord_trans(coil->
rmag[p],t,FIFFV_MOVE);
539 FiffCoordTransOld::fiff_coord_trans(coil->
cosmag[p],t,FIFFV_NO_MOVE);
549 bool FwdCoilSet::is_planar_coil_type(
int type)
const
553 for (
int k = 0;
k < this->ncoil;
k++)
554 if (this->coils[
k]->type == type)
555 return this->coils[
k]->coil_class == FWD_COILC_PLANAR_GRAD;
561 bool FwdCoilSet::is_axial_coil_type(
int type)
const
565 for (
int k = 0;
k < this->ncoil;
k++)
566 if (this->coils[
k]->type == type)
567 return (this->coils[
k]->coil_class == FWD_COILC_MAG ||
568 this->coils[
k]->coil_class == FWD_COILC_AXIAL_GRAD ||
569 this->coils[
k]->coil_class == FWD_COILC_AXIAL_GRAD2);
575 bool FwdCoilSet::is_magnetometer_coil_type(
int type)
const
579 for (
int k = 0;
k < this->ncoil;
k++)
580 if (this->coils[
k]->type == type)
581 return this->coils[
k]->coil_class == FWD_COILC_MAG;
587 bool FwdCoilSet::is_eeg_electrode_type(
int type)
const