ANIMA  4.0
animaDWISimulatorFromDTIImageFilter.hxx
Go to the documentation of this file.
1 #pragma once
3 
4 #include <itkImageRegionIterator.h>
5 #include <itkImageRegionIteratorWithIndex.h>
6 #include <itkImageRegionConstIterator.h>
7 
8 namespace anima
9 {
10 
11 template <class PixelScalarType>
12 void
14 ::AddGradientDirection(unsigned int i, std::vector <double> &grad)
15 {
16  if (i == m_GradientDirections.size())
17  m_GradientDirections.push_back(grad);
18  else if (i > m_GradientDirections.size())
19  std::cerr << "Trying to add a direction not contiguous... Add directions contiguously (0,1,2,3,...)..." << std::endl;
20  else
21  m_GradientDirections[i] = grad;
22 }
23 
24 template <class PixelScalarType>
25 void
28 {
29  // Override the method in itkImageSource, so we can set the vector length of
30  // the output itk::VectorImage
31 
32  this->Superclass::GenerateOutputInformation();
33 
34  OutputImageType *output = this->GetOutput();
35  output->SetVectorLength(m_GradientDirections.size());
36 }
37 
38 template <class PixelScalarType>
39 void
42 {
43  if (this->GetInput()->GetNumberOfComponentsPerPixel() != m_NumberOfComponents)
44  throw itk::ExceptionObject(__FILE__, __LINE__,"Input image should have 6 dimensions...",ITK_LOCATION);
45 
46  Superclass::BeforeThreadedGenerateData();
47 
48  if (!m_S0Image)
49  {
50  m_S0Image = S0ImageType::New();
51  m_S0Image->Initialize();
52  m_S0Image->SetRegions(this->GetInput()->GetLargestPossibleRegion());
53  m_S0Image->SetSpacing (this->GetInput()->GetSpacing());
54  m_S0Image->SetOrigin (this->GetInput()->GetOrigin());
55  m_S0Image->SetDirection (this->GetInput()->GetDirection());
56  m_S0Image->Allocate();
57 
58  m_S0Image->FillBuffer(m_S0Value);
59  }
60 }
61 
62 template <class PixelScalarType>
63 void
66 {
67  typedef itk::ImageRegionConstIterator <InputImageType> ImageIteratorType;
68 
69  ImageIteratorType inIterator(this->GetInput(),outputRegionForThread);
70 
71  typedef itk::ImageRegionIterator <OutputImageType> OutImageIteratorType;
72  OutImageIteratorType outIterator(this->GetOutput(),outputRegionForThread);
73 
74  typedef itk::ImageRegionIterator <S0ImageType> S0ImageIteratorType;
75  S0ImageIteratorType s0Iterator(m_S0Image,outputRegionForThread);
76 
77  typedef typename OutputImageType::PixelType OutputPixelType;
78 
79  unsigned int outputSize = m_GradientDirections.size();
80  InputPixelType inVecTens(m_NumberOfComponents);
81  OutputPixelType resVec(outputSize);
82 
83  while (!outIterator.IsAtEnd())
84  {
85  for (unsigned int i = 0;i < outputSize;++i)
86  resVec[i] = 0;
87 
88  inVecTens = inIterator.Get();
89  if (this->isZero(inVecTens))
90  {
91  outIterator.Set(resVec);
92 
93  ++inIterator;
94  ++outIterator;
95  ++s0Iterator;
96  continue;
97  }
98 
99  for (unsigned int i = 0;i < outputSize;++i)
100  {
101  unsigned int pos = 0;
102  for (unsigned int j = 0;j < 3;++j)
103  for (unsigned int k = 0;k <= j;++k)
104  {
105  if (j != k)
106  resVec[i] += 2.0 * m_GradientDirections[i][j] * m_GradientDirections[i][k] * inVecTens[pos];
107  else
108  resVec[i] += m_GradientDirections[i][j] * m_GradientDirections[i][j] * inVecTens[pos];
109 
110  ++pos;
111  }
112 
113  resVec[i] *= - m_BValuesList[i];
114  resVec[i] = s0Iterator.Get() * std::exp(resVec[i]);
115  }
116 
117  outIterator.Set(resVec);
118 
119  ++inIterator;
120  ++outIterator;
121  ++s0Iterator;
122  }
123 }
124 
125 template <class PixelScalarType>
126 bool
129 {
130  unsigned int sizeVec = vec.GetSize();
131 
132  for (unsigned int i = 0;i < sizeVec;++i)
133  {
134  if (vec[i] != 0)
135  return false;
136  }
137 
138  return true;
139 }
140 
141 template <class PixelScalarType>
145 {
146  this->Update();
147 
148  typename OutputImageType::Pointer outPtr = this->GetOutput();
149  unsigned int ndim = outPtr->GetNumberOfComponentsPerPixel();
150 
151  typename Image4DType::RegionType region4d;
152  typename InputImageType::RegionType region3d = outPtr->GetLargestPossibleRegion();
153  typename Image4DType::SizeType size4d;
154  typename Image4DType::SpacingType spacing4d;
155  typename Image4DType::PointType origin4d;
156  typename Image4DType::DirectionType direction4d;
157 
158  region4d.SetIndex(3,0);
159  region4d.SetSize(3,ndim);
160  size4d[3] = ndim;
161  spacing4d[3] = 1;
162  origin4d[3] = 0;
163  direction4d(3,3) = 1;
164 
165  for (unsigned int i = 0;i < 3;++i)
166  {
167  region4d.SetIndex(i,region3d.GetIndex()[i]);
168  region4d.SetSize(i,region3d.GetSize()[i]);
169 
170  size4d[i] = region3d.GetSize()[i];
171  spacing4d[i] = outPtr->GetSpacing()[i];
172  origin4d[i] = outPtr->GetOrigin()[i];
173  for (unsigned int j = 0;j < 3;++j)
174  direction4d(i,j) = (outPtr->GetDirection())(i,j);
175 
176  direction4d(i,3) = 0;
177  direction4d(3,i) = 0;
178  }
179 
180  m_Output4D = Image4DType::New();
181  m_Output4D->Initialize();
182  m_Output4D->SetRegions(region4d);
183  m_Output4D->SetSpacing (spacing4d);
184  m_Output4D->SetOrigin (origin4d);
185  m_Output4D->SetDirection (direction4d);
186  m_Output4D->Allocate();
187 
188  typedef itk::ImageRegionConstIterator <OutputImageType> OutImageIteratorType;
189  typedef itk::ImageRegionIterator <Image4DType> Image4DIteratorType;
190 
191  for (unsigned int i = 0;i < ndim;++i)
192  {
193  region4d.SetIndex(3,i);
194  region4d.SetSize(3,1);
195 
196  OutImageIteratorType outItr(outPtr,region3d);
197  Image4DIteratorType fillItr(m_Output4D,region4d);
198 
199  while (!fillItr.IsAtEnd())
200  {
201  fillItr.Set(outItr.Get()[i]);
202  ++fillItr;
203  ++outItr;
204  }
205  }
206 
207  return m_Output4D;
208 }
209 
210 } // end namespace anima
Superclass::OutputImageRegionType OutputImageRegionType
void AddGradientDirection(unsigned int i, std::vector< double > &grad)
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) ITK_OVERRIDE