ANIMA  4.0
animaMultiCompartmentModelCreator.cxx
Go to the documentation of this file.
2 
11 
12 namespace anima
13 {
14 
16 {
17  m_CompartmentType = Tensor;
18  m_ModelWithFreeWaterComponent = false;
19  m_ModelWithStationaryWaterComponent = false;
20  m_ModelWithRestrictedWaterComponent = false;
21  m_ModelWithStaniszComponent = false;
22 
23  m_NumberOfCompartments = 1;
24  m_VariableProjectionEstimationMode = true;
25 
26  m_UseConstrainedDiffusivity = false;
27  m_UseConstrainedFreeWaterDiffusivity = true;
28  m_UseConstrainedIRWDiffusivity = true;
29  m_UseConstrainedStaniszDiffusivity = true;
30  m_UseConstrainedStaniszRadius = true;
31  m_UseConstrainedOrientationConcentration = false;
32  m_UseConstrainedExtraAxonalFraction = false;
33 
34  m_UseCommonDiffusivities = false;
35  m_UseCommonConcentrations = false;
36  m_UseCommonExtraAxonalFractions = false;
37 
38  m_AxialDiffusivity = 1.71e-3;
39  m_FreeWaterDiffusivity = 3.0e-3;
40  m_IRWDiffusivity = 7.5e-4;
41  m_StaniszDiffusivity = 1.71e-3;
42  m_RadialDiffusivity1 = 1.9e-4;
43  m_RadialDiffusivity2 = 1.5e-4;
44  m_ExtraAxonalFraction = 0.1;
45  m_OrientationConcentration = 10.0;
46 }
47 
49 {
50  MCMPointer outputMCM = MCMType::New();
51  outputMCM->SetOptimizeWeights(!m_VariableProjectionEstimationMode);
52  outputMCM->SetCommonDiffusivityParameters(m_UseCommonDiffusivities);
53  outputMCM->SetCommonConcentrationParameters(m_UseCommonConcentrations);
54  outputMCM->SetCommonExtraAxonalFractionParameters(m_UseCommonExtraAxonalFractions);
55 
56  double numCompartments = m_ModelWithFreeWaterComponent + m_ModelWithRestrictedWaterComponent +
57  m_ModelWithStaniszComponent + m_ModelWithStationaryWaterComponent + m_NumberOfCompartments;
58  double defaultWeight = 1.0 / numCompartments;
59 
60  if (m_ModelWithFreeWaterComponent)
61  {
62  typedef anima::FreeWaterCompartment FreeWaterType;
63  FreeWaterType::Pointer fwComp = FreeWaterType::New();
64  fwComp->SetEstimateAxialDiffusivity(!m_UseConstrainedFreeWaterDiffusivity);
65  fwComp->SetAxialDiffusivity(m_FreeWaterDiffusivity);
66 
67  outputMCM->AddCompartment(defaultWeight,fwComp);
68  }
69 
70  if (m_ModelWithStationaryWaterComponent)
71  {
72  typedef anima::StationaryWaterCompartment SWType;
73  SWType::Pointer swComp = SWType::New();
74 
75  outputMCM->AddCompartment(defaultWeight,swComp);
76  }
77 
78  if (m_ModelWithRestrictedWaterComponent)
79  {
81  IRWType::Pointer restComp = IRWType::New();
82  restComp->SetEstimateAxialDiffusivity(!m_UseConstrainedIRWDiffusivity);
83  restComp->SetAxialDiffusivity(m_IRWDiffusivity);
84 
85  outputMCM->AddCompartment(defaultWeight,restComp);
86  }
87 
88  if (m_ModelWithStaniszComponent)
89  {
90  typedef anima::StaniszCompartment StaniszType;
91  StaniszType::Pointer restComp = StaniszType::New();
92  restComp->SetEstimateAxialDiffusivity(!m_UseConstrainedStaniszDiffusivity);
93  restComp->SetEstimateTissueRadius(!m_UseConstrainedStaniszRadius);
94  restComp->SetAxialDiffusivity(m_StaniszDiffusivity);
95 
96  outputMCM->AddCompartment(defaultWeight,restComp);
97  }
98 
99  for (unsigned int i = 0;i < m_NumberOfCompartments;++i)
100  {
102  bool applyCommonConstraints = (i > 0);
103 
104  switch (m_CompartmentType)
105  {
106  case Stick:
107  this->CreateStickCompartment(tmpPointer,applyCommonConstraints);
108  break;
109 
110  case Zeppelin:
111  this->CreateZeppelinCompartment(tmpPointer,applyCommonConstraints);
112  break;
113 
114  case Tensor:
115  this->CreateTensorCompartment(tmpPointer,applyCommonConstraints);
116  break;
117 
118  case NODDI:
119  this->CreateNODDICompartment(tmpPointer,applyCommonConstraints);
120  break;
121 
122  case DDI:
123  this->CreateDDICompartment(tmpPointer,applyCommonConstraints);
124  break;
125 
126  default:
127  throw itk::ExceptionObject(__FILE__, __LINE__,"Creation of multiple free water compartment model not handled",ITK_LOCATION);
128  break;
129  }
130 
131  // Kind of ugly but required for optimization, otherwise initialization from simplified models may fail
132  tmpPointer->SetOrientationConcentration(m_OrientationConcentration);
133 
134  outputMCM->AddCompartment(defaultWeight,tmpPointer);
135  }
136 
137  return outputMCM;
138 }
139 
140 void MultiCompartmentModelCreator::CreateStickCompartment(BaseCompartmentPointer &compartmentPointer, bool applyConstraints)
141 {
142  typedef anima::StickCompartment StickType;
143 
144  StickType::Pointer stickComp = StickType::New();
145  stickComp->SetEstimateAxialDiffusivity(!m_UseConstrainedDiffusivity);
146 
147  stickComp->SetAxialDiffusivity(m_AxialDiffusivity);
148  stickComp->SetRadialDiffusivity1((m_RadialDiffusivity1 + m_RadialDiffusivity2) / 2.0);
149 
150  if (applyConstraints)
151  {
152  if (m_UseCommonDiffusivities)
153  stickComp->SetEstimateAxialDiffusivity(false);
154  }
155 
156  compartmentPointer = stickComp;
157 }
158 
159 void MultiCompartmentModelCreator::CreateZeppelinCompartment(BaseCompartmentPointer &compartmentPointer, bool applyConstraints)
160 {
161  typedef anima::ZeppelinCompartment ZeppelinType;
162 
163  ZeppelinType::Pointer zepComp = ZeppelinType::New();
164  zepComp->SetEstimateDiffusivities(!m_UseConstrainedDiffusivity);
165 
166  zepComp->SetAxialDiffusivity(m_AxialDiffusivity);
167  zepComp->SetRadialDiffusivity1((m_RadialDiffusivity1 + m_RadialDiffusivity2) / 2.0);
168 
169  if (applyConstraints)
170  {
171  if (m_UseCommonDiffusivities)
172  zepComp->SetEstimateDiffusivities(false);
173  }
174 
175  compartmentPointer = zepComp;
176 }
177 
178 void MultiCompartmentModelCreator::CreateTensorCompartment(BaseCompartmentPointer &compartmentPointer, bool applyConstraints)
179 {
180  typedef anima::TensorCompartment TensorType;
181 
182  TensorType::Pointer tensComp = TensorType::New();
183  tensComp->SetEstimateDiffusivities(!m_UseConstrainedDiffusivity);
184 
185  tensComp->SetAxialDiffusivity(m_AxialDiffusivity);
186  tensComp->SetRadialDiffusivity1(m_RadialDiffusivity1);
187  tensComp->SetRadialDiffusivity2(m_RadialDiffusivity2);
188 
189  if (applyConstraints)
190  {
191  if (m_UseCommonDiffusivities)
192  tensComp->SetEstimateDiffusivities(false);
193  }
194 
195  compartmentPointer = tensComp;
196 }
197 
198 void MultiCompartmentModelCreator::CreateNODDICompartment(BaseCompartmentPointer &compartmentPointer, bool applyConstraints)
199 {
200  typedef anima::NODDICompartment NODDIType;
201 
202  NODDIType::Pointer noddiComp = NODDIType::New();
203  noddiComp->SetEstimateAxialDiffusivity(!m_UseConstrainedDiffusivity);
204 
205  noddiComp->SetOrientationConcentration(m_OrientationConcentration);
206  noddiComp->SetExtraAxonalFraction(m_ExtraAxonalFraction);
207  noddiComp->SetAxialDiffusivity(m_AxialDiffusivity);
208 
209  if (applyConstraints)
210  {
211  if (m_UseCommonDiffusivities)
212  noddiComp->SetEstimateAxialDiffusivity(false);
213 
214  if (this->GetUseCommonConcentrations())
215  noddiComp->SetEstimateOrientationConcentration(false);
216 
218  noddiComp->SetEstimateExtraAxonalFraction(false);
219  }
220 
221  compartmentPointer = noddiComp;
222 }
223 
224 void MultiCompartmentModelCreator::CreateDDICompartment(BaseCompartmentPointer &compartmentPointer, bool applyConstraints)
225 {
226  std::string error("DDI model not implemented in the public version of ANIMA");
227  throw itk::ExceptionObject(__FILE__, __LINE__,error,ITK_LOCATION);
228 }
229 
230 } // end namespace anima
itk::SmartPointer< Self > Pointer