ANIMA  4.0
animaMultiT2RelaxometryEstimationImageFilter.h
Go to the documentation of this file.
1 #pragma once
2 
4 #include <itkVectorImage.h>
5 #include <itkImage.h>
6 
7 #include <animaNNLSOptimizer.h>
9 
10 namespace anima
11 {
12 
22 template <class TPixelScalarType>
24 public anima::MaskedImageToImageFilter<itk::Image <TPixelScalarType, 3>, itk::Image <TPixelScalarType, 3> >
25 {
26 public:
29  typedef itk::Image <TPixelScalarType, 3> TInputImage;
30  typedef itk::Image <TPixelScalarType, 3> TOutputImage;
32  typedef itk::SmartPointer<Self> Pointer;
33  typedef itk::SmartPointer<const Self> ConstPointer;
34 
36  itkNewMacro(Self)
37 
38 
40 
41 
42  typedef TInputImage InputImageType;
43  typedef typename InputImageType::IndexType IndexType;
44  typedef TOutputImage OutputImageType;
45  typedef itk::VectorImage <TPixelScalarType, 3> VectorOutputImageType;
46  typedef typename VectorOutputImageType::PixelType OutputVectorType;
47  typedef typename InputImageType::Pointer InputImagePointer;
48  typedef typename OutputImageType::Pointer OutputImagePointer;
49  typedef typename VectorOutputImageType::Pointer VectorOutputImagePointer;
50 
52  typedef typename Superclass::MaskImageType MaskImageType;
53  typedef typename Superclass::InputImageRegionType InputImageRegionType;
54  typedef typename Superclass::OutputImageRegionType OutputImageRegionType;
55 
57  typedef NNLSOptimizerType::Pointer NNLSOptimizerPointer;
58  typedef NNLSOptimizerType::MatrixType DataMatrixType;
59  typedef NNLSOptimizerType::ParametersType T2VectorType;
60 
61  typedef anima::NonLocalT2DistributionPatchSearcher <VectorOutputImageType,InputImageType> PatchSearcherType;
62 
63  itkSetMacro(NumberOfT2Compartments, unsigned int)
64  itkSetMacro(MyelinThreshold, double)
65  itkSetMacro(LowerT2Bound, double)
66  itkSetMacro(UpperT2Bound, double)
67  itkSetMacro(EchoSpacing, double)
68  itkSetMacro(RegularizationIntensity, double)
69 
70  void SetT1Map(InputImageType *map) {m_T1Map = map;}
71  InputImageType *GetT1Map() {return m_T1Map;}
72 
73  itkSetMacro(NLEstimation, bool)
74  itkSetObjectMacro(InitialB1Map, InputImageType)
75  itkSetObjectMacro(InitialM0Map, InputImageType)
76  itkSetObjectMacro(InitialT2Map, VectorOutputImageType)
77  itkSetMacro(PatchHalfSize, unsigned int)
78  itkSetMacro(SearchNeighborhood, unsigned int)
79  itkSetMacro(SearchStepSize, unsigned int)
80  itkSetMacro(WeightThreshold, double)
81  itkSetMacro(BetaParameter, double)
82  itkSetMacro(MeanMinThreshold, double)
83  itkSetMacro(VarMinThreshold, double)
84 
85  itkSetMacro(AverageSignalThreshold, double)
86 
87  InputImageType *GetM0OutputImage() {return this->GetOutput(0);}
88  InputImageType *GetMWFOutputImage() {return this->GetOutput(1);}
89  InputImageType *GetB1OutputImage() {return this->GetOutput(2);}
90  InputImageType *GetCostOutputImage() {return this->GetOutput(3);}
91  VectorOutputImageType *GetT2OutputImage() {return m_T2OutputImage;}
92 
93  itkSetMacro(T2ExcitationFlipAngle, double)
94  itkSetMacro(B1MaximumOptimizerIterations, unsigned int)
95  itkSetMacro(B1OptimizerStopCondition, double)
96  itkSetMacro(B1OptimizerInitialStep, double)
97  itkSetMacro(B1Tolerance, double)
98 
99  void SetT2FlipAngles(std::vector <double> & flipAngles) {m_T2FlipAngles = flipAngles;}
100  void SetT2FlipAngles(double singleAngle, unsigned int numAngles) {m_T2FlipAngles = std::vector <double> (numAngles,singleAngle);}
101 
102 protected:
104  : Superclass()
105  {
106  // There are 4 outputs: M0, MWF, B1, Cost
107  this->SetNumberOfRequiredOutputs(4);
108 
109  for (unsigned int i = 0;i < 4;++i)
110  this->SetNthOutput(i, this->MakeOutput(i));
111 
112  m_AverageSignalThreshold = 0;
113  m_EchoSpacing = 1;
114  m_RegularizationIntensity = 1.08;
115 
116  m_NumberOfT2Compartments = 40;
117  m_MyelinThreshold = 50;
118  m_LowerT2Bound = 15;
119  m_UpperT2Bound = 2000;
120 
121  m_NLEstimation = false;
122 
123  m_T2ExcitationFlipAngle = M_PI / 6;
124  m_B1Tolerance = 1.0e-4;
125  m_B1MaximumOptimizerIterations = 200;
126  m_B1OptimizerStopCondition = 1.0e-4;
127  m_B1OptimizerInitialStep = 10;
128 
129  m_MeanMinThreshold = 0.95;
130  m_VarMinThreshold = 0.5;
131  m_WeightThreshold = 0.0;
132  m_BetaParameter = 1.0;
133  m_PatchHalfSize = 3;
134  m_SearchStepSize = 3;
135  m_SearchNeighborhood = 6;
136  m_LocalNeighborhood = 1;
137  }
138 
140 
141  void CheckComputationMask() ITK_OVERRIDE;
142 
143  void BeforeThreadedGenerateData() ITK_OVERRIDE;
144  void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) ITK_OVERRIDE;
145 
147  void ComputeTikhonovPrior(const IndexType &refIndex, OutputVectorType &refDistribution,
148  PatchSearcherType &nlPatchSearcher, T2VectorType &priorDistribution,
149  std::vector <double> &workDataWeights, std::vector <OutputVectorType> &workDataSamples);
150 
152  T2VectorType &signalValues, double lambdaSq,
153  T2VectorType &priorDistribution, T2VectorType &t2OptimizedWeights);
154 
155 private:
156  MultiT2RelaxometryEstimationImageFilter(const Self&); //purposely not implemented
157  void operator=(const Self&); //purposely not implemented
158 
159  unsigned int m_NumberOfT2Compartments;
160  double m_MyelinThreshold;
161  double m_LowerT2Bound;
162  double m_UpperT2Bound;
163  double m_AverageSignalThreshold;
164 
165  // T1 relaxometry specific values
166  InputImagePointer m_T1Map;
167 
168  // Optional input images, mainly used for NL estimation
169  InputImagePointer m_InitialB1Map;
170  InputImagePointer m_InitialM0Map;
171  VectorOutputImagePointer m_InitialT2Map;
172 
173  bool m_NLEstimation;
174  std::vector <PatchSearcherType> m_NLPatchSearchers;
175  double m_MeanMinThreshold;
176  double m_VarMinThreshold;
177  double m_WeightThreshold;
178  double m_BetaParameter;
179 
180  unsigned int m_PatchHalfSize;
181  unsigned int m_SearchStepSize;
182  unsigned int m_SearchNeighborhood;
183  unsigned int m_LocalNeighborhood;
184 
185  // Additional result image
186  VectorOutputImagePointer m_T2OutputImage;
187 
188  // T2 relaxometry specific values
189  std::vector <double> m_T2CompartmentValues;
190  double m_EchoSpacing;
191  double m_RegularizationIntensity;
192  std::vector <double> m_T2FlipAngles;
193  double m_T2ExcitationFlipAngle;
194 
195  double m_B1Tolerance;
196  double m_B1OptimizerInitialStep;
197  double m_B1OptimizerStopCondition;
198  unsigned int m_B1MaximumOptimizerIterations;
199 };
200 
201 } // end namespace anima
202 
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) ITK_OVERRIDE
STL namespace.
void ComputeTikhonovPrior(const IndexType &refIndex, OutputVectorType &refDistribution, PatchSearcherType &nlPatchSearcher, T2VectorType &priorDistribution, std::vector< double > &workDataWeights, std::vector< OutputVectorType > &workDataSamples)
Implements multi-peak T2 relaxometry estimation (with or without regularization)
double ComputeTikhonovRegularizedSolution(anima::NNLSOptimizer *nnlsOpt, DataMatrixType &AMatrix, T2VectorType &signalValues, double lambdaSq, T2VectorType &priorDistribution, T2VectorType &t2OptimizedWeights)
anima::MaskedImageToImageFilter< TInputImage, TOutputImage > Superclass
Non negative least squares optimizer. Implements Lawson et al method, of squared problem is activated...
void SetT2FlipAngles(double singleAngle, unsigned int numAngles)