Tomato
itkCalculatorT1ImageFilter.hxx
Go to the documentation of this file.
1 
7 #ifndef itkCalculatorT1ImageFilter_txx
8 #define itkCalculatorT1ImageFilter_txx
9 
10 #include "CmakeConfigForTomato.h"
11 #ifdef USE_ITK
12 
13 namespace itk {
14 
15  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
16  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
17  ::CalculatorT1ImageFilter() {
18  this->m_LimitOutputIntensity = true;
19  this->m_UpperLimitOutputIntensity = 4000;
20  this->m_LowerLimitOutputIntensity = 0;
21 
22  this->SetNumberOfRequiredInputs(1);
23  this->SetNumberOfRequiredOutputs(13);
24  for (unsigned i = 0; i < this->GetNumberOfRequiredOutputs(); ++i) {
25  this->SetNthOutput(i, (TImageOut1::New()).GetPointer());
26  }
27  this->SetNumberOfRequiredOutputs(this->GetNumberOfRequiredOutputs() + 1);
28  this->SetNthOutput(this->GetNumberOfRequiredOutputs()-1, (TImageOut2::New()).GetPointer());
29 
30  this->m_ImageRegionSplitter = ImageRegionSplitterDirection::New();
31  this->m_ImageRegionSplitter->SetDirection(2);
32 
33  }
34 
35  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
36  void
37  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
38  ::SetInputMagImage(const TImageIn *image) {
39  this->SetNthInput(0, const_cast<TImageIn *>(image));
40  }
41 
42  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
43  void
44  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
45  ::SetInputPhaImage(const TImageIn *image) {
46  this->SetNthInput(1, const_cast<TImageIn *>(image));
47  }
48 
49  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
50  void
51  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
52  ::BeforeThreadedGenerateData() {
53 
54  if(!m_Calculator) throw itk::ExceptionObject(__FILE__, __LINE__, "Set the Calculator!");
55 
56  printf("Number of threads: %d. ", this->GetNumberOfThreads());
57 
58  if (m_Calculator->getInvTimes()) {
59  printf("\nInvTimes: ");
60  for (size_t i = 0; i < m_Calculator->getNSamples(); i++) {
61  printf("%.0f ", m_Calculator->getInvTimes()[i]);
62  }
63  }
64 
65  if (m_Calculator->getEchoTimes()) {
66  printf("\nEchoTimes: ");
67  for (size_t i = 0; i < m_Calculator->getNSamples(); i++) {
68  printf("%.1f ", m_Calculator->getEchoTimes()[i]);
69  }
70  }
71 
72  printf("\n");
73  }
74 
75  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
76  void
77  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
78  ::GenerateOutputInformation(){
79  typename TImageIn::ConstPointer imageMag = this->GetInput(0);
80  typename TImageIn::RegionType magImageRegion = imageMag->GetLargestPossibleRegion();
81 
82  typename TImageOut1::IndexType start;
83  start[0] = magImageRegion.GetIndex()[0];
84  start[1] = magImageRegion.GetIndex()[1];
85 
86  typename TImageOut1::SizeType size;
87  size[0] = magImageRegion.GetSize()[0];
88  size[1] = magImageRegion.GetSize()[1];
89 
90  typename TImageOut1::RegionType region;
91  region.SetSize(size);
92  region.SetIndex(start);
93 
94  typename TImageOut1::SpacingType spacing;
95  spacing[0] = imageMag->GetSpacing()[0];
96  spacing[1] = imageMag->GetSpacing()[1];
97 
98  typename TImageOut1::PointType origin;
99  origin[0] = imageMag->GetOrigin()[0];
100  origin[1] = imageMag->GetOrigin()[1];
101 
102  typename TImageOut1::DirectionType direction;
103 
104  direction[0][0] = imageMag->GetDirection()[0][0];
105  direction[0][1] = imageMag->GetDirection()[0][1];
106  direction[1][0] = imageMag->GetDirection()[1][0];
107  direction[1][1] = imageMag->GetDirection()[1][1];
108 
109  // last output has different type and is configured below
110  for (unsigned int i = 0; i < this->GetNumberOfOutputs()-1; i++){
111  this->GetOutput(i)->SetRegions(region);
112  this->GetOutput(i)->SetSpacing(spacing);
113  this->GetOutput(i)->SetOrigin(origin);
114  this->GetOutput(i)->SetDirection(direction);
115  }
116 
117  // last output
118  this->GetMagSignRecovered()->SetRegions(magImageRegion);
119  this->GetMagSignRecovered()->SetSpacing(imageMag->GetSpacing());
120  this->GetMagSignRecovered()->SetOrigin(imageMag->GetOrigin());
121  this->GetMagSignRecovered()->SetDirection(imageMag->GetDirection());
122  this->GetMagSignRecovered()->Allocate();
123  this->GetMagSignRecovered()->FillBuffer(0);
124 
125  }
126 
127  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
128  typename TImageOut1::PixelType
129  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
130  ::LimitResult( typename TImageOut1::PixelType result ) {
131 
132  if (GetLimitOutputIntensity()) {
133  if (result < m_LowerLimitOutputIntensity) {
134  result = m_LowerLimitOutputIntensity;
135  }
136  if (result > m_UpperLimitOutputIntensity) {
137  result = m_UpperLimitOutputIntensity;
138  }
139  }
140  return result;
141  }
142 
143  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
144  void
145  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
146  ::ThreadedGenerateData( const OutputImageRegionType& outputRegionForThread, ThreadIdType threadId ){
147 
148  typename TImageIn::IndexType idx;
149 
150  typename TImageIn::ConstPointer imageMag = this->GetInput(0);
151  typename TImageIn::ConstPointer imagePha = this->GetInput(1);
152 
153  std::vector<typename TImageOut1::Pointer> outputImagesVector;
154  for (unsigned int i = 0; i < this->GetNumberOfOutputs()-1; ++i){
155  outputImagesVector.push_back(this->GetOutput(i));
156  }
157  typename TImageOut2::Pointer imageMagSignRecov = this->GetMagSignRecovered();
158 
159  typename TImageIn::SizeType magImageSize = imageMag->GetLargestPossibleRegion().GetSize();
160 
161  typename TImageIn::SizeType inputSize = imageMag->GetLargestPossibleRegion().GetSize();
162  inputSize[0] = outputRegionForThread.GetSize()[0];
163  inputSize[1] = outputRegionForThread.GetSize()[1];
164 
165  typename TImageIn::IndexType inputIndex = imageMag->GetLargestPossibleRegion().GetIndex();;
166  inputIndex[0] = outputRegionForThread.GetIndex()[0];
167  inputIndex[1] = outputRegionForThread.GetIndex()[1];
168 
169  typename TImageIn::RegionType inputRegion = imageMag->GetLargestPossibleRegion();
170  inputRegion.SetSize(inputSize);
171  inputRegion.SetIndex(inputIndex);
172 
173  typedef itk::ImageLinearConstIteratorWithIndex< TImageIn > InputIteratorType;
174  typedef itk::ImageRegionIterator< TImageOut1 > Output2dIteratorType;
175  typedef itk::ImageLinearIteratorWithIndex< TImageIn > Output3dIteratorType;
176 
177  InputIteratorType itMag( imageMag, inputRegion );
178  InputIteratorType itPha;
179 
180  if (imagePha) {
181  InputIteratorType temp( imagePha, inputRegion );
182  itPha = temp;
183  }
184 
185  std::vector<Output2dIteratorType> itOutVector;
186  for (unsigned int i = 0; i < outputImagesVector.size(); ++i){
187  itOutVector.push_back(Output2dIteratorType(outputImagesVector[i], outputRegionForThread));
188  }
189  Output3dIteratorType itOutMagSignRecov(imageMagSignRecov, inputRegion);
190 
191  itMag.SetDirection( 2 ); // Walk along third dimension it.GoToBegin();
192  if (imagePha) itPha.SetDirection( 2 ); // Walk along third dimension it.GoToBegin();
193  itOutMagSignRecov.SetDirection(2);
194 
199  int nSamples = magImageSize[2];
200  Ox::Calculator<PixelTypeIn> *calculator = m_Calculator->newByCloning();
201  Ox::Model<PixelTypeIn> *functionsObject = m_Calculator->getModel()->newByCloning();
202  Ox::Fitter<PixelTypeIn> *fitter = m_Calculator->getFitter()->newByCloning();
203  Ox::SignCalculator<PixelTypeIn> *signCalculator = 0;
204  if (m_Calculator->getSignCalculator()) {
205  signCalculator = m_Calculator->getSignCalculator()->newByCloning();
206  }
207  Ox::StartPointCalculator<PixelTypeIn> *startPointCalculator = 0;
208  if (m_Calculator->getStartPointCalculator()) {
209  startPointCalculator = m_Calculator->getStartPointCalculator()->newByCloning();
210  }
211 
212  // configure
213  calculator->setModel(functionsObject);
214  calculator->setFitter(fitter);
215  calculator->setSignCalculator(signCalculator);
216  calculator->setStartPointCalculator(startPointCalculator);
217  calculator->setNSamples(nSamples);
218  calculator->setInvTimes(m_Calculator->getInvTimes());
219  calculator->setEchoTimes(m_Calculator->getEchoTimes());
220  calculator->setNoise(m_Calculator->getNoise());
221 
222  // set the thread id in the minimiser
223  fitter->setThreadId(threadId);
224 
225  // move output iterators
226  for (unsigned int i = 0; i < outputImagesVector.size(); ++i) {
227  itOutVector[i].GoToBegin();
228  }
229  itOutMagSignRecov.GoToBegin();
230 
231  // init alloc
232  PixelTypeIn *sigMag = new PixelTypeIn[nSamples];
233  PixelTypeIn *sigPha = new PixelTypeIn[nSamples];
234 
235  while( !itMag.IsAtEnd() ) {
236  // move input iterators
237  itMag.GoToBeginOfLine();
238  if (imagePha) itPha.GoToBeginOfLine();
239 
240  // get mag and phase from the iterators
241  while ( !itMag.IsAtEndOfLine() ) {
242  // get index
243  idx = itMag.GetIndex();
244 
245  // get mag and phase
246  sigMag[idx[2]] = itMag.Get();
247  if (imagePha) sigPha[idx[2]] = itPha.Get();
248 
249  // move iterators
250  ++itMag;
251  if (imagePha) ++itPha;
252  }
253 
254  // set Mag and Phase
255  calculator->setSigMag(sigMag);
256  calculator->setSigPha(sigPha);
257 
258  // calculate
259  calculator->prepareToCalculate();
260  calculator->calculate();
261 
262  // to add/remove output
263  // 1. change this->SetNumberOfRequiredOutputs(XXX); in the constructor
264  // 2. add GetXXXImage method. Numbers below have to agree with GetXXXImage methods
265  itOutVector[0].Set(LimitResult(calculator->getResults()["T1"]));
266  itOutVector[1].Set(LimitResult(calculator->getResults()["R2"]));
267  itOutVector[2].Set(LimitResult(calculator->getResults()["A"]));
268  itOutVector[3].Set(LimitResult(calculator->getResults()["B"]));
269  itOutVector[4].Set(LimitResult(calculator->getResults()["T1star"]));
270  itOutVector[5].Set(LimitResult(calculator->getResults()["ChiSqrt"]));
271  itOutVector[6].Set(LimitResult(calculator->getResults()["SNR"]));
272  itOutVector[7].Set(LimitResult(calculator->getResults()["NShmolliSamplesUsed"]));
273  itOutVector[8].Set(LimitResult(calculator->getResults()["deltaA"]));
274  itOutVector[9].Set(LimitResult(calculator->getResults()["deltaB"]));
275  itOutVector[10].Set(LimitResult(calculator->getResults()["deltaT1"]));
276  itOutVector[11].Set(LimitResult(calculator->getResults()["T2"]));
277  itOutVector[12].Set(LimitResult(calculator->getResults()["R2Abs"]));
278 
279  if (calculator->getSigns()) {
280  itOutMagSignRecov.GoToBeginOfLine();
281  while (!itOutMagSignRecov.IsAtEndOfLine()) {
282  idx = itOutMagSignRecov.GetIndex();
283  PixelTypeOut temp = calculator->getSigMag()[idx[2]] * calculator->getSigns()[idx[2]] + 4095;
284  itOutMagSignRecov.Set(temp);
285  ++itOutMagSignRecov;
286  }
287  }
288 
289  // iterate all iterators accordingly
290  for (unsigned int i = 0; i < outputImagesVector.size(); ++i) {
291  ++itOutVector[i];
292  }
293  itMag.NextLine();
294  if (imagePha) itPha.NextLine();
295  itOutMagSignRecov.NextLine();
296  }
297  // cleanup
298  delete functionsObject;
299  delete fitter;
300  delete signCalculator;
301  delete startPointCalculator;
302  delete calculator;
303  delete [] sigMag;
304  delete [] sigPha;
305  }
306 
307  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
308  TImageOut1*
309  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
310  ::GetT1Image() {
311  return dynamic_cast< TImageOut1 * >(
312  this->ProcessObject::GetOutput(0) );
313  }
314 
315  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
316  TImageOut1*
317  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
318  ::GetR2Image() {
319  return dynamic_cast< TImageOut1 * >(
320  this->ProcessObject::GetOutput(1) );
321  }
322 
323  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
324  TImageOut1*
325  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
326  ::GetAImage() {
327  return dynamic_cast< TImageOut1 * >(
328  this->ProcessObject::GetOutput(2) );
329  }
330 
331  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
332  TImageOut1*
333  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
334  ::GetBImage() {
335  return dynamic_cast< TImageOut1 * >(
336  this->ProcessObject::GetOutput(3) );
337  }
338 
339  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
340  TImageOut1*
341  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
342  ::GetT1starImage() {
343  return dynamic_cast< TImageOut1 * >(
344  this->ProcessObject::GetOutput(4) );
345  }
346 
347  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
348  TImageOut1*
349  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
350  ::GetChiSqrtImage(){
351  return dynamic_cast< TImageOut1 * >(
352  this->ProcessObject::GetOutput(5) );
353  }
354 
355  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
356  TImageOut1*
357  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
358  ::GetSNRImage() {
359  return dynamic_cast< TImageOut1 * >(
360  this->ProcessObject::GetOutput(6) );
361  }
362 
363  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
364  TImageOut1*
365  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
366  ::GetNShmolliSamplesUsedImage() {
367  return dynamic_cast< TImageOut1 * >(
368  this->ProcessObject::GetOutput(7) );
369  }
370 
371  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
372  TImageOut1*
373  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
374  ::GetDeltaAImage() {
375  return dynamic_cast< TImageOut1 * >(
376  this->ProcessObject::GetOutput(8) );
377  }
378 
379  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
380  TImageOut1*
381  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
382  ::GetDeltaBImage() {
383  return dynamic_cast< TImageOut1 * >(
384  this->ProcessObject::GetOutput(9) );
385  }
386 
387  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
388  TImageOut1*
389  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
390  ::GetDeltaT1Image() {
391  return dynamic_cast< TImageOut1 * >(
392  this->ProcessObject::GetOutput(10) );
393  }
394 
395  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
396  TImageOut1*
397  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
398  ::GetT2Image() {
399  return dynamic_cast< TImageOut1 * >(
400  this->ProcessObject::GetOutput(11) );
401  }
402 
403  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
404  TImageOut1*
405  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
406  ::GetR2AbsImage(){
407  return dynamic_cast< TImageOut1 * >(
408  this->ProcessObject::GetOutput(12) );
409  }
410 
411  template< typename TImageIn, typename TImageOut1, typename TImageOut2>
412  TImageOut2*
413  CalculatorT1ImageFilter<TImageIn, TImageOut1, TImageOut2>
414  ::GetMagSignRecovered(){
415  return dynamic_cast< TImageOut2 * >(this->ProcessObject::GetOutput(13) );
416  }
417 
418 }// end namespace itk
419 
420 #endif // USE_ITK
421 
422 #endif //itkCalculatorT1ImageFilter_txx
virtual SignCalculator< MeasureType > * newByCloning()=0
Container for a model function, cost function and Least-Squares function. And derivatives.
Definition: OxModel.h:26
virtual const MeasureType * getSigMag() const
Definition: OxCalculator.hxx:90
Definition: itkImageFileReaderKW.h:31
virtual int prepareToCalculate()=0
Definition: OxCalculator.h:28
virtual Model< MeasureType > * newByCloning()=0
Definition: OxSignCalculator.h:21
virtual StartPointCalculator< MeasureType > * newByCloning()=0
Definition: OxStartPointCalculator.h:21
virtual int calculate()=0
virtual Fitter< MeasureType > * newByCloning()=0
Definition: OxFitter.h:22
virtual Calculator< MeasureType > * newByCloning()=0
virtual void setNSamples(int _nSamples)
Definition: OxCalculator.hxx:240