DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
itkSHCoefficientsPowerImageFilter.h
Go to the documentation of this file.
1 
12 #ifndef __itkSHCoefficientsPowerImageFilter_h
13 #define __itkSHCoefficientsPowerImageFilter_h
14 
15 #include "itkUnaryFunctorImageFilter.h"
16 #include <cmath>
17 
18 #include "utlNDArray.h"
19 #include "utl.h"
21 
22 
23 namespace itk
24 {
36 namespace Functor
37 {
38 template <class TInput, class TOutput>
40 {
41 public:
42 
45  typedef utl_shared_ptr<MatrixType> MatrixPointer;
46 
48  m_SHBasisMatrix(new MatrixType())
49  {
50  m_Power = 1.0;
51  m_SHRank = -1;
52  }
53 
55  {
56  }
57 
58  bool operator!=(const SHCoefficientsPower & other) const
59  {
60  return !( *this == other );
61  }
62 
63  bool operator==(const SHCoefficientsPower & other) const
64  {
65  return false;
66  }
67 
68  inline TOutput operator()(const TInput & shCoef)
69  {
70  if (utl::IsSame<double>(m_Power, 1))
71  return shCoef;
72  else if (utl::IsSame<double>(m_Power, 2))
73  {
74  int shInputDim = shCoef.GetSize();
75  int shOutputDim = utl::RankToDimSH( 2* utl::DimToRankSH(shInputDim) );
76 
77  TOutput out(shOutputDim);
78  out.Fill(0.0);
79  if (shCoef.GetSquaredNorm()>0)
80  {
81  unsigned index[3];
82  for ( int k = 0; k < shOutputDim; k += 1 )
83  {
84  index[2]=k;
85  for ( int i = 0; i < shInputDim; i += 1 )
86  {
87  index[1]=i;
88  for ( int j = 0; j < shInputDim; j += 1 )
89  {
90  index[0]=j;
91  out[k] += shCoef[i]*shCoef[j]* (*utl::SH3IntegralTable)(index);
92  }
93  }
94  }
95  }
96  return out;
97  }
98  else
99  {
100  int shOutputDim = utl::RankToDimSH( m_SHRank );
101  TOutput out(shOutputDim);
102  out.Fill(0.0);
103  if (shCoef.GetSquaredNorm()>0)
104  {
105  VectorType shInput(shCoef.GetSize());
106  shInput.SetData(const_cast<double* const>(shCoef.GetDataPointer()), shCoef.GetSize());
107  VectorType sf = (*m_SHBasisMatrix) * shInput;
108  utl::PowerVector(sf.Begin(), sf.End(), m_Power);
109  VectorType shOutput = *m_SHBasisMatrixInverse * sf;
110  utl::VectorToVector(shOutput, out, shOutput.Size());
111  }
112  return out;
113  }
114  }
115 
116  utlSetGetMacro(Power, double);
117  utlSetGetMacro(SHRank, int);
118  utlSetGetMacro(SHBasisMatrix, MatrixPointer);
119  utlSetGetMacro(SHBasisMatrixInverse, MatrixPointer);
120 
121 private:
122 
123  MatrixPointer m_SHBasisMatrix;
124  MatrixPointer m_SHBasisMatrixInverse;
125 
127  double m_Power;
128 
130  int m_SHRank;
131 };
132 }
133 
134 template <class TInputImage, class TOutputImage=itk::Image<double,3> >
136  public
137  UnaryFunctorImageFilter<TInputImage, TOutputImage,
138  Functor::SHCoefficientsPower<
139  typename TInputImage::PixelType,
140  typename TOutputImage::PixelType> >
141 {
142 public:
145  typedef UnaryFunctorImageFilter<
146  TInputImage, TOutputImage,
148  typename TInputImage::PixelType, typename TOutputImage::PixelType>
150 
151  typedef SmartPointer<Self> Pointer;
152  typedef SmartPointer<const Self> ConstPointer;
153 
155  itkNewMacro( Self );
156 
158  itkTypeMacro( SHCoefficientsPowerImageFilter, UnaryFunctorImageFilter );
159 
160  typedef Functor::SHCoefficientsPower< typename TInputImage::PixelType,
161  typename TOutputImage::PixelType> FunctorType;
162 
165 
166  itkFunctorSetGetMacro(Power, double);
167  itkFunctorSetGetMacro(SHRank, int);
168 
169 protected:
171  {
172  }
173 
175  {
176  }
177 
179  {
180  typename TInputImage::Pointer inputSH = const_cast<TInputImage *>(this->GetInput());
181  int shRank = utl::DimToRankSH(inputSH->GetNumberOfComponentsPerPixel());
182  if (utl::IsSame<double>(this->GetPower(), 2))
183  {
184  utl::InitializeSHTripleIntegrationTable(shRank, shRank, 2*shRank);
185  }
186  else if (!utl::IsSame<double>(this->GetPower(), 1))
187  {
188  utlGlobalException(this->GetSHRank()<=0, "need to set SHRank to fit the SH coefficients when power is not 1 or 2");
189  MatrixPointer grad(new MatrixType()), shMatrixInput(new MatrixType()), shMatrixOutput(new MatrixType()), shMatrixOutputInverse(new MatrixType());
190  grad = utl::ReadGrad<double>(4, DIRECTION_NODUPLICATE, CARTESIAN_TO_SPHERICAL);
191 
192  shMatrixInput = utl::ComputeSHMatrix(shRank, *grad, SPHERICAL_TO_SPHERICAL);
193  this->GetFunctor().SetSHBasisMatrix(shMatrixInput);
194 
195  shMatrixOutput = utl::ComputeSHMatrix(this->GetSHRank(), *grad, SPHERICAL_TO_SPHERICAL);
196  *shMatrixOutputInverse = utl::PInverseMatrix(*shMatrixOutput);
197  this->GetFunctor().SetSHBasisMatrixInverse(shMatrixOutputInverse);
198  }
199  }
200 
202  {
203  Superclass::GenerateOutputInformation();
204  typename TOutputImage::Pointer outputPtr = this->GetOutput();
205  typename TInputImage::Pointer inputSH = const_cast<TInputImage *>(this->GetInput());
206 
207  int numberOfComponentsPerPixel=0;
208  int dimInput = inputSH->GetNumberOfComponentsPerPixel();
209  if (this->GetPower()==1)
210  numberOfComponentsPerPixel = dimInput;
211  else if (this->GetPower()==2)
212  numberOfComponentsPerPixel = utl::RankToDimSH ( 2*utl::DimToRankSH(dimInput));
213  else
214  {
215  utlGlobalException(this->GetSHRank()<=0, "need to set shRank when power is not 1 or 2");
216  numberOfComponentsPerPixel = utl::RankToDimSH (this->GetSHRank() );
217  }
218  outputPtr->SetNumberOfComponentsPerPixel(numberOfComponentsPerPixel);
219  }
220 
221 
222 private:
223  SHCoefficientsPowerImageFilter(const Self &); // purposely not implemented
224  void operator=(const Self &); // purposely not implemented
225 };
226 } // end namespace itk
227 
228 
229 #endif
NDArray is a N-Dimensional array class (row-major, c version)
Definition: utlFunctors.h:131
Functor::SHCoefficientsPower< typename TInputImage::PixelType, typename TOutputImage::PixelType > FunctorType
bool operator==(const SHCoefficientsPower &other) const
void InitializeSHTripleIntegrationTable(const int rank0=-1, const int rank1=-1, const int rank2=-1, const bool useExactSize=false)
helper functions specifically used in dmritool
void VectorToVector(const T1 &v1, T2 &v2, const int N)
Definition: utlCore.h:1699
Iterator Begin()
Definition: utlNDArray.h:582
UnaryFunctorImageFilter< TInputImage, TOutputImage, Functor::SHCoefficientsPower< typename TInputImage::PixelType, typename TOutputImage::PixelType > > Superclass
int DimToRankSH(const int dimm)
Definition: utlDMRI.h:182
void PowerVector(IteratorType v1, IteratorType v2, const double poww)
Definition: utlCore.h:1619
#define ITK_OVERRIDE
Definition: utlITKMacro.h:46
std::shared_ptr< NDArray< T, 2 > > ComputeSHMatrix(const unsigned int rank, const NDArray< T, 2 > &grad, const int mode)
Definition: utl.h:171
#define itkFunctorSetGetMacro(name, type)
Definition: utlITKMacro.h:160
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
NDArray< T, 2 > PInverseMatrix(const NDArray< T, 2 > &mat, const double eps=1e-10)
int RankToDimSH(const int shRank)
Definition: utlDMRI.h:193
Iterator End()
Definition: utlNDArray.h:602
In each vxoel, the input VectorImage is a SH coefficient vector which represents a spherical function...
bool operator!=(const SHCoefficientsPower &other) const