ANIMA  4.0
animaT2RelaxometryEstimationImageFilter.hxx
Go to the documentation of this file.
1 #pragma once
3 
4 #include <itkImageRegionIterator.h>
5 #include <itkImageRegionConstIterator.h>
6 
7 #include <animaNLOPTOptimizers.h>
9 
10 namespace anima
11 {
12 
13 template <typename TInputImage, typename TOutputImage>
14 void
15 T2RelaxometryEstimationImageFilter <TInputImage,TOutputImage>
16 ::CheckComputationMask()
17 {
18  if (this->GetComputationMask())
19  return;
20 
21  typedef itk::ImageRegionConstIterator <InputImageType> IteratorType;
22  typedef itk::ImageRegionIterator <MaskImageType> MaskIteratorType;
23 
24  std::vector <IteratorType> inItrs(this->GetNumberOfIndexedInputs());
25  for (unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
26  inItrs[i] = IteratorType(this->GetInput(i),this->GetOutput()->GetLargestPossibleRegion());
27 
28  typename MaskImageType::Pointer maskImage = MaskImageType::New();
29  maskImage->Initialize();
30  maskImage->SetRegions(this->GetInput(0)->GetLargestPossibleRegion());
31  maskImage->SetSpacing (this->GetInput(0)->GetSpacing());
32  maskImage->SetOrigin (this->GetInput(0)->GetOrigin());
33  maskImage->SetDirection (this->GetInput(0)->GetDirection());
34  maskImage->Allocate();
35 
36  MaskIteratorType maskItr (maskImage,this->GetOutput()->GetLargestPossibleRegion());
37  while (!maskItr.IsAtEnd())
38  {
39  double averageVal = 0;
40  for (unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
41  averageVal += inItrs[i].Get();
42 
43  averageVal /= this->GetNumberOfIndexedInputs();
44 
45  bool maskPoint = (averageVal <= m_AverageSignalThreshold);
46 
47  if (maskPoint)
48  maskItr.Set(0);
49  else
50  maskItr.Set(1);
51 
52  for (unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
53  ++inItrs[i];
54 
55  ++maskItr;
56  }
57 
58  this->SetComputationMask(maskImage);
59 }
60 
61 template <typename TInputImage, typename TOutputImage>
62 void
64 ::DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread)
65 {
66  typedef itk::ImageRegionConstIterator <InputImageType> ImageIteratorType;
67  typedef itk::ImageRegionIterator <OutputImageType> OutImageIteratorType;
68 
69  OutImageIteratorType outT2Iterator(this->GetOutput(0),outputRegionForThread);
70  OutImageIteratorType outM0Iterator(this->GetOutput(1),outputRegionForThread);
71 
72  unsigned int numInputs = this->GetNumberOfIndexedInputs();
73  std::vector <ImageIteratorType> inIterators;
74  for (unsigned int i = 0;i < numInputs;++i)
75  inIterators.push_back(ImageIteratorType(this->GetInput(i),outputRegionForThread));
76 
77  typedef itk::ImageRegionIterator <MaskImageType> MaskIteratorType;
78  MaskIteratorType maskItr(this->GetComputationMask(),outputRegionForThread);
79 
80  OutImageIteratorType t1MapItr;
81  if (m_T1Map)
82  t1MapItr = OutImageIteratorType(m_T1Map,outputRegionForThread);
83 
84  typedef anima::NLOPTOptimizers OptimizerType;
85  typedef anima::T2RelaxometryCostFunction CostFunctionType;
86 
87  typename CostFunctionType::Pointer cost = CostFunctionType::New();
88  cost->SetT2EchoSpacing(m_EchoSpacing);
89  cost->SetTRValue(m_TRValue);
90 
91  unsigned int dimension = cost->GetNumberOfParameters();
92  itk::Array<double> lowerBounds(dimension);
93  itk::Array<double> upperBounds(dimension);
94  OptimizerType::ParametersType p(dimension);
95 
96  std::vector <double> relaxoT2Data(numInputs,0);
97 
98  while (!maskItr.IsAtEnd())
99  {
100  if (maskItr.Get() == 0)
101  {
102  outT2Iterator.Set(0);
103  outM0Iterator.Set(0);
104 
105  ++maskItr;
106  ++outT2Iterator;
107  ++outM0Iterator;
108 
109  for (unsigned int i = 0;i < numInputs;++i)
110  ++inIterators[i];
111 
112  if (m_T1Map)
113  ++t1MapItr;
114 
115  continue;
116  }
117 
118  double t1Value = 1000.0;
119 
120  if (m_T1Map)
121  {
122  t1Value = t1MapItr.Get();
123  if (t1Value <= 0.0)
124  t1Value = 1000;
125  }
126 
127  for (unsigned int i = 0;i < numInputs;++i)
128  relaxoT2Data[i] = inIterators[i].Get();
129 
130  cost->SetT2RelaxometrySignals(relaxoT2Data);
131 
132  OptimizerType::Pointer optimizer = OptimizerType::New();
133  optimizer->SetAlgorithm(NLOPT_LN_BOBYQA);
134  optimizer->SetXTolRel(m_OptimizerStopCondition);
135  optimizer->SetFTolRel(1.0e-2 * m_OptimizerStopCondition);
136  optimizer->SetMaxEval(5000);
137  optimizer->SetVectorStorageSize(2000);
138 
139  lowerBounds[0] = 1.0;
140  upperBounds[0] = m_T2UpperBoundValue;
141  if (m_T1Map && (m_T2UpperBoundValue > t1Value))
142  upperBounds[0] = t1Value;
143 
144  p[0] = 100;
145  if (p[0] > upperBounds[0])
146  p[0] = (upperBounds[0] - lowerBounds[0]) / 2.0;
147 
148  optimizer->SetLowerBoundParameters(lowerBounds);
149  optimizer->SetUpperBoundParameters(upperBounds);
150  optimizer->SetMaximize(false);
151 
152  optimizer->SetCostFunction(cost);
153 
154  optimizer->SetInitialPosition(p);
155  optimizer->StartOptimization();
156 
157  p = optimizer->GetCurrentPosition();
158 
159  cost->GetValue(p);
160 
161  outT2Iterator.Set(p[0]);
162  outM0Iterator.Set(cost->GetM0Value());
163 
164  ++maskItr;
165  ++outT2Iterator;
166  ++outM0Iterator;
167 
168  for (unsigned int i = 0;i < numInputs;++i)
169  ++inIterators[i];
170 
171  if (m_T1Map)
172  ++t1MapItr;
173  }
174 }
175 
176 } // end namespace anima
Implements an ITK wrapper for the NLOPT library.
Superclass::OutputImageRegionType OutputImageRegionType