OTB  9.0.0
Orfeo Toolbox
otbStatisticsXMLFileReader.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbStatisticsXMLFileReader_hxx
22 #define otbStatisticsXMLFileReader_hxx
23 
25 #include "itkMacro.h"
26 #include "itksys/SystemTools.hxx"
27 #include "otb_tinyxml.h"
28 #include "otbStringUtils.h"
29 
30 namespace otb
31 {
32 
33 
34 template <class TMeasurementVector>
36 {
37 }
38 
39 template <class TMeasurementVector>
41 {
42  return m_MeasurementVectorContainer.size() + m_GenericMapContainer.size();
43 }
44 
45 template <class TMeasurementVector>
47 {
48  // Read the xml file once
49  if (!m_IsUpdated)
50  {
51  this->Read();
52  }
53 
54  std::vector<std::string> output;
55  for (unsigned int i = 0; i < m_MeasurementVectorContainer.size(); ++i)
56  {
57  output.push_back(m_MeasurementVectorContainer[i].first);
58  }
59  return output;
60 }
61 
62 template <class TMeasurementVector>
64 {
65  // Read the xml file once
66  if (!m_IsUpdated)
67  {
68  this->Read();
69  }
70 
71  std::vector<std::string> output;
72  for (GenericMapContainer::iterator it = m_GenericMapContainer.begin(); it != m_GenericMapContainer.end(); ++it)
73  {
74  output.push_back(it->first);
75  }
76  return output;
77 }
78 
79 template <class TMeasurementVector>
82 {
83  // Read the xml file once
84  if (!m_IsUpdated)
85  {
86  this->Read();
87  }
88 
89  // Check if the name of the Statistic is present
90  bool found = false;
91  unsigned int index = 0;
92  for (unsigned int idx = 0; idx < m_MeasurementVectorContainer.size(); ++idx)
93  {
94  if (m_MeasurementVectorContainer[idx].first == statisticName)
95  {
96  found = true;
97  index = idx;
98  }
99  }
100 
101  // if token not found throw an axception
102  if (!found)
103  itkExceptionMacro(<< "No entry corresponding to the token selected (" << statisticName << ") in the XML file");
104 
105  return m_MeasurementVectorContainer[index].second;
106 }
107 
108 template <class TMeasurementVector>
109 template <typename MapType>
111 {
112  // Read the xml file once
113  if (!m_IsUpdated)
114  {
115  this->Read();
116  }
117 
118  // Check if the name of the Statistic is present
119  std::string statName(statisticName);
120  if (m_GenericMapContainer.count(statName) == 0)
121  {
122  itkExceptionMacro(<< "No entry corresponding to the token selected (" << statName << ") in the XML file");
123  }
124 
125  MapType outputMap;
126  typename MapType::key_type tmpKey;
127  typename MapType::mapped_type tmpVal;
128  for (GenericMapType::iterator it = m_GenericMapContainer[statName].begin(); it != m_GenericMapContainer[statName].end(); ++it)
129  {
130  tmpKey = boost::lexical_cast<typename MapType::key_type>(it->first);
131  tmpVal = boost::lexical_cast<typename MapType::mapped_type>(it->second);
132  outputMap[tmpKey] = tmpVal;
133  }
134  return outputMap;
135 }
136 
137 template <class TMeasurementVector>
139 {
140  // Check if the filename is not empty
141  if (m_FileName.empty())
142  itkExceptionMacro(<< "The XML output FileName is empty, please set the filename via the method SetFileName");
143 
144  // Check that the right extension is given : expected .xml */
145  std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName);
146  if (itksys::SystemTools::LowerCase(extension) != ".xml")
147  {
148  itkExceptionMacro(<< extension << " is a wrong Extension FileName : Expected .xml");
149  }
150 
151  // Clean outputs
152  m_MeasurementVectorContainer.clear();
153  m_GenericMapContainer.clear();
154 
155  // Open the xml file
156  TiXmlDocument doc(m_FileName.c_str());
157  if (!doc.LoadFile())
158  {
159  itkExceptionMacro(<< "Can't open file " << m_FileName);
160  }
161 
162  TiXmlHandle hDoc(&doc);
163  TiXmlElement* root = hDoc.FirstChildElement("FeatureStatistics").ToElement();
164 
165  if (root)
166  {
167  // Iterate through the tree to get all the stats
168  for (TiXmlElement* currentStat = root->FirstChildElement(); currentStat != nullptr; currentStat = currentStat->NextSiblingElement())
169  {
170  InputDataType currentStatisticVector;
171 
172  // Store the stat type name
173  currentStatisticVector.first = currentStat->Attribute("name");
174 
175  // The size is not stored in the XML file
176  // Store the value in a std::vector, get the size and then
177  // build a measurement vector
178  std::vector<double> tempMeasurementVector;
179 
180  for (TiXmlElement* sample = currentStat->FirstChildElement("StatisticVector"); sample != nullptr; sample = sample->NextSiblingElement())
181  {
182  // Get the current value of the statistic vector
183  double value;
184  sample->QueryDoubleAttribute("value", &value);
185  // Store the value
186  tempMeasurementVector.push_back(value);
187  }
188 
189  // resize the Measurement Vector
190  currentStatisticVector.second.SetSize(tempMeasurementVector.size());
191  for (unsigned int i = 0; i < tempMeasurementVector.size(); ++i)
192  currentStatisticVector.second.SetElement(i, (static_cast<InputValueType>(tempMeasurementVector[i])));
193  m_MeasurementVectorContainer.push_back(currentStatisticVector);
194  }
195  }
196 
197  // Parse Map statistics
198  std::string key;
199  std::string value;
200  root = hDoc.FirstChildElement("GeneralStatistics").ToElement();
201  if (root)
202  {
203  // Iterate through the tree to get all the stats
204  for (TiXmlElement* currentStat = root->FirstChildElement(); currentStat != nullptr; currentStat = currentStat->NextSiblingElement())
205  {
206  GenericMapType currentMap;
207  std::string currentName(currentStat->Attribute("name"));
208 
209  for (TiXmlElement* sample = currentStat->FirstChildElement("StatisticMap"); sample != nullptr; sample = sample->NextSiblingElement())
210  {
211  // Get the current pair of the statistic map
212  const char* c_key = sample->Attribute("key");
213  const char* c_value = sample->Attribute("value");
214  if (c_key == nullptr)
215  {
216  itkExceptionMacro("'key' attribute not found in StatisticMap !");
217  }
218  if (c_value == nullptr)
219  {
220  itkExceptionMacro("'value' attribute not found in StatisticMap !");
221  }
222  key = std::string(c_key);
223  value = std::string(c_value);
224  // Store the pair
225  currentMap[key] = value;
226  }
227  m_GenericMapContainer[currentName] = currentMap;
228  }
229  }
230  // Reader is up-to-date
231  m_IsUpdated = true;
232 }
233 
234 
235 template <class TMeasurementVector>
236 void StatisticsXMLFileReader<TMeasurementVector>::PrintSelf(std::ostream& os, itk::Indent indent) const
237 {
238  // Call superclass implementation
239  Superclass::PrintSelf(os, indent);
240 
241  // Print info about statistics
242  os << indent << "Input FileName: " << m_FileName << std::endl;
243  os << indent << "Vector statistics: ";
244  for (unsigned int i = 0; i < m_MeasurementVectorContainer.size(); ++i)
245  {
246  if (i > 0)
247  os << ", ";
248  os << m_MeasurementVectorContainer[i].first;
249  }
250  os << std::endl;
251  os << indent << "Map statistics: ";
252  for (GenericMapContainer::const_iterator it = m_GenericMapContainer.begin(); it != m_GenericMapContainer.end(); ++it)
253  {
254  if (it != m_GenericMapContainer.begin())
255  os << ", ";
256  os << it->first;
257  }
258  os << std::endl;
259 }
260 
261 } // End namespace otb
262 
263 #endif
otb::StatisticsXMLFileReader::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbStatisticsXMLFileReader.hxx:236
otb::StatisticsXMLFileReader::GetStatisticVectorByName
MeasurementVectorType GetStatisticVectorByName(const char *statisticName)
Definition: otbStatisticsXMLFileReader.hxx:81
otbStatisticsXMLFileReader.h
otb::StatisticsXMLFileReader::GetStatisticVectorNames
std::vector< std::string > GetStatisticVectorNames()
Definition: otbStatisticsXMLFileReader.hxx:46
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::StatisticsXMLFileReader::GetNumberOfOutputs
unsigned int GetNumberOfOutputs()
Definition: otbStatisticsXMLFileReader.hxx:40
otb::StatisticsXMLFileReader::Read
virtual void Read()
Definition: otbStatisticsXMLFileReader.hxx:138
otb::StatisticsXMLFileReader::InputDataType
std::pair< std::string, MeasurementVectorType > InputDataType
Definition: otbStatisticsXMLFileReader.h:62
otb::StatisticsXMLFileReader::InputValueType
MeasurementVectorType::ValueType InputValueType
Definition: otbStatisticsXMLFileReader.h:59
otb::StatisticsXMLFileReader::MeasurementVectorType
TMeasurementVector MeasurementVectorType
Definition: otbStatisticsXMLFileReader.h:55
otb::StatisticsXMLFileReader::StatisticsXMLFileReader
StatisticsXMLFileReader()
Definition: otbStatisticsXMLFileReader.hxx:35
otb::StatisticsXMLFileReader::GetStatisticMapNames
std::vector< std::string > GetStatisticMapNames()
Definition: otbStatisticsXMLFileReader.hxx:63
otbStringUtils.h
otb::Wrapper::XML::Read
OTBApplicationEngine_EXPORT int Read(const std::string &filename, Application::Pointer application)
otb::StatisticsXMLFileReader::GenericMapType
std::map< std::string, std::string > GenericMapType
Definition: otbStatisticsXMLFileReader.h:65
otb::StatisticsXMLFileReader::GetStatisticMapByName
MapType GetStatisticMapByName(const char *statisticName)
Definition: otbStatisticsXMLFileReader.hxx:110