ANIMA  4.0
animaMCMFileReader.hxx
Go to the documentation of this file.
1 #pragma once
2 #include "animaMCMFileReader.h"
3 
5 
10 #include <animaStickCompartment.h>
12 #include <animaTensorCompartment.h>
13 #include <animaNODDICompartment.h>
14 
15 #include <itkImageRegionIterator.h>
16 #include <tinyxml2.h>
17 
18 namespace anima
19 {
20 
21 template <class PixelType, unsigned int ImageDimension>
22 MCMFileReader <PixelType, ImageDimension>
24 {
25  m_FileName = "";
26 }
27 
28 template <class PixelType, unsigned int ImageDimension>
30 ::~MCMFileReader()
31 {
32 }
33 
34 template <class PixelType, unsigned int ImageDimension>
35 void
37 ::Update()
38 {
39  tinyxml2::XMLDocument doc;
40  tinyxml2::XMLError loadOk = doc.LoadFile(m_FileName.c_str());
41 
42  std::replace(m_FileName.begin(),m_FileName.end(),'\\','/');
43  std::string basePath, baseName;
44  std::size_t lastSlashPos = m_FileName.find_last_of("/");
45 
46  if (lastSlashPos != std::string::npos)
47  {
48  basePath.append(m_FileName.begin(),m_FileName.begin() + lastSlashPos);
49  ++lastSlashPos;
50  }
51  else
52  lastSlashPos = 0;
53 
54  if (basePath.length() != 0)
55  basePath = basePath + "/";
56 
57  std::size_t lastDotPos = m_FileName.find_last_of(".");
58  baseName.append(m_FileName.begin() + lastSlashPos, m_FileName.begin() + lastDotPos);
59 
60  if (loadOk != tinyxml2::XML_SUCCESS)
61  {
62  std::string error("Unable to read input summary file: ");
63  error += m_FileName;
64  throw itk::ExceptionObject(__FILE__, __LINE__,error,ITK_LOCATION);
65  }
66 
67  // Read XML file into transform information vector
68  tinyxml2::XMLElement *modelNode = doc.FirstChildElement( "Model" );
69  if (!modelNode)
70  {
71  std::string error("Model node missing in ");
72  error += m_FileName;
73  throw itk::ExceptionObject(__FILE__, __LINE__,error,ITK_LOCATION);
74  }
75 
76  tinyxml2::XMLElement *weightsNode = modelNode->FirstChildElement( "Weights" );
77 
78  if (!weightsNode)
79  {
80  std::string error("Weights file missing in ");
81  error += m_FileName;
82  throw itk::ExceptionObject(__FILE__, __LINE__,error,ITK_LOCATION);
83  }
84 
85  std::string weightsFileName = basePath + baseName + "/";
86  weightsFileName += weightsNode->GetText();
87 
88  BaseInputImagePointer weightsImage = anima::readImage <BaseInputImageType>(weightsFileName);
89  unsigned int numCompartments = weightsImage->GetVectorLength();
90 
91  tinyxml2::XMLElement *compartmentNode = modelNode->FirstChildElement( "Compartment" );
92  ModelPointer referenceModel = ModelType::New();
93 
94  std::vector <BaseInputImagePointer> compartmentImages;
95  while (compartmentNode)
96  {
97  tinyxml2::XMLElement *typeNode = compartmentNode->FirstChildElement("Type");
98  std::string compartmentType = typeNode->GetText();
99 
100  anima::BaseCompartment::Pointer additionalCompartment = this->CreateCompartmentForType(compartmentType);
101 
102  referenceModel->AddCompartment(1.0 / numCompartments,additionalCompartment);
103 
104  tinyxml2::XMLElement *fileNameNode = compartmentNode->FirstChildElement("FileName");
105  std::string imageFileName = basePath + baseName + "/";
106  imageFileName += fileNameNode->GetText();
107 
108  compartmentImages.push_back(anima::readImage <BaseInputImageType> (imageFileName));
109 
110  compartmentNode = compartmentNode->NextSiblingElement("Compartment");
111  }
112 
113  unsigned int vectorFinalSize = referenceModel->GetSize();
114  m_OutputImage = OutputImageType::New();
115  m_OutputImage->Initialize();
116  m_OutputImage->CopyInformation(compartmentImages[0]);
117  m_OutputImage->SetRegions(compartmentImages[0]->GetLargestPossibleRegion());
118  m_OutputImage->SetNumberOfComponentsPerPixel(vectorFinalSize);
119  m_OutputImage->Allocate();
120  m_OutputImage->SetDescriptionModel(referenceModel);
121 
122  typedef itk::ImageRegionIterator <BaseInputImageType> InputImageIteratorType;
123  typedef itk::ImageRegionIterator <OutputImageType> OutputImageIteratorType;
124 
125  std::vector <InputImageIteratorType> inputIterators(numCompartments);
126  for (unsigned int i = 0;i < numCompartments;++i)
127  inputIterators[i] = InputImageIteratorType(compartmentImages[i],m_OutputImage->GetLargestPossibleRegion());
128 
129  InputImageIteratorType weightsIterator(weightsImage,m_OutputImage->GetLargestPossibleRegion());
130  OutputImageIteratorType outItr(m_OutputImage,m_OutputImage->GetLargestPossibleRegion());
131 
132  typedef typename OutputImageType::PixelType ImagePixelType;
133  ImagePixelType outValue(vectorFinalSize);
134  ImagePixelType weightsData(vectorFinalSize);
135 
136  ImagePixelType inputCompartmentValue;
137  ModelType::ModelOutputVectorType inputMCMValue;
138  ModelType::ListType weightsVector(numCompartments);
139 
140  while (!outItr.IsAtEnd())
141  {
142  weightsData = weightsIterator.Get();
143  for (unsigned int i = 0;i < numCompartments;++i)
144  weightsVector[i] = weightsData[i];
145 
146  referenceModel->SetCompartmentWeights(weightsVector);
147 
148  for (unsigned int i = 0;i < numCompartments;++i)
149  {
150  inputCompartmentValue = inputIterators[i].Get();
151  unsigned int compartmentSize = inputCompartmentValue.GetSize();
152 
153  if (inputMCMValue.GetSize() != compartmentSize)
154  inputMCMValue.SetSize(compartmentSize);
155  for (unsigned int j = 0;j < compartmentSize;++j)
156  inputMCMValue[j] = inputCompartmentValue[j];
157 
158  referenceModel->GetCompartment(i)->SetCompartmentVector(inputMCMValue);
159  }
160 
161  outValue = referenceModel->GetModelVector();
162  outItr.Set(outValue);
163 
164  ++outItr;
165  ++weightsIterator;
166  for (unsigned int i = 0;i < numCompartments;++i)
167  ++inputIterators[i];
168  }
169 }
170 
171 template <class PixelType, unsigned int ImageDimension>
174 ::CreateCompartmentForType(std::string &compartmentType)
175 {
176  anima::BaseCompartment::Pointer additionalCompartment;
177 
178  if (compartmentType == "FreeWater")
179  additionalCompartment = anima::FreeWaterCompartment::New();
180  else if (compartmentType == "StationaryWater")
181  additionalCompartment = anima::StationaryWaterCompartment::New();
182  else if (compartmentType == "IRWater")
183  additionalCompartment = anima::IsotropicRestrictedWaterCompartment::New();
184  else if (compartmentType == "Stanisz")
185  additionalCompartment = anima::StaniszCompartment::New();
186  else if (compartmentType == "Stick")
187  additionalCompartment = anima::StickCompartment::New();
188  else if (compartmentType == "Zeppelin")
189  additionalCompartment = anima::ZeppelinCompartment::New();
190  else if (compartmentType == "Tensor")
191  additionalCompartment = anima::TensorCompartment::New();
192  else if (compartmentType == "NODDI")
193  additionalCompartment = anima::NODDICompartment::New();
194  else
195  {
196  std::string error("Unsupported compartment type: ");
197  error += compartmentType;
198  throw itk::ExceptionObject(__FILE__, __LINE__,error,ITK_LOCATION);
199  }
200 
201  return additionalCompartment;
202 }
203 
204 } // end namespace anima
static Pointer New()
static Pointer New()
BaseCompartment::ListType ListType
itk::SmartPointer< Self > Pointer
static Pointer New()
static Pointer New()
BaseInputImageType::Pointer BaseInputImagePointer
BaseCompartment::ModelOutputVectorType ModelOutputVectorType
ModelType::Pointer ModelPointer