DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
itkSphericalHarmonicsGenerator.h
Go to the documentation of this file.
1 
18 #ifndef __itkSphericalHarmonicsGenerator_h
19 #define __itkSphericalHarmonicsGenerator_h
20 
21 #include <complex>
22 #include <itkObject.h>
23 #include <itkObjectFactory.h>
24 
25 #include "utlDMRIStoredTables.h"
26 
27 
28 namespace itk
29 {
30 
53 template<class PreciseType = double>
54 class ITK_EXPORT SphericalHarmonicsGenerator : public Object
55 {
56 public:
59  typedef Object Superclass;
60  typedef SmartPointer<Self> Pointer;
61  typedef SmartPointer<const Self> ConstPointer;
62 
64  itkNewMacro(Self);
65 
67  itkTypeMacro(SphericalHarmonicsGenerator, Object);
68 
70  static std::complex<PreciseType> ComplexSH(const int l, const int m, const PreciseType theta, const PreciseType phi);
72  static PreciseType RealSH(const int l, const int m, const PreciseType theta, const PreciseType phi);
73 
75  static PreciseType ComplexTripleIntegration(const int l1, const int m1, const int l2, const int m2, const int l3, const int m3);
77  static PreciseType RealTripleIntegration(const int l1, const int m1, const int l2, const int m2, const int l3, const int m3, const bool is_precalculated=true);
78 
80  static std::complex<double> ComplexDerivativeOfTheta ( const int l, const int m, const double theta, const double phi);
82  static std::complex<double> ComplexDerivativeOfPhi ( const int l, const int m, const double theta, const double phi);
83 
85  static double RealDerivativeOfTheta ( const int l, const int m, const double theta, const double phi);
87  static double RealDerivativeOfPhi ( const int l, const int m, const double theta, const double phi);
88 
89 protected:
91  virtual ~SphericalHarmonicsGenerator();
92 
93  void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE;
94 
95 private :
96  SphericalHarmonicsGenerator(const Self&); //purposely not implemented
97  void operator=(const Self&); //purposely not implemented
98 
99 };
100 
101 
102 }
103 
104 namespace utl
105 {
110 inline void
111 InitializeSHTripleIntegrationTable(const int rank0=-1, const int rank1=-1, const int rank2=-1, const bool useExactSize=false)
112 {
113  int dim[3];
114  dim[0]=rank0>0? utl::RankToDimSH(rank0) : 0;
115  dim[1]=rank1>0? utl::RankToDimSH(rank1) : 0;
116  dim[2]=rank2>0? utl::RankToDimSH(rank2) : 0;
117 
118  const unsigned* shapeOld = SH3IntegralTable->GetShape();
119 
120  // no useExactSize, SH3IntegralTable is larger than what is requested
121  if (!useExactSize && SH3IntegralTable->Size()>0 && dim[0]<=shapeOld[0] && dim[1]<=shapeOld[1] && dim[2]<=shapeOld[2])
122  return;
123 
124  // SH3IntegralTable is the same as what is requested
125  if (SH3IntegralTable->Size()>0 && dim[0]==shapeOld[0] && dim[1]==shapeOld[1] && dim[2]==shapeOld[2])
126  return;
127 
128  typedef itk::Image<double,3> ImageType;
129  static ImageType::Pointer image = ImageType::New();
130  if (itk::IsImageEmpty(image))
131  itk::ReadImage<ImageType>(utl::SH3Itegralhdr, image);
132  ImageType::RegionType region = image->GetLargestPossibleRegion();
133  ImageType::SizeType size = region.GetSize();
134  ImageType::IndexType pixelIndex;
135 
136  unsigned shape[3];
137  for ( int i = 0; i < 3; ++i )
138  shape[i] = useExactSize? dim[i] : utl::max<int>(dim[i], size[i]);
139 
140  if (SH3IntegralTable->Size()==0
141  || useExactSize
142  || (!useExactSize && SH3IntegralTable->Size()>0 && (dim[0]>SH3IntegralTable->GetShape()[0] || dim[1]>SH3IntegralTable->GetShape()[1] || dim[2]>SH3IntegralTable->GetShape()[2])) )
143  {
144  SH3IntegralTable->ReSize(shape);
145 
146  unsigned index[3];
147  for ( int i = 0; i < shape[0]; ++i )
148  for ( int j = 0; j < shape[1]; ++j )
149  for ( int k = 0; k < shape[2]; ++k )
150  {
151  index[0]=i, index[1]=j, index[2]=k;
152  if (i<size[0] && j<size[1] && k<size[2] )
153  {
154  pixelIndex[0]=i, pixelIndex[1]=j, pixelIndex[2]=k;
155  (*SH3IntegralTable)(index) = image->GetPixel(pixelIndex);
156  }
157  else
158  {
159  std::vector<int> v1, v2, v3;
160  v1 = utl::GetIndexSHlm(i);
161  v2 = utl::GetIndexSHlm(j);
162  v3 = utl::GetIndexSHlm(k);
163  (*SH3IntegralTable)(index) = itk::SphericalHarmonicsGenerator<double>::RealTripleIntegration(v1[0],v1[1],v2[0],v2[1],v3[0],v3[1],false);
164  }
165  }
166  }
167 }
168 
169 }
170 
171 // Define instantiation macro for this template.
172 #define ITK_TEMPLATE_SphericalHarmonicsGenerator(_, EXPORT, x, y) namespace itk { \
173  _(2(class EXPORT SphericalHarmonicsGenerator< ITK_TEMPLATE_2 x >)) \
174  namespace Templates { typedef SphericalHarmonicsGenerator< ITK_TEMPLATE_2 x > SphericalHarmonicsGenerator##y; } \
175  }
176 
177 #if ITK_TEMPLATE_EXPLICIT
178 # include "Templates/itkSphericalHarmonicsGenerator+-.h"
179 #endif
180 
181 #if !defined(ITK_MANUAL_INSTANTIATION) && !defined(__itkSphericalHarmonicsGenerator_hxx)
183 #endif
184 
185 #endif
Created "11-12-2015.
void InitializeSHTripleIntegrationTable(const int rank0=-1, const int rank1=-1, const int rank2=-1, const bool useExactSize=false)
static std::shared_ptr< NDArray< double, 3 > > SH3IntegralTable(new NDArray< double, 3 >)
bool IsImageEmpty(const SmartPointer< ImageType > &image)
Definition: utlITK.h:435
std::vector< int > GetIndexSHlm(const int j)
Definition: utlDMRI.h:211
#define ITK_OVERRIDE
Definition: utlITKMacro.h:46
Definition: utl.h:90
Generate complex and real Spherical Harmonic Basis.
static const std::string SH3Itegralhdr
int RankToDimSH(const int shRank)
Definition: utlDMRI.h:193