Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.cpp
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_cpp
17 #define __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_cpp
18 
20 #include "itkImageRegionConstIterator.h"
21 #include "itkImageRegionConstIteratorWithIndex.h"
22 #include "itkImageRegionIterator.h"
23 
24 #include "vnl/vnl_matrix.h"
25 #include "vnl/algo/vnl_symmetric_eigensystem.h"
26 
28 
29 #include <mitkLogMacros.h>
30 
31 #define IVIM_FOO -100000
32 
33 namespace itk {
34 
35 
36 template< class TIn, class TOut>
39  m_GradientDirectionContainer(nullptr),
40  m_Method(IVIM_DSTAR_FIX),
41  m_FitDStar(true),
42  m_Verbose(false)
43 {
44  this->SetNumberOfRequiredInputs( 1 );
45 
46  this->SetNumberOfRequiredOutputs( 3 );
47  typename OutputImageType::Pointer outputPtr1 = OutputImageType::New();
48  this->SetNthOutput(0, outputPtr1.GetPointer());
49  typename OutputImageType::Pointer outputPtr2 = OutputImageType::New();
50  this->SetNthOutput(1, outputPtr2.GetPointer());
51  typename OutputImageType::Pointer outputPtr3 = OutputImageType::New();
52  this->SetNthOutput(2, outputPtr3.GetPointer());
53 }
54 
55 
56 
57 template< class TIn, class TOut>
60 {
61 
62  // Input must be an itk::VectorImage.
63  std::string gradientImageClassName(
64  this->ProcessObject::GetInput(0)->GetNameOfClass());
65  if ( strcmp(gradientImageClassName.c_str(),"VectorImage") != 0 )
66  {
67  itkExceptionMacro( <<
68  "There is only one Gradient image. I expect that to be a VectorImage. "
69  << "But its of type: " << gradientImageClassName );
70  }
71 
72  // Compute the indicies of the baseline images and gradient images
73  // If no b=0 mm/s² gradients ar found, the next lowest b-value is used.
74  GradientDirectionContainerType::ConstIterator gdcit = this->m_GradientDirectionContainer->Begin();
75  double minNorm = itk::NumericTraits<double>::max();
76  while( gdcit != this->m_GradientDirectionContainer->End() )
77  {
78  double norm = gdcit.Value().one_norm();
79  if (norm<minNorm)
80  minNorm = norm;
81  ++gdcit;
82  }
83  minNorm += 0.001;
84  gdcit = this->m_GradientDirectionContainer->Begin();
85  while( gdcit != this->m_GradientDirectionContainer->End() )
86  {
87  if(gdcit.Value().one_norm() <= minNorm)
88  {
89  m_Snap.baselineind.push_back(gdcit.Index());
90  }
91  else
92  {
93  m_Snap.gradientind.push_back(gdcit.Index());
94  double twonorm = gdcit.Value().two_norm();
95  m_Snap.bvals.push_back( m_BValue*twonorm*twonorm );
96  }
97  ++gdcit;
98  }
99  if (m_Snap.gradientind.size()==0)
100  itkExceptionMacro("Only one b-value supplied. At least two needed for IVIM fit.");
101 
102  // check sind die grad und base gleichlang? alle grad gerade und base ungerade? dann iterierende aufnahme!!
103  m_Snap.iterated_sequence = false;
104  if(m_Snap.baselineind.size() == m_Snap.gradientind.size())
105  {
106  int size = m_Snap.baselineind.size();
107  int sum_b = 0, sum_g = 0;
108  for(int i=0; i<size; i++)
109  {
110  sum_b += m_Snap.baselineind.at(i) % 2;
111  sum_g += m_Snap.gradientind.at(i) % 2;
112  }
113  if( (sum_b == size || sum_b == 0)
114  && (sum_g == size || sum_g == 0) )
115  {
116  m_Snap.iterated_sequence = true;
117  if(m_Verbose)
118  {
119  MITK_INFO << "Iterating b0 and diffusion weighted aquisition detected. Weighting each weighted measurement with its own b0.";
120  }
121  }
122  }
123 
124  // number of measurements
125  m_Snap.N = m_Snap.gradientind.size();
126 
127  // bvalue array
128  m_Snap.bvalues.set_size(m_Snap.N);
129  for(int i=0; i<m_Snap.N; i++)
130  {
131  m_Snap.bvalues[i] = m_Snap.bvals.at(i);
132  }
133 
134  if(m_Verbose)
135  {
136  std::cout << "ref bval: " << m_BValue << "; b-values: ";
137  for(int i=0; i<m_Snap.N; i++)
138  {
139  std::cout << m_Snap.bvalues[i] << "; ";
140  }
141  std::cout << std::endl;
142  }
143 
144  // extract bvals higher than threshold
145  if(m_Method == IVIM_D_THEN_DSTAR || m_Method == IVIM_LINEAR_D_THEN_F || m_Method == IVIM_REGULARIZED)
146  {
147  for(int i=0; i<m_Snap.N; i++)
148  {
149  if(m_Snap.bvalues[i]>m_BThres)
150  {
151  m_Snap.high_indices.push_back(i);
152  }
153  }
154  }
155  m_Snap.Nhigh = m_Snap.high_indices.size();
156  m_Snap.high_bvalues.set_size(m_Snap.Nhigh);
157  m_Snap.high_meas.set_size(m_Snap.Nhigh);
158  for(int i=0; i<m_Snap.Nhigh; i++)
159  {
160  m_Snap.high_bvalues[i] = m_Snap.bvalues[m_Snap.high_indices.at(i)];
161  }
162 
163 }
164 
165 template< class TIn, class TOut>
167 ::ApplyS0Threshold(vnl_vector<double> &meas, vnl_vector<double> &bvals)
168 {
169  std::vector<double> newmeas;
170  std::vector<double> newbvals;
171 
172  int N = meas.size();
173  for(int i=0; i<N; i++)
174  {
175  if( meas[i] != IVIM_FOO )
176  {
177  newmeas.push_back(meas[i]);
178  newbvals.push_back(bvals[i]);
179  }
180  }
181 
182  MeasAndBvals retval;
183 
184  retval.N = newmeas.size();
185 
186  retval.meas.set_size(retval.N);
187  for(size_t i=0; i<newmeas.size(); i++)
188  {
189  retval.meas[i] = newmeas[i];
190  }
191 
192  retval.bvals.set_size(retval.N);
193  for(size_t i=0; i<newbvals.size(); i++)
194  {
195  retval.bvals[i] = newbvals[i];
196  }
197 
198  return retval;
199 }
200 
201 template< class TIn, class TOut>
203 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
204  ThreadIdType )
205 {
206 
207  typename OutputImageType::Pointer outputImage =
208  static_cast< OutputImageType * >(this->ProcessObject::GetPrimaryOutput());
209  ImageRegionIterator< OutputImageType > oit(outputImage, outputRegionForThread);
210  oit.GoToBegin();
211 
212  typename OutputImageType::Pointer dImage =
213  static_cast< OutputImageType * >(this->ProcessObject::GetOutput(1));
214  ImageRegionIterator< OutputImageType > oit1(dImage, outputRegionForThread);
215  oit1.GoToBegin();
216 
217  typename OutputImageType::Pointer dstarImage =
218  static_cast< OutputImageType * >(this->ProcessObject::GetOutput(2));
219  ImageRegionIterator< OutputImageType > oit2(dstarImage, outputRegionForThread);
220  oit2.GoToBegin();
221 
222  typedef ImageRegionConstIterator< InputImageType > InputIteratorType;
223  typedef typename InputImageType::PixelType InputVectorType;
224  typename InputImageType::Pointer inputImagePointer = NULL;
225 
226  // Would have liked a dynamic_cast here, but seems SGI doesn't like it
227  // The enum will DiffusionIntravoxelIncoherentMotionReconstructionImageFilterensure that an inappropriate cast is not done
228  inputImagePointer = static_cast< InputImageType * >(
229  this->ProcessObject::GetInput(0) );
230 
231  InputIteratorType iit(inputImagePointer, outputRegionForThread );
232  iit.GoToBegin();
233 
234  // init internal vector image for regularized fit
235  m_InternalVectorImage = VectorImageType::New();
236  m_InternalVectorImage->SetSpacing( inputImagePointer->GetSpacing() ); // Set the image spacing
237  m_InternalVectorImage->SetOrigin( inputImagePointer->GetOrigin() ); // Set the image origin
238  m_InternalVectorImage->SetDirection( inputImagePointer->GetDirection() ); // Set the image direction
239  m_InternalVectorImage->SetRegions( inputImagePointer->GetLargestPossibleRegion() );
240 
241  m_InitialFitImage = InitialFitImageType::New();
242  m_InitialFitImage->SetSpacing( inputImagePointer->GetSpacing() ); // Set the image spacing
243  m_InitialFitImage->SetOrigin( inputImagePointer->GetOrigin() ); // Set the image origin
244  m_InitialFitImage->SetDirection( inputImagePointer->GetDirection() ); // Set the image direction
245  m_InitialFitImage->SetRegions( inputImagePointer->GetLargestPossibleRegion() );
246 
247  if(m_Method == IVIM_REGULARIZED)
248  {
249  m_InternalVectorImage->SetVectorLength(m_Snap.Nhigh);
250  m_InternalVectorImage->Allocate();
251  VectorImageType::PixelType varvec(m_Snap.Nhigh);
252  for(int i=0; i<m_Snap.Nhigh; i++) varvec[i] = IVIM_FOO;
253  m_InternalVectorImage->FillBuffer(varvec);
254 
255  m_InitialFitImage->Allocate();
257  vec[0] = 0.5; vec[1] = 0.01; vec[2]=0.001;
258  m_InitialFitImage->FillBuffer(vec);
259  }
260 
261  typedef itk::ImageRegionIterator<VectorImageType> VectorIteratorType;
262  VectorIteratorType vecit(m_InternalVectorImage, outputRegionForThread );
263  vecit.GoToBegin();
264 
265  typedef itk::ImageRegionIterator<InitialFitImageType> InitIteratorType;
266  InitIteratorType initit(m_InitialFitImage, outputRegionForThread );
267  initit.GoToBegin();
268 
269  while( !iit.IsAtEnd() )
270  {
271  InputVectorType measvec = iit.Get();
272 
273  typename NumericTraits<InputPixelType>::AccumulateType b0 = NumericTraits<InputPixelType>::Zero;
274 
275  m_Snap.meas.set_size(m_Snap.N);
276  m_Snap.allmeas.set_size(m_Snap.N);
277  if(!m_Snap.iterated_sequence)
278  {
279  // Average the baseline image pixels
280  for(unsigned int i = 0; i < m_Snap.baselineind.size(); ++i)
281  {
282  b0 += measvec[m_Snap.baselineind[i]];
283  }
284  if(m_Snap.baselineind.size())
285  b0 /= m_Snap.baselineind.size();
286 
287  // measurement vector
288  for(int i = 0; i < m_Snap.N; ++i)
289  {
290  m_Snap.allmeas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001);
291 
292  if(measvec[m_Snap.gradientind[i]] > m_S0Thres)
293  {
294  m_Snap.meas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001);
295  }
296  else
297  {
298  m_Snap.meas[i] = IVIM_FOO;
299  }
300  }
301  }
302  else
303  {
304  // measurement vector
305  for(int i = 0; i < m_Snap.N; ++i)
306  {
307  b0 = measvec[m_Snap.baselineind[i]];
308 
309  m_Snap.allmeas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001);
310 
311  if(measvec[m_Snap.gradientind[i]] > m_S0Thres)
312  {
313  m_Snap.meas[i] = measvec[m_Snap.gradientind[i]] / (b0+.0001);
314  }
315  else
316  {
317  m_Snap.meas[i] = IVIM_FOO;
318  }
319  }
320  }
321 
322  m_Snap.currentF = 0;
323  m_Snap.currentD = 0;
324  m_Snap.currentDStar = 0;
325 
326  switch(m_Method)
327  {
328 
329  case IVIM_D_THEN_DSTAR:
330  {
331 
332  for(int i=0; i<m_Snap.Nhigh; i++)
333  {
334  m_Snap.high_meas[i] = m_Snap.meas[m_Snap.high_indices.at(i)];
335  }
336 
337  MeasAndBvals input = ApplyS0Threshold(m_Snap.high_meas, m_Snap.high_bvalues);
338  m_Snap.bvals1 = input.bvals;
339  m_Snap.meas1 = input.meas;
340 
341  if (input.N < 2)
342  {
343  if (input.N == 1)
344  {
345  m_Snap.currentD = - log(input.meas[0]) / input.bvals[0];
346  m_Snap.currentF = 0;
347  m_Snap.currentDStar = 0;
348  }
349  break;
350  }
351 
352  IVIM_d_and_f f_donly(input.N);
353  f_donly.set_bvalues(input.bvals);
354  f_donly.set_measurements(input.meas);
355 
356  vnl_vector< double > x_donly(2);
357  x_donly[0] = 0.001;
358  x_donly[1] = 0.1;
359  // f 0.1 Dstar 0.01 D 0.001
360 
361  vnl_levenberg_marquardt lm_donly(f_donly);
362  lm_donly.set_f_tolerance(0.0001);
363  lm_donly.minimize(x_donly);
364  m_Snap.currentD = x_donly[0];
365  m_Snap.currentF = x_donly[1];
366 
367 
368  if(m_FitDStar)
369  {
370  MeasAndBvals input2 = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues);
371  m_Snap.bvals2 = input2.bvals;
372  m_Snap.meas2 = input2.meas;
373  if (input2.N < 2) break;
374 
375  IVIM_dstar_only f_dstar_only(input2.N,m_Snap.currentD,m_Snap.currentF);
376  f_dstar_only.set_bvalues(input2.bvals);
377  f_dstar_only.set_measurements(input2.meas);
378 
379  vnl_vector< double > x_dstar_only(1);
380  vnl_vector< double > fx_dstar_only(input2.N);
381 
382  double opt = 1111111111111111.0;
383  int opt_idx = -1;
384  int num_its = 100;
385  double min_val = .001;
386  double max_val = .15;
387  for(int i=0; i<num_its; i++)
388  {
389  x_dstar_only[0] = min_val + i * ((max_val-min_val) / num_its);
390  f_dstar_only.f(x_dstar_only, fx_dstar_only);
391  double err = fx_dstar_only.two_norm();
392  if(err<opt)
393  {
394  opt = err;
395  opt_idx = i;
396  }
397  }
398 
399  m_Snap.currentDStar = min_val + opt_idx * ((max_val-min_val) / num_its);
400  // IVIM_fixd f_fixd(input2.N,m_Snap.currentD);
401  // f_fixd.set_bvalues(input2.bvals);
402  // f_fixd.set_measurements(input2.meas);
403 
404  // vnl_vector< double > x_fixd(2);
405  // x_fixd[0] = 0.1;
406  // x_fixd[1] = 0.01;
407  // // f 0.1 Dstar 0.01 D 0.001
408 
409  // vnl_levenberg_marquardt lm_fixd(f_fixd);
410  // lm_fixd.set_f_tolerance(0.0001);
411  // lm_fixd.minimize(x_fixd);
412 
413  // m_Snap.currentF = x_fixd[0];
414  // m_Snap.currentDStar = x_fixd[1];
415  }
416 
417  break;
418  }
419 
420  case IVIM_DSTAR_FIX:
421  {
422  MeasAndBvals input = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues);
423  m_Snap.bvals1 = input.bvals;
424  m_Snap.meas1 = input.meas;
425  if (input.N < 2) break;
426 
427  IVIM_fixdstar f_fixdstar(input.N,m_DStar);
428  f_fixdstar.set_bvalues(input.bvals);
429  f_fixdstar.set_measurements(input.meas);
430 
431  vnl_vector< double > x(2);
432  x[0] = 0.1;
433  x[1] = 0.001;
434  // f 0.1 Dstar 0.01 D 0.001
435 
436  vnl_levenberg_marquardt lm(f_fixdstar);
437  lm.set_f_tolerance(0.0001);
438  lm.minimize(x);
439 
440  m_Snap.currentF = x[0];
441  m_Snap.currentD = x[1];
442  m_Snap.currentDStar = m_DStar;
443 
444  break;
445  }
446 
447  case IVIM_FIT_ALL:
448  {
449 
450  MeasAndBvals input = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues);
451  m_Snap.bvals1 = input.bvals;
452  m_Snap.meas1 = input.meas;
453  if (input.N < 3) break;
454 
455  IVIM_3param f_3param(input.N);
456  f_3param.set_bvalues(input.bvals);
457  f_3param.set_measurements(input.meas);
458 
459  vnl_vector< double > x(3);
460  x[0] = 0.1;
461  x[1] = 0.001;
462  x[2] = 0.01;
463  // f 0.1 Dstar 0.01 D 0.001
464 
465  vnl_levenberg_marquardt lm(f_3param);
466  lm.set_f_tolerance(0.0001);
467  lm.minimize(x);
468 
469  m_Snap.currentF = x[0];
470  m_Snap.currentD = x[1];
471  m_Snap.currentDStar = x[2];
472 
473  break;
474  }
475 
476  case IVIM_LINEAR_D_THEN_F:
477  {
478 
479  // // neglect zero-measurements
480  // bool zero = false;
481  // for(int i=0; i<Nhigh; i++)
482  // {
483  // if( meas[high_indices.at(i)] == 0 )
484  // {
485  // f=0;
486  // zero = true;
487  // break;
488  // }
489  // }
490  // if(zero) break;
491 
492  for(int i=0; i<m_Snap.Nhigh; i++)
493  {
494  m_Snap.high_meas[i] = m_Snap.meas[m_Snap.high_indices.at(i)];
495  }
496 
497  MeasAndBvals input = ApplyS0Threshold(m_Snap.high_meas, m_Snap.high_bvalues);
498  m_Snap.bvals1 = input.bvals;
499  m_Snap.meas1 = input.meas;
500 
501  if (input.N < 2)
502  {
503  if (input.N == 1)
504  {
505  m_Snap.currentD = - log(input.meas[0]) / input.bvals[0];
506  m_Snap.currentF = 0;
507  m_Snap.currentDStar = 0;
508  }
509  break;
510  }
511 
512  for(int i=0; i<input.N; i++)
513  {
514  input.meas[i] = log(input.meas[i]);
515  }
516 
517  double bval_m = 0;
518  double meas_m = 0;
519  for(int i=0; i<input.N; i++)
520  {
521  bval_m += input.bvals[i];
522  meas_m += input.meas[i];
523  }
524  bval_m /= input.N;
525  meas_m /= input.N;
526 
527  vnl_matrix<double> X(input.N,2);
528  for(int i=0; i<input.N; i++)
529  {
530  X(i,0) = input.bvals[i] - bval_m;
531  X(i,1) = input.meas[i] - meas_m;
532  }
533 
534  vnl_matrix<double> XX = X.transpose() * X;
535  vnl_symmetric_eigensystem<double> eigs(XX);
536 
537  vnl_vector<double> eig;
538  if(eigs.get_eigenvalue(0) > eigs.get_eigenvalue(1))
539  eig = eigs.get_eigenvector(0);
540  else
541  eig = eigs.get_eigenvector(1);
542 
543  m_Snap.currentF = 1 - exp( meas_m - bval_m*(eig(1)/eig(0)) );
544  m_Snap.currentD = -eig(1)/eig(0);
545 
546  if(m_FitDStar)
547  {
548  MeasAndBvals input2 = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues);
549  m_Snap.bvals2 = input2.bvals;
550  m_Snap.meas2 = input2.meas;
551  if (input2.N < 2) break;
552 
553  IVIM_dstar_only f_dstar_only(input2.N,m_Snap.currentD,m_Snap.currentF);
554  f_dstar_only.set_bvalues(input2.bvals);
555  f_dstar_only.set_measurements(input2.meas);
556 
557  vnl_vector< double > x_dstar_only(1);
558  vnl_vector< double > fx_dstar_only(input2.N);
559 
560  double opt = 1111111111111111.0;
561  int opt_idx = -1;
562  int num_its = 100;
563  double min_val = .001;
564  double max_val = .15;
565  for(int i=0; i<num_its; i++)
566  {
567  x_dstar_only[0] = min_val + i * ((max_val-min_val) / num_its);
568  f_dstar_only.f(x_dstar_only, fx_dstar_only);
569  double err = fx_dstar_only.two_norm();
570  if(err<opt)
571  {
572  opt = err;
573  opt_idx = i;
574  }
575  }
576 
577  m_Snap.currentDStar = min_val + opt_idx * ((max_val-min_val) / num_its);
578  }
579  // MITK_INFO << "choosing " << opt_idx << " => " << DStar;
580  // x_dstar_only[0] = 0.01;
581  // // f 0.1 Dstar 0.01 D 0.001
582 
583  // vnl_levenberg_marquardt lm_dstar_only(f_dstar_only);
584  // lm_dstar_only.set_f_tolerance(0.0001);
585  // lm_dstar_only.minimize(x_dstar_only);
586 
587  // DStar = x_dstar_only[0];
588 
589  break;
590  }
591 
592  case IVIM_REGULARIZED:
593  {
594  //m_Snap.high_meas, m_Snap.high_bvalues;
595  for(int i=0; i<m_Snap.Nhigh; i++)
596  {
597  m_Snap.high_meas[i] = m_Snap.meas[m_Snap.high_indices.at(i)];
598  }
599 
600  MeasAndBvals input = ApplyS0Threshold(m_Snap.high_meas, m_Snap.high_bvalues);
601 
602  vnl_vector< double > x_donly(2);
603  x_donly[0] = 0.001;
604  x_donly[1] = 0.1;
605 
606  if(input.N >= 2)
607  {
608  IVIM_d_and_f f_donly(input.N);
609  f_donly.set_bvalues(input.bvals);
610  f_donly.set_measurements(input.meas);
611  //MITK_INFO << "initial fit N=" << input.N << ", min-b = " << input.bvals[0] << ", max-b = " << input.bvals[input.N-1];
612  vnl_levenberg_marquardt lm_donly(f_donly);
613  lm_donly.set_f_tolerance(0.0001);
614  lm_donly.minimize(x_donly);
615  }
616 
617  typename InitialFitImageType::PixelType initvec;
618  initvec[0] = x_donly[1];
619  initvec[1] = x_donly[0];
620  initit.Set(initvec);
621  //MITK_INFO << "Init vox " << initit.GetIndex() << " with " << initvec[0] << "; " << initvec[1];
622  ++initit;
623 
624  int N = m_Snap.high_meas.size();
625  typename VectorImageType::PixelType vec(N);
626  for(int i=0; i<N; i++)
627  {
628  vec[i] = m_Snap.high_meas[i];
629  //MITK_INFO << "vec" << i << " = " << m_Snap.high_meas[i];
630  }
631 
632  vecit.Set(vec);
633  ++vecit;
634 
635  if(!m_Verbose)
636  {
637  // report the middle voxel
638  if( vecit.GetIndex()[0] == m_CrossPosition[0]
639  && vecit.GetIndex()[0] == m_CrossPosition[1]
640  && vecit.GetIndex()[0] == m_CrossPosition[2] )
641  {
642  MeasAndBvals input = ApplyS0Threshold(m_Snap.high_meas, m_Snap.high_bvalues);
643  m_Snap.bvals1 = input.bvals;
644  m_Snap.meas1 = input.meas;
645 
646  MeasAndBvals input2 = ApplyS0Threshold(m_Snap.meas, m_Snap.bvalues);
647  m_Snap.bvals2 = input2.bvals;
648  m_Snap.meas2 = input2.meas;
649 
650  m_tmp_allmeas = m_Snap.allmeas;
651  }
652  }
653 
654  break;
655  }
656  }
657  m_Snap.currentFunceiled = m_Snap.currentF;
658  IVIM_CEIL( m_Snap.currentF, 0.0, 1.0 );
659 
660  oit.Set( m_Snap.currentF );
661  oit1.Set( m_Snap.currentD );
662  oit2.Set( m_Snap.currentDStar );
663 
664  // std::cout << "\tf=" << x[0] << "\tD=" << x[1] << " ; "<<std::endl;
665 
666  ++oit;
667  ++oit1;
668  ++oit2;
669  ++iit;
670  }
671 
672  if(m_Verbose)
673  {
674  std::cout << "One Thread finished reconstruction" << std::endl;
675  }
676 }
677 
678 template< class TIn, class TOut>
681 {
682  if(m_Method == IVIM_REGULARIZED)
683  {
684  typename OutputImageType::Pointer outputImage =
685  static_cast< OutputImageType * >(this->ProcessObject::GetPrimaryOutput());
686  ImageRegionIterator< OutputImageType > oit0(outputImage, outputImage->GetLargestPossibleRegion());
687  oit0.GoToBegin();
688 
689  typename OutputImageType::Pointer dImage =
690  static_cast< OutputImageType * >(this->ProcessObject::GetOutput(1));
691  ImageRegionIterator< OutputImageType > oit1(dImage, dImage->GetLargestPossibleRegion());
692  oit1.GoToBegin();
693 
694  typename OutputImageType::Pointer dstarImage =
695  static_cast< OutputImageType * >(this->ProcessObject::GetOutput(2));
696  ImageRegionIterator< OutputImageType > oit2(dstarImage, dstarImage->GetLargestPossibleRegion());
697  oit2.GoToBegin();
698 
700  <double,double,float> RegFitType;
702  filter->SetInput(m_InitialFitImage);
703  filter->SetReferenceImage(m_InternalVectorImage);
704  filter->SetBValues(m_Snap.high_bvalues);
705  filter->SetNumberIterations(m_NumberIterations);
706  filter->SetNumberOfThreads(1);
707  filter->SetLambda(m_Lambda);
708  filter->Update();
709  typename RegFitType::OutputImageType::Pointer outimg = filter->GetOutput();
710 
711  ImageRegionConstIterator< RegFitType::OutputImageType > iit(outimg, outimg->GetLargestPossibleRegion());
712  iit.GoToBegin();
713 
714  while( !iit.IsAtEnd() )
715  {
716  double f = iit.Get()[0];
717  IVIM_CEIL( f, 0.0, 1.0 );
718 
719  oit0.Set( myround(f * 100.0) );
720  oit1.Set( myround(iit.Get()[1] * 10000.0) );
721  oit2.Set( myround(iit.Get()[2] * 1000.0) );
722 
723  if(!m_Verbose)
724  {
725  // report the middle voxel
726  if( iit.GetIndex()[0] == m_CrossPosition[0]
727  && iit.GetIndex()[1] == m_CrossPosition[1]
728  && iit.GetIndex()[2] == m_CrossPosition[2] )
729  {
730  m_Snap.currentF = f;
731  m_Snap.currentD = iit.Get()[1];
732  m_Snap.currentDStar = iit.Get()[2];
733  m_Snap.allmeas = m_tmp_allmeas;
734  MITK_INFO << "setting " << f << ";" << iit.Get()[1] << ";" << iit.Get()[2];
735  }
736  }
737 
738  ++oit0;
739  ++oit1;
740  ++oit2;
741  ++iit;
742  }
743  }
744 }
745 
746 template< class TIn, class TOut>
748 ::myround(double number)
749 {
750  return number < 0.0 ? ceil(number - 0.5) : floor(number + 0.5);
751 }
752 
753 template< class TIn, class TOut>
756 {
757  this->m_GradientDirectionContainer = gradientDirection;
758  this->m_NumberOfGradientDirections = gradientDirection->Size();
759 }
760 
761 template< class TIn, class TOut>
763 ::PrintSelf(std::ostream& os, Indent indent) const
764 {
765  Superclass::PrintSelf(os,indent);
766 
767  if ( m_GradientDirectionContainer )
768  {
769  os << indent << "GradientDirectionContainer: "
770  << m_GradientDirectionContainer << std::endl;
771  }
772  else
773  {
774  os << indent <<
775  "GradientDirectionContainer: (Gradient directions not set)" << std::endl;
776  }
777 }
778 
779 }
780 
781 #endif // __itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter_cpp
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
void f(const vnl_vector< double > &x, vnl_vector< double > &fx) override
static T max(T x, T y)
Definition: svm.cpp:70
Applies a total variation denoising filter to an image.
unsigned short PixelType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.