v2.0.0
Loading...
Searching...
No Matches
inv_dipole_fit_settings.cpp
Go to the documentation of this file.
1//=============================================================================================================
18
19//=============================================================================================================
20// INCLUDES
21//=============================================================================================================
22
24
25//=============================================================================================================
26// USED NAMESPACES
27//=============================================================================================================
28
29using namespace Eigen;
30using namespace INVLIB;
31
32//=============================================================================================================
33// DEFINE STATIC HELPERS
34//=============================================================================================================
35
36namespace
37{
38
39//=============================================================================================================
48bool parseFloat(const char* arg, float& value)
49{
50 bool bOk = false;
51 const float parsed = QString::fromUtf8(arg).toFloat(&bOk);
52 if (bOk) {
53 value = parsed;
54 }
55
56 return bOk;
57}
58
59//=============================================================================================================
68bool parseInt(const char* arg, int& value)
69{
70 bool bOk = false;
71 const int parsed = QString::fromUtf8(arg).toInt(&bOk);
72 if (bOk) {
73 value = parsed;
74 }
75
76 return bOk;
77}
78
79//=============================================================================================================
88bool parseTriplet(const char* arg, Eigen::Vector3f& values)
89{
90 const QStringList parts = QString::fromUtf8(arg).split(':');
91 if (parts.size() != 3) {
92 return false;
93 }
94
95 Eigen::Vector3f parsed;
96 for (int i = 0; i < 3; ++i) {
97 bool bOk = false;
98 parsed[i] = parts.at(i).toFloat(&bOk);
99 if (!bOk) {
100 return false;
101 }
102 }
103
104 values = parsed;
105
106 return true;
107}
108
109} // namespace
110
111//=============================================================================================================
112// DEFINE MEMBER METHODS
113//=============================================================================================================
114
116{
117 initMembers();
118}
119
120//=============================================================================================================
121
123{
124 initMembers();
125
126 if (!check_args(argc, argv))
127 return;
128
130}
131
132//=============================================================================================================
133
137
138//=============================================================================================================
139
140void InvDipoleFitSettings::initMembers()
141{
142 // Init origin
143 r0 << 0.0f, 0.0f, 0.04f;
144
145 filter.filter_on = true;
146 filter.size = 4096;
147 filter.taper_size = 2048;
148 filter.highpass = 0.0;
150 filter.lowpass = 40.0;
151 filter.lowpass_width = 5.0;
152 filter.eog_highpass = 0.0;
154 filter.eog_lowpass = 40.0;
156
157 accurate = false;
158
159 guess_rad = 0.080f;
160 guess_mindist = 0.010f;
161 guess_exclude = 0.020f;
162 guess_grid = 0.010f;
163
164 grad_std = 5e-13f;
165 mag_std = 20e-15f;
166 eeg_std = 0.2e-6f;
167 diagnoise = false;
168
169 is_raw = false;
170 include_meg = false;
171 include_eeg = false;
172 tmin = -2 * BIG_TIME;
173 tmax = 2 * BIG_TIME;
174 tstep = -1.0;
175 integ = 0.0;
176 bmin = BIG_TIME;
177 bmax = BIG_TIME;
178 do_baseline = false;
179 setno = 1;
180 verbose = false;
181 omit_data_proj = false;
182
183
184 eeg_sphere_rad = 0.09f;
185 scale_eeg_pos = false;
186 mag_reg = 0.1f;
187 fit_mag_dipoles = false;
188
189 grad_reg = 0.1f;
190 eeg_reg = 0.1f;
191
192 gui = false;
193}
194
195//=============================================================================================================
196
198{
200
201 if (measname.isEmpty()) {
202 qCritical("Data file name missing. Please specify one using the --meas option.");
203 return false;
204 }
205 if (guessname.isEmpty()) {
206 if (bemname.isEmpty() && !guess_surfname.isEmpty() && mriname.isEmpty()) {
207 qCritical("Please specify the MRI/head coordinate transformation with the --mri option");
208 return false;
209 }
210 }
211 if (!include_meg && !include_eeg) {
212 qCritical("Specify one or both of the --eeg and --meg options");
213 return false;
214 }
215 // Calling this again (e.g. once per fit) must not add the data file's projections twice
216 if (!omit_data_proj && !projnames.contains(measname))
217 projnames.prepend(measname);
218
219 if (!bemname.isEmpty())
220 qInfo("BEM : %s", bemname.toUtf8().data());
221 else {
222 qInfo("Sphere model : origin at (% 7.2f % 7.2f % 7.2f) mm",
223 1000 * r0[0], 1000 * r0[1], 1000 * r0[2]);
224 }
225 qInfo("Using %s MEG coil definitions.", accurate ? "accurate" : "standard");
226 if (!mriname.isEmpty())
227 qInfo("MRI transform : %s", mriname.toUtf8().data());
228 if (!guessname.isEmpty())
229 qInfo("Guesses : %s", guessname.toUtf8().data());
230 else {
231 if (!guess_surfname.isEmpty())
232 qInfo("Guess space bounded by %s", guess_surfname.toUtf8().data());
233 else
234 qInfo("Spherical guess space, rad = %.1f mm", 1000 * guess_rad);
235 qInfo("Guess grid : %6.1f mm", 1000 * guess_grid);
236 if (guess_mindist > 0.0)
237 qInfo("Guess mindist : %6.1f mm", 1000 * guess_mindist);
238 if (guess_exclude > 0)
239 qInfo("Guess exclude : %6.1f mm", 1000 * guess_exclude);
240 }
241 qInfo("Data : %s", measname.toUtf8().data());
242 if (projnames.size() > 0) {
243 qInfo("SSP sources :");
244 for (int k = 0; k < projnames.size(); k++)
245 qInfo("\t%s", projnames[k].toUtf8().data());
246 }
247 if (!badname.isEmpty())
248 qInfo("Bad channels : %s", badname.toUtf8().data());
249 if (do_baseline)
250 qInfo("Baseline : %10.2f ... %10.2f ms", 1000 * bmin, 1000 * bmax);
251 if (!noisename.isEmpty()) {
252 qInfo("Noise covariance : %s", noisename.toUtf8().data());
253 if (include_meg) {
254 if (mag_reg > 0.0)
255 qInfo("\tNoise-covariance regularization (mag) : %-5.2f", mag_reg);
256 if (grad_reg > 0.0)
257 qInfo("\tNoise-covariance regularization (grad) : %-5.2f", grad_reg);
258 }
259 if (include_eeg && eeg_reg > 0.0)
260 qInfo("\tNoise-covariance regularization (EEG) : %-5.2f", eeg_reg);
261 }
262 if (fit_mag_dipoles)
263 qInfo("Fit data with magnetic dipoles");
264 if (!dipname.isEmpty())
265 qInfo("dip output : %s", dipname.toUtf8().data());
266 if (!bdipname.isEmpty())
267 qInfo("bdip output : %s", bdipname.toUtf8().data());
268 return true;
269}
270
271//=============================================================================================================
272
273void InvDipoleFitSettings::usage(const char* name)
274{
275 qInfo("usage: %s [options]", name);
276 qInfo("This is a program for sequential single dipole fitting.");
277 qInfo("\nInput data:\n");
278 qInfo("\t--meas name specify an evoked-response data file");
279 qInfo("\t--set no evoked data set number to use (default: 1)");
280 qInfo("\t--bad name take bad channel list from here");
281
282 qInfo("\nModality selection:\n");
283 qInfo("\t--meg employ MEG data in fitting");
284 qInfo("\t--eeg employ EEG data in fitting");
285
286 qInfo("\nTime scale selection:\n");
287 qInfo("\t--tmin time/ms specify the starting analysis time");
288 qInfo("\t--tmax time/ms specify the ending analysis time");
289 qInfo("\t--tstep time/ms specify the time step between frames (default 1/(sampling frequency))");
290 qInfo("\t--integ time/ms specify the time integration for each frame (default 0)");
291
292 qInfo("\nPreprocessing:\n");
293 qInfo("\t--bmin time/ms specify the baseline starting time (evoked data only)");
294 qInfo("\t--bmax time/ms specify the baseline ending time (evoked data only)");
295 qInfo("\t--proj name Load the linear projection from here");
296 qInfo("\t Multiple projections can be specified.");
297 qInfo("\t The data file will be automatically included, unless --noproj is present.");
298 qInfo("\t--noproj Do not load the projection from the data file, just those given with the --proj option.");
299 qInfo("\n\tFiltering (raw data only):\n");
300 qInfo("\t--filtersize size desired filter length (default = %d)", filter.size);
301 qInfo("\t--highpass val/Hz highpass corner (default = %6.1f Hz)", filter.highpass);
302 qInfo("\t--lowpass val/Hz lowpass corner (default = %6.1f Hz)", filter.lowpass);
303 qInfo("\t--lowpassw val/Hz lowpass transition width (default = %6.1f Hz)", filter.lowpass_width);
304 qInfo("\t--filteroff do not filter the data");
305
306 qInfo("\nNoise specification:\n");
307 qInfo("\t--noise name take the noise-covariance matrix from here");
308 qInfo("\t--gradnoise val specify a gradiometer noise value in fT/cm");
309 qInfo("\t--magnoise val specify a magnetometer noise value in fT");
310 qInfo("\t--eegnoise val specify an EEG value in uV");
311 qInfo("\t NOTE: The above will be used only if --noise is missing");
312 qInfo("\t--diagnoise omit off-diagonal terms from the noise-covariance matrix");
313 qInfo("\t--reg amount Apply regularization to the noise-covariance matrix (same fraction for all channels).");
314 qInfo("\t--gradreg amount Apply regularization to the MEG noise-covariance matrix (planar gradiometers, default = %6.2f).", grad_reg);
315 qInfo("\t--magreg amount Apply regularization to the MEG noise-covariance matrix (axial gradiometers and magnetometers, default = %6.2f).", mag_reg);
316 qInfo("\t--eegreg amount Apply regularization to the EEG noise-covariance matrix (default = %6.2f).", eeg_reg);
317
318 qInfo("\nForward model:\n");
319 qInfo("\t--mri name take head/MRI coordinate transform from here (Neuromag MRI description file)");
320 qInfo("\t--bem name BEM model name");
321 qInfo("\t--origin x:y:z/mm use a sphere model with this origin (head coordinates/mm)");
322 qInfo("\t--eegscalp scale the electrode locations to the surface of the scalp when using a sphere model");
323 qInfo("\t--eegmodels name read EEG sphere model specifications from here.");
324 qInfo("\t--eegmodel name name of the EEG sphere model to use (default : Default)");
325 qInfo("\t--eegrad val radius of the scalp surface to use in EEG sphere model (default : %7.1f mm)", 1000 * eeg_sphere_rad);
326 qInfo("\t--accurate use accurate coil definitions in MEG forward computation");
327
328 qInfo("\nFitting parameters:\n");
329 qInfo("\t--guess name The source space of initial guesses.");
330 qInfo("\t If not present, the values below are used to generate the guess grid.");
331 qInfo("\t--guesssurf name Read the inner skull surface from this fif file to generate the guesses.");
332 qInfo("\t--guessrad value Radius of a spherical guess volume if neither of the above is present (default : %.1f mm)", 1000 * guess_rad);
333 qInfo("\t--exclude dist/mm Exclude points which are closer than this distance from the CM of the inner skull surface (default = %6.1f mm).", 1000 * guess_exclude);
334 qInfo("\t--mindist dist/mm Exclude points which are closer than this distance from the inner skull surface (default = %6.1f mm).", 1000 * guess_mindist);
335 qInfo("\t--grid dist/mm Source space grid size (default = %6.1f mm).", 1000 * guess_grid);
336 qInfo("\t--magdip Fit magnetic dipoles instead of current dipoles.");
337 qInfo("\nOutput:\n");
338 qInfo("\t--dip name xfit dip format output file name");
339 qInfo("\t--bdip name xfit bdip format output file name");
340 qInfo("\nGeneral:\n");
341 qInfo("\t--gui Enables the gui.");
342 qInfo("\t--help print this info.");
343 qInfo("\t--version print version info.");
344}
345
346//=============================================================================================================
347
348bool InvDipoleFitSettings::check_unrecognized_args(int argc, char** argv)
349{
350 if (argc > 1) {
351 QString args;
352 for (int k = 1; k < argc; k++)
353 args += QString(argv[k]) + " ";
354 qCritical("Unrecognized arguments : %s", args.trimmed().toUtf8().data());
355 return false;
356 }
357 return true;
358}
359
360//=============================================================================================================
361
362bool InvDipoleFitSettings::check_args(int* argc, char** argv)
363{
364 int found;
365 float fval;
366 int ival, filter_size;
367
368 for (int k = 0; k < *argc; k++) {
369 found = 0;
370 if (strcmp(argv[k], "--gui") == 0) {
371 found = 1;
372 gui = true;
373 } else if (strcmp(argv[k], "--version") == 0) {
374 qInfo("%s compiled at %s %s",
375 argv[0], __DATE__, __TIME__);
376 exit(0);
377 } else if (strcmp(argv[k], "--help") == 0) {
378 usage(argv[0]);
379 exit(0);
380 } else if (strcmp(argv[k], "--guess") == 0) {
381 found = 2;
382 if (k == *argc - 1) {
383 qCritical("--guess: argument required.");
384 return false;
385 }
386 guessname = QString(argv[k + 1]);
387 } else if (strcmp(argv[k], "--gsurf") == 0) {
388 found = 2;
389 if (k == *argc - 1) {
390 qCritical("--gsurf: argument required.");
391 return false;
392 }
393 guess_surfname = QString(argv[k + 1]);
394 } else if (strcmp(argv[k], "--guesssurf") == 0) {
395 found = 2;
396 if (k == *argc - 1) {
397 qCritical("--guesssurf: argument required.");
398 return false;
399 }
400 guess_surfname = QString(argv[k + 1]);
401 } else if (strcmp(argv[k], "--guessrad") == 0) {
402 found = 2;
403 if (k == *argc - 1) {
404 qCritical("--guessrad: argument required.");
405 return false;
406 }
407 if (!parseFloat(argv[k + 1], fval)) {
408 qCritical("Could not interpret the radius.");
409 return false;
410 }
411 if (fval <= 0.0) {
412 qCritical("Radius should be positive");
413 return false;
414 }
415 guess_rad = fval / 1000.0;
416 } else if (strcmp(argv[k], "--mindist") == 0) {
417 found = 2;
418 if (k == *argc - 1) {
419 qCritical("--mindist: argument required.");
420 return false;
421 }
422 if (!parseFloat(argv[k + 1], fval)) {
423 qCritical("Could not interpret the distance.");
424 return false;
425 }
426 guess_mindist = fval / 1000.0;
427 if (guess_mindist <= 0.0)
428 guess_mindist = 0.0;
429 } else if (strcmp(argv[k], "--exclude") == 0) {
430 found = 2;
431 if (k == *argc - 1) {
432 qCritical("--exclude: argument required.");
433 return false;
434 }
435 if (!parseFloat(argv[k + 1], fval)) {
436 qCritical("Could not interpret the distance.");
437 return false;
438 }
439 guess_exclude = fval / 1000.0;
440 if (guess_exclude <= 0.0)
441 guess_exclude = 0.0;
442 } else if (strcmp(argv[k], "--grid") == 0) {
443 found = 2;
444 if (k == *argc - 1) {
445 qCritical("--grid: argument required.");
446 return false;
447 }
448 if (!parseFloat(argv[k + 1], fval)) {
449 qCritical("Could not interpret the distance.");
450 return false;
451 }
452 if (fval <= 0.0) {
453 qCritical("Grid spacing should be positive");
454 return false;
455 }
456 // MNE-C divided the default instead of the value given, so --grid was ignored.
457 guess_grid = fval / 1000.0;
458 } else if (strcmp(argv[k], "--mri") == 0) {
459 found = 2;
460 if (k == *argc - 1) {
461 qCritical("--mri: argument required.");
462 return false;
463 }
464 mriname = QString(argv[k + 1]);
465 } else if (strcmp(argv[k], "--bem") == 0) {
466 found = 2;
467 if (k == *argc - 1) {
468 qCritical("--bem: argument required.");
469 return false;
470 }
471 bemname = QString(argv[k + 1]);
472 } else if (strcmp(argv[k], "--accurate") == 0) {
473 found = 1;
474 accurate = true;
475 } else if (strcmp(argv[k], "--meg") == 0) {
476 found = 1;
477 include_meg = true;
478 } else if (strcmp(argv[k], "--eeg") == 0) {
479 found = 1;
480 include_eeg = true;
481 } else if (strcmp(argv[k], "--origin") == 0) {
482 found = 2;
483 if (k == *argc - 1) {
484 qCritical("--origin: argument required.");
485 return false;
486 }
487 if (!parseTriplet(argv[k + 1], r0)) {
488 qCritical("Could not interpret the origin.");
489 return false;
490 }
491 r0[0] = r0[0] / 1000.0f;
492 r0[1] = r0[1] / 1000.0f;
493 r0[2] = r0[2] / 1000.0f;
494 } else if (strcmp(argv[k], "--eegrad") == 0) {
495 found = 2;
496 if (k == *argc - 1) {
497 qCritical("--eegrad: argument required.");
498 return false;
499 }
500 if (!parseFloat(argv[k + 1], eeg_sphere_rad)) {
501 qCritical() << "Incomprehensible radius:" << argv[k + 1];
502 return false;
503 }
504 if (eeg_sphere_rad <= 0) {
505 qCritical("Radius must be positive");
506 return false;
507 }
509 } else if (strcmp(argv[k], "--eegmodels") == 0) {
510 found = 2;
511 if (k == *argc - 1) {
512 qCritical("--eegmodels: argument required.");
513 return false;
514 }
515 eeg_model_file = QString(argv[k + 1]);
516 } else if (strcmp(argv[k], "--eegmodel") == 0) {
517 found = 2;
518 if (k == *argc - 1) {
519 qCritical("--eegmodel: argument required.");
520 return false;
521 }
522 eeg_model_name = QString(argv[k + 1]);
523 } else if (strcmp(argv[k], "--eegscalp") == 0) {
524 found = 1;
525 scale_eeg_pos = true;
526 } else if (strcmp(argv[k], "--meas") == 0) {
527 found = 2;
528 if (k == *argc - 1) {
529 qCritical("--meas: argument required.");
530 return false;
531 }
532 measname = QString(argv[k + 1]);
533 is_raw = false;
534 } else if (strcmp(argv[k], "--raw") == 0) {
535 found = 2;
536 if (k == *argc - 1) {
537 qCritical("--raw: argument required.");
538 return false;
539 }
540 measname = QString(argv[k + 1]);
541 is_raw = true;
542 } else if (strcmp(argv[k], "--proj") == 0) {
543 found = 2;
544 if (k == *argc - 1) {
545 qCritical("--proj: argument required.");
546 return false;
547 }
548 projnames.append(QString(argv[k + 1]));
549 } else if (strcmp(argv[k], "--noproj") == 0) {
550 found = 1;
551 omit_data_proj = true;
552 } else if (strcmp(argv[k], "--bad") == 0) {
553 found = 2;
554 if (k == *argc - 1) {
555 qCritical("--bad: argument required.");
556 return false;
557 }
558 badname = QString(argv[k + 1]);
559 } else if (strcmp(argv[k], "--noise") == 0) {
560 found = 2;
561 if (k == *argc - 1) {
562 qCritical("--noise: argument required.");
563 return false;
564 }
565 noisename = QString(argv[k + 1]);
566 } else if (strcmp(argv[k], "--gradnoise") == 0) {
567 found = 2;
568 if (k == *argc - 1) {
569 qCritical("--gradnoise: argument required.");
570 return false;
571 }
572 if (!parseFloat(argv[k + 1], fval)) {
573 qCritical() << "Incomprehensible value:" << argv[k + 1];
574 return false;
575 }
576 if (fval < 0.0) {
577 qCritical("Value should be positive");
578 return false;
579 }
580 grad_std = 1e-13 * fval;
581 } else if (strcmp(argv[k], "--magnoise") == 0) {
582 found = 2;
583 if (k == *argc - 1) {
584 qCritical("--magnoise: argument required.");
585 return false;
586 }
587 if (!parseFloat(argv[k + 1], fval)) {
588 qCritical() << "Incomprehensible value:" << argv[k + 1];
589 return false;
590 }
591 if (fval < 0.0) {
592 qCritical("Value should be positive");
593 return false;
594 }
595 mag_std = 1e-15 * fval;
596 } else if (strcmp(argv[k], "--eegnoise") == 0) {
597 found = 2;
598 if (k == *argc - 1) {
599 qCritical("--eegnoise: argument required.");
600 return false;
601 }
602 if (!parseFloat(argv[k + 1], fval)) {
603 qCritical() << "Incomprehensible value:" << argv[k + 1];
604 return false;
605 }
606 if (fval < 0.0) {
607 qCritical("Value should be positive");
608 return false;
609 }
610 eeg_std = 1e-6 * fval;
611 } else if (strcmp(argv[k], "--diagnoise") == 0) {
612 found = 1;
613 diagnoise = true;
614 } else if (strcmp(argv[k], "--eegreg") == 0) {
615 found = 2;
616 if (k == *argc - 1) {
617 qCritical("--eegreg: argument required.");
618 return false;
619 }
620 if (!parseFloat(argv[k + 1], fval)) {
621 qCritical() << "Incomprehensible value:" << argv[k + 1];
622 return false;
623 }
624 if (fval < 0 || fval > 1) {
625 qCritical("Regularization value should be positive and smaller than one.");
626 return false;
627 }
628 eeg_reg = fval;
629 } else if (strcmp(argv[k], "--magreg") == 0) {
630 found = 2;
631 if (k == *argc - 1) {
632 qCritical("--magreg: argument required.");
633 return false;
634 }
635 if (!parseFloat(argv[k + 1], fval)) {
636 qCritical() << "Incomprehensible value:" << argv[k + 1];
637 return false;
638 }
639 if (fval < 0 || fval > 1) {
640 qCritical("Regularization value should be positive and smaller than one.");
641 return false;
642 }
643 mag_reg = fval;
644 } else if (strcmp(argv[k], "--gradreg") == 0) {
645 found = 2;
646 if (k == *argc - 1) {
647 qCritical("--gradreg: argument required.");
648 return false;
649 }
650 if (!parseFloat(argv[k + 1], fval)) {
651 qCritical() << "Incomprehensible value:" << argv[k + 1];
652 return false;
653 }
654 if (fval < 0 || fval > 1) {
655 qCritical("Regularization value should be positive and smaller than one.");
656 return false;
657 }
658 grad_reg = fval;
659 } else if (strcmp(argv[k], "--reg") == 0) {
660 found = 2;
661 if (k == *argc - 1) {
662 qCritical("--reg: argument required.");
663 return false;
664 }
665 if (!parseFloat(argv[k + 1], fval)) {
666 qCritical() << "Incomprehensible value:" << argv[k + 1];
667 return false;
668 }
669 if (fval < 0 || fval > 1) {
670 qCritical("Regularization value should be positive and smaller than one.");
671 return false;
672 }
673 grad_reg = fval;
674 mag_reg = fval;
675 eeg_reg = fval;
676 } else if (strcmp(argv[k], "--tstep") == 0) {
677 found = 2;
678 if (k == *argc - 1) {
679 qCritical("--tstep: argument required.");
680 return false;
681 }
682 if (!parseFloat(argv[k + 1], fval)) {
683 qCritical() << "Incomprehensible tstep:" << argv[k + 1];
684 return false;
685 }
686 if (fval < 0.0) {
687 qCritical("Time step should be positive");
688 return false;
689 }
690 tstep = fval / 1000.0;
691 } else if (strcmp(argv[k], "--integ") == 0) {
692 found = 2;
693 if (k == *argc - 1) {
694 qCritical("--integ: argument required.");
695 return false;
696 }
697 if (!parseFloat(argv[k + 1], fval)) {
698 qCritical() << "Incomprehensible integration time:" << argv[k + 1];
699 return false;
700 }
701 if (fval <= 0.0) {
702 qCritical("Integration time should be positive.");
703 return false;
704 }
705 integ = fval / 1000.0f;
706 } else if (strcmp(argv[k], "--tmin") == 0) {
707 found = 2;
708 if (k == *argc - 1) {
709 qCritical("--tmin: argument required.");
710 return false;
711 }
712 if (!parseFloat(argv[k + 1], fval)) {
713 qCritical() << "Incomprehensible tmin:" << argv[k + 1];
714 return false;
715 }
716 tmin = fval / 1000.0f;
717 } else if (strcmp(argv[k], "--tmax") == 0) {
718 found = 2;
719 if (k == *argc - 1) {
720 qCritical("--tmax: argument required.");
721 return false;
722 }
723 if (!parseFloat(argv[k + 1], fval)) {
724 qCritical() << "Incomprehensible tmax:" << argv[k + 1];
725 return false;
726 }
727 tmax = fval / 1000.0;
728 } else if (strcmp(argv[k], "--bmin") == 0) {
729 found = 2;
730 if (k == *argc - 1) {
731 qCritical("--bmin: argument required.");
732 return false;
733 }
734 if (!parseFloat(argv[k + 1], fval)) {
735 qCritical() << "Incomprehensible bmin:" << argv[k + 1];
736 return false;
737 }
738 bmin = fval / 1000.0f;
739 } else if (strcmp(argv[k], "--bmax") == 0) {
740 found = 2;
741 if (k == *argc - 1) {
742 qCritical("--bmax: argument required.");
743 return false;
744 }
745 if (!parseFloat(argv[k + 1], fval)) {
746 qCritical() << "Incomprehensible bmax:" << argv[k + 1];
747 return false;
748 }
749 bmax = fval / 1000.0f;
750 } else if (strcmp(argv[k], "--set") == 0) {
751 found = 2;
752 if (k == *argc - 1) {
753 qCritical("--set: argument required.");
754 return false;
755 }
756 if (!parseInt(argv[k + 1], setno)) {
757 qCritical() << "Incomprehensible data set number:" << argv[k + 1];
758 return false;
759 }
760 if (setno <= 0) {
761 qCritical("Data set number must be > 0");
762 return false;
763 }
764 } else if (strcmp(argv[k], "--filteroff") == 0) {
765 found = 1;
766 filter.filter_on = false;
767 } else if (strcmp(argv[k], "--lowpass") == 0) {
768 found = 2;
769 if (k == *argc - 1) {
770 qCritical("--lowpass: argument required.");
771 return false;
772 }
773 if (!parseFloat(argv[k + 1], fval)) {
774 qCritical() << "Illegal number:" << argv[k + 1];
775 return false;
776 }
777 if (fval <= 0) {
778 qCritical("Lowpass corner must be positive");
779 return false;
780 }
781 filter.lowpass = fval;
782 } else if (strcmp(argv[k], "--lowpassw") == 0) {
783 found = 2;
784 if (k == *argc - 1) {
785 qCritical("--lowpassw: argument required.");
786 return false;
787 }
788 if (!parseFloat(argv[k + 1], fval)) {
789 qCritical() << "Illegal number:" << argv[k + 1];
790 return false;
791 }
792 if (fval <= 0) {
793 qCritical("Lowpass width must be positive");
794 return false;
795 }
796 filter.lowpass_width = fval;
797 } else if (strcmp(argv[k], "--highpass") == 0) {
798 found = 2;
799 if (k == *argc - 1) {
800 qCritical("--highpass: argument required.");
801 return false;
802 }
803 if (!parseFloat(argv[k + 1], fval)) {
804 qCritical() << "Illegal number:" << argv[k + 1];
805 return false;
806 }
807 if (fval <= 0) {
808 qCritical("Highpass corner must be positive");
809 return false;
810 }
811 filter.highpass = fval;
812 } else if (strcmp(argv[k], "--filtersize") == 0) {
813 found = 2;
814 if (k == *argc - 1) {
815 qCritical("--filtersize: argument required.");
816 return false;
817 }
818 if (!parseInt(argv[k + 1], ival)) {
819 qCritical() << "Illegal number:" << argv[k + 1];
820 return false;
821 }
822 if (ival < 1024) {
823 qCritical("Filtersize should be at least 1024.");
824 return false;
825 }
826 for (filter_size = 1024; filter_size < ival; filter_size = 2 * filter_size)
827 ;
828 filter.size = filter_size;
829 filter.taper_size = filter_size / 2;
830 } else if (strcmp(argv[k], "--magdip") == 0) {
831 found = 1;
832 fit_mag_dipoles = true;
833 } else if (strcmp(argv[k], "--dip") == 0) {
834 found = 2;
835 if (k == *argc - 1) {
836 qCritical("--dip: argument required.");
837 return false;
838 }
839 dipname = QString(argv[k + 1]);
840 } else if (strcmp(argv[k], "--bdip") == 0) {
841 found = 2;
842 if (k == *argc - 1) {
843 qCritical("--bdip: argument required.");
844 return false;
845 }
846 bdipname = QString(argv[k + 1]);
847 } else if (strcmp(argv[k], "--verbose") == 0) {
848 found = 1;
849 verbose = true;
850 }
851 if (found) {
852 for (int p = k; p < *argc - found; p++)
853 argv[p] = argv[p + found];
854 *argc = *argc - found;
855 k = k - found;
856 }
857 }
858 return check_unrecognized_args(*argc, argv);
859}
Command-line and programmatic settings struct for the mne_dipole_fit driver.
Inverse source estimation (MNE, dSPM, sLORETA, dipole fitting).
constexpr double BIG_TIME