ANIMA  4.0
animaStimulatedSpinEchoImageFilter.hxx
Go to the documentation of this file.
1 #pragma once
3 
4 #include <itkImageRegionIterator.h>
5 #include <itkImageRegionConstIterator.h>
6 
8 
9 namespace anima
10 {
11 
12 template <class TImage, class TOutputImage>
13 void
14 StimulatedSpinEchoImageFilter <TImage,TOutputImage>
15 ::GenerateOutputInformation()
16 {
17  this->Superclass::GenerateOutputInformation();
18 
19  OutputImageType *output = this->GetOutput();
20  output->SetVectorLength(m_NumberOfEchoes);
21 }
22 
23 template <class TImage, class TOutputImage>
26 {
27  this->SetNumberOfRequiredInputs(3);
28 
29  m_NumberOfEchoes = 1;
30  m_EchoSpacing = 10;
31  m_ExcitationFlipAngle = M_PI / 2.0;
32  m_FlipAngle = M_PI;
33 }
34 
35 template <class TImage, class TOutputImage>
37 ::SetInputT1(const TImage* T1)
38 {
39  SetInput(0, const_cast<TImage*>(T1));
40 }
41 
42 template <class TImage, class TOutputImage>
44 ::SetInputT2(const TImage* T2)
45 {
46  SetInput(1, const_cast<TImage*>(T2));
47 }
48 
49 template <class TImage, class TOutputImage>
51 ::SetInputM0(const TImage* M0)
52 {
53  SetInput(2, const_cast<TImage*>(M0));
54 }
55 
56 template <class TImage, class TOutputImage>
58 ::SetInputB1(const TImage* B1)
59 {
60  this->SetInput(3, const_cast<TImage*>(B1));
61 }
62 
63 template <class TImage, class TOutputImage>
66 ::GetOutputAs4DImage()
67 {
68  OutputImageType* outPtr = this->GetOutput();
69  unsigned int ndim = outPtr->GetNumberOfComponentsPerPixel();
70 
71  typename Image4DType::RegionType region4d;
72  typename TImage::RegionType region3d = outPtr->GetLargestPossibleRegion();
73  typename Image4DType::SizeType size4d;
74  typename Image4DType::SpacingType spacing4d;
75  typename Image4DType::PointType origin4d;
76  typename Image4DType::DirectionType direction4d;
77 
78  region4d.SetIndex(3,0);
79  region4d.SetSize(3,ndim);
80  size4d[3] = ndim;
81  spacing4d[3] = 1;
82  origin4d[3] = 0;
83  direction4d(3,3) = 1;
84 
85  for (unsigned int i = 0;i < 3;++i)
86  {
87  region4d.SetIndex(i,region3d.GetIndex()[i]);
88  region4d.SetSize(i,region3d.GetSize()[i]);
89 
90  size4d[i] = region3d.GetSize()[i];
91  spacing4d[i] = outPtr->GetSpacing()[i];
92  origin4d[i] = outPtr->GetOrigin()[i];
93  for (unsigned int j = 0;j < 3;++j)
94  direction4d(i,j) = (outPtr->GetDirection())(i,j);
95 
96  direction4d(i,3) = 0;
97  direction4d(3,i) = 0;
98  }
99 
100  m_Output4D = Image4DType::New();
101  m_Output4D->Initialize();
102  m_Output4D->SetRegions(region4d);
103  m_Output4D->SetSpacing (spacing4d);
104  m_Output4D->SetOrigin (origin4d);
105  m_Output4D->SetDirection (direction4d);
106  m_Output4D->Allocate();
107 
108  typedef itk::ImageRegionConstIterator <OutputImageType> OutImageIteratorType;
109  typedef itk::ImageRegionIterator <Image4DType> Image4DIteratorType;
110 
111  for (unsigned int i = 0;i < ndim;++i)
112  {
113  region4d.SetIndex(3,i);
114  region4d.SetSize(3,1);
115 
116  OutImageIteratorType outItr(outPtr,region3d);
117  Image4DIteratorType fillItr(m_Output4D,region4d);
118 
119  while (!fillItr.IsAtEnd())
120  {
121  fillItr.Set(outItr.Get()[i]);
122  ++fillItr;
123  ++outItr;
124  }
125  }
126 
127  return m_Output4D;
128 }
129 
130 template <class TImage, class TOutputImage>
132 ::DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread)
133 {
134  typename TImage::ConstPointer T1 = this->GetInput(0);
135  typename TImage::ConstPointer T2 = this->GetInput(1);
136  typename TImage::ConstPointer M0 = this->GetInput(2);
137  typename TImage::ConstPointer B1;
138 
139  itk::ImageRegionIterator <TOutputImage> outputIterator(this->GetOutput(), outputRegionForThread);
140  itk::ImageRegionConstIterator <TImage> inputIteratorT1(T1, outputRegionForThread);
141  itk::ImageRegionConstIterator <TImage> inputIteratorT2(T2, outputRegionForThread);
142  itk::ImageRegionConstIterator <TImage> inputIteratorM0(M0, outputRegionForThread);
143 
144  itk::ImageRegionConstIterator <TImage> inputIteratorB1;
145  bool b1DataPresent = (this->GetNumberOfIndexedInputs() == 4);
146  if (b1DataPresent)
147  {
148  B1 = this->GetInput(3);
149  inputIteratorB1 = itk::ImageRegionConstIterator <TImage> (B1, outputRegionForThread);
150  }
151 
152  typedef typename TOutputImage::PixelType VectorType;
153  VectorType outputVector(m_NumberOfEchoes);
154 
155  anima::EPGSignalSimulator t2SignalSimulator;
156  t2SignalSimulator.SetNumberOfEchoes(m_NumberOfEchoes);
157  t2SignalSimulator.SetEchoSpacing(m_EchoSpacing);
158  t2SignalSimulator.SetExcitationFlipAngle(m_ExcitationFlipAngle);
159 
161 
162  // For each voxel, calculate the signal of SP-GRE
163  while(!outputIterator.IsAtEnd())
164  {
165  outputVector.Fill(0);
166  if ((inputIteratorT1.Get() <= 0) || ( inputIteratorT2.Get() <= 0))
167  {
168  outputIterator.Set(outputVector);
169 
170  ++inputIteratorT1;
171  ++inputIteratorT2;
172  ++inputIteratorM0;
173  if (b1DataPresent)
174  ++inputIteratorB1;
175 
176  ++outputIterator;
177  continue;
178  }
179 
180  double b1Value = 1;
181  if (b1DataPresent)
182  b1Value = inputIteratorB1.Get();
183 
184  double t1Value = inputIteratorT1.Get();
185  double t2Value = inputIteratorT2.Get();
186  double m0Value = inputIteratorM0.Get();
187 
188  tmpOutputVector = t2SignalSimulator.GetValue(t1Value,t2Value,b1Value * m_FlipAngle,m0Value);
189 
190  for (unsigned int i = 0;i < m_NumberOfEchoes;++i)
191  outputVector[i] = tmpOutputVector[i];
192 
193  outputIterator.Set(outputVector);
194 
195  ++inputIteratorT1;
196  ++inputIteratorT2;
197  ++inputIteratorM0;
198  if (b1DataPresent)
199  ++inputIteratorB1;
200 
201  ++outputIterator;
202  }
203 }
204 
205 }// end of namespace anima
itk::Image< typename TImage::PixelType, 4 > Image4DType
std::vector< double > RealVectorType
Superclass::OutputImageRegionType OutputImageRegionType
RealVectorType & GetValue(double t1Value, double t2Value, double flipAngle, double m0Value)
Get EPG values at given point.
void SetNumberOfEchoes(unsigned int val)