DMRITool  v0.1.1-139-g860d86b4
Diffusion MRI Tool
itkCylinderModelGenerator.hxx
Go to the documentation of this file.
1 
18 #ifndef __itkCylinderModelGenerator_hxx
19 #define __itkCylinderModelGenerator_hxx
20 
23 
24 namespace itk
25 {
26 
27 template <class PreciseType>
30 {
31  m_Length = 5.0;
32  m_Radius = 0.005;
33  m_D0 = 2.02e-3;
34  // m_DeltaBig = 0.0208;
35  // m_DeltaSmall = 0.0024;
36 
37  m_CylinderAxis[0]=0;
38  m_CylinderAxis[1]=0;
39  m_CylinderAxis[2]=1.0;
40 
41  m_LUTExp = LUTExpType::New();
42  m_LUTExp->SetVariableMax(0);
43  m_LUTExp->SetVariableMin(-30);
44  m_LUTExp->SetNumberOfBins(30*1e3);
45  // m_LUTExp->BuildLUT();
46 }
47 
48 template <class PreciseType>
49 typename LightObject::Pointer
52 {
53  typename LightObject::Pointer loPtr = Superclass::InternalClone();
54 
55  typename Self::Pointer rval = dynamic_cast<Self *>(loPtr.GetPointer());
56  if(rval.IsNull())
57  {
58  itkExceptionMacro(<< "downcast to type " << this->GetNameOfClass()<< " failed.");
59  }
60 
61  rval->m_Length = m_Length;
62  rval->m_Radius = m_Radius;
63  rval->m_D0 = m_D0;
64  rval->m_CylinderAxis = m_CylinderAxis;
65  rval->m_LUTExp = m_LUTExp->Clone();
66 
67  return loPtr;
68 }
69 
70 template <class PreciseType>
71 void
74 {
75  m_LUTExp->BuildTable();
76 }
77 
78 template <class PreciseType>
79 void
81 ::PrintSelf(std::ostream& os, Indent indent) const
82 {
83  Superclass::PrintSelf(os, indent);
84  PrintVar3(true, m_Length, m_Radius, m_D0, os<<indent);
85  os << indent << "m_CylinderAxis = " << m_CylinderAxis << std::endl;
86 }
87 
88 // template <class PreciseType>
89 // void
90 // CylinderModelGenerator<PreciseType>
91 // ::VerifyInputParameters() const
92 // {
93 // }
94 
95 template <class PreciseType>
96 void
98 ::Rotate(const MatrixType& mat)
99 {
100  VectorType axis = m_CylinderAxis.GetVnlVector();
101  axis = mat*axis;
102  for ( int i = 0; i < 3; i += 1 )
103  m_CylinderAxis[i] = axis[i];
104 }
105 
106 template <class PreciseType>
107 void
110 {
111  utlShowPosition(this->GetDebug());
112  this->VerifyInputParameters();
113  utlGlobalException(this->m_SamplingSchemeQSpace->GetNumberOfSamples()==0, "need to set m_SamplingSchemeQSpace");
114  utlGlobalException(!m_LUTExp->IsTableBuilt(), "need to build m_LUTExp first");
115 
116  const int nMax = 1000, mMax = 10, kMax = 10;
117  int N = this->m_SamplingSchemeQSpace->GetNumberOfSamples();
118  STDVectorPointer qVector = this->m_SamplingSchemeQSpace->GetRadiusVector();
119 
120  double deltaBig = this->m_SamplingSchemeQSpace->GetDeltaBig();
121  double d0DeltaBig = m_D0*deltaBig;
122  double radius2 = m_Radius*m_Radius;
123 
124  std::vector<double> nPiLength2(nMax+1);
125  std::vector<double> nPiLength2D0Delta(nMax+1);
126  for ( int n = 0; n <= nMax; n += 1 )
127  {
128  nPiLength2[n] = std::pow(n*M_PI/m_Length,2);
129  nPiLength2D0Delta[n] = d0DeltaBig *nPiLength2[n];
130  }
131 
132  this->m_DWISamples = VectorPointer(new VectorType(N));
133 
134  // m_LUTExp->Print(std::cout<<"lut = ");
135 
136 
137  int i=0;
138 #pragma omp parallel for private (i)
139  for(i=0; i < N; i++)
140  {
141 
142  PointType sample = (*this->m_SamplingSchemeQSpace)[i];
143  double dott = sample[0]*m_CylinderAxis[0] + sample[1]*m_CylinderAxis[1] + sample[2]*m_CylinderAxis[2];
144  double angle = std::acos( dott>=1?1:(dott<=-1?-1:dott) );
145  if (angle>M_PI/2) // only in [0,90]
146  angle = M_PI - angle;
147  if (M_PI/2-angle<1.0e-5) // NOTE: 0 and 90 is a sigular point
148  angle = M_PI/2 - 1.0e-5;
149  if (angle<1e-5)
150  angle = 1e-5;
151  double angle2sin = std::sin(2*angle);
152 
153  double signal_temp=0;
154  double qq = (*qVector)[i];
155  double pi2qcos = 2.0*M_PI*qq*std::cos(angle);
156  double pi2qsin = 2.0*M_PI*qq*std::sin(angle);
157  double pi2qsinRadius = pi2qsin*m_Radius;
158  double pi2qcosLengthcos = std::cos(pi2qcos*m_Length);
159  double first_temp = 2.0*std::pow(m_Radius,2) *std::pow(2*M_PI*qq,4)*angle2sin*angle2sin / (m_Length*m_Length);
160  MatrixType third_temp(mMax+1, nMax+1);
161  for ( int n = 0; n <= nMax; n += 1 )
162  {
163  double num2 = (n%2 ? (1+pi2qcosLengthcos) : (1-pi2qcosLengthcos));
164  double tmp1 = std::pow( nPiLength2[n] - std::pow(pi2qcos,2), 2 );
165  for ( int m = 0; m <= mMax; m += 1 )
166  {
167  // utlPrintVar2(true, m, n);
168  double K_mn = m>0? (n>0?4:2) : (n>0?2:1);
169  third_temp(m,n) = num2 *K_mn / tmp1;
170  }
171  }
172 
173  std::vector<double> besselJnVec(mMax+2);
174  for ( int m = 0; m <= mMax; m += 1 )
175  besselJnVec[m] = gsl_sf_bessel_Jn(m,pi2qsinRadius);
176 
177  for ( int m = 0; m <=mMax; m += 1 )
178  {
179  double J_m_d = m/(pi2qsinRadius)*besselJnVec[m] - besselJnVec[m+1];
180  double J_m_d2 = J_m_d*J_m_d;
181  for ( int k = 1; k <=kMax; k += 1 )
182  {
183  double gamma_km = utl::BesselJPrimeZerosTable[kMax*m+k-1];
184  double gamma_km2 = gamma_km * gamma_km;
185  // utlPrintVar4(true, m,k, gamma_km, J_m_d2);
186  double gamma_km_Radius2_D0Delta = gamma_km2/radius2 * d0DeltaBig;
187  double second_temp = J_m_d2 / std::pow(gamma_km2-std::pow(pi2qsinRadius,2) ,2) ;
188  if (m!=0)
189  second_temp *= gamma_km2 / (gamma_km2-m*m);
190  for ( int n = 0; n <=nMax; n += 1 )
191  {
192  // double fourth_temp = std::exp(- (gamma_km_Radius2_D0Delta+nPiLength2D0Delta[n]) );
193  // double fourth_temp = utl::ExpNegtiveLUT(gamma_km_Radius2_D0Delta + nPiLength2D0Delta[n], 30.0, 1e3);
194  double fourth_temp = m_LUTExp->GetFunctionValue( - (gamma_km_Radius2_D0Delta+nPiLength2D0Delta[n]));
195  // double val = (gamma_km_Radius2_D0Delta+nPiLength2D0Delta[n]);
196  // utlPrintVar3(true, val, utl::ExpNegtiveLUT(val, 30.0, 1e3), m_LUTExp->GetFunctionValue(-val));
197  signal_temp += first_temp*second_temp*third_temp(m,n)*fourth_temp;
198  }
199  }
200  }
201  (*this->m_DWISamples)[i] = signal_temp;
202  if (this->GetDebug())
203  {
204  std::cout << "i = " << i << std::endl << std::flush;
205  std::cout << "sample = " << sample << std::endl << std::flush;
206  std::cout << "qq = " << qq << std::endl << std::flush;
207  std::cout << "signal_temp = " << signal_temp << std::endl << std::flush;
208  }
209  }
210 }
211 
212 template <class PreciseType>
213 void
216 {
217  this->VerifyInputParameters();
218  utlGlobalException(this->m_SamplingSchemeRSpace->GetNumberOfSamples()==0, "need to set m_SamplingSchemeRSpace");
219 
220 }
221 
222 template <class PreciseType>
223 void
226 {
227  this->VerifyInputParameters();
228  utlGlobalException(this->m_SamplingSchemeRSpace->GetNumberOfSamples()==0, "need to set m_SamplingSchemeRSpace");
229 }
230 
231 }
232 
233 #endif
234 
235 
236 
LightObject::Pointer InternalClone() const
generate ground truth DWI/EAP/ODF ets from a given model
Superclass::STDVectorPointer STDVectorPointer
#define M_PI
Definition: utlCoreMacro.h:57
static const double BesselJPrimeZerosTable[]
Definition: utlMath.h:37
#define utlGlobalException(cond, expout)
Definition: utlCoreMacro.h:372
Superclass::VectorPointer VectorPointer
void PrintSelf(std::ostream &os, Indent indent) const
#define PrintVar3(cond, var1, var2, var3, os)
Definition: utlCoreMacro.h:462
#define utlShowPosition(cond)
Definition: utlCoreMacro.h:554
void Rotate(const MatrixType &mat)