6 using namespace INVERSELIB;
15 #define MALLOC(x,t) (t *)malloc((x)*sizeof(t))
16 #define REALLOC(x,y,t) (t *)((x == NULL) ? malloc((y)*sizeof(t)) : realloc((x),(y)*sizeof(t)))
22 #ifndef PROGRAM_VERSION
23 #define PROGRAM_VERSION "1.00"
34 DipoleFitSettings::DipoleFitSettings()
41 DipoleFitSettings::DipoleFitSettings(
int *argc,
char **argv)
45 if (!check_args(argc,argv))
49 printf(
"%s version %s compiled at %s %s\n",argv[0],PROGRAM_VERSION,__DATE__,__TIME__);
56 DipoleFitSettings::~DipoleFitSettings()
63 void DipoleFitSettings::initMembers()
66 r0 << 0.0f,0.0f,0.04f;
68 filter.filter_on =
true;
70 filter.taper_size = 2048;
71 filter.highpass = 0.0;
72 filter.highpass_width = 0.0;
73 filter.lowpass = 40.0;
74 filter.lowpass_width = 5.0;
75 filter.eog_highpass = 0.0;
76 filter.eog_highpass_width = 0.0;
77 filter.eog_lowpass = 40.0;
78 filter.eog_lowpass_width = 5.0;
83 guess_mindist = 0.010f;
84 guess_exclude = 0.020f;
105 omit_data_proj =
false;
108 eeg_sphere_rad = 0.09f;
109 scale_eeg_pos =
false;
111 fit_mag_dipoles =
false;
121 void DipoleFitSettings::checkIntegrity()
123 do_baseline = (bmin < BIG_TIME && bmax < BIG_TIME);
125 if (measname.isEmpty()) {
126 qCritical (
"Data file name missing. Please specify one using the --meas option.");
129 if (dipname.isEmpty() && bdipname.isEmpty()) {
130 qCritical (
"Output file name missing. Please use the --dip or --bdip options to do this.");
133 if (guessname.isEmpty()) {
134 if (bemname.isEmpty() && !guess_surfname.isEmpty() && mriname.isEmpty()) {
135 qCritical (
"Please specify the MRI/head coordinate transformation with the --mri option");
139 if (!include_meg && !include_eeg) {
140 qCritical (
"Specify one or both of the --eeg and --meg options");
144 projnames.prepend(measname);
147 if (!bemname.isEmpty())
148 printf(
"BEM : %s\n",bemname.toUtf8().data());
150 printf(
"Sphere model : origin at (% 7.2f % 7.2f % 7.2f) mm\n",
151 1000*r0[X],1000*r0[Y],1000*r0[Z]);
153 printf(
"Using %s MEG coil definitions.\n",accurate ?
"accurate" :
"standard");
154 if (!mriname.isEmpty())
155 printf(
"MRI transform : %s\n",mriname.toUtf8().data());
156 if (!guessname.isEmpty())
157 printf(
"Guesses : %s\n",guessname.toUtf8().data());
159 if (!guess_surfname.isEmpty())
160 printf(
"Guess space bounded by %s\n",guess_surfname.toUtf8().data());
162 printf(
"Spherical guess space, rad = %.1f mm\n",1000*guess_rad);
163 printf(
"Guess grid : %6.1f mm\n",1000*guess_grid);
164 if (guess_mindist > 0.0)
165 printf(
"Guess mindist : %6.1f mm\n",1000*guess_mindist);
166 if (guess_exclude > 0)
167 printf(
"Guess exclude : %6.1f mm\n",1000*guess_exclude);
169 printf(
"Data : %s\n",measname.toUtf8().data());
170 if (projnames.size() > 0) {
171 printf(
"SSP sources :\n");
172 for (
int k = 0;
k < projnames.size();
k++)
173 printf(
"\t%s\n",projnames[
k].toUtf8().data());
176 printf(
"Bad channels : %s\n",badname);
178 printf(
"Baseline : %10.2f ... %10.2f ms\n", 1000*bmin,1000*bmax);
179 if (!noisename.isEmpty()) {
180 printf(
"Noise covariance : %s\n",noisename.toUtf8().data());
183 printf(
"\tNoise-covariange regularization (mag) : %-5.2f\n",mag_reg);
185 printf(
"\tNoise-covariange regularization (grad) : %-5.2f\n",grad_reg);
187 if (include_eeg && eeg_reg > 0.0)
188 printf(
"\tNoise-covariange regularization (EEG) : %-5.2f\n",eeg_reg);
191 printf(
"Fit data with magnetic dipoles\n");
192 if (!dipname.isEmpty())
193 printf(
"dip output : %s\n",dipname.toUtf8().data());
194 if (!bdipname.isEmpty())
195 printf(
"bdip output : %s\n",bdipname.toUtf8().data());
201 void DipoleFitSettings::usage(
char *name)
203 printf(
"usage: %s [options]\n",name);
204 printf(
"This is a program for sequential single dipole fitting.\n");
205 printf(
"\nInput data:\n\n");
206 printf(
"\t--meas name specify an evoked-response data file\n");
207 printf(
"\t--set no evoked data set number to use (default: 1)\n");
208 printf(
"\t--bad name take bad channel list from here\n");
210 printf(
"\nModality selection:\n\n");
211 printf(
"\t--meg employ MEG data in fitting\n");
212 printf(
"\t--eeg employ EEG data in fitting\n");
214 printf(
"\nTime scale selection:\n\n");
215 printf(
"\t--tmin time/ms specify the starting analysis time\n");
216 printf(
"\t--tmax time/ms specify the ending analysis time\n");
217 printf(
"\t--tstep time/ms specify the time step between frames (default 1/(sampling frequency))\n");
218 printf(
"\t--integ time/ms specify the time integration for each frame (default 0)\n");
220 printf(
"\nPreprocessing:\n\n");
221 printf(
"\t--bmin time/ms specify the baseline starting time (evoked data only)\n");
222 printf(
"\t--bmax time/ms specify the baseline ending time (evoked data only)\n");
223 printf(
"\t--proj name Load the linear projection from here\n");
224 printf(
"\t Multiple projections can be specified.\n");
225 printf(
"\t The data file will be automatically included, unless --noproj is present.\n");
226 printf(
"\t--noproj Do not load the projection from the data file, just those given with the --proj option.\n");
227 printf(
"\n\tFiltering (raw data only):\n\n");
228 printf(
"\t--filtersize size desired filter length (default = %d)\n",filter.size);
229 printf(
"\t--highpass val/Hz highpass corner (default = %6.1f Hz)\n",filter.highpass);
230 printf(
"\t--lowpass val/Hz lowpass corner (default = %6.1f Hz)\n",filter.lowpass);
231 printf(
"\t--lowpassw val/Hz lowpass transition width (default = %6.1f Hz)\n",filter.lowpass_width);
232 printf(
"\t--filteroff do not filter the data\n");
234 printf(
"\nNoise specification:\n\n");
235 printf(
"\t--noise name take the noise-covariance matrix from here\n");
236 printf(
"\t--gradnoise val specify a gradiometer noise value in fT/cm\n");
237 printf(
"\t--magnoise val specify a gradiometer noise value in fT\n");
238 printf(
"\t--eegnoise val specify an EEG value in uV\n");
239 printf(
"\t NOTE: The above will be used only if --noise is missing\n");
240 printf(
"\t--diagnoise omit off-diagonal terms from the noise-covariance matrix\n");
241 printf(
"\t--reg amount Apply regularization to the noise-covariance matrix (same fraction for all channels).\n");
242 printf(
"\t--gradreg amount Apply regularization to the MEG noise-covariance matrix (planar gradiometers, default = %6.2f).\n",grad_reg);
243 printf(
"\t--magreg amount Apply regularization to the EEG noise-covariance matrix (axial gradiometers and magnetometers, default = %6.2f).\n",mag_reg);
244 printf(
"\t--eegreg amount Apply regularization to the EEG noise-covariance matrix (default = %6.2f).\n",eeg_reg);
246 printf(
"\nForward model:\n\n");
247 printf(
"\t--mri name take head/MRI coordinate transform from here (Neuromag MRI description file)\n");
248 printf(
"\t--bem name BEM model name\n");
249 printf(
"\t--origin x:y:z/mm use a sphere model with this origin (head coordinates/mm)\n");
250 printf(
"\t--eegscalp scale the electrode locations to the surface of the scalp when using a sphere model\n");
251 printf(
"\t--eegmodels name read EEG sphere model specifications from here.\n");
252 printf(
"\t--eegmodel name name of the EEG sphere model to use (default : Default)\n");
253 printf(
"\t--eegrad val radius of the scalp surface to use in EEG sphere model (default : %7.1f mm)\n",1000*eeg_sphere_rad);
254 printf(
"\t--accurate use accurate coil definitions in MEG forward computation\n");
256 printf(
"\nFitting parameters:\n\n");
257 printf(
"\t--guess name The source space of initial guesses.\n");
258 printf(
"\t If not present, the values below are used to generate the guess grid.\n");
259 printf(
"\t--guesssurf name Read the inner skull surface from this fif file to generate the guesses.\n");
260 printf(
"\t--guessrad value Radius of a spherical guess volume if neither of the above is present (default : %.1f mm)\n",1000*guess_rad);
261 printf(
"\t--exclude dist/mm Exclude points which are closer than this distance from the CM of the inner skull surface (default = %6.1f mm).\n",1000*guess_exclude);
262 printf(
"\t--mindist dist/mm Exclude points which are closer than this distance from the inner skull surface (default = %6.1f mm).\n",1000*guess_mindist);
263 printf(
"\t--grid dist/mm Source space grid size (default = %6.1f mm).\n",1000*guess_grid);
264 printf(
"\t--magdip Fit magnetic dipoles instead of current dipoles.\n");
265 printf(
"\nOutput:\n\n");
266 printf(
"\t--dip name xfit dip format output file name\n");
267 printf(
"\t--bdip name xfit bdip format output file name\n");
268 printf(
"\nGeneral:\n\n");
269 printf(
"\t--gui Enables the gui.\n");
270 printf(
"\t--help print this info.\n");
271 printf(
"\t--version print version info.\n\n");
277 bool DipoleFitSettings::check_unrecognized_args(
int argc,
char **argv)
280 printf(
"Unrecognized arguments : ");
281 for (
int k = 1;
k < argc;
k++)
282 printf(
"%s ",argv[
k]);
284 qCritical (
"Check the command line.");
292 bool DipoleFitSettings::check_args (
int *argc,
char **argv)
296 int ival,filter_size;
298 for (
int k = 0;
k < *argc;
k++) {
300 if (strcmp(argv[
k],
"--gui") == 0) {
304 else if (strcmp(argv[
k],
"--version") == 0) {
305 printf(
"%s version %s compiled at %s %s\n",
306 argv[0],PROGRAM_VERSION,__DATE__,__TIME__);
309 else if (strcmp(argv[
k],
"--help") == 0) {
313 else if (strcmp(argv[
k],
"--guess") == 0) {
315 if (
k == *argc - 1) {
316 qCritical (
"--guess: argument required.");
319 guessname = QString(argv[
k+1]);
321 else if (strcmp(argv[
k],
"--gsurf") == 0) {
323 if (
k == *argc - 1) {
324 qCritical (
"--gsurf: argument required.");
327 guess_surfname = strdup(argv[
k+1]);
329 else if (strcmp(argv[
k],
"--guesssurf") == 0) {
331 if (
k == *argc - 1) {
332 qCritical (
"--guesssurf: argument required.");
335 guess_surfname = strdup(argv[
k+1]);
337 else if (strcmp(argv[
k],
"--guessrad") == 0) {
339 if (
k == *argc - 1) {
340 qCritical (
"--guessrad: argument required.");
343 if (sscanf(argv[
k+1],
"%f",&fval) != 1) {
344 qCritical (
"Could not interpret the radius.");
348 qCritical (
"Radius should be positive");
351 guess_rad = fval/1000.0;
353 else if (strcmp(argv[
k],
"--mindist") == 0) {
355 if (
k == *argc - 1) {
356 qCritical (
"--mindist: argument required.");
359 if (sscanf(argv[
k+1],
"%f",&fval) != 1) {
360 qCritical (
"Could not interpret the distance.");
363 guess_mindist = fval/1000.0;
364 if (guess_mindist <= 0.0)
367 else if (strcmp(argv[
k],
"--exclude") == 0) {
369 if (
k == *argc - 1) {
370 qCritical (
"--exclude: argument required.");
373 if (sscanf(argv[
k+1],
"%f",&fval) != 1) {
374 qCritical (
"Could not interpret the distance.");
377 guess_exclude = fval/1000.0;
378 if (guess_exclude <= 0.0)
381 else if (strcmp(argv[
k],
"--grid") == 0) {
383 if (
k == *argc - 1) {
384 qCritical (
"--grid: argument required.");
387 if (sscanf(argv[
k+1],
"%f",&fval) != 1) {
388 qCritical (
"Could not interpret the distance.");
392 qCritical (
"Grid spacing should be positive");
395 guess_grid = guess_grid/1000.0;
397 else if (strcmp(argv[
k],
"--mri") == 0) {
399 if (
k == *argc - 1) {
400 qCritical (
"--mri: argument required.");
403 mriname = QString(argv[
k+1]);
405 else if (strcmp(argv[
k],
"--bem") == 0) {
407 if (
k == *argc - 1) {
408 qCritical (
"--bem: argument required.");
411 bemname = QString(argv[
k+1]);
413 else if (strcmp(argv[
k],
"--accurate") == 0) {
417 else if (strcmp(argv[
k],
"--meg") == 0) {
421 else if (strcmp(argv[
k],
"--eeg") == 0) {
425 else if (strcmp(argv[
k],
"--origin") == 0) {
427 if (
k == *argc - 1) {
428 qCritical (
"--origin: argument required.");
431 if (sscanf(argv[
k+1],
"%f:%f:%f",r0[X],r0[Y],r0[Z]) != 3) {
432 qCritical (
"Could not interpret the origin.");
435 r0[X] = r0[X]/1000.0;
436 r0[Y] = r0[Y]/1000.0;
437 r0[Z] = r0[Z]/1000.0;
439 else if (strcmp(argv[
k],
"--eegrad") == 0) {
441 if (
k == *argc - 1) {
442 qCritical (
"--eegrad: argument required.");
445 if (sscanf(argv[
k+1],
"%g",&eeg_sphere_rad) != 1) {
446 qCritical () <<
"Incomprehensible radius:" << argv[
k+1];
449 if (eeg_sphere_rad <= 0) {
450 qCritical (
"Radius must be positive");
453 eeg_sphere_rad = eeg_sphere_rad/1000.0;
455 else if (strcmp(argv[
k],
"--eegmodels") == 0) {
457 if (
k == *argc - 1) {
458 qCritical (
"--eegmodels: argument required.");
461 eeg_model_file = QString(argv[
k+1]);
463 else if (strcmp(argv[
k],
"--eegmodel") == 0) {
465 if (
k == *argc - 1) {
466 qCritical (
"--eegmodel: argument required.");
469 eeg_model_name = QString(argv[
k+1]);
471 else if (strcmp(argv[
k],
"--eegscalp") == 0) {
473 scale_eeg_pos =
true;
475 else if (strcmp(argv[
k],
"--meas") == 0) {
477 if (
k == *argc - 1) {
478 qCritical (
"--meas: argument required.");
481 measname = QString(argv[
k+1]);
484 else if (strcmp(argv[
k],
"--raw") == 0) {
486 if (
k == *argc - 1) {
487 qCritical (
"--raw: argument required.");
490 measname = QString(argv[
k+1]);
493 else if (strcmp(argv[
k],
"--proj") == 0) {
495 if (
k == *argc - 1) {
496 qCritical (
"--proj: argument required.");
499 projnames.append(QString(argv[
k+1]));
501 else if (strcmp(argv[
k],
"--noproj") == 0) {
503 omit_data_proj =
true;
505 else if (strcmp(argv[
k],
"--bad") == 0) {
507 if (
k == *argc - 1) {
508 qCritical (
"--bad: argument required.");
511 badname = strdup(argv[
k+1]);
513 else if (strcmp(argv[
k],
"--noise") == 0) {
515 if (
k == *argc - 1) {
516 qCritical (
"--noise: argument required.");
519 noisename = QString(argv[
k+1]);
521 else if (strcmp(argv[
k],
"--gradnoise") == 0) {
523 if (
k == *argc - 1) {
524 qCritical (
"--gradnoise: argument required.");
527 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
528 qCritical() <<
"Incomprehensible value:" << argv[
k+1];
532 qCritical (
"Value should be positive");
535 grad_std = 1e-13*fval;
537 else if (strcmp(argv[
k],
"--magnoise") == 0) {
539 if (
k == *argc - 1) {
540 qCritical (
"--magnoise: argument required.");
543 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
544 qCritical() <<
"Incomprehensible value:" << argv[
k+1];
548 qCritical (
"Value should be positive");
551 mag_std = 1e-15*fval;
553 else if (strcmp(argv[
k],
"--eegnoise") == 0) {
555 if (
k == *argc - 1) {
556 qCritical (
"--eegnoise: argument required.");
559 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
560 qCritical () <<
"Incomprehensible value:" << argv[
k+1];
564 qCritical (
"Value should be positive");
569 else if (strcmp(argv[
k],
"--diagnoise") == 0) {
573 else if (strcmp(argv[
k],
"--eegreg") == 0) {
575 if (
k == *argc - 1) {
576 qCritical (
"--eegreg: argument required.");
579 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
580 qCritical () <<
"Incomprehensible value:" << argv[
k+1];
583 if (fval < 0 || fval > 1) {
584 qCritical (
"Regularization value should be positive and smaller than one.");
589 else if (strcmp(argv[
k],
"--magreg") == 0) {
591 if (
k == *argc - 1) {
592 qCritical (
"--magreg: argument required.");
595 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
596 qCritical () <<
"Incomprehensible value:" << argv[
k+1];
599 if (fval < 0 || fval > 1) {
600 qCritical (
"Regularization value should be positive and smaller than one.");
605 else if (strcmp(argv[
k],
"--gradreg") == 0) {
607 if (
k == *argc - 1) {
608 qCritical (
"--gradreg: argument required.");
611 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
612 qCritical () <<
"Incomprehensible value:" << argv[
k+1] ;
615 if (fval < 0 || fval > 1) {
616 qCritical (
"Regularization value should be positive and smaller than one.");
621 else if (strcmp(argv[
k],
"--reg") == 0) {
623 if (
k == *argc - 1) {
624 qCritical (
"--reg: argument required.");
627 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
628 qCritical () <<
"Incomprehensible value:" << argv[
k+1];
631 if (fval < 0 || fval > 1) {
632 qCritical (
"Regularization value should be positive and smaller than one.");
639 else if (strcmp(argv[
k],
"--tstep") == 0) {
641 if (
k == *argc - 1) {
642 qCritical (
"--tstep: argument required.");
645 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
646 qCritical() <<
"Incomprehensible tstep:" << argv[
k+1];
650 qCritical (
"Time step should be positive");
655 else if (strcmp(argv[
k],
"--integ") == 0) {
657 if (
k == *argc - 1) {
658 qCritical (
"--integ: argument required.");
661 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
662 qCritical() <<
"Incomprehensible integration time:" << argv[
k+1];
666 qCritical (
"Integration time should be positive.");
669 integ = fval/1000.0f;
671 else if (strcmp(argv[
k],
"--tmin") == 0) {
673 if (
k == *argc - 1) {
674 qCritical (
"--tmin: argument required.");
677 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
678 qCritical() <<
"Incomprehensible tmin:" << argv[
k+1];
683 else if (strcmp(argv[
k],
"--tmax") == 0) {
685 if (
k == *argc - 1) {
686 qCritical (
"--tmax: argument required.");
689 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
690 qCritical() <<
"Incomprehensible tmax:" << argv[
k+1];
695 else if (strcmp(argv[
k],
"--bmin") == 0) {
697 if (
k == *argc - 1) {
698 qCritical (
"--bmin: argument required.");
701 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
702 qCritical() <<
"Incomprehensible bmin:" << argv[
k+1];
707 else if (strcmp(argv[
k],
"--bmax") == 0) {
709 if (
k == *argc - 1) {
710 qCritical (
"--bmax: argument required.");
713 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
714 qCritical() <<
"Incomprehensible bmax:" << argv[
k+1];
719 else if (strcmp(argv[
k],
"--set") == 0) {
721 if (
k == *argc - 1) {
722 qCritical (
"--set: argument required.");
725 if (sscanf(argv[
k+1],
"%d",&setno) != 1) {
726 qCritical() <<
"Incomprehensible data set number:" << argv[
k+1];
730 qCritical (
"Data set number must be > 0");
734 else if (strcmp(argv[
k],
"--filteroff") == 0) {
736 filter.filter_on =
false;
738 else if (strcmp(argv[
k],
"--lowpass") == 0) {
740 if (
k == *argc - 1) {
741 qCritical (
"--lowpass: argument required.");
744 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
745 qCritical() <<
"Illegal number:" << argv[
k+1];
749 qCritical (
"Lowpass corner must be positive");
752 filter.lowpass = fval;
754 else if (strcmp(argv[
k],
"--lowpassw") == 0) {
756 if (
k == *argc - 1) {
757 qCritical (
"--lowpassw: argument required.");
760 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
761 qCritical() <<
"Illegal number:" << argv[
k+1];
765 qCritical (
"Lowpass width must be positive");
768 filter.lowpass_width = fval;
770 else if (strcmp(argv[
k],
"--highpass") == 0) {
772 if (
k == *argc - 1) {
773 qCritical (
"--highpass: argument required.");
776 if (sscanf(argv[
k+1],
"%g",&fval) != 1) {
777 qCritical() <<
"Illegal number:" << argv[
k+1];
781 qCritical (
"Highpass corner must be positive");
784 filter.highpass = fval;
786 else if (strcmp(argv[
k],
"--filtersize") == 0) {
788 if (
k == *argc - 1) {
789 qCritical (
"--filtersize: argument required.");
792 if (sscanf(argv[
k+1],
"%d",&ival) != 1) {
793 qCritical() <<
"Illegal number:" << argv[
k+1];
797 qCritical (
"Filtersize should be at least 1024.");
800 for (filter_size = 1024; filter_size < ival; filter_size = 2*filter_size)
802 filter.size = filter_size;
803 filter.taper_size = filter_size/2;
805 else if (strcmp(argv[
k],
"--magdip") == 0) {
807 fit_mag_dipoles =
true;
809 else if (strcmp(argv[
k],
"--dip") == 0) {
811 if (
k == *argc - 1) {
812 qCritical (
"--dip: argument required.");
815 dipname = QString(argv[
k+1]);
817 else if (strcmp(argv[
k],
"--bdip") == 0) {
819 if (
k == *argc - 1) {
820 qCritical (
"--bdip: argument required.");
823 bdipname = QString(argv[
k+1]);
825 else if (strcmp(argv[
k],
"--verbose") == 0) {
830 for (
int p =
k; p < *argc-found; p++)
831 argv[p] = argv[p+found];
832 *argc = *argc - found;
836 return check_unrecognized_args(*argc,argv);