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