OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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//
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
42namespace 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
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
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
columnList sddsColumns_m
Definition: file.hpp:46
parameterList sddsParameters_m
Definition: file.hpp:45