OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
SDDSParser.h
Go to the documentation of this file.
1 //
2 // Class SDDSParser
3 // This class writes column entries of SDDS files.
4 //
5 // Copyright (c) 2015, Christof Metzger-Kraus, Helmholtz-Zentrum Berlin
6 // All rights reserved
7 //
8 // This file is part of OPAL.
9 //
10 // OPAL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
17 //
18 #include "Util/SDDSParser/ast.hpp"
19 #include "Util/SDDSParser/file.hpp"
24 #include "Util/SDDSParser/data.hpp"
28 
30 
31 
32 #include "boost/optional/optional_io.hpp"
33 
34 #include <iostream>
35 #include <fstream>
36 #include <string>
37 #include <map>
38 
39 #ifndef __SDDSPARSER_H__
40 #define __SDDSPARSER_H__
41 
42 namespace SDDS {
43 
44  class SDDSParser {
45  private:
46  std::string readFile();
47  static void fixCaseSensitivity(std::string &for_string);
48  static std::string fixCaseSensitivity(const std::string &for_string) {
49  std::string retval(for_string);
50  fixCaseSensitivity(retval);
51  return retval;
52  }
53  std::string sddsFileName_m;
54 
56  std::map<std::string, int> paramNameToID_m;
58  std::map<std::string, int> columnNameToID_m;
59 
61 
62  public:
63  SDDSParser();
64  SDDSParser(const std::string &input);
65  void setInput(const std::string &input);
66  file run();
67 
68  file getData();
69  ast::columnData_t getColumnData(const std::string &columnName);
70 
71  ast::datatype getColumnType(const std::string &col_name) {
72  int index = getColumnIndex(col_name);
73  return *sddsData_m.sddsColumns_m[index].type_m;
74  }
75 
84  template <typename T>
85  void getValue(int t, std::string column_name, T& nval) {
86 
87  fixCaseSensitivity(column_name);
88 
89  int col_idx = getColumnIndex(column_name);
90 
91  // round timestep to last if not in range
92  size_t row_idx = 0;
93  size_t num_rows = sddsData_m.sddsColumns_m[col_idx].values_m.size();
94  if(t <= 0 || static_cast<size_t>(t) > num_rows)
95  row_idx = num_rows - 1;
96  else
97  row_idx = static_cast<size_t>(t) - 1;
98 
99  ast::variant_t val = sddsData_m.sddsColumns_m[col_idx].values_m[row_idx];
100  nval = getBoostVariantValue<T>(val, (int)getColumnType(column_name));
101  }
102 
103 
113  template <typename T>
114  void getInterpolatedValue(std::string ref_name, double ref_val,
115  std::string col_name, T& nval) {
116  T value_before = 0;
117  T value_after = 0;
118  double value_before_ref = 0;
119  double value_after_ref = 0;
120 
121 
122  size_t col_idx_ref = getColumnIndex(ref_name);
123  ast::columnData_t &ref_values = sddsData_m.sddsColumns_m[col_idx_ref].values_m;
124  int index = getColumnIndex(col_name);
125  ast::columnData_t &col_values = sddsData_m.sddsColumns_m[index].values_m;
126 
127  size_t this_row = 0;
128  size_t num_rows = ref_values.size();
129  int datatype = (int)getColumnType(col_name);
130  for(this_row = 0; this_row < num_rows; this_row++) {
131  value_after_ref = boost::get<double>(ref_values[this_row]);
132 
133  if(ref_val < value_after_ref) {
134 
135  size_t prev_row = 0;
136  if(this_row > 0) prev_row = this_row - 1;
137 
138  value_before = getBoostVariantValue<T>(col_values[prev_row], datatype);
139  value_after = getBoostVariantValue<T>(col_values[this_row], datatype);
140 
141  value_before_ref = boost::get<double>(ref_values[prev_row]);
142  value_after_ref = boost::get<double>(ref_values[this_row]);
143 
144  break;
145  }
146  }
147 
148  if(this_row == num_rows)
149  throw SDDSParserException("SDDSParser::getInterpolatedValue",
150  "all values < specified reference value");
151 
152  // simple linear interpolation
153  if(ref_val - value_before_ref < 1e-8)
154  nval = value_before;
155  else
156  nval = value_before + (ref_val - value_before_ref)
157  * (value_after - value_before)
158  / (value_after_ref - value_before_ref);
159 
160  if (!std::isfinite(nval))
161  throw SDDSParserException("SDDSParser::getInterpolatedValue",
162  "Interpolated value either NaN or Inf.");
163  }
164 
173  template <typename T>
174  void getInterpolatedValue(double spos, std::string col_name, T& nval) {
175  getInterpolatedValue("s", spos, col_name, nval);
176  }
177 
185  template <typename T>
186  void getParameterValue(std::string parameter_name, T& nval) {
187  fixCaseSensitivity(parameter_name);
188 
189  if (paramNameToID_m.count(parameter_name) > 0) {
190  size_t id = paramNameToID_m[parameter_name];
191  auto value = sddsData_m.sddsParameters_m[id].value_m;
192  nval = boost::get<T>(value);
193  } else {
194  throw SDDSParserException("SDDSParser::getParameterValue",
195  "unknown parameter name: '" + parameter_name + "'!");
196  }
197  }
198 
200  // use integer instead of ast::datatype enum since otherwise boost has ambigious overloads
201  // as tested on 8-1-2019, boost 1.68, gcc 7.3
202  template <typename T>
204  T value;
205  try {
206  switch (datatype) {
207  case ast::FLOAT:
208  value = boost::get<float>(val);
209  break;
210  case ast::DOUBLE:
211  value = boost::get<double>(val);
212  break;
213  case ast::SHORT:
214  value = boost::get<short>(val);
215  break;
216  case ast::LONG:
217  value = boost::get<long>(val);
218  break;
219  default:
220  throw SDDSParserException("SDDSParser::getBoostVariantValue",
221  "can't convert value to type T");
222  }
223  }
224  catch (...) {
225  throw SDDSParserException("SDDSParser::getBoostVariantValue",
226  "can't convert value");
227  }
228  return value;
229  }
230 
231  private:
232 
233  int getColumnIndex(std::string col_name) const;
234  };
235 
236  inline
238  return sddsData_m;
239  }
240 }
241 
242 #endif
constexpr double e
The value of.
Definition: Physics.h:39
Definition: array.hpp:33
std::vector< variant_t > columnData_t
Definition: ast.hpp:50
datatype
Definition: ast.hpp:28
@ DOUBLE
Definition: ast.hpp:29
@ LONG
Definition: ast.hpp:31
@ FLOAT
Definition: ast.hpp:28
@ SHORT
Definition: ast.hpp:30
boost::variant< float, double, short, long, char, std::string > variant_t
Definition: ast.hpp:48
columnList sddsColumns_m
Definition: file.hpp:46
parameterList sddsParameters_m
Definition: file.hpp:45
std::map< std::string, int > columnNameToID_m
mapping from column name to ID in columns_m
Definition: SDDSParser.h:58
void getParameterValue(std::string parameter_name, T &nval)
Definition: SDDSParser.h:186
std::string readFile()
Definition: SDDSParser.cpp:94
ast::columnData_t getColumnData(const std::string &columnName)
Definition: SDDSParser.cpp:116
ast::datatype getColumnType(const std::string &col_name)
Definition: SDDSParser.h:71
std::string sddsFileName_m
Definition: SDDSParser.h:53
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:203
void getInterpolatedValue(std::string ref_name, double ref_val, std::string col_name, T &nval)
Definition: SDDSParser.h:114
static void fixCaseSensitivity(std::string &for_string)
Definition: SDDSParser.cpp:136
void setInput(const std::string &input)
Definition: SDDSParser.cpp:30
void getValue(int t, std::string column_name, T &nval)
Definition: SDDSParser.h:85
static std::string fixCaseSensitivity(const std::string &for_string)
Definition: SDDSParser.h:48
void getInterpolatedValue(double spos, std::string col_name, T &nval)
Definition: SDDSParser.h:174
SDDS::file sddsData_m
Definition: SDDSParser.h:60
int getColumnIndex(std::string col_name) const
Definition: SDDSParser.cpp:123
std::map< std::string, int > paramNameToID_m
mapping from parameter name to offset in params_m
Definition: SDDSParser.h:56