9 m_OptimizeWeights =
true;
10 m_CommonDiffusivityParameters =
false;
11 m_CommonConcentrationParameters =
false;
12 m_CommonExtraAxonalFractionParameters =
false;
13 m_NegativeWeightBounds =
false;
15 m_NumberOfIsotropicCompartments = 0;
24 itk::LightObject::Pointer outputValue = Superclass::InternalClone();
26 Self *mcm = dynamic_cast <
Self *> (outputValue.GetPointer());
27 for (
unsigned int i = 0;i < m_Compartments.size();++i)
45 for (pos = m_Compartments.size();pos > 0;--pos)
47 if (m_Compartments[pos - 1]->GetCompartmentType() <= compartment->
GetCompartmentType())
51 m_Compartments.insert(m_Compartments.begin() + pos, compartment);
52 m_CompartmentWeights.insert(m_CompartmentWeights.begin() + pos, weight);
58 ++m_NumberOfIsotropicCompartments;
66 return m_Compartments[i];
71 unsigned int vectorSize = 0;
72 for (
unsigned int i = 0;i < m_Compartments.size();++i)
77 vectorSize += numWeightsToOptimize;
79 m_ParametersVector.resize(vectorSize);
84 for (
unsigned int i = 0;i < numWeightsToOptimize;++i)
85 m_ParametersVector[i] = m_CompartmentWeights[i];
87 pos += numWeightsToOptimize;
89 for (
unsigned int i = 0;i < m_Compartments.size();++i)
91 m_WorkVector = m_Compartments[i]->GetParametersAsVector();
93 for (
unsigned int j = 0;j < m_WorkVector.size();++j)
94 m_ParametersVector[pos + j] = m_WorkVector[j];
96 pos += m_WorkVector.size();
99 return m_ParametersVector;
104 if (i >= m_CompartmentWeights.size())
105 itkExceptionMacro(
"Trying to access an unreferenced weight index");
107 return m_CompartmentWeights[i];
112 if (weights.size() != m_CompartmentWeights.size())
113 itkExceptionMacro(
"Compartment weights sizes differ in set");
115 for (
unsigned int i = 0;i < weights.size();++i)
116 m_CompartmentWeights[i] = weights[i];
121 unsigned int pos = 0;
126 for (
unsigned int i = 0;i < numWeightsToOptimize;++i)
127 m_CompartmentWeights[i] = params[i];
129 pos = numWeightsToOptimize;
131 for (
unsigned int i = 0;i < numCompartments;++i)
133 unsigned int tmpCompartmentSize = m_Compartments[i]->GetNumberOfParameters();
136 m_WorkVector.resize(tmpCompartmentSize);
137 std::copy(params.begin() + pos,params.begin() + pos + tmpCompartmentSize,m_WorkVector.begin());
139 m_Compartments[i]->SetParametersFromVector(m_WorkVector);
141 if (i > m_NumberOfIsotropicCompartments)
143 if (m_CommonDiffusivityParameters)
145 m_Compartments[i]->SetAxialDiffusivity(m_Compartments[m_NumberOfIsotropicCompartments]->GetAxialDiffusivity());
146 m_Compartments[i]->SetRadialDiffusivity1(m_Compartments[m_NumberOfIsotropicCompartments]->GetRadialDiffusivity1());
147 m_Compartments[i]->SetRadialDiffusivity2(m_Compartments[m_NumberOfIsotropicCompartments]->GetRadialDiffusivity2());
150 if (m_CommonConcentrationParameters)
151 m_Compartments[i]->SetOrientationConcentration(m_Compartments[m_NumberOfIsotropicCompartments]->GetOrientationConcentration());
153 if (m_CommonExtraAxonalFractionParameters)
154 m_Compartments[i]->SetExtraAxonalFraction(m_Compartments[m_NumberOfIsotropicCompartments]->GetExtraAxonalFraction());
157 pos += tmpCompartmentSize;
163 if (m_ModelVector.GetSize() != this->
GetSize())
164 m_ModelVector.SetSize(this->GetSize());
165 m_ModelVector.Fill(0.0);
169 for (
unsigned int i = 0;i < numCompartments;++i)
170 m_ModelVector[i] = m_CompartmentWeights[i];
172 unsigned int pos = numCompartments;
175 for (
unsigned int i = 0;i < numCompartments;++i)
177 if (m_CompartmentWeights[i] != 0.0)
179 tmpParams = m_Compartments[i]->GetCompartmentVector();
180 for (
unsigned int j = 0;j < m_Compartments[i]->GetCompartmentSize();++j)
181 m_ModelVector[pos + j] = tmpParams[j];
184 pos += m_Compartments[i]->GetCompartmentSize();
187 return m_ModelVector;
194 for (
unsigned int i = 0;i < numCompartments;++i)
195 m_CompartmentWeights[i] = mcmVec[i];
197 unsigned int pos = numCompartments;
199 for (
unsigned int i = 0;i < numCompartments;++i)
201 unsigned int compartmentSize = m_Compartments[i]->GetCompartmentSize();
203 for (
unsigned int j = 0;j < compartmentSize;++j)
204 inputVector[j] = mcmVec[pos + j];
206 m_Compartments[i]->SetCompartmentVector(inputVector);
207 pos += compartmentSize;
215 for (
unsigned int i = 0;i < numCompartments;++i)
216 m_CompartmentWeights[i] = mcmVec[i];
218 unsigned int pos = numCompartments;
220 for (
unsigned int i = 0;i < numCompartments;++i)
222 unsigned int compartmentSize = m_Compartments[i]->GetCompartmentSize();
224 for (
unsigned int j = 0;j < compartmentSize;++j)
225 inputVector[j] = mcmVec[pos + j];
227 m_Compartments[i]->SetCompartmentVector(inputVector);
228 pos += compartmentSize;
234 double ftDiffusionProfile = 0;
236 for (
unsigned int i = 0;i < m_Compartments.size();++i)
238 if (m_CompartmentWeights[i] != 0.0)
239 ftDiffusionProfile += m_CompartmentWeights[i] * m_Compartments[i]->GetFourierTransformedDiffusionProfile(smallDelta, bigDelta, gradientStrength, gradient);
242 return ftDiffusionProfile;
247 unsigned int jacobianSize = 0;
248 for (
unsigned int i = 0;i < m_Compartments.size();++i)
252 jacobianSize += numWeightsToOptimize;
254 m_JacobianVector.resize(jacobianSize);
255 std::fill(m_JacobianVector.begin(), m_JacobianVector.end(), 0.0);
257 unsigned int pos = 0;
260 for (
unsigned int i = 0;i < numWeightsToOptimize;++i)
261 m_JacobianVector[i] = - m_Compartments[i]->GetFourierTransformedDiffusionProfile(smallDelta, bigDelta, gradientStrength, gradient);
263 pos += numWeightsToOptimize;
265 for (
unsigned int i = 0;i < m_Compartments.size();++i)
267 m_WorkVector = m_Compartments[i]->GetSignalAttenuationJacobian(smallDelta, bigDelta, gradientStrength, gradient);
269 for (
unsigned int j = 0;j < m_WorkVector.size();++j)
270 m_JacobianVector[pos + j] -= m_CompartmentWeights[i] * m_WorkVector[j];
272 pos += m_WorkVector.size();
275 return m_JacobianVector;
282 for (
unsigned int i = 0;i < m_Compartments.size();++i)
284 if (m_CompartmentWeights[i] != 0.0)
285 resVal += m_CompartmentWeights[i] * std::exp(m_Compartments[i]->GetLogDiffusionProfile(sample));
293 unsigned int vectorSize = 0;
294 for (
unsigned int i = 0;i < m_Compartments.size();++i)
298 vectorSize += numWeightsToOptimize;
300 m_ParametersLowerBoundsVector.resize(vectorSize);
302 unsigned int pos = 0;
304 if (!m_NegativeWeightBounds)
306 for (
unsigned int i = 0;i < numWeightsToOptimize;++i)
311 for (
unsigned int i = 0;i < numWeightsToOptimize;++i)
315 pos += numWeightsToOptimize;
317 for (
unsigned int i = 0;i < m_Compartments.size();++i)
319 m_WorkVector = m_Compartments[i]->GetParameterLowerBounds();
320 for (
unsigned int j = 0;j < m_WorkVector.size();++j)
321 m_ParametersLowerBoundsVector[pos + j] = m_WorkVector[j];
323 pos += m_WorkVector.size();
326 return m_ParametersLowerBoundsVector;
331 unsigned int vectorSize = 0;
332 for (
unsigned int i = 0;i < m_Compartments.size();++i)
337 vectorSize += numWeightsToOptimize;
338 m_ParametersUpperBoundsVector.resize(vectorSize);
340 unsigned int pos = 0;
342 if (!m_NegativeWeightBounds)
344 for (
unsigned int i = 0;i < numWeightsToOptimize;++i)
349 for (
unsigned int i = 0;i < numWeightsToOptimize;++i)
353 pos += numWeightsToOptimize;
355 for (
unsigned int i = 0;i < m_Compartments.size();++i)
357 m_WorkVector = m_Compartments[i]->GetParameterUpperBounds();
358 for (
unsigned int j = 0;j < m_WorkVector.size();++j)
359 m_ParametersUpperBoundsVector[pos + j] = m_WorkVector[j];
361 pos += m_WorkVector.size();
364 return m_ParametersUpperBoundsVector;
369 int numWeightsToOptimize = 0;
370 if (m_OptimizeWeights)
371 numWeightsToOptimize = m_Compartments.size();
373 return numWeightsToOptimize;
378 unsigned int numParams = 0;
380 for (
unsigned int i = 0;i < m_Compartments.size();++i)
391 unsigned int numParams = m_Compartments.size();
394 for (
unsigned int i = 0;i < m_Compartments.size();++i)
395 numParams += m_Compartments[i]->GetCompartmentSize();
402 for (
unsigned int i = 0;i < m_Compartments.size();++i)
403 m_Compartments[i]->
Reorient(orientationMatrix,affineTransform);
double GetCompartmentWeight(unsigned int i)
BaseCompartment::Pointer BaseCompartmentPointer
const double MCMZeroLowerBound
Default zero lower bound (in case we want something else than zero one day)
BaseCompartment * GetCompartment(unsigned int i)
void SetCommonExtraAxonalFractionParameters(bool val)
unsigned int GetNumberOfCompartments()
ListType & GetSignalJacobian(double smallDelta, double bigDelta, double gradientStrength, const Vector3DType &gradient)
unsigned int GetNumberOfParameters()
Number of parameters to be optimized.
double GetDiffusionProfile(Vector3DType &sample)
void SetCompartmentWeights(const ListType &weights)
void SetParametersFromVector(ListType ¶ms)
BaseCompartment::ListType ListType
const double MCMFractionUpperBound
Fraction upper bound (intra/extra axonal)
unsigned int GetNumberOfOptimizedWeights()
Number of weights that are optimized.
itk::LightObject::Pointer InternalClone() const ITK_OVERRIDE
void SetCommonDiffusivityParameters(bool val)
void SetOptimizeWeights(bool val)
DiffusionModelCompartmentType
void SetModelVector(const itk::VariableLengthVector< float > &mcmVec)
const double MCMCompartmentsFractionUpperBound
Compartment fractions upper bound (B0 times weight)
BaseCompartment::Vector3DType Vector3DType
ListType & GetParametersAsVector()
virtual DiffusionModelCompartmentType GetCompartmentType()=0
Utility function to return compartment type without needing dynamic casts.
MultiCompartmentModel: holds several diffusion compartments, ordered by type It also handles weights ...
void SetCommonConcentrationParameters(bool val)
void AddCompartment(double weight, BaseCompartment *compartment)
ModelOutputVectorType & GetModelVector()
double GetPredictedSignal(double smallDelta, double bigDelta, double gradientStrength, const Vector3DType &gradient)
ListType & GetParameterUpperBounds()
ListType & GetParameterLowerBounds()
void Reorient(vnl_matrix< double > &orientationMatrix, bool affineTransform)
Re-orient the MCM using the provided transform, the flag precises if the transform id rigid or affine...
BaseCompartment::ModelOutputVectorType ModelOutputVectorType
unsigned int GetSize()
Number of parameters to have a self-contained description of the MCM.