ANIMA  4.0
animaT2EPGRelaxometryEstimationImageFilter.hxx
Go to the documentation of this file.
1 #pragma once
4 
5 #include <itkImageRegionIterator.h>
6 #include <itkImageRegionConstIterator.h>
7 
9 #include <animaNLOPTOptimizers.h>
10 
11 namespace anima
12 {
13 
14 template <typename TInputImage, typename TOutputImage>
15 void
16 T2EPGRelaxometryEstimationImageFilter <TInputImage,TOutputImage>
17 ::CheckComputationMask()
18 {
19  if (this->GetComputationMask())
20  return;
21 
22  typedef itk::ImageRegionConstIterator <InputImageType> IteratorType;
23  typedef itk::ImageRegionIterator <MaskImageType> MaskIteratorType;
24 
25  std::vector <IteratorType> inItrs(this->GetNumberOfIndexedInputs());
26  for (unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
27  inItrs[i] = IteratorType(this->GetInput(i),this->GetOutput()->GetLargestPossibleRegion());
28 
29  typename MaskImageType::Pointer maskImage = MaskImageType::New();
30  maskImage->Initialize();
31  maskImage->SetRegions(this->GetInput(0)->GetLargestPossibleRegion());
32  maskImage->SetSpacing (this->GetInput(0)->GetSpacing());
33  maskImage->SetOrigin (this->GetInput(0)->GetOrigin());
34  maskImage->SetDirection (this->GetInput(0)->GetDirection());
35  maskImage->Allocate();
36 
37  MaskIteratorType maskItr (maskImage,this->GetOutput()->GetLargestPossibleRegion());
38  while (!maskItr.IsAtEnd())
39  {
40  double averageVal = 0;
41  for (unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
42  averageVal += inItrs[i].Get();
43 
44  averageVal /= this->GetNumberOfIndexedInputs();
45 
46  bool maskPoint = (averageVal <= m_AverageSignalThreshold);
47 
48  if (maskPoint)
49  maskItr.Set(0);
50  else
51  maskItr.Set(1);
52 
53  for (unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
54  ++inItrs[i];
55 
56  ++maskItr;
57  }
58 
59  this->SetComputationMask(maskImage);
60 }
61 
62 template <typename TInputImage, typename TOutputImage>
63 void
65 ::BeforeThreadedGenerateData()
66 {
67  this->Superclass::BeforeThreadedGenerateData();
68 
70  typename InitT2FilterType::Pointer initFilter = InitT2FilterType::New();
71 
72  for (unsigned int i = 0;i < this->GetNumberOfIndexedInputs();++i)
73  initFilter->SetInput(i,this->GetInput(i));
74 
75  initFilter->SetT1Map(m_T1Map);
76 
77  initFilter->SetEchoSpacing(m_EchoSpacing);
78  initFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
79  initFilter->SetComputationMask(this->GetComputationMask());
80  initFilter->SetTRValue(m_TRValue);
81  initFilter->SetT2UpperBoundValue(m_T2UpperBound);
82  initFilter->SetOptimizerStopCondition(m_OptimizerStopCondition);
83  initFilter->SetMaximumOptimizerIterations(m_MaximumOptimizerIterations);
84 
85  initFilter->Update();
86 
87  m_InitialT2Image = initFilter->GetOutput();
88  m_InitialT2Image->DisconnectPipeline();
89 }
90 
91 template <typename TInputImage, typename TOutputImage>
92 void
94 ::DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread)
95 {
96  typedef itk::ImageRegionConstIterator <InputImageType> ImageIteratorType;
97  typedef itk::ImageRegionIterator <OutputImageType> OutImageIteratorType;
98 
99  OutImageIteratorType initT2Iterator(m_InitialT2Image,outputRegionForThread);
100  OutImageIteratorType outT2Iterator(this->GetOutput(0),outputRegionForThread);
101  OutImageIteratorType outM0Iterator(this->GetOutput(1),outputRegionForThread);
102  OutImageIteratorType outB1Iterator(this->GetOutput(2),outputRegionForThread);
103 
104  unsigned int numInputs = this->GetNumberOfIndexedInputs();
105  std::vector <ImageIteratorType> inIterators;
106  for (unsigned int i = 0;i < numInputs;++i)
107  inIterators.push_back(ImageIteratorType(this->GetInput(i),outputRegionForThread));
108 
109  typedef itk::ImageRegionIterator <MaskImageType> MaskIteratorType;
110  MaskIteratorType maskItr(this->GetComputationMask(),outputRegionForThread);
111 
112  OutImageIteratorType t1MapItr;
113  if (m_T1Map)
114  t1MapItr = OutImageIteratorType(m_T1Map,outputRegionForThread);
115 
116  std::vector <double> relaxoT2Data(numInputs,0);
117 
118  typedef anima::NLOPTOptimizers OptimizerType;
119  typedef anima::T2EPGRelaxometryCostFunction CostFunctionType;
120 
121  typename CostFunctionType::Pointer cost = CostFunctionType::New();
122  cost->SetT2EchoSpacing(m_EchoSpacing);
123  cost->SetT2ExcitationFlipAngle(m_T2ExcitationFlipAngle);
124  cost->SetT2FlipAngles(m_T2FlipAngles);
125 
126  unsigned int dimension = cost->GetNumberOfParameters();
127  itk::Array<double> lowerBounds(dimension);
128  itk::Array<double> upperBounds(dimension);
129  OptimizerType::ParametersType p(dimension);
130 
131  while (!maskItr.IsAtEnd())
132  {
133  double t1Value = m_T2UpperBound;
134 
135  if (m_T1Map)
136  {
137  t1Value = t1MapItr.Get();
138  if (t1Value <= 0.0)
139  t1Value = 1000;
140  }
141 
142  double b1Value = 1.0;
143  double t2Value = initT2Iterator.Get();
144 
145  if (maskItr.Get() == 0)
146  {
147  outT2Iterator.Set(0);
148  outM0Iterator.Set(0);
149  outB1Iterator.Set(0);
150 
151  ++maskItr;
152  ++outT2Iterator;
153  ++outM0Iterator;
154  ++outB1Iterator;
155  ++initT2Iterator;
156 
157  for (unsigned int i = 0;i < numInputs;++i)
158  ++inIterators[i];
159 
160  if (m_T1Map)
161  ++t1MapItr;
162 
163  continue;
164  }
165 
166  cost->SetT1Value(t1Value);
167 
168  // Here go the T2 and B1 estimation
169  for (unsigned int i = 0;i < numInputs;++i)
170  relaxoT2Data[i] = inIterators[i].Get();
171 
172  cost->SetT2RelaxometrySignals(relaxoT2Data);
173 
174  OptimizerType::Pointer optimizer = OptimizerType::New();
175  optimizer->SetAlgorithm(NLOPT_LN_BOBYQA);
176  optimizer->SetXTolRel(m_OptimizerStopCondition);
177  optimizer->SetFTolRel(1.0e-2 * m_OptimizerStopCondition);
178  optimizer->SetMaxEval(m_MaximumOptimizerIterations);
179  optimizer->SetVectorStorageSize(2000);
180 
181  lowerBounds[0] = 1.0;
182  upperBounds[0] = m_T2UpperBound;
183  if (m_T1Map && (m_T2UpperBound > t1Value))
184  upperBounds[0] = t1Value;
185 
186  lowerBounds[1] = 1.0;
187  upperBounds[1] = 2.0;
188 
189  p[0] = t2Value;
190  p[1] = b1Value;
191 
192  optimizer->SetLowerBoundParameters(lowerBounds);
193  optimizer->SetUpperBoundParameters(upperBounds);
194  optimizer->SetMaximize(false);
195 
196  optimizer->SetCostFunction(cost);
197 
198  optimizer->SetInitialPosition(p);
199  optimizer->StartOptimization();
200 
201  p = optimizer->GetCurrentPosition();
202 
203  t2Value = p[0];
204  b1Value = p[1];
205  cost->GetValue(p);
206 
207  outT2Iterator.Set(t2Value);
208  outM0Iterator.Set(cost->GetM0Value());
209  outB1Iterator.Set(b1Value);
210 
211  this->IncrementNumberOfProcessedPoints();
212  ++maskItr;
213  ++outT2Iterator;
214  ++outM0Iterator;
215  ++outB1Iterator;
216  ++initT2Iterator;
217 
218  for (unsigned int i = 0;i < numInputs;++i)
219  ++inIterators[i];
220 
221  if (m_T1Map)
222  ++t1MapItr;
223  }
224 }
225 
226 } // end namespace anima
Implements an ITK wrapper for the NLOPT library.
Superclass::OutputImageRegionType OutputImageRegionType