EddyCommandLineOptions.h 31.2 KB
Newer Older
wangkx1's avatar
init  
wangkx1 committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
#include <cstdlib>
#include <string>
#include <vector>
#include <limits>
#include "utils/options.h"
#include "newimage/newimage.h"
#include "EddyHelperClasses.h"

#ifndef EddyCommandLineOptions_h
#define EddyCommandLineOptions_h

namespace EDDY {

/****************************************************************//***
* \brief This is the exception that is being thrown by
*  EddyCommandLineOptions if there is a problem with the
*  user input.
*
*  This is the exception that is being thrown by
*  EddyCommandLineOptions if there is a problem with the
*  user input. It is different to EddyException because
*  I don't want it to generate a stack dump that might
*  confuse the user.
*
********************************************************************/
class EddyInputError: public std::exception
{
public:
  EddyInputError(const std::string& msg) noexcept : m_msg(std::string("EddyInputError:  ") + msg) {}
  ~EddyInputError() noexcept {}
  virtual const char * what() const noexcept { return(m_msg.c_str()); }
private:
  std::string m_msg;
};

class S2VParam {
public:
  S2VParam() EddyTry : _order(std::vector<int>(1,0)), _lambda(std::vector<float>(1,0.0)),
	       _fwhm(std::vector<float>(1,0.0)), _niter(std::vector<int>(1,0)) {} EddyCatch
  S2VParam(const std::vector<int>& order, const std::vector<float>& lambda,
	   const std::vector<float>& fwhm, const std::vector<int>& niter);
  unsigned int NOrder() const;
  unsigned int Order(unsigned int oi) const;
  std::vector<unsigned int> Order() const;
  unsigned int NIter(unsigned int oi) const;
  double Lambda(unsigned int oi) const;
  std::vector<double> Lambda() const;
  float FWHM(unsigned int oi, unsigned int iter) const;
  std::vector<float> FWHM(unsigned int oi) const;
private:
  std::vector<int>      _order;
  std::vector<float>    _lambda;
  std::vector<float>    _fwhm;
  std::vector<int>      _niter;
  unsigned int total_niter() const EddyTry {
    unsigned int rval=0;
    for (unsigned int i=0; i<_niter.size(); i++) rval += static_cast<unsigned int>(_niter[i]);
    return(rval);
  } EddyCatch
};

class DebugIndexClass {
public:
  DebugIndexClass(const std::string& in);
  DebugIndexClass(unsigned int frst, unsigned int lst) EddyTry { _indx.resize(lst-frst+1); for (unsigned int i=0; i<lst-frst+1; i++) _indx[i]=frst+i; } EddyCatch
  DebugIndexClass() : _indx(0) {}
  bool IsAmongIndicies(unsigned int indx) const EddyTry { for (unsigned int i=0; i<_indx.size(); i++) if (indx==_indx[i]) return(true); return(false); } EddyCatch
  unsigned int Min() const EddyTry {
    unsigned int rval=std::numeric_limits<unsigned int>::max(); for (unsigned int i=0; i<_indx.size(); i++) rval=min(rval,_indx[i]); return(rval);
  } EddyCatch
  unsigned int Max() const EddyTry {
    unsigned int rval=std::numeric_limits<unsigned int>::min(); for (unsigned int i=0; i<_indx.size(); i++) rval=max(rval,_indx[i]); return(rval);
  } EddyCatch
  const std::vector<unsigned int>& GetIndicies() const EddyTry { return(_indx); } EddyCatch
  void SetIndicies(const std::vector<unsigned int>& indx) EddyTry { _indx=indx; } EddyCatch
private:
  std::vector<unsigned int> _indx;

  std::vector<unsigned int> parse_commaseparated_numbers(const std::string& list) const;
  std::vector<std::string> parse_commaseparated_list(const std::string&  list) const;
  unsigned int min(unsigned int i, unsigned int j) const { if (i<=j) return(i); else return(j); }
  unsigned int max(unsigned int i, unsigned int j) const { if (i>=j) return(i); else return(j); }
};

class EddyCommandLineOptions {
public:
  EddyCommandLineOptions(int argc, char *argv[]);
  // These are utility functions used to enquire about the user input.
  // Below they are sorted  into functions relevant to both diffusion and fMRI,
  // only to diffusion or only to fMRI.
  //
  // Functions relevant to both diffusion and fMRI
  bool IsfMRI() const { return(_is_fmri); }
  bool IsDiffusion() const { return(!IsfMRI()); }
  // Names of input files
  std::string ImaFname() const EddyTry { return(_imain.value()); } EddyCatch
  std::string MaskFname() const EddyTry { return(_mask.value()); } EddyCatch
  std::string AcqpFname() const EddyTry { return(_acqp.value()); } EddyCatch
  std::string IndexFname() const EddyTry { return(_index.value()); } EddyCatch
  std::string TopupFname() const EddyTry { return(_topup.value()); } EddyCatch
  std::string FieldFname() const EddyTry { return(_field.value()); } EddyCatch
  // Names of output files
  std::string ParOutFname() const EddyTry { return(_out.value()+std::string(".eddy_parameters")); } EddyCatch
  std::string MovementOverTimeOutFname() const EddyTry { return(_out.value()+std::string(".eddy_movement_over_time")); } EddyCatch
  std::string IOutFname() const EddyTry { return(_out.value()); } EddyCatch
  std::string OutMaskFname() const EddyTry { return((_dont_mask_output.value()) ? _out.value()+std::string(".eddy_output_mask") : std::string(""));} EddyCatch
  std::string MoveBySuscFirstOrderFname() const EddyTry { return(_out.value()+std::string(".eddy_mbs_first_order_fields")); } EddyCatch
  std::string MoveBySuscSecondOrderFname() const EddyTry { return(_out.value()+std::string(".eddy_mbs_second_order_fields")); } EddyCatch
  std::string RMSOutFname() const EddyTry { return(_out.value()+std::string(".eddy_movement_rms")); } EddyCatch
  std::string DFieldOutFname() const EddyTry { return(_out.value()+std::string(".eddy_displacement_fields")); } EddyCatch
  std::string OLReportFname() const EddyTry { return(_out.value()+std::string(".eddy_outlier_report")); } EddyCatch
  std::string OLMapReportFname(bool problem=false) const EddyTry {
    if (problem) return(_out.value()+std::string(".eddy_outlier_map_written_when_all_volumes_in_a_shell_has_outliers"));
    else return(_out.value()+std::string(".eddy_outlier_map"));
  } EddyCatch
  std::string OLNStDevMapReportFname(bool problem=false) const EddyTry {
    if (problem) return(_out.value()+std::string(".eddy_outlier_n_stdev_map_written_when_all_volumes_in_a_shell_has_outliers"));
    else return(_out.value()+std::string(".eddy_outlier_n_stdev_map"));
  } EddyCatch
  std::string OLNSqrStDevMapReportFname(bool problem=false) const EddyTry {
    if (problem) return(_out.value()+std::string(".eddy_outlier_n_sqr_stdev_map_written_when_all_volumes_in_a_shell_has_outliers"));
    else return(_out.value()+std::string(".eddy_outlier_n_sqr_stdev_map"));
  } EddyCatch
  std::string OLFreeDataFname() const EddyTry { return(_out.value()+std::string(".eddy_outlier_free_data")); } EddyCatch
  std::string ResidualsOutFname() const EddyTry { return((_residuals.value()) ? _out.value()+std::string(".eddy_residuals") : std::string("")); } EddyCatch
  std::string ShellIndexOutFname() const EddyTry { return(_out.value()+std::string(".eddy_shell_indicies.json")); } EddyCatch
  std::string JsonOutFname() const EddyTry { return(_out.value()+std::string(".eddy.json")); } EddyCatch
  std::string AdditionalWithOutliersOutFname() const EddyTry { return(_out.value()+std::string(".eddy_results_with_outliers_retained")); } EddyCatch
  std::string PredictionsOutFname() const EddyTry { return(_out.value()+std::string(".eddy_predictions")); } EddyCatch
  std::string PredictionsInScanSpaceOutFname() const EddyTry { return(_out.value()+std::string(".eddy_predictions_in_scan_space")); } EddyCatch
  std::string LoggerFname() const EddyTry { return(_out.value()+std::string(".eddy_timing_log")); } EddyCatch
  std::string FieldMatFname() const EddyTry { return(_field_mat.value()); } EddyCatch
  bool SupressOldStyleTextFiles() const EddyTry { return(_no_text_files.value()); } EddyCatch;
  std::vector<unsigned int> Indicies() const EddyTry { return(_indvec); } EddyCatch
  std::vector<unsigned int> SessionIndicies() const EddyTry { return(_sessvec); } EddyCatch
  unsigned int Session(unsigned int i) const EddyTry { return((i < _sessvec.size()) ? _sessvec[i] : 0); } EddyCatch
  float RepetitionTime() const EddyTry { return(IsfMRI() ? _fmri._rep_time.value() : _diff._rep_time.value()); } EddyCatch
  bool RepetitionTimeIsSet() const EddyTry { return(IsfMRI() ? true : _diff._rep_time.set()); } EddyCatch
  float FWHM(unsigned int iter) const;
  std::vector<float> FWHM() const EddyTry { return(_fwhm); } EddyCatch
  unsigned int NIter() const { return(_niter); }
  void SetNIterAndFWHM(unsigned int niter, const std::vector<float>& fwhm);
  unsigned int S2V_NIter(unsigned int  oi) const EddyTry { return(_s2vparam.NIter(oi)); } EddyCatch
  void SetS2VParam(unsigned int order, float lambda, float fwhm, unsigned int niter);
  unsigned int Index(unsigned int i) const EddyTry { return(_indvec[i]); } EddyCatch
  EDDY::MultiBandGroups MultiBand() const;
  unsigned int NumOfNonZeroMovementModelOrder() const EddyTry { return(_s2vparam.NOrder()); } EddyCatch
  unsigned int MovementModelOrder(unsigned int oi) const EddyTry { return(_s2vparam.Order(oi)); } EddyCatch
  std::vector<unsigned int> MovementModelOrder() const EddyTry { return(_s2vparam.Order()); } EddyCatch
  double S2V_Lambda(unsigned int oi) const EddyTry { return(_s2vparam.Lambda(oi)); } EddyCatch
  std::vector<double> S2V_Lambda() const EddyTry { return(_s2vparam.Lambda()); } EddyCatch
  float S2V_FWHM(unsigned int oi, unsigned int iter) const EddyTry { return(_s2vparam.FWHM(oi,iter)); } EddyCatch
  std::vector<float> S2V_FWHM(unsigned int oi) const EddyTry { return(_s2vparam.FWHM(oi)); } EddyCatch
  bool IsSliceToVol() const EddyTry { return(NumOfNonZeroMovementModelOrder()>0); } EddyCatch
  bool EstimateMoveBySusc() const EddyTry { return(_estimate_mbs.value()); } EddyCatch
  unsigned int MoveBySuscNiter() const EddyTry { return(static_cast<unsigned int>(_mbs_niter.value())); } EddyCatch
  unsigned int N_MBS_Interleaves() const { return(3); }
  double MoveBySuscLambda() const EddyTry { return(static_cast<double>(_mbs_lambda.value())); } EddyCatch
  std::vector<unsigned int> MoveBySuscParam() const EddyTry { std::vector<unsigned int> rval(2); rval[0] = 3; rval[1] = 4; return(rval); } EddyCatch
  unsigned int MoveBySuscOrder() const { return(1); }
  bool MoveBySuscUseJacobian() const { return(true); }
  double MoveBySuscKsp() const EddyTry { return(static_cast<double>(_mbs_ksp.value())); } EddyCatch
  EDDY::ECModelType FirstLevelModel() const;
  EDDY::ECModelType b0_FirstLevelModel() const;
  bool ReplaceOutliers() const EddyTry { return(_rep_ol.value()); } EddyCatch
  bool WriteOutlierFreeData() const EddyTry { return(_rep_ol.value()); } EddyCatch
  const EDDY::OutlierDefinition& OLDef() const EddyTry { return(_oldef); } EddyCatch
  unsigned int OLErrorType() const EddyTry { return(_ol_ec.value()); } EddyCatch
  unsigned int RefScanNumber() const EddyTry { return(static_cast<unsigned int>(_ref_scan_no.value())); } EddyCatch
  EDDY::OLType OLType() const EddyTry { if (_ol_type.value()==std::string("sw")) return(OLType::SliceWise);
                                    else if (_ol_type.value()==std::string("gw")) return(OLType::GroupWise);
                                    else return(OLType::Both); } EddyCatch
  double OLUpperThresholdJacobianMask() const EddyTry { return(_ol_jacut.value()); } EddyCatch
  bool WriteMovementRMS() const { return(true); }
  bool WriteDisplacementFields() const EddyTry { return(_dfields.value()); } EddyCatch
  bool WriteResiduals() const EddyTry { return(_residuals.value()); } EddyCatch
  bool WriteAdditionalResultsWithOutliersRetained() const EddyTry { return(_with_outliers.value()); } EddyCatch
  bool WritePredictions() const EddyTry { return(_write_predictions.value()); } EddyCatch
  bool LogTimings() const EddyTry { return(_log_timings.value()); } EddyCatch
  bool History() const EddyTry { return(_history.value()); } EddyCatch
  bool FillEmptyPlanes() const EddyTry { return(_fep.value() ? true : !IsDiffusion() ? false : _diff._resamp.value() == std::string("lsr") ? true : false); } EddyCatch
  std::string InitFname() const EddyTry { return(_init.value()); } EddyCatch
  std::string InitS2VFname() const EddyTry { return(_init_s2v.value()); } EddyCatch
  std::string InitMBSFname() const EddyTry { return(_init_mbs.value()); } EddyCatch
  unsigned int NumberOfThreads() const EddyTry { return(static_cast<unsigned int>(_nthr.value())); } EddyCatch
  bool Verbose() const EddyTry { return(_verbose.value()); } EddyCatch
  bool VeryVerbose() const EddyTry { return(_very_verbose.value()); } EddyCatch
  bool WriteSliceStats() const EddyTry { return(_write_slice_stats.value()); } EddyCatch
  int DebugLevel() const { return(_debug); }
  const DebugIndexClass& DebugIndicies() const EddyTry { return(_dbg_indx); } EddyCatch
  void SetDebug(unsigned int level, const std::vector<unsigned int>& indx) EddyTry { _debug=level; _dbg_indx.SetIndicies(indx); } EddyCatch
  FinalResamplingType ResamplingMethod() const;
  CovarianceFunctionType CovarianceFunction() const;
  HyParCostFunctionType HyParCostFunction() const;
  bool MaskOutput() const EddyTry { return(!_dont_mask_output.value()); } EddyCatch
  int  InitRand() const { return(_init_rand); }
  unsigned int NVoxHp() const { return(_nvoxhp_internal); }
  void SetNVoxHp(unsigned int n) { _nvoxhp_internal = n; }
  double HyParFudgeFactor() const { return(_hypar_ff_internal); }
  void SetHyParFudgeFactor(double ff) { _hypar_ff_internal = ff; }
  bool HyperParFixed() const { return(_fixed_hpar); }
  void SetHyperParFixed(bool val=true) { _fixed_hpar = val; }
  NEWMAT::ColumnVector HyperParValues() const;
  void SetHyperParValues(const NEWMAT::ColumnVector& p);
  NEWIMAGE::interpolation InterpolationMethod() const;
  NEWIMAGE::extrapolation ExtrapolationMethod() const;
  bool ExtrapolationValidInPE() const EddyTry { return(_epvalid.value()); } EddyCatch
  NEWIMAGE::interpolation S2VInterpolationMethod() const;
  EDDY::PolationPara PolationParameters() const EddyTry {
    return(EDDY::PolationPara(InterpolationMethod(),ExtrapolationMethod(),ExtrapolationValidInPE(),S2VInterpolationMethod()));
  } EddyCatch
  bool ShapeReferencesSet() const EddyTry { return(_shape_references_set); } EddyCatch

  // Functions relevant only to diffusion
  std::string BVecsFname() const EddyTry { return(IsDiffusion() ? _diff._bvecs.value() : std::string("")); } EddyCatch
  std::string BValsFname() const EddyTry { return(IsDiffusion() ? _diff._bvals.value() : std::string("")); } EddyCatch
  std::string BDeltasFname() const EddyTry { return(IsDiffusion() ? _diff._bdeltas.value() : std::string("")); } EddyCatch
  std::string ECFOutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_fields") : std::string("")); } EddyCatch
  std::string LongECOutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_long_ec_parameters") : std::string("")); } EddyCatch
  std::string RotatedBVecsOutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_rotated_bvecs") : std::string("")); } EddyCatch
  std::string RotatedBVecsLSROutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_rotated_bvecs_for_SLR") : std::string("")); } EddyCatch
  std::string BVecsLSROutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_bvecs_for_SLR") : std::string("")); } EddyCatch
  std::string RestrictedRMSOutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_restricted_movement_rms") : std::string("")); } EddyCatch
  std::string DwiMssHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_dwi_mss_history") : std::string("")); } EddyCatch
  std::string DwiParHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_dwi_parameter_history") : std::string("")); } EddyCatch
  std::string B0MssHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_b0_mss_history") : std::string("")); } EddyCatch
  std::string B0ParHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_b0_parameter_history") : std::string("")); } EddyCatch
  std::string DwiMssS2VHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_slice_to_vol_dwi_mss_history") : std::string("")); } EddyCatch
  std::string DwiParS2VHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_slice_to_vol_dwi_parameter_history") : std::string("")); } EddyCatch
  std::string B0MssS2VHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_slice_to_vol_b0_mss_history") : std::string("")); } EddyCatch
  std::string B0ParS2VHistoryFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_slice_to_vol_b0_parameter_history") : std::string("")); } EddyCatch
  std::string PeasReportFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_post_eddy_shell_alignment_parameters") : std::string("")); } EddyCatch
  std::string PeasAlongPEReportFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_post_eddy_shell_PE_translation_parameters") : std::string("")); } EddyCatch
  std::string CNROutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_cnr_maps") : std::string("")); } EddyCatch
  std::string RangeCNROutFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_range_cnr_maps") : std::string("")); } EddyCatch
  std::string ScatterBrainPredictionsOutFname() const EddyTry { return(_out.value()+std::string(".eddy_scatter_brain_predictions")); } EddyCatch
  std::string VolumeScatterBrainPredictionsOutFname() const EddyTry { return(_out.value()+std::string(".eddy_volume_scatter_brain_predictions")); } EddyCatch
  std::string MIPrintFname() const EddyTry { return(IsDiffusion() ? _out.value()+std::string(".eddy_PEAS_MI_values") : std::string("")); } EddyCatch
  double BValueRange() const { return(IsDiffusion() ? static_cast<double>(_diff._brange.value()) : 0.0); }
  EDDY::SecondLevelECModelType SecondLevelModel() const { return(IsDiffusion() ? _diff._slm : SecondLevelECModelType::None); }
  EDDY::SecondLevelECModelType b0_SecondLevelModel() const { return(IsDiffusion() ? _diff._b0_slm : SecondLevelECModelType::None); }
  void SetSecondLevelModel(EDDY::SecondLevelECModelType slm) { if (IsDiffusion()) _diff._slm = slm; }
  void Set_b0_SecondLevelModel(EDDY::SecondLevelECModelType b0_slm) { if (IsDiffusion()) _diff._b0_slm = b0_slm; }
  bool HasSecondLevelModel() const EddyTry { return(SecondLevelModel() != EDDY::SecondLevelECModelType::None); } EddyCatch
  bool Has_b0_SecondLevelModel() const EddyTry { return(b0_SecondLevelModel() != EDDY::SecondLevelECModelType::None); } EddyCatch
  EDDY::LongECModelType LongECModel() const EddyTry { return(IsDiffusion() ? _diff._long_ec_model : EDDY::LongECModelType::None); } EddyCatch
  std::string LongECModelString() const;
  bool EstimateLongEC() const EddyTry { return(IsDiffusion() ? this->LongECModel() != EDDY::LongECModelType::None : false); } EddyCatch
  unsigned int LongECNIter() const EddyTry { return(IsDiffusion() ? 5 : 0); } EddyCatch
  bool ReestimateECWhenEstimatingLongEC() const EddyTry { return(IsDiffusion() ? !_diff._long_ec_dont_reest.value() : false); } EddyCatch 
  bool SeparateOffsetFromMovementWhenEstimatingLongEC() const EddyTry { return(IsDiffusion() ? _diff._long_ec_sep_offs_move.value() : false); } EddyCatch
  bool SeparateOffsetFromMovement() const EddyTry { return(IsDiffusion() ? !_diff._dont_sep_offs_move_internal : false); } EddyCatch
  void SetSeparateOffsetFromMovement(bool val=true) EddyTry { if (IsDiffusion()) _diff._dont_sep_offs_move_internal = val; } EddyCatch 
  EDDY::OffsetModelType OffsetModel() const;
  EDDY::OLSumStats OLSummaryStatistics() const;
  bool AddNoiseToReplacements() const EddyTry { return(IsDiffusion() ? _diff._rep_noise.value() : false); } EddyCatch
  bool RegisterDWI() const { return(IsDiffusion() ? _diff._rdwi : false); }
  bool Registerb0() const { return(IsDiffusion() ? _diff._rb0 : false); }
  bool WriteFields() const EddyTry { return(IsDiffusion() ? _diff._fields.value() : false); } EddyCatch
  bool WriteRotatedBVecs() const { return(IsDiffusion() ? true : false); }
  bool WriteCNRMaps() const EddyTry { return(IsDiffusion() ? _diff._write_cnr_maps.value() : false); } EddyCatch
  bool WriteRangeCNRMaps() const EddyTry { return(IsDiffusion() ? _diff._write_range_cnr_maps.value() : false); } EddyCatch
  bool WriteScatterBrainPredictions() const EddyTry { return(IsDiffusion() ? _diff._write_scatter_brain_predictions.value() : false); } EddyCatch
  bool WriteVolumeScatterBrainPredictions() const EddyTry { return(IsDiffusion() ? _diff._write_scatter_brain_predictions.value() : false); } EddyCatch
  bool RotateBVecsDuringEstimation() const EddyTry { return(IsDiffusion() ? _diff._rbvde_internal : false); } EddyCatch
  void SetRotateBVecsDuringEstimation(bool val=true) EddyTry { if (IsDiffusion()) _diff._rbvde_internal = val; } EddyCatch
  bool AlignShellsPostEddy() const EddyTry { return(IsDiffusion() ? !_diff._dont_peas.value() : false); } EddyCatch
  bool UseB0sToAlignShellsPostEddy() const EddyTry { return(IsDiffusion() ? _diff._use_b0s_for_peas.value() : false); } EddyCatch
  bool DontCheckShelling() const EddyTry { return(IsDiffusion() ? _diff._data_is_shelled.value() : true); } EddyCatch
  bool DoTestRot() const EddyTry { return(IsDiffusion() ? _diff._test_rot.set() : false); } EddyCatch
  bool PrintMIValues() const EddyTry { return(IsDiffusion() ? _diff._print_mi_values.value() : false); } EddyCatch
  bool PrintMIPlanes() const EddyTry { return(IsDiffusion() ? _diff._print_mi_planes.value() : false); } EddyCatch
  std::vector<float> TestRotAngles() const;
  double LSResamplingLambda() const EddyTry { return(IsDiffusion() ? _diff._lsr_lambda.value() : 0.0); } EddyCatch
  int B0ShapeReference() const EddyTry { return(IsDiffusion() ? _diff._b0_shape_reference : -1); } EddyCatch 
  std::pair<int,double> ShellShapeReference(unsigned int i) const;

  // Functions relevant only to fMRI
  std::string fMRIMssHistoryFname() const EddyTry { return(IsfMRI() ? _out.value()+std::string(".eddy_fmri_mss_history") : std::string("")); } EddyCatch
  std::string fMRIParHistoryFname() const EddyTry { return(IsfMRI() ? _out.value()+std::string(".eddy_fmri_parameter_history") : std::string("")); } EddyCatch
  std::string fMRIMssS2VHistoryFname() const EddyTry { return(IsfMRI() ? _out.value()+std::string(".eddy_slice_to_vol_fmri_mss_history") : std::string("")); } EddyCatch
  std::string fMRIParS2VHistoryFname() const EddyTry { return(IsfMRI() ? _out.value()+std::string(".eddy_slice_to_vol_fmri_parameter_history") : std::string("")); } EddyCatch
  float EchoTime() const EddyTry { return(IsfMRI() ? _fmri._echo_time.value() : 0.0f); } EddyCatch
  bool WriteSNRMaps() const EddyTry { return(IsfMRI() ? _fmri._write_snr_maps.value() : false); } EddyCatch
  int fMRIShapeReference() const EddyTry { return(IsfMRI() ? _fmri._shape_reference : -1); } EddyCatch
private:
  /// Struct that hold options specific to diffusion
  struct diff
  {
    diff();
    Utilities::Option<std::string>               _bvecs;
    Utilities::Option<std::string>               _bvals;
    Utilities::FmribOption<std::string>          _bdeltas;
    Utilities::Option<bool>                      _data_is_shelled;
    Utilities::Option<float>                     _brange;
    Utilities::Option<std::string>               _resamp;
    Utilities::FmribOption<float>                _lsr_lambda;
    Utilities::Option<std::string>               _flm;
    Utilities::Option<std::string>               _slm_str;
    Utilities::FmribOption<std::string>          _b0_flm;
    Utilities::FmribOption<std::string>          _b0_slm_str;
    Utilities::FmribOption<float>                _rep_time;
    Utilities::FmribOption<std::string>          _long_ec_str;
    Utilities::HiddenOption<bool>                _long_ec_dont_reest;
    Utilities::HiddenOption<bool>                _long_ec_sep_offs_move;
    Utilities::Option<bool>                      _rep_noise;
    Utilities::FmribOption<std::string>          _ol_ss;
    Utilities::Option<bool>                      _ol_pos;
    Utilities::Option<bool>                      _ol_sqr;
    Utilities::FmribOption<std::string>          _covfunc;
    Utilities::FmribOption<bool>                 _rbvde;
    Utilities::Option<bool>                      _dont_sep_offs_move;
    Utilities::FmribOption<std::string>          _offset_model;
    Utilities::Option<bool>                      _dont_peas;
    Utilities::FmribOption<bool>                 _use_b0s_for_peas;
    Utilities::Option<std::string>               _session;
    Utilities::FmribOption<bool>                 _fields;
    Utilities::Option<bool>                      _write_cnr_maps;
    Utilities::FmribOption<bool>                 _write_range_cnr_maps;
    Utilities::FmribOption<bool>                 _write_scatter_brain_predictions;
    Utilities::FmribOption<bool>                 _dwi_only;
    Utilities::FmribOption<bool>                 _b0_only;
    Utilities::HiddenOption<std::vector<float> > _test_rot;
    Utilities::HiddenOption<bool>                _print_mi_values;
    Utilities::HiddenOption<bool>                _print_mi_planes;
    Utilities::HiddenOption<int>                 _mb_offs;             // Deprecated
    Utilities::HiddenOption<bool>                _sep_offs_move;       // Deprecated
    Utilities::HiddenOption<bool>                _peas;                // Deprecated
    Utilities::HiddenOption<bool>                _rms;                 // Deprecated
    Utilities::HiddenOption<std::string>         _slorder;             // Deprecated
    EDDY::SecondLevelECModelType                 _slm;
    EDDY::SecondLevelECModelType                 _b0_slm;
    EDDY::LongECModelType                        _long_ec_model;
    bool                                         _rdwi;
    bool                                         _rb0;
    bool                                         _rbvde_internal;
    bool                                         _dont_sep_offs_move_internal;
    int                                          _b0_shape_reference;
    struct shell_shape_ref_struct {
      shell_shape_ref_struct(int indx, double b_val) : _indx(indx), _b_val(b_val) {} 
      int    _indx;
      double _b_val;
    };
    std::vector<shell_shape_ref_struct>          _shell_shape_references;
  };
  /// Struct that hold options specific to fmri
  struct fmri
  {
    fmri(); 
    Utilities::Option<std::string>               _session;
    Utilities::Option<float>                     _rep_time;
    Utilities::Option<float>                     _echo_time;
    Utilities::FmribOption<std::string>          _covfunc;
    Utilities::Option<bool>                      _write_snr_maps;
    Utilities::FmribOption<std::string>          _fast_map;
    int                                          _shape_reference;
  };
  std::string                                  _title;
  std::string                                  _examples;
  Utilities::Option<std::string>               _imain;
  Utilities::Option<std::string>               _mask;
  Utilities::Option<std::string>               _acqp;
  Utilities::Option<std::string>               _index;
  Utilities::Option<std::string>               _out;
  Utilities::Option<std::string>               _topup;
  Utilities::Option<std::string>               _field;
  Utilities::Option<std::string>               _field_mat;
  Utilities::Option<int>                       _niter_tmp;
  Utilities::Option<std::vector<float> >       _fwhm_tmp;
  Utilities::FmribOption<int>                  _ref_scan_no;
  Utilities::Option<std::vector<int> >         _shape_ref_scan_nos;
  Utilities::Option<std::string>               _interp;
  Utilities::FmribOption<std::string>          _extrap;
  Utilities::FmribOption<bool>                 _epvalid;
  Utilities::Option<bool>                      _rep_ol;
  Utilities::Option<float>                     _ol_nstd;
  Utilities::Option<int>                       _ol_nvox;
  Utilities::FmribOption<int>                  _ol_ec;
  Utilities::Option<std::string>               _ol_type;
  Utilities::FmribOption<float>                _ol_jacut;
  Utilities::Option<int>                       _mb;
  Utilities::Option<std::string>               _slspec;
  Utilities::Option<std::string>               _json;
  Utilities::Option<std::vector<int> >         _mp_order;
  Utilities::Option<std::vector<float> >       _s2v_lambda;
  Utilities::Option<std::vector<int> >         _s2v_niter;
  Utilities::FmribOption<std::vector<float> >  _s2v_fwhm;
  Utilities::Option<std::string>               _s2v_interp;
  Utilities::Option<bool>                      _estimate_mbs;
  Utilities::Option<int>                       _mbs_niter;
  Utilities::Option<float>                     _mbs_lambda;
  Utilities::Option<float>                     _mbs_ksp;
  Utilities::FmribOption<std::string>          _hyparcostfunc;
  Utilities::Option<int>                       _nvoxhp;
  Utilities::Option<int>                       _initrand;
  Utilities::Option<float>                     _hyparfudgefactor;
  Utilities::FmribOption<std::vector<float> >  _hypar;
  Utilities::Option<bool>                      _fep;
  Utilities::FmribOption<bool>                 _dont_mask_output;
  Utilities::FmribOption<std::string>          _init;
  Utilities::FmribOption<std::string>          _init_s2v;
  Utilities::FmribOption<std::string>          _init_mbs;
  Utilities::FmribOption<bool>                 _dfields;
  Utilities::Option<bool>                      _residuals;
  Utilities::FmribOption<bool>                 _with_outliers;
  Utilities::FmribOption<bool>                 _history;
  Utilities::FmribOption<bool>                 _write_slice_stats;
  Utilities::FmribOption<bool>                 _write_predictions;
  Utilities::Option<bool>                      _no_text_files;
  Utilities::FmribOption<int>                  _debug_tmp;
  Utilities::FmribOption<std::string>          _dbg_indx_str;
  Utilities::HiddenOption<bool>                _log_timings;
  Utilities::Option<int>                       _nthr;
  Utilities::FmribOption<bool>                 _very_verbose;
  Utilities::Option<bool>                      _verbose;
  Utilities::Option<bool>                      _help;
  diff                                         _diff; // Diffusion specific arguments
  fmri                                         _fmri; // fMRI specific arguments
  bool                                         _is_fmri;
  bool                                         _init_rand;
  bool                                         _fixed_hpar;
  double                                       _hypar_ff_internal;
  unsigned int                                 _nvoxhp_internal;
  std::vector<float>                           _hypar_internal;
  std::vector<unsigned int>                    _indvec;
  std::vector<unsigned int>                    _sessvec;
  unsigned int                                 _debug;
  DebugIndexClass                              _dbg_indx;
  EDDY::OutlierDefinition                      _oldef;
  unsigned int                                 _niter;
  std::vector<float>                           _fwhm;
  EDDY::S2VParam                               _s2vparam;
  bool                                         _shape_references_set;

  void do_initial_parsing(int argc, char *argv[]);
  bool indicies_kosher(NEWMAT::Matrix indx, NEWMAT::Matrix acqp);
  bool session_indicies_kosher(NEWMAT::Matrix indx);
  std::vector<unsigned int> get_slorder(const std::string& fname,
					unsigned int       ngrp) const;
  void set_shape_refs(const std::vector<int>&   shape_refs,
		      const std::vector<int>&   shells,
		      const std::vector<double> shell_b_vals);
};

} // End namespace EDDY

#endif // End #ifndef EddyCommandLineOptions_h