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 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  return;
59 }
60 
61 //========================================================================
62 int rowFromHeaderCol(const std::string& str)
63 {
64  const size_t begin = str.rfind(".");
65  if (begin == std::string::npos)
66  {
67  // no content, so invalid row Id
68  return -1;
69  }
70  int row = -1;
71  bool valid = convert(str.substr(begin + 1), row);
72  return (valid) ? row : -1;
73 }
74 
75 //========================================================================
76 std::string nameFromHeaderCol(const std::string& str)
77 {
78  const size_t begin = str.rfind(".");
79  if (begin == std::string::npos)
80  {
81  // no content
82  return str;
83  }
84  std::string t(str.substr(0, begin));
85  trim(t);
86  return t;
87 }
88 
89 //========================================================================
90 void split(const std::string& s, const char& delim, std::vector<std::string>& elems)
91 {
92  std::stringstream ss(s);
93  std::string item;
94  while (std::getline(ss, item, delim))
95  {
96  trim(item);
97  elems.push_back(item);
98  }
99  return;
100 }
101 
102 //========================================================================
103 void getMetaHeaderInfo(const std::string& s, const char& delim, std::map<std::string, int>& fields,
104  std::map<int, std::string>& lookup)
105 {
106  std::stringstream ss(s);
107  std::string item;
108  size_t count = 0;
109  int index = 0;
110  while (std::getline(ss, item, delim))
111  {
112  trim(item);
113 
114  // some hscth files have "time" with different case, so we change the
115  // case to a consistent value i.e. all lowercase (BUG #12983).
116  if (vtksys::SystemTools::LowerCase(item) == "time")
117  {
118  item = "time";
119  }
120  if (fields.find(item) != fields.end())
121  {
122  ++count;
123  fields[item] = index;
124  lookup[index] = item;
125  }
126  if (count == fields.size())
127  {
128  return;
129  }
130  ++index;
131  }
132  return;
133 }
134 
135 //========================================================================
136 void getTimeStepInfo(const std::string& s, const char& delim, std::map<int, std::string>& lookup,
137  std::map<std::string, std::string>& info)
138 {
139  std::stringstream ss(s);
140  std::string item;
141  int index = 0;
142  size_t count = 0;
143  while (std::getline(ss, item, delim))
144  {
145  trim(item);
146  if (lookup.find(index) != lookup.end())
147  {
148  // map the header name to this rows value
149  // ie time is col 3, so map info[time] to this rows 3rd col
150  info[lookup[index]] = item;
151  ++count;
152  }
153  if (count == lookup.size())
154  {
155  break;
156  }
157  ++index;
158  }
159  return;
160 }
161 
162 //========================================================================
163 std::vector<std::string> createTableLayoutFromHeader(std::string& header, const char& delim,
164  std::map<int, int>& columnIndexToRowId, std::map<int, std::string>& fieldCols)
165 {
166  // the single presumption we have is that all the properties points
167  // are continuous in the header
168  std::vector<std::string> cols;
169  cols.reserve(header.size());
170  split(header, delim, cols);
171  std::vector<std::string>::const_iterator it;
172 
173  // setup the size of the new header
174  std::vector<std::string> newHeader;
175  newHeader.reserve(cols.size());
176 
177  // find the first "." variable
178  bool foundStart = false;
179  int rowNumber = -1;
180  int index = 0;
181 
182  for (it = cols.begin(); it != cols.end(); ++it)
183  {
184  if ((*it).find(".") != std::string::npos)
185  {
186  foundStart = true;
187  rowNumber = rowFromHeaderCol(*it);
188  newHeader.push_back(nameFromHeaderCol(*it));
189  columnIndexToRowId.insert(std::pair<int, int>(index, rowNumber));
190  break;
191  }
192  else
193  {
194  // this is a field property
195  fieldCols[index] = nameFromHeaderCol(*it);
196  }
197  ++index;
198  }
199  if (!foundStart)
200  {
201  return newHeader;
202  }
203 
204  // now track the number of variables we have,
205  // and the names of each variable. This way we know how
206  // many rows to have in our new table
207  ++index;
208  ++it;
209  int numberOfCols = 1;
210  while (rowFromHeaderCol(*it) == rowNumber)
211  {
212  newHeader.push_back(nameFromHeaderCol(*it));
213  ++index;
214  ++it;
215  ++numberOfCols;
216  }
217  while (it != cols.end() && (rowNumber = rowFromHeaderCol(*it)) != -1)
218  {
219  columnIndexToRowId.insert(std::pair<int, int>(index, rowNumber));
220  index += numberOfCols;
221  it += numberOfCols;
222  }
223  while (it != cols.end())
224  {
225  // this is a field property
226  fieldCols[index] = nameFromHeaderCol(*it);
227  ;
228  ++it;
229  ++index;
230  }
231  return newHeader;
232 }
233 }
234 
235 #endif
236 // 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)