11 if ((std::abs(smallDelta - m_CurrentSmallDelta) < 1.0e-6) &&
12 (std::abs(bigDelta - m_CurrentBigDelta)) &&
13 (std::abs(gradientStrength - m_CurrentGradientStrength) < 1.0e-6) &&
14 (!m_ModifiedParameters))
20 double alphaRs = alpha * tissueRadius;
21 double alphaRsSquare = alphaRs * alphaRs;
22 double deltaDiff = bigDelta - smallDelta / 3.0;
24 m_FirstSummation = 0.0;
25 m_SecondSummation = 0.0;
26 m_ThirdSummation = 0.0;
27 m_FourthSummation = 0.0;
28 for (
unsigned int n = 1;n <= m_MaximumNumberOfSumElements;++n)
30 double npiSquare = n * M_PI * n * M_PI;
31 double expInternalValue = npiSquare * deltaDiff * axialDiff / (tissueRadius * tissueRadius);
32 double denomValue = alphaRsSquare - npiSquare;
34 double internalTermCos = std::exp(- expInternalValue);
35 if (internalTermCos == 0)
38 double internalTermSin = internalTermCos;
42 internalTermCos *= 1.0 - std::cos(alphaRs);
43 internalTermSin *= std::sin(alphaRs);
47 internalTermCos *= 1.0 + std::cos(alphaRs);
48 internalTermSin *= - std::sin(alphaRs);
51 internalTermCos /= denomValue * denomValue;
52 internalTermSin /= denomValue * denomValue;
54 m_FirstSummation += internalTermCos;
55 m_SecondSummation += internalTermCos * n * n;
56 m_ThirdSummation += internalTermSin;
57 m_FourthSummation += internalTermCos / denomValue;
60 m_CurrentSmallDelta = smallDelta;
61 m_CurrentBigDelta = bigDelta;
62 m_CurrentGradientStrength = gradientStrength;
63 m_ModifiedParameters =
false;
72 double alphaRsSquare = alphaRs * alphaRs;
74 double signalValue = 4.0 * alphaRsSquare * m_FirstSummation;
77 signalValue += 1.0 - alphaRsSquare / 12.0;
79 signalValue += 2.0 * (1.0 - std::cos(alphaRs)) / alphaRsSquare;
93 double alphaRs = alpha * tissueRadius;
94 double alphaRsSquare = alphaRs * alphaRs;
95 double piSquare = M_PI * M_PI;
101 if (m_EstimateTissueRadius)
103 if (alphaRs < 1.0e-8)
106 m_JacobianVector[pos] = 2.0 * (alphaRs * std::sin(alphaRs) - 2.0 * (1.0 - std::cos(alphaRs))) / (alphaRsSquare * tissueRadius);
109 m_JacobianVector[pos] += 8.0 * piSquare * bValue * axialDiff * m_SecondSummation / tissueRadius;
111 m_JacobianVector[pos] -= 16.0 * alpha * alphaRs * alphaRsSquare * m_FourthSummation;
116 if (m_EstimateAxialDiffusivity)
128 double bValue = 1000.0;
134 double alphaRsSquare = alphaRs * alphaRs;
135 double signalValue = 4.0 * alphaRsSquare * m_FirstSummation;
137 if (alphaRs < 1.0e-8)
138 signalValue += 1.0 - alphaRsSquare / 12.0;
140 signalValue += 2.0 * (1.0 - std::cos(alphaRs)) / alphaRsSquare;
142 double equivalentGaussianDiffusivity = - std::log(signalValue) / bValue;
144 double resVal = - 1.5 * std::log(2.0 * M_PI * equivalentGaussianDiffusivity);
146 resVal -= sample.squared_magnitude() / (2.0 * equivalentGaussianDiffusivity);
155 m_ModifiedParameters =
true;
164 m_ModifiedParameters =
true;
174 unsigned int pos = 0;
175 if (m_EstimateTissueRadius)
181 if (m_EstimateAxialDiffusivity)
189 unsigned int pos = 0;
190 if (m_EstimateTissueRadius)
196 if (m_EstimateAxialDiffusivity)
206 unsigned int pos = 0;
207 if (m_EstimateTissueRadius)
213 if (m_EstimateAxialDiffusivity)
223 unsigned int pos = 0;
224 if (m_EstimateTissueRadius)
230 if (m_EstimateAxialDiffusivity)
238 if (m_EstimateAxialDiffusivity == arg)
241 m_EstimateAxialDiffusivity = arg;
242 m_ChangedConstraints =
true;
247 if (m_EstimateTissueRadius == arg)
250 m_EstimateTissueRadius = arg;
251 m_ChangedConstraints =
true;
257 itkExceptionMacro(
"The input vector size does not match the size of the compartment");
262 m_ModifiedParameters =
false;
272 if (!m_ChangedConstraints)
273 return m_NumberOfParameters;
275 m_NumberOfParameters = 2;
277 if (!m_EstimateTissueRadius)
278 --m_NumberOfParameters;
280 if (!m_EstimateAxialDiffusivity)
281 --m_NumberOfParameters;
283 m_ChangedConstraints =
false;
284 return m_NumberOfParameters;
virtual ListType & GetParametersAsVector() ITK_OVERRIDE
double GetGradientStrengthFromBValue(double bValue, double smallDelta, double bigDelta)
Given b-value in s/mm^2 and deltas in s, computes gradient strength in T/mm.
ModelOutputVectorType & GetCompartmentVector() ITK_OVERRIDE
Get compartment overall description vector, mainly for writing, should be self-contained.
unsigned int GetNumberOfParameters() ITK_OVERRIDE
Number of optimized parameters: smaller than total number of parameters.
std::vector< double > ListType
virtual void SetAxialDiffusivity(double num)
ListType m_ParametersLowerBoundsVector
Vector holding current parameters lower bounds.
virtual ListType & GetSignalAttenuationJacobian(double smallDelta, double bigDelta, double gradientStrength, const Vector3DType &gradient) ITK_OVERRIDE
virtual void SetTissueRadius(double num)
virtual ListType & GetParameterLowerBounds() ITK_OVERRIDE
void SetAxialDiffusivity(double num) ITK_OVERRIDE
void UpdateSignals(double smallDelta, double bigDelta, double gradientStrength)
void SetEstimateAxialDiffusivity(bool arg)
virtual double GetAxialDiffusivity()
virtual double GetLogDiffusionProfile(const Vector3DType &sample) ITK_OVERRIDE
ListType m_ParametersVector
Vector holding current parameters vector.
const double DiffusionBigDelta
Default big delta value (classical values)
double GetBValueFromAcquisitionParameters(double smallDelta, double bigDelta, double gradientStrength)
Given gyromagnetic ratio in rad/s/T, gradient strength in T/mm and deltas in s, computes b-value in s...
void SetEstimateTissueRadius(bool arg)
const double DiffusionSmallDelta
Default small delta value (classical values)
const double MCMTissueRadiusUpperBound
Tissue radius upper bound (in Stanisz for now)
double GetApparentFractionalAnisotropy() ITK_OVERRIDE
Superclass::ModelOutputVectorType ModelOutputVectorType
void SetTissueRadius(double num) ITK_OVERRIDE
unsigned int GetCompartmentSize() ITK_OVERRIDE
Number of parameters to describe the model, these parameters will be self-contained, i.e. include fixed parameters for example.
const double DiffusionGyromagneticRatio
Gyromagnetic ratio (in rad/s/T), from Nelson, J., Nuclear Magnetic Resonance Spectroscopy, Prentice Hall, Londres, 2003.
Superclass::Vector3DType Vector3DType
ListType m_ParametersUpperBoundsVector
Vector holding current parameters upper bounds.
void SetCompartmentVector(ModelOutputVectorType &compartmentVector) ITK_OVERRIDE
Set compartment overall description vector, for setting automatically the individual parameters when ...
ListType m_JacobianVector
Vector holding current jacobian value.
virtual ListType & GetParameterUpperBounds() ITK_OVERRIDE
const double MCMDiffusivityUpperBound
Diffusivity upper bound.
const double MCMTissueRadiusLowerBound
Tissue radius lower bound (in Stanisz for now)
const double MCMDiffusivityLowerBound
Diffusivity lower bound for estimation.
virtual double GetTissueRadius()
virtual double GetFourierTransformedDiffusionProfile(double smallDelta, double bigDelta, double gradientStrength, const Vector3DType &gradient) ITK_OVERRIDE
ModelOutputVectorType m_CompartmentVector
Vector to hold working value of compartment vector.
virtual void SetParametersFromVector(const ListType ¶ms) ITK_OVERRIDE
Various methods for optimization parameters setting and getting.