Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 #ifndef __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_h
17 #define __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_h
18 
19 #include "itkImageToImageFilter.h"
20 //#include "vnl/vnl_matrix.h"
21 #include "vnl/vnl_vector_fixed.h"
22 #include "vnl/vnl_matrix.h"
23 #include "vnl/algo/vnl_svd.h"
24 #include "itkVectorContainer.h"
25 #include "itkVectorImage.h"
26 //#include "QuadProg.h"
27 #include "itkVectorImage.h"
28 
29 #include "vnl/vnl_least_squares_function.h"
30 #include "vnl/algo/vnl_levenberg_marquardt.h"
31 #include "vnl/vnl_math.h"
32 
33 #define IVIM_CEIL(val,u,o) (val) = \
34  ( (val) < (u) ) ? ( (u) ) : ( ( (val)>(o) ) ? ( (o) ) : ( (val) ) );
35 
36 namespace itk{
37 
39  struct IVIM_base
40  {
41 
42  void set_measurements(const vnl_vector<double>& x)
43  {
44  measurements.set_size(x.size());
45  measurements.copy_in(x.data_block());
46  }
47 
48  void set_bvalues(const vnl_vector<double>& x)
49  {
50  bvalues.set_size(x.size());
51  bvalues.copy_in(x.data_block());
52  }
53 
54  vnl_vector<double> measurements;
55  vnl_vector<double> bvalues;
56 
57  int N;
58 
59  };
60 
62  struct IVIM_3param : public IVIM_base, vnl_least_squares_function
63  {
64 
65  IVIM_3param(unsigned int number_of_measurements) :
66  vnl_least_squares_function(3, number_of_measurements, no_gradient)
67  {
68  N = get_number_of_residuals();
69  }
70 
71  void f(const vnl_vector<double>& x, vnl_vector<double>& fx) override {
72 
73  double ef = x[0];
74  double D = x[1];
75  double Dstar = x[2];
76 
77  for(int s=0; s<N; s++)
78  {
79  double approx = (1-ef)*exp(-bvalues[s]*D)+ef*exp(-bvalues[s]*(D+Dstar));
80  fx[s] = vnl_math_abs( measurements[s] - approx );
81  }
82 
83  }
84  };
85 
87  struct IVIM_fixdstar : public IVIM_base, vnl_least_squares_function
88  {
89 
90  IVIM_fixdstar(unsigned int number_of_measurements, double DStar) :
91  vnl_least_squares_function(2, number_of_measurements, no_gradient)
92  {
93  N = get_number_of_residuals();
94  fixDStar = DStar;
95  }
96 
97  void f(const vnl_vector<double>& x, vnl_vector<double>& fx) override {
98 
99  double ef = x[0];
100  double D = x[1];
101 
102  for(int s=0; s<N; s++)
103  {
104  double approx = (1-ef)*exp(-bvalues[s]*D)+ef*exp(-bvalues[s]*(D+fixDStar));
105  fx[s] = vnl_math_abs( measurements[s] - approx );
106  }
107 
108  }
109 
110  double fixDStar;
111 
112  };
113 
115  struct IVIM_d_and_f : public IVIM_base, vnl_least_squares_function
116  {
117 
118  IVIM_d_and_f(unsigned int number_of_measurements) :
119  vnl_least_squares_function(2, number_of_measurements, no_gradient)
120  {
121  N = get_number_of_residuals();
122  }
123 
124  void f(const vnl_vector<double>& x, vnl_vector<double>& fx) override {
125 
126  double D = x[0];
127  double f = x[1];
128 
129  for(int s=0; s<N; s++)
130  {
131  double approx = (1-f) * exp(-bvalues[s]*D);
132  fx[s] = vnl_math_abs( measurements[s] - approx );
133  }
134 
135  }
136  };
137 
139  struct IVIM_fixd : public IVIM_base, vnl_least_squares_function
140  {
141 
142  IVIM_fixd(unsigned int number_of_measurements, double D) :
143  vnl_least_squares_function(2, number_of_measurements, no_gradient)
144  {
145  N = get_number_of_residuals();
146  fixD = D;
147  }
148 
149  void f(const vnl_vector<double>& x, vnl_vector<double>& fx) override {
150 
151  double ef = x[0];
152  double Dstar = x[1];
153 
154  for(int s=0; s<N; s++)
155  {
156  double approx = (1-ef)*exp(-bvalues[s]*fixD)+ef*exp(-bvalues[s]*(fixD+Dstar));
157  fx[s] = vnl_math_abs( measurements[s] - approx );
158  }
159 
160  }
161 
162  double fixD;
163  };
164 
166  struct IVIM_dstar_only : public IVIM_base, vnl_least_squares_function
167  {
168 
169  IVIM_dstar_only(unsigned int number_of_measurements, double D, double f) :
170  vnl_least_squares_function(1, number_of_measurements, no_gradient)
171  {
172  N = get_number_of_residuals();
173  fixD = D;
174  fixF = f;
175  }
176 
177  void f(const vnl_vector<double>& x, vnl_vector<double>& fx) override {
178 
179  double Dstar = x[0];
180 
181  for(int s=0; s<N; s++)
182  {
183  double approx = (1-fixF)*exp(-bvalues[s]*fixD)+fixF*exp(-bvalues[s]*(fixD+Dstar));
184  fx[s] = vnl_math_abs( measurements[s] - approx );
185  }
186 
187  }
188 
189  double fixD;
190  double fixF;
191  };
192 
194  {
195  vnl_vector<double> meas;
196  vnl_vector<double> bvals;
197  int N;
198  };
199 
201  template< class TInputPixelType,
202  class TOutputPixelType>
204  public ImageToImageFilter< VectorImage< TInputPixelType, 3 >,
205  Image< TOutputPixelType, 3 > >
206  {
207 
208  public:
209 
211  {
212  double currentF;
214  double currentD;
215  double currentDStar;
216 
217  bool iterated_sequence; // wether each measurement has its own b0-acqu.
218  std::vector<unsigned int> baselineind; // baseline image indicies
219 
220  int N; // total number of measurements
221  std::vector<unsigned int> gradientind; // gradient image indicies
222  std::vector<double> bvals; // b-values != 0
223  vnl_vector<double> bvalues; // copy of bvalues != 0
224  vnl_vector<double> meas; // all measurements, thresholded blanked out
225  vnl_vector<double> allmeas; // all measurements
226 
227  int Nhigh; // number of used measurements
228  std::vector<int> high_indices; // indices of used measurements
229  vnl_vector<double> high_bvalues; // bvals of used measurements
230  vnl_vector<double> high_meas; // used measurements
231 
232  vnl_vector<double> meas1;
233  vnl_vector<double> bvals1;
234 
235  vnl_vector<double> meas2;
236  vnl_vector<double> bvals2;
237 
238  };
239 
241  {
247  };
248 
252  typedef ImageToImageFilter< VectorImage< TInputPixelType, 3>,
253  Image< TOutputPixelType,3 > > Superclass;
254 
256  itkFactorylessNewMacro(Self)
257  itkCloneMacro(Self)
258 
261  ImageToImageFilter);
262 
263  typedef TOutputPixelType OutputPixelType;
264 
265  typedef TInputPixelType InputPixelType;
266 
269  typedef typename Superclass::InputImageType InputImageType;
270 
271  typedef Image< OutputPixelType, 3 > OutputImageType;
272 
273  typedef typename Superclass::OutputImageRegionType
275 
277  typedef vnl_vector_fixed< double, 3 > GradientDirectionType;
278 
280  typedef VectorContainer< unsigned int,
281  GradientDirectionType > GradientDirectionContainerType;
282 
283  // vector image typedefs for regularized fit
284  typedef itk::VectorImage<float,3> VectorImageType;
285  typedef itk::Image<itk::Vector<double, 3>, 3> InitialFitImageType;
286 
293  void SetGradientDirections( GradientDirectionContainerType * );
294 
295  void SetBValue(double bval){m_BValue = bval;}
296  void SetBThres(double bval){m_BThres = bval;}
297  void SetS0Thres(double val){m_S0Thres = val;}
298  void SetDStar(double dstar){m_DStar = dstar;}
299  void SetFitDStar(bool fit){m_FitDStar = fit;}
300  void SetVerbose(bool verbose){m_Verbose = verbose;}
301  void SetNumberIterations(int num){m_NumberIterations = num;}
302  void SetLambda(double lambda){m_Lambda = lambda;}
303  void SetCrossPosition(typename InputImageType::IndexType crosspos){this->m_CrossPosition = crosspos;}
304  void SetMethod(IVIM_Method method){m_Method = method;}
305 
306  IVIMSnapshot GetSnapshot(){return m_Snap;}
307 
309  virtual GradientDirectionType GetGradientDirection( unsigned int idx) const
310  {
311  if( idx >= m_NumberOfGradientDirections )
312  {
313  itkExceptionMacro( << "Gradient direction " << idx << "does not exist" );
314  }
315  return m_GradientDirectionContainer->ElementAt( idx+1 );
316  }
317 
318  protected:
321  void PrintSelf(std::ostream& os, Indent indent) const;
322 
324  void ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread,
325  ThreadIdType);
327 
328  MeasAndBvals ApplyS0Threshold(vnl_vector<double> &meas, vnl_vector<double> &bvals);
329 
330  private:
331 
332  double myround(double number);
333 
335  GradientDirectionContainerType::Pointer m_GradientDirectionContainer;
336 
338  unsigned int m_NumberOfGradientDirections;
339 
340  double m_BValue;
341 
342  double m_BThres;
343 
344  double m_S0Thres;
345 
346  double m_DStar;
347 
348  IVIM_Method m_Method;
349 
350  typename OutputImageType::Pointer m_DMap;
351 
352  typename OutputImageType::Pointer m_DStarMap;
353 
354  bool m_FitDStar;
355 
356  IVIMSnapshot m_Snap;
357 
358  bool m_Verbose;
359 
360  typename VectorImageType::Pointer m_InternalVectorImage;
361 
362  typename InitialFitImageType::Pointer m_InitialFitImage;
363 
364  int m_NumberIterations; // for total variation
365 
366  vnl_vector<double> m_tmp_allmeas;
367 
368  double m_Lambda;
369 
370  typename InputImageType::IndexType m_CrossPosition;
371 
372  };
373 
374 }
375 
376 #ifndef ITK_MANUAL_INSTANTIATION
378 #endif
379 
380 #endif //__itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_h
381 
void f(const vnl_vector< double > &x, vnl_vector< double > &fx) override
itk::SmartPointer< Self > Pointer
ImageToImageFilter< VectorImage< TInputPixelType, 3 >, Image< TOutputPixelType, 3 > > Superclass
void f(const vnl_vector< double > &x, vnl_vector< double > &fx) override
class ITK_EXPORT Image
IVIM_dstar_only(unsigned int number_of_measurements, double D, double f)
IVIM_fixd(unsigned int number_of_measurements, double D)
void f(const vnl_vector< double > &x, vnl_vector< double > &fx) override
IVIM_fixdstar(unsigned int number_of_measurements, double DStar)
void f(const vnl_vector< double > &x, vnl_vector< double > &fx) override
void f(const vnl_vector< double > &x, vnl_vector< double > &fx) override