OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
SDDSParser.h
Go to the documentation of this file.
1 //
2 // Copyright & License: See Copyright.readme in src directory
3 //
4 
11 #include "Util/SDDSParser/data.hpp"
15 
17 
18 
19 #include "boost/optional/optional_io.hpp"
20 
21 #include <iostream>
22 #include <fstream>
23 #include <string>
24 #include <map>
25 
26 #ifndef __SDDSPARSER_H__
27 #define __SDDSPARSER_H__
28 
29 namespace SDDS {
30 
31  class SDDSParser {
32  private:
33  std::string readFile();
34  static void fixCaseSensitivity(std::string &for_string);
35  static std::string fixCaseSensitivity(const std::string &for_string) {
36  std::string retval(for_string);
37  fixCaseSensitivity(retval);
38  return retval;
39  }
40  std::string sddsFileName_m;
41 
43  std::map<std::string, int> paramNameToID_m;
45  std::map<std::string, int> columnNameToID_m;
46 
48 
49  public:
50  SDDSParser();
51  SDDSParser(const std::string &input);
52  void setInput(const std::string &input);
53  file run();
54 
55  file getData();
56  ast::columnData_t getColumnData(const std::string &columnName);
57 
58  ast::datatype getColumnType(const std::string &col_name) {
59  int index = getColumnIndex(col_name);
60  return *sddsData_m.sddsColumns_m[index].type_m;
61  }
62 
71  template <typename T>
72  void getValue(int t, std::string column_name, T& nval) {
73 
74  fixCaseSensitivity(column_name);
75 
76  int col_idx = getColumnIndex(column_name);
77 
78  // round timestep to last if not in range
79  size_t row_idx = 0;
80  size_t num_rows = sddsData_m.sddsColumns_m[col_idx].values_m.size();
81  if(t <= 0 || static_cast<size_t>(t) > num_rows)
82  row_idx = num_rows - 1;
83  else
84  row_idx = static_cast<size_t>(t) - 1;
85 
86  ast::variant_t val = sddsData_m.sddsColumns_m[col_idx].values_m[row_idx];
87  nval = getBoostVariantValue<T>(val, (int)getColumnType(column_name));
88  }
89 
90 
100  template <typename T>
101  void getInterpolatedValue(std::string ref_name, double ref_val,
102  std::string col_name, T& nval) {
103  T value_before = 0;
104  T value_after = 0;
105  double value_before_ref = 0;
106  double value_after_ref = 0;
107 
108 
109  size_t col_idx_ref = getColumnIndex(ref_name);
110  ast::columnData_t &ref_values = sddsData_m.sddsColumns_m[col_idx_ref].values_m;
111  int index = getColumnIndex(col_name);
112  ast::columnData_t &col_values = sddsData_m.sddsColumns_m[index].values_m;
113 
114  size_t this_row = 0;
115  size_t num_rows = ref_values.size();
116  int datatype = (int)getColumnType(col_name);
117  for(this_row = 0; this_row < num_rows; this_row++) {
118  value_after_ref = boost::get<double>(ref_values[this_row]);
119 
120  if(ref_val < value_after_ref) {
121 
122  size_t prev_row = 0;
123  if(this_row > 0) prev_row = this_row - 1;
124 
125  value_before = getBoostVariantValue<T>(col_values[prev_row], datatype);
126  value_after = getBoostVariantValue<T>(col_values[this_row], datatype);
127 
128  value_before_ref = boost::get<double>(ref_values[prev_row]);
129  value_after_ref = boost::get<double>(ref_values[this_row]);
130 
131  break;
132  }
133  }
134 
135  if(this_row == num_rows)
136  throw SDDSParserException("SDDSParser::getInterpolatedValue",
137  "all values < specified reference value");
138 
139  // simple linear interpolation
140  if(ref_val - value_before_ref < 1e-8)
141  nval = value_before;
142  else
143  nval = value_before + (ref_val - value_before_ref)
144  * (value_after - value_before)
145  / (value_after_ref - value_before_ref);
146 
147  if (!std::isfinite(nval))
148  throw SDDSParserException("SDDSParser::getInterpolatedValue",
149  "Interpolated value either NaN or Inf.");
150  }
151 
160  template <typename T>
161  void getInterpolatedValue(double spos, std::string col_name, T& nval) {
162  getInterpolatedValue("s", spos, col_name, nval);
163  }
164 
172  template <typename T>
173  void getParameterValue(std::string parameter_name, T& nval) {
174  fixCaseSensitivity(parameter_name);
175 
176  if (paramNameToID_m.count(parameter_name) > 0) {
177  size_t id = paramNameToID_m[parameter_name];
178  auto value = sddsData_m.sddsParameters_m[id].value_m;
179  nval = boost::get<T>(value);
180  } else {
181  throw SDDSParserException("SDDSParser::getParameterValue",
182  "unknown parameter name: '" + parameter_name + "'!");
183  }
184  }
185 
187  // use integer instead of ast::datatype enum since otherwise boost has ambigious overloads
188  // as tested on 8-1-2019, boost 1.68, gcc 7.3
189  template <typename T>
191  T value;
192  try {
193  switch (datatype) {
194  case ast::FLOAT:
195  value = boost::get<float>(val);
196  break;
197  case ast::DOUBLE:
198  value = boost::get<double>(val);
199  break;
200  case ast::SHORT:
201  value = boost::get<short>(val);
202  break;
203  case ast::LONG:
204  value = boost::get<long>(val);
205  break;
206  default:
207  throw SDDSParserException("SDDSParser::getBoostVariantValue",
208  "can't convert value to type T");
209  }
210  }
211  catch (...) {
212  throw SDDSParserException("SDDSParser::getBoostVariantValue",
213  "can't convert value");
214  }
215  return value;
216  }
217 
218  private:
219 
220  int getColumnIndex(std::string col_name) const;
221  };
222 
223  inline
225  return sddsData_m;
226  }
227 }
228 
229 #endif
constexpr double e
The value of .
Definition: Physics.h:40
Definition: rbendmap.h:8
std::string readFile()
Definition: SDDSParser.cpp:77
void getParameterValue(std::string parameter_name, T &nval)
Definition: SDDSParser.h:173
ast::columnData_t getColumnData(const std::string &columnName)
Definition: SDDSParser.cpp:99
int getColumnIndex(std::string col_name) const
Definition: SDDSParser.cpp:106
static void fixCaseSensitivity(std::string &for_string)
Definition: SDDSParser.cpp:119
std::map< std::string, int > columnNameToID_m
mapping from column name to ID in columns_m
Definition: SDDSParser.h:45
void setInput(const std::string &input)
Definition: SDDSParser.cpp:13
void getInterpolatedValue(double spos, std::string col_name, T &nval)
Definition: SDDSParser.h:161
boost::variant< float, double, short, long, char, std::string > variant_t
Definition: ast.hpp:40
std::vector< variant_t > columnData_t
Definition: ast.hpp:42
parameterList sddsParameters_m
Definition: file.hpp:37
std::map< std::string, int > paramNameToID_m
mapping from parameter name to offset in params_m
Definition: SDDSParser.h:43
void getInterpolatedValue(std::string ref_name, double ref_val, std::string col_name, T &nval)
Definition: SDDSParser.h:101
T getBoostVariantValue(const ast::variant_t &val, int datatype) const
Convert value from boost variant (only numeric types) to a value of type T.
Definition: SDDSParser.h:190
columnList sddsColumns_m
Definition: file.hpp:38
void getValue(int t, std::string column_name, T &nval)
Definition: SDDSParser.h:72
ast::datatype getColumnType(const std::string &col_name)
Definition: SDDSParser.h:58
SDDS::file sddsData_m
Definition: SDDSParser.h:47
static std::string fixCaseSensitivity(const std::string &for_string)
Definition: SDDSParser.h:35
std::string sddsFileName_m
Definition: SDDSParser.h:40
datatype
Definition: ast.hpp:20