ANIMA  4.0
animaMCMFileWriter.hxx
Go to the documentation of this file.
1 #pragma once
2 #include "animaMCMFileWriter.h"
3 
4 #include <itkImageRegionIterator.h>
5 #include <itkFileTools.h>
7 
8 namespace anima
9 {
10 
11 template <class PixelType, unsigned int ImageDimension>
12 MCMFileWriter <PixelType, ImageDimension>
14 {
15  m_FileName = "";
16 }
17 
18 template <class PixelType, unsigned int ImageDimension>
20 ::~MCMFileWriter()
21 {
22 }
23 
24 template <class PixelType, unsigned int ImageDimension>
25 void
27 ::SetFileName(std::string fileName)
28 {
29  if (fileName.find('.') != std::string::npos)
30  fileName.erase(fileName.find_first_of('.'));
31  m_FileName = fileName;
32 }
33 
34 template <class PixelType, unsigned int ImageDimension>
35 void
37 ::Update()
38 {
39  if (m_FileName == "")
40  throw itk::ExceptionObject(__FILE__, __LINE__,"No filename specified for writing",ITK_LOCATION);
41 
42  if (!m_InputImage)
43  throw itk::ExceptionObject(__FILE__, __LINE__,"No input file to write",ITK_LOCATION);
44 
45  if (!m_InputImage->GetDescriptionModel())
46  throw itk::ExceptionObject(__FILE__, __LINE__,"No reference model provided for writing MCM file",ITK_LOCATION);
47 
48  std::replace(m_FileName.begin(),m_FileName.end(),'\\','/');
49  std::string noPathName = m_FileName;
50  std::size_t lastSlashPos = m_FileName.find_last_of("/");
51 
52  if (lastSlashPos != std::string::npos)
53  {
54  noPathName.clear();
55  noPathName.append(m_FileName.begin() + lastSlashPos + 1,m_FileName.end());
56  }
57 
58  itk::FileTools::CreateDirectory(m_FileName.c_str());
59  std::string headerName = m_FileName + ".mcm";
60  std::ofstream outputHeaderFile(headerName.c_str());
61  outputHeaderFile << "<?xml version=\"1.0\"?>" << std::endl;
62  outputHeaderFile << "<Model>" << std::endl;
63 
64  // Output weights image
65  ModelPointer descriptionModel = m_InputImage->GetDescriptionModel();
66 
67  unsigned int numberOfCompartments = descriptionModel->GetNumberOfCompartments();
68  BaseOutputImagePointer weightsImage = BaseOutputImageType::New();
69  weightsImage->Initialize();
70  weightsImage->SetRegions(m_InputImage->GetLargestPossibleRegion());
71  weightsImage->SetSpacing (m_InputImage->GetSpacing());
72  weightsImage->SetOrigin (m_InputImage->GetOrigin());
73  weightsImage->SetDirection (m_InputImage->GetDirection());
74  weightsImage->SetVectorLength(numberOfCompartments);
75  weightsImage->Allocate();
76 
77  typedef itk::ImageRegionIterator <InputImageType> InputImageIteratorType;
78  typedef itk::ImageRegionIterator <BaseOutputImageType> BaseOutputImageIteratorType;
79  typedef typename InputImageType::PixelType VectorType;
80 
81  BaseOutputImageIteratorType weightsItr(weightsImage,m_InputImage->GetLargestPossibleRegion());
82  InputImageIteratorType inputItr(m_InputImage,m_InputImage->GetLargestPossibleRegion());
83 
84  VectorType tmpWeights(numberOfCompartments);
85  VectorType workVector;
86  while (!weightsItr.IsAtEnd())
87  {
88  workVector = inputItr.Get();
89 
90  for (unsigned int i = 0;i < numberOfCompartments;++i)
91  tmpWeights[i] = workVector[i];
92 
93  weightsItr.Set(tmpWeights);
94 
95  ++weightsItr;
96  ++inputItr;
97  }
98 
99  std::string weightsName = m_FileName + "/";
100  weightsName += noPathName;
101  weightsName += "_weights.nrrd";
102 
103  anima::writeImage <BaseOutputImageType> (weightsName,weightsImage);
104  std::string xmlFileNameWeights = noPathName + "_weights.nrrd";
105 
106  outputHeaderFile << "<Weights>" << xmlFileNameWeights << "</Weights>" << std::endl;
107 
108  // Start index is after weights for image data
109  unsigned int pos = numberOfCompartments;
110 
111  for (unsigned int i = 0;i < descriptionModel->GetNumberOfCompartments();++i)
112  {
113  outputHeaderFile << "<Compartment>" << std::endl;
114  switch(descriptionModel->GetCompartment(i)->GetCompartmentType())
115  {
116  case Stick:
117  outputHeaderFile << "<Type>Stick</Type>" << std::endl;
118  break;
119 
120  case Zeppelin:
121  outputHeaderFile << "<Type>Zeppelin</Type>" << std::endl;
122  break;
123 
124  case Tensor:
125  outputHeaderFile << "<Type>Tensor</Type>" << std::endl;
126  break;
127 
128  case NODDI:
129  outputHeaderFile << "<Type>NODDI</Type>" << std::endl;
130  break;
131 
132  case DDI:
133  outputHeaderFile << "<Type>DDI</Type>" << std::endl;
134  break;
135 
136  case FreeWater:
137  outputHeaderFile << "<Type>FreeWater</Type>" << std::endl;
138  break;
139 
140  case StationaryWater:
141  outputHeaderFile << "<Type>StationaryWater</Type>" << std::endl;
142  break;
143 
144  case Stanisz:
145  outputHeaderFile << "<Type>Stanisz</Type>" << std::endl;
146  break;
147 
149  default:
150  outputHeaderFile << "<Type>IRWater</Type>" << std::endl;
151  break;
152  }
153 
154  // Output compartment image
155  unsigned int compartmentSize = descriptionModel->GetCompartment(i)->GetCompartmentSize();
156 
157  BaseOutputImagePointer compartmentImage = BaseOutputImageType::New();
158  compartmentImage->Initialize();
159  compartmentImage->SetRegions(m_InputImage->GetLargestPossibleRegion());
160  compartmentImage->SetSpacing (m_InputImage->GetSpacing());
161  compartmentImage->SetOrigin (m_InputImage->GetOrigin());
162  compartmentImage->SetDirection (m_InputImage->GetDirection());
163  compartmentImage->SetVectorLength(compartmentSize);
164  compartmentImage->Allocate();
165 
166  inputItr.GoToBegin();
167  BaseOutputImageIteratorType compartmentItr(compartmentImage,m_InputImage->GetLargestPossibleRegion());
168 
169  VectorType tmpCompartment(compartmentSize);
170  while (!compartmentItr.IsAtEnd())
171  {
172  workVector = inputItr.Get();
173 
174  for (unsigned int j = 0;j < compartmentSize;++j)
175  tmpCompartment[j] = workVector[pos + j];
176 
177  compartmentItr.Set(tmpCompartment);
178 
179  ++compartmentItr;
180  ++inputItr;
181  }
182 
183  pos += compartmentSize;
184 
185  std::string fullPathCompartmentName = m_FileName + "/";
186  std::string compartmentName = noPathName + "_";
187 
188  char tmpStr[2048];
189  sprintf(tmpStr,"%d",i);
190  compartmentName += tmpStr;
191  compartmentName += ".nrrd";
192 
193  fullPathCompartmentName += compartmentName;
194 
195  std::string xmlFileNameCompartment = compartmentName;
196 
197  anima::writeImage <BaseOutputImageType> (fullPathCompartmentName,compartmentImage);
198  outputHeaderFile << "<FileName>" << xmlFileNameCompartment << "</FileName>" << std::endl;
199 
200  outputHeaderFile << "</Compartment>" << std::endl;
201  }
202 
203  outputHeaderFile << "</Model>" << std::endl;
204  outputHeaderFile.close();
205 }
206 
207 } // end namespace anima
ModelType::Pointer ModelPointer
BaseOutputImageType::Pointer BaseOutputImagePointer