OPALX (Object Oriented Parallel Accelerator Library for Exascal) MINIorX
OPALX
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
19#include "SDDSParser/ast.hpp"
20#include "SDDSParser/file.hpp"
22#include "SDDSParser/array.hpp"
24#include "SDDSParser/column.hpp"
25#include "SDDSParser/data.hpp"
29
31
32
33#include "boost/optional/optional_io.hpp"
34
35#include <iostream>
36#include <fstream>
37#include <string>
38#include <map>
39
40#ifndef __SDDSPARSER_H__
41#define __SDDSPARSER_H__
42
43namespace SDDS {
44
45 class SDDSParser {
46 private:
47 std::string readFile();
48 static void fixCaseSensitivity(std::string &for_string);
49 static std::string fixCaseSensitivity(const std::string &for_string) {
50 std::string retval(for_string);
51 fixCaseSensitivity(retval);
52 return retval;
53 }
54 std::string sddsFileName_m;
55
57 std::map<std::string, int> paramNameToID_m;
59 std::map<std::string, int> columnNameToID_m;
60
62
63 public:
64 SDDSParser();
65 SDDSParser(const std::string &input);
66 void setInput(const std::string &input);
67 file run();
68
69 file getData();
70 ast::columnData_t getColumnData(const std::string &columnName);
71
72 ast::datatype getColumnType(const std::string &col_name) {
73 int index = getColumnIndex(col_name);
74 return *sddsData_m.sddsColumns_m[index].type_m;
75 }
76
85 template <typename T>
86 void getValue(int t, std::string column_name, T& nval) {
87
88 fixCaseSensitivity(column_name);
89
90 int col_idx = getColumnIndex(column_name);
91
92 // round timestep to last if not in range
93 size_t row_idx = 0;
94 size_t num_rows = sddsData_m.sddsColumns_m[col_idx].values_m.size();
95 if(t <= 0 || static_cast<size_t>(t) > num_rows)
96 row_idx = num_rows - 1;
97 else
98 row_idx = static_cast<size_t>(t) - 1;
99
100 ast::variant_t val = sddsData_m.sddsColumns_m[col_idx].values_m[row_idx];
101 nval = getBoostVariantValue<T>(val, (int)getColumnType(column_name));
102 }
103
104
114 template <typename T>
115 void getInterpolatedValue(std::string ref_name, double ref_val,
116 std::string col_name, T& nval) {
117 T value_before = 0;
118 T value_after = 0;
119 double value_before_ref = 0;
120 double value_after_ref = 0;
121
122
123 size_t col_idx_ref = getColumnIndex(ref_name);
124 ast::columnData_t &ref_values = sddsData_m.sddsColumns_m[col_idx_ref].values_m;
125 int index = getColumnIndex(col_name);
126 ast::columnData_t &col_values = sddsData_m.sddsColumns_m[index].values_m;
127
128 size_t this_row = 0;
129 size_t num_rows = ref_values.size();
130 int datatype = (int)getColumnType(col_name);
131 for(this_row = 0; this_row < num_rows; this_row++) {
132 value_after_ref = boost::get<double>(ref_values[this_row]);
133
134 if(ref_val < value_after_ref) {
135
136 size_t prev_row = 0;
137 if(this_row > 0) prev_row = this_row - 1;
138
139 value_before = getBoostVariantValue<T>(col_values[prev_row], datatype);
140 value_after = getBoostVariantValue<T>(col_values[this_row], datatype);
141
142 value_before_ref = boost::get<double>(ref_values[prev_row]);
143 value_after_ref = boost::get<double>(ref_values[this_row]);
144
145 break;
146 }
147 }
148
149 if(this_row == num_rows)
150 throw SDDSParserException("SDDSParser::getInterpolatedValue",
151 "all values < specified reference value");
152
153 // simple linear interpolation
154 if(ref_val - value_before_ref < 1e-8)
155 nval = value_before;
156 else
157 nval = value_before + (ref_val - value_before_ref)
158 * (value_after - value_before)
159 / (value_after_ref - value_before_ref);
160
161 if (!std::isfinite(nval))
162 throw SDDSParserException("SDDSParser::getInterpolatedValue",
163 "Interpolated value either NaN or Inf.");
164 }
165
174 template <typename T>
175 void getInterpolatedValue(double spos, std::string col_name, T& nval) {
176 getInterpolatedValue("s", spos, col_name, nval);
177 }
178
186 template <typename T>
187 void getParameterValue(std::string parameter_name, T& nval) {
188 fixCaseSensitivity(parameter_name);
189
190 if (paramNameToID_m.count(parameter_name) > 0) {
191 size_t id = paramNameToID_m[parameter_name];
192 auto value = sddsData_m.sddsParameters_m[id].value_m;
193 nval = boost::get<T>(value);
194 } else {
195 throw SDDSParserException("SDDSParser::getParameterValue",
196 "unknown parameter name: '" + parameter_name + "'!");
197 }
198 }
199
201 // use integer instead of ast::datatype enum since otherwise boost has ambigious overloads
202 // as tested on 8-1-2019, boost 1.68, gcc 7.3
203 template <typename T>
204 T getBoostVariantValue(const ast::variant_t& val, int datatype) const {
205 T value;
206 try {
207 switch (datatype) {
208 case ast::FLOAT:
209 value = boost::get<float>(val);
210 break;
211 case ast::DOUBLE:
212 value = boost::get<double>(val);
213 break;
214 case ast::SHORT:
215 value = boost::get<short>(val);
216 break;
217 case ast::LONG:
218 value = boost::get<long>(val);
219 break;
220 default:
221 throw SDDSParserException("SDDSParser::getBoostVariantValue",
222 "can't convert value to type T");
223 }
224 }
225 catch (...) {
226 throw SDDSParserException("SDDSParser::getBoostVariantValue",
227 "can't convert value");
228 }
229 return value;
230 }
231
232 private:
233
234 int getColumnIndex(std::string col_name) const;
235 };
236
237 inline
239 return sddsData_m;
240 }
241}
242
243#endif
double T
Definition datatypes.h:7
std::vector< variant_t > columnData_t
Definition ast.hpp:50
@ 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
std::map< std::string, int > columnNameToID_m
mapping from column name to ID in columns_m
Definition SDDSParser.h:59
void getParameterValue(std::string parameter_name, T &nval)
Definition SDDSParser.h:187
std::string readFile()
ast::columnData_t getColumnData(const std::string &columnName)
ast::datatype getColumnType(const std::string &col_name)
Definition SDDSParser.h:72
std::string sddsFileName_m
Definition SDDSParser.h:54
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:204
void getInterpolatedValue(std::string ref_name, double ref_val, std::string col_name, T &nval)
Definition SDDSParser.h:115
static void fixCaseSensitivity(std::string &for_string)
void setInput(const std::string &input)
void getValue(int t, std::string column_name, T &nval)
Definition SDDSParser.h:86
static std::string fixCaseSensitivity(const std::string &for_string)
Definition SDDSParser.h:49
void getInterpolatedValue(double spos, std::string col_name, T &nval)
Definition SDDSParser.h:175
SDDS::file sddsData_m
Definition SDDSParser.h:61
int getColumnIndex(std::string col_name) const
std::map< std::string, int > paramNameToID_m
mapping from parameter name to offset in params_m
Definition SDDSParser.h:57