ANIMA  4.0
animaGradientFileReader.hxx
Go to the documentation of this file.
1 #pragma once
2 
4 
5 #include <fstream>
6 #include <sstream>
7 #include <cstdlib>
8 #include <itkMacro.h>
9 
10 #include <animaVectorOperations.h>
11 #include <animaMCMConstants.h>
12 
13 namespace anima
14 {
15 
16 template <class GradientType, class BValueScalarType>
19 {
20  m_GradientFileName = "";
21  m_BValueBaseString = "";
22 
23  m_B0ValueThreshold = 0;
24  m_TotalNumberOfDirections = 0;
25 
26  m_SmallDelta = anima::DiffusionSmallDelta;
27  m_BigDelta = anima::DiffusionBigDelta;
28 
29  m_GradientIndependentNormalization = true;
30  m_Modified = false;
31 }
32 
33 template <class GradientType, class BValueScalarType>
34 std::vector <bool>
37 {
38  if (m_Modified)
39  this->Update();
40 
41  std::vector <bool> resVal(m_TotalNumberOfDirections,false);
42 
43  for (unsigned int i = 0;i < m_TotalNumberOfDirections;++i)
44  {
45  if (m_BValues[i] <= m_B0ValueThreshold)
46  resVal[i] = true;
47  }
48 
49  return resVal;
50 }
51 
52 template <class GradientType, class BValueScalarType>
56 {
57  if (m_Modified)
58  this->Update();
59 
60  return m_Gradients;
61 }
62 
63 template <class GradientType, class BValueScalarType>
67 {
68  if (m_Modified)
69  this->Update();
70 
71  return m_BValues;
72 }
73 
74 template <class GradientType, class BValueScalarType>
78 {
79  if (m_Modified)
80  this->Update();
81 
82  return m_GradientStrengths;
83 }
84 
85 template <class GradientType, class BValueScalarType>
86 unsigned int
89 {
90  if (m_Modified)
91  this->Update();
92 
93  return m_TotalNumberOfDirections;
94 }
95 
96 template <class GradientType, class BValueScalarType>
97 void
100 {
101  if (!m_Modified)
102  return;
103 
104  int startIndex = m_GradientFileName.size() - 6;
105  if (startIndex < 0)
106  startIndex = 0;
107 
108  std::string testExt = m_GradientFileName.substr(startIndex);
109  if (testExt.find("bvec") != std::string::npos)
110  this->ReadGradientsFromBVecFile();
111  else
112  this->ReadGradientsFromTextFile();
113 
114  if (m_BValueBaseString != "")
115  {
116  this->ReadBValues();
117 
118  // Normalize gradient directions
119  for (unsigned int i = 0;i < m_TotalNumberOfDirections;++i)
120  {
121  if ((m_BValues[i] <= m_B0ValueThreshold)||(anima::ComputeNorm(m_Gradients[i]) == 0))
122  {
123  m_BValues[i] = 0;
124 
125  for (unsigned int j = 0;j < 3;++j)
126  m_Gradients[i][j] = 0;
127 
128  continue;
129  }
130 
131  double norm = 1;
132  if (!m_GradientIndependentNormalization)
133  norm = anima::ComputeNorm(m_Gradients[i]);
134 
135  anima::Normalize(m_Gradients[i],m_Gradients[i]);
136 
137  if (!m_GradientIndependentNormalization)
138  m_BValues[i] *= norm;
139  }
140 
141  // Finally get gradient strengths from bvalues and small/big delta
142 
143  m_GradientStrengths.resize(m_TotalNumberOfDirections);
144  for (unsigned int i = 0;i < m_TotalNumberOfDirections;++i)
145  m_GradientStrengths[i] = anima::GetGradientStrengthFromBValue(m_BValues[i], m_SmallDelta, m_BigDelta);
146  }
147 
148  m_Modified = false;
149 }
150 
151 template <class GradientType, class BValueScalarType>
152 void
155 {
156  std::ifstream gradFile(m_GradientFileName.c_str());
157  m_TotalNumberOfDirections = 0;
158 
159  if (!gradFile.is_open())
160  throw itk::ExceptionObject(__FILE__, __LINE__,"Could not open gradient file as a bvec file",ITK_LOCATION);
161 
162  m_Gradients.clear();
163  std::vector < std::vector <double> > trVecs(3);
164 
165  for (unsigned int i = 0;i < 3;++i)
166  {
167  if (gradFile.eof())
168  {
169  gradFile.close();
170  throw itk::ExceptionObject(__FILE__, __LINE__,"BVec file is missing data",ITK_LOCATION);
171  }
172 
173  std::string workStr;
174  do {
175  std::getline(gradFile,workStr);
176  } while((workStr == "")&&(!gradFile.eof()));
177 
178  workStr.erase(workStr.find_last_not_of(" \n\r\t")+1);
179 
180  std::istringstream iss(workStr);
181  std::string shortStr;
182  do
183  {
184  iss >> shortStr;
185  trVecs[i].push_back(std::stod(shortStr));
186  }
187  while (!iss.eof());
188  }
189 
190  m_TotalNumberOfDirections = trVecs[0].size();
191 
192  m_Gradients.resize(m_TotalNumberOfDirections);
193  for (unsigned int i = 0;i < m_TotalNumberOfDirections;++i)
194  {
195  this->InitializeEmptyGradient(m_Gradients[i]);
196  for (unsigned int j = 0;j < 3;++j)
197  m_Gradients[i][j] = trVecs[j][i];
198  }
199 
200  gradFile.close();
201 }
202 
203 template <class GradientType, class BValueScalarType>
204 void
207 {
208  std::ifstream gradFile(m_GradientFileName.c_str());
209  m_TotalNumberOfDirections = 0;
210 
211  if (!gradFile.is_open())
212  {
213  throw itk::ExceptionObject(__FILE__, __LINE__,"Could not open gradient file as a text file",ITK_LOCATION);
214  }
215 
216  GradientType gradTmp;
217  this->InitializeEmptyGradient(gradTmp);
218  m_Gradients.clear();
219 
220  while (!gradFile.eof())
221  {
222  char tmpStr[2048];
223  gradFile.getline(tmpStr,2048);
224 
225  if (strcmp(tmpStr,"") == 0)
226  continue;
227 
228  double a0, a1, a2;
229  std::stringstream tmpStrStream(tmpStr);
230  tmpStrStream >> a0 >> a1 >> a2;
231 
232  gradTmp[0] = a0;
233  gradTmp[1] = a1;
234  gradTmp[2] = a2;
235 
236  m_Gradients.push_back(gradTmp);
237  }
238 
239  m_TotalNumberOfDirections = m_Gradients.size();
240 
241  gradFile.close();
242 }
243 
244 template <class GradientType, class BValueScalarType>
245 void
247 ReadBValues()
248 {
249  m_BValues.resize(m_TotalNumberOfDirections);
250 
251  std::ifstream bvalFile(m_BValueBaseString.c_str());
252 
253  if (!bvalFile.is_open())
254  {
255  for (unsigned int i = 0;i < m_TotalNumberOfDirections;++i)
256  m_BValues[i] = std::stod(m_BValueBaseString);
257 
258  return;
259  }
260 
261  int startIndex = m_BValueBaseString.size() - 6;
262  if (startIndex < 0)
263  startIndex = 0;
264 
265  std::string testExt = m_BValueBaseString.substr(startIndex);
266  if (testExt.find("bval") != testExt.size())
267  {
268  std::string workStr;
269  do {
270  std::getline(bvalFile,workStr);
271  } while((workStr == "")&&(!bvalFile.eof()));
272 
273  workStr.erase(workStr.find_last_not_of(" \n\r\t")+1);
274 
275  std::istringstream iss(workStr);
276  std::string shortStr;
277  unsigned int i = 0;
278  do
279  {
280  iss >> shortStr;
281  m_BValues[i] = std::stod(shortStr);
282  ++i;
283  }
284  while (!iss.eof());
285  }
286  else // text file
287  {
288  unsigned int i = 0;
289  while (!bvalFile.eof())
290  {
291  char tmpStr[2048];
292  bvalFile.getline(tmpStr,2048);
293 
294  if (strcmp(tmpStr,"") == 0)
295  continue;
296 
297  m_BValues[i] = std::stod(tmpStr);
298  ++i;
299  }
300  }
301 
302  bvalFile.close();
303 }
304 
305 } // end namespace anima
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.
std::vector< BValueScalarType > BValueVectorType
double ComputeNorm(const VectorType &v)
std::vector< bool > GetB0Directions()
const double DiffusionBigDelta
Default big delta value (classical values)
GradientVectorType & GetGradients()
const double DiffusionSmallDelta
Default small delta value (classical values)
std::vector< GradientType > GradientVectorType
BValueVectorType & GetGradientStrengths()
void Normalize(const VectorType &v, const unsigned int NDimension, VectorType &resVec)