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