vtkSpyPlotHistoryReaderPrivate.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
2 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
3 // SPDX-License-Identifier: BSD-3-Clause
4 
14 #ifndef vtkSpyPlotHistoryReaderPrivate_h
15 #define vtkSpyPlotHistoryReaderPrivate_h
16 
17 #include <vtksys/SystemTools.hxx> // for vtksys::SystemTools::LowerCase
18 
19 #include <map> // Needed for STL map.
20 #include <set> // Needed for STL set.
21 #include <sstream> // Needed for STL sstream.
22 #include <string> // Needed for STL string.
23 #include <vector> // Needed for STL vector.
24 
25 //-----------------------------------------------------------------------------
27 {
28 
29 //========================================================================
30 class TimeStep
31 {
32 public:
33  double time;
34  std::streampos file_pos;
35 };
36 
37 //========================================================================
38 template <class T>
39 bool convert(const std::string& num, T& t)
40 {
41  std::istringstream i(num);
42  i >> t;
43  return !i.fail();
44 }
45 
46 //========================================================================
47 inline void trim(std::string& string, const std::string& whitespace = " \t\"")
48 {
49  const size_t begin = string.find_first_not_of(whitespace);
50  if (begin == std::string::npos)
51  {
52  // no content
53  return;
54  }
55  const size_t end = string.find_last_not_of(whitespace);
56  const size_t range = end - begin + 1;
57  string = string.substr(begin, range);
58 }
59 
60 //========================================================================
61 inline int rowFromHeaderCol(const std::string& str)
62 {
63  const size_t begin = str.rfind('.');
64  if (begin == std::string::npos)
65  {
66  // no content, so invalid row Id
67  return -1;
68  }
69  int row = -1;
70  bool valid = convert(str.substr(begin + 1), row);
71  return (valid) ? row : -1;
72 }
73 
74 //========================================================================
75 inline std::string nameFromHeaderCol(const std::string& str)
76 {
77  const size_t begin = str.rfind('.');
78  if (begin == std::string::npos)
79  {
80  // no content
81  return str;
82  }
83  std::string t(str.substr(0, begin));
84  trim(t);
85  return t;
86 }
87 
88 //========================================================================
89 inline void split(const std::string& s, const char& delim, std::vector<std::string>& elems)
90 {
91  std::stringstream ss(s);
92  std::string item;
93  while (std::getline(ss, item, delim))
94  {
95  trim(item);
96  elems.push_back(item);
97  }
98 }
99 
100 //========================================================================
101 inline void getMetaHeaderInfo(const std::string& s, const char& delim,
102  std::map<std::string, int>& fields, std::map<int, std::string>& lookup)
103 {
104  std::stringstream ss(s);
105  std::string item;
106  size_t count = 0;
107  int index = 0;
108  while (std::getline(ss, item, delim))
109  {
110  trim(item);
111 
112  // some hscth files have "time" with different case, so we change the
113  // case to a consistent value i.e. all lowercase (BUG #12983).
114  if (vtksys::SystemTools::LowerCase(item) == "time")
115  {
116  item = "time";
117  }
118  if (fields.find(item) != fields.end())
119  {
120  ++count;
121  fields[item] = index;
122  lookup[index] = item;
123  }
124  if (count == fields.size())
125  {
126  return;
127  }
128  ++index;
129  }
130 }
131 
132 //========================================================================
133 inline void getTimeStepInfo(const std::string& s, const char& delim,
134  std::map<int, std::string>& lookup, std::map<std::string, std::string>& info)
135 {
136  std::stringstream ss(s);
137  std::string item;
138  int index = 0;
139  size_t count = 0;
140  while (std::getline(ss, item, delim))
141  {
142  trim(item);
143  if (lookup.find(index) != lookup.end())
144  {
145  // map the header name to this rows value
146  // ie time is col 3, so map info[time] to this rows 3rd col
147  info[lookup[index]] = item;
148  ++count;
149  }
150  if (count == lookup.size())
151  {
152  break;
153  }
154  ++index;
155  }
156 }
157 
158 //========================================================================
159 inline std::vector<std::string> createTableLayoutFromHeader(std::string& header, const char& delim,
160  std::map<int, int>& columnIndexToRowId, std::map<int, std::string>& fieldCols)
161 {
162  // the single presumption we have is that all the properties points
163  // are continuous in the header
164  std::vector<std::string> cols;
165  cols.reserve(header.size());
166  split(header, delim, cols);
167  std::vector<std::string>::const_iterator it;
168 
169  // setup the size of the new header
170  std::vector<std::string> newHeader;
171  newHeader.reserve(cols.size());
172 
173  // find the first "." variable
174  bool foundStart = false;
175  int rowNumber = -1;
176  int index = 0;
177 
178  for (it = cols.begin(); it != cols.end(); ++it)
179  {
180  if ((*it).find(".") != std::string::npos)
181  {
182  foundStart = true;
183  rowNumber = rowFromHeaderCol(*it);
184  newHeader.push_back(nameFromHeaderCol(*it));
185  columnIndexToRowId.insert(std::pair<int, int>(index, rowNumber));
186  break;
187  }
188  else
189  {
190  // this is a field property
191  fieldCols[index] = nameFromHeaderCol(*it);
192  }
193  ++index;
194  }
195  if (!foundStart)
196  {
197  return newHeader;
198  }
199 
200  // now track the number of variables we have,
201  // and the names of each variable. This way we know how
202  // many rows to have in our new table
203  ++index;
204  ++it;
205  int numberOfCols = 1;
206  while (rowFromHeaderCol(*it) == rowNumber)
207  {
208  newHeader.push_back(nameFromHeaderCol(*it));
209  ++index;
210  ++it;
211  ++numberOfCols;
212  }
213  while (it != cols.end() && (rowNumber = rowFromHeaderCol(*it)) != -1)
214  {
215  columnIndexToRowId.insert(std::pair<int, int>(index, rowNumber));
216  index += numberOfCols;
217  it += numberOfCols;
218  }
219  while (it != cols.end())
220  {
221  // this is a field property
222  fieldCols[index] = nameFromHeaderCol(*it);
223  ;
224  ++it;
225  ++index;
226  }
227  return newHeader;
228 }
229 }
230 
231 #endif
232 // VTK-HeaderTest-Exclude: vtkSpyPlotHistoryReaderPrivate.h
std::string nameFromHeaderCol(const std::string &str)
void getTimeStepInfo(const std::string &s, const char &delim, std::map< int, std::string > &lookup, std::map< std::string, std::string > &info)
void getMetaHeaderInfo(const std::string &s, const char &delim, std::map< std::string, int > &fields, std::map< int, std::string > &lookup)
void split(const std::string &s, const char &delim, std::vector< std::string > &elems)
range
int rowFromHeaderCol(const std::string &str)
std::vector< std::string > createTableLayoutFromHeader(std::string &header, const char &delim, std::map< int, int > &columnIndexToRowId, std::map< int, std::string > &fieldCols)
index
void trim(std::string &string, const std::string &whitespace=" \")
bool convert(const std::string &num, T &t)