Tomato
Tomato.hxx
1 
7 #ifndef Tomato_Tomato_HXX
8 #define Tomato_Tomato_HXX
9 
10 #include "CmakeConfigForTomato.h"
11 #ifdef USE_ITK
12 
13 namespace Ox {
14 
15  template< typename MeasureType >
16  Tomato<MeasureType>
17  ::Tomato(std::string inputFileName){
18 
19  _nSamples = 0;
20  _invTimes = 0; // nullptr
21  _echoTimes = 0; // nullptr
22 
23  _opts = new TomatoOptions<InputPixelType>(inputFileName);
24  _imageCalculatorItk = CalculatorT1ImageFilterType::New();
25  //_sorterMag = SortInvTimesImageFilterType::New();
26  //_sorterPha = SortInvTimesImageFilterType::New();
27  }
28 
29  template< typename MeasureType >
30  Tomato<MeasureType>
31  ::~Tomato(){
32  delete _opts;
33  delete [] _invTimes;
34  delete [] _echoTimes;
35  }
36 
37  template< typename MeasureType >
38  int
39  Tomato<MeasureType>
40  ::readAndSort(){
41 
42  typename ReadFileListFilterType::Pointer readerMag = ReadFileListFilterType::New();
43  readerMag->SetFileList(_opts->files_magnitude);
44  readerMag->SetDirName(_opts->dir_magnitude);
45  readerMag->Update();
46 
47  // have we read magnitudes?
48  if (readerMag->GetInvTimes().empty()){
49  throw std::runtime_error("\nNo magnitude images read, check the paths!");
50  }
51 
52  if (_opts->files_magnitude.empty()){
53  _opts->files_magnitude = readerMag->GetFileList();
54  }
55 
56  typename SortInvTimesImageFilterType::Pointer sorterMag = SortInvTimesImageFilterType::New();
57  sorterMag->SetInvTimesNonSorted(readerMag->GetInvTimes());
58  sorterMag->SetEchoTimesNonSorted(readerMag->GetEchoTimes());
59  sorterMag->SetInput(readerMag->GetOutput());
60  if (_opts->parameter_type == T1) {
61  sorterMag->SortByInvTimes();
62  } else if (_opts->parameter_type == T2){
63  sorterMag->SortByEchoTimes();
64  }
65  sorterMag->Update();
66 
67  typename ReadFileListFilterType::Pointer readerPha = ReadFileListFilterType::New();
68  readerPha->SetFileList(_opts->files_phase);
69  readerPha->SetDirName(_opts->dir_phase);
70  readerPha->Update();
71 
72  // is phase empty?
73  if (readerPha->GetInvTimes().empty()) {
74  if (_opts->sign_calc_method != NoSign){
75  std::cerr << "\nNo phase images read, setting the sign_calc_method to NoSign" << std::endl;
76  _opts->sign_calc_method = NoSign;
77  }
78  }
79 
80  if (_opts->files_phase.empty()){
81  _opts->files_phase = readerPha->GetFileList();
82  }
83 
84  typename SortInvTimesImageFilterType::Pointer sorterPha = SortInvTimesImageFilterType::New();
85  if (_opts->sign_calc_method != NoSign) {
86  sorterPha->SetInvTimesNonSorted(readerPha->GetInvTimes());
87  sorterPha->SetEchoTimesNonSorted(readerMag->GetEchoTimes());
88  sorterPha->SetInput(readerPha->GetOutput());
89  if (_opts->parameter_type == T1) {
90  sorterPha->SortByInvTimes();
91  } else if (_opts->parameter_type == T2){
92  sorterPha->SortByEchoTimes();
93  }
94  sorterPha->Update();
95  }
96 
97  // are the inversion times in magnitude and phase series equal?
98  if (_opts->sign_calc_method != NoSign) {
99  if (sorterMag->GetInvTimesSorted() != sorterPha->GetInvTimesSorted()) {
100  throw std::runtime_error("\nMag and Pha inv times are not equal");
101  }
102  }
103 
104  vnl_vector<InputPixelType > tempInv = sorterMag->GetInvTimesSorted();
105  _nSamples = (int)tempInv.size();
106  _invTimes = new InputPixelType[_nSamples];
107  KWUtil::copyArrayToArray(_nSamples, _invTimes, tempInv.data_block());
108 
109  if (_opts->inversion_times.empty()){
110  tempInv = sorterMag->GetInvTimesNonSorted();
111  _opts->inversion_times = std::vector<InputPixelType >(tempInv.begin(), tempInv.end());
112  }
113 
114  vnl_vector<InputPixelType > tempEcho = sorterMag->GetEchoTimesSorted();
115  _nSamples = (int)tempEcho.size();
116  _echoTimes = new InputPixelType[_nSamples];
117  KWUtil::copyArrayToArray(_nSamples, _echoTimes, tempEcho.data_block());
118 
119  if (_opts->echo_times.empty()){
120  tempEcho = sorterMag->GetEchoTimesNonSorted();
121  _opts->echo_times = std::vector<InputPixelType >(tempEcho.begin(), tempEcho.end());
122  }
123 
124  _dictionaryInput = readerMag->GetDicomIO()->GetMetaDataDictionary();
125  _imageMag = sorterMag->GetOutput();
126  if (_opts->sign_calc_method != NoSign) {
127  _imagePha = sorterPha->GetOutput();
128  }
129 
130  return 0; // EXIT_SUCCESS
131  }
132 
133  template< typename MeasureType >
134  int
135  Tomato<MeasureType>
136  ::calculate() {
137 
138  // alloc and init
139  Calculator<InputPixelType> *calculator = FactoryOfCalculators<InputPixelType>::newByFactory(_opts);
140  Model<InputPixelType> *model = FactoryOfModels<InputPixelType>::newByFactory(_opts);
141  Fitter<InputPixelType> *fitter = FactoryOfFitters<InputPixelType>::newByFactory(_opts);
142  SignCalculator<InputPixelType> *signCalculator = FactoryOfSignCalculators<InputPixelType>::newByFactory(_opts);
143  StartPointCalculator<InputPixelType> *startPointCalculator = FactoryOfStartPointCalculators<InputPixelType>::newByFactory(_opts);
144 
145  // configure calculator
146  calculator->setModel(model);
147  calculator->setFitter(fitter);
148  calculator->setSignCalculator(signCalculator);
149  calculator->setStartPointCalculator(startPointCalculator);
150  calculator->setInvTimes(_invTimes);
151  calculator->setEchoTimes(_echoTimes);
152  if (_opts->noise.size() > 0){
153  calculator->setNoise(&(_opts->noise)[0]);
154  }
155  calculator->setNSamples(_nSamples);
156 
157  // configure calculator itk filter
158  //CalculatorT1ImageFilterType::Pointer _imageCalculatorItk = CalculatorT1ImageFilterType::New();
159  //_imageCalculatorItk = CalculatorT1ImageFilterType::New();
160  _imageCalculatorItk->SetInputMagImage(_imageMag);
161  _imageCalculatorItk->SetInputPhaImage(_imagePha);
162  if (_opts->number_of_threads > 0)
163  _imageCalculatorItk->SetNumberOfThreads(_opts->number_of_threads);
164  _imageCalculatorItk->SetCalculator(calculator);
165 
166  // calculations
167  itk::TimeProbe clock;
168  clock.Start();
169  try {
170  _imageCalculatorItk->Update();
171  } catch( itk::ExceptionObject & err ) {
172  std::cerr << "ExceptionObject caught !" << std::endl;
173  std::cerr << err << std::endl;
174  }
175  clock.Stop();
176  _opts->calculation_time = clock.GetTotal();
177  printf("Calculation time: %.4fs.\n", clock.GetTotal());
178 
179  delete model;
180  delete fitter;
181  delete signCalculator;
182  delete startPointCalculator;
183  delete calculator;
184 
185  return 0; // EXIT_SUCCESS
186  }
187 
188  template< typename MeasureType >
189  int
190  Tomato<MeasureType>
191  ::exportToDicom(){
192  if (_opts->parameter_type == Ox::T1){
193  exportT1ToDicom();
194  exportT1MagSignRecovToDicom();
195  return 0; // EXIT_SUCCESS
196  }
197  else if (_opts->parameter_type == Ox::T2){
198  return exportT2ToDicom();
199  }
200  else {
201  std::cerr << "Tomato::exportToDicom: Export has not been implemented" << std::endl;
202  return 1; // EXIT_FAILURE
203  }
204  }
205 
206  template< typename IType, typename EType >
207  class CastPixelAccessor
208  {
209  public:
210 
211  typedef IType InternalType;
212  typedef EType ExternalType;
213 
214  static void Set(InternalType & output, const ExternalType & input)
215  {
216  output = static_cast<InternalType>( input );
217  }
218 
219  static ExternalType Get( const InternalType & input )
220  {
221  return static_cast<ExternalType>( input );
222  }
223  };
224 
225 } // namespace Ox
226 
227 #endif
228 
229 #endif //Tomato_Tomato_H
Definition: OxCalculator.h:19