OPALX (Object Oriented Parallel Accelerator Library for Exascal) master (dc2a29eed580)
OPALX
Loading...
Searching...
No Matches
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/array.hpp"
21#include "SDDSParser/ast.hpp"
22#include "SDDSParser/column.hpp"
23#include "SDDSParser/data.hpp"
25#include "SDDSParser/file.hpp"
29
31
32#include <fstream>
33#include <iostream>
34#include <map>
35#include <string>
36
37#ifndef __SDDSPARSER_H__
38#define __SDDSPARSER_H__
39
40namespace SDDS {
41
42 class SDDSParser {
43 private:
44 std::string readFile();
45 static void fixCaseSensitivity(std::string& for_string);
46 static std::string fixCaseSensitivity(const std::string& for_string) {
47 std::string retval(for_string);
48 fixCaseSensitivity(retval);
49 return retval;
50 }
51 std::string sddsFileName_m;
52
54 std::map<std::string, int> paramNameToID_m;
56 std::map<std::string, int> columnNameToID_m;
57
59
60 public:
61 SDDSParser();
62 SDDSParser(const std::string& input);
63 void setInput(const std::string& input);
64 file run();
65
66 file getData();
67 ast::columnData_t getColumnData(const std::string& columnName);
68
69 ast::datatype getColumnType(const std::string& col_name) {
70 int index = getColumnIndex(col_name);
71 return *sddsData_m.sddsColumns_m[index].type_m;
72 }
73
82 template <typename T>
83 void getValue(int t, std::string column_name, T& nval) {
84 fixCaseSensitivity(column_name);
85
86 int col_idx = getColumnIndex(column_name);
87
88 // round timestep to last if not in range
89 size_t row_idx = 0;
90 size_t num_rows = sddsData_m.sddsColumns_m[col_idx].values_m.size();
91 if (t <= 0 || static_cast<size_t>(t) > num_rows)
92 row_idx = num_rows - 1;
93 else
94 row_idx = static_cast<size_t>(t) - 1;
95
96 ast::variant_t val = sddsData_m.sddsColumns_m[col_idx].values_m[row_idx];
97 nval = getBoostVariantValue<T>(val, (int)getColumnType(column_name));
98 }
99
109 template <typename T>
111 std::string ref_name, double ref_val, std::string col_name, T& nval) {
112 T value_before = 0;
113 T value_after = 0;
114 double value_before_ref = 0;
115 double value_after_ref = 0;
116
117 size_t col_idx_ref = getColumnIndex(ref_name);
118 ast::columnData_t& ref_values = sddsData_m.sddsColumns_m[col_idx_ref].values_m;
119 int index = getColumnIndex(col_name);
120 ast::columnData_t& col_values = sddsData_m.sddsColumns_m[index].values_m;
121
122 size_t this_row = 0;
123 size_t num_rows = ref_values.size();
124 int datatype = (int)getColumnType(col_name);
125 for (this_row = 0; this_row < num_rows; this_row++) {
126 value_after_ref = std::get<double>(ref_values[this_row]);
127
128 if (ref_val < value_after_ref) {
129 size_t prev_row = 0;
130 if (this_row > 0) prev_row = this_row - 1;
131
132 value_before = getBoostVariantValue<T>(col_values[prev_row], datatype);
133 value_after = getBoostVariantValue<T>(col_values[this_row], datatype);
134
135 value_before_ref = std::get<double>(ref_values[prev_row]);
136 value_after_ref = std::get<double>(ref_values[this_row]);
137
138 break;
139 }
140 }
141
142 if (this_row == num_rows)
144 "SDDSParser::getInterpolatedValue",
145 "all values < specified reference value");
146
147 // simple linear interpolation
148 if (ref_val - value_before_ref < 1e-8)
149 nval = value_before;
150 else
151 nval = value_before
152 + (ref_val - value_before_ref) * (value_after - value_before)
153 / (value_after_ref - value_before_ref);
154
155 // Check for NaN or Inf using a simple approach
156 double dval = static_cast<double>(nval);
157 if (dval != dval || (dval == dval * 2.0 && dval != 0.0))
159 "SDDSParser::getInterpolatedValue",
160 "Interpolated value either NaN or Inf.");
161 }
162
171 template <typename T>
172 void getInterpolatedValue(double spos, std::string col_name, T& nval) {
173 getInterpolatedValue("s", spos, col_name, nval);
174 }
175
183 template <typename T>
184 void getParameterValue(std::string parameter_name, T& nval) {
185 fixCaseSensitivity(parameter_name);
186
187 if (paramNameToID_m.count(parameter_name) > 0) {
188 size_t id = paramNameToID_m[parameter_name];
189 auto value = sddsData_m.sddsParameters_m[id].value_m;
190 nval = std::get<T>(value);
191 } else {
193 "SDDSParser::getParameterValue",
194 "unknown parameter name: '" + parameter_name + "'!");
195 }
196 }
197
199 // use integer instead of ast::datatype enum since otherwise std::variant has ambigious
200 // overloads
201 template <typename T>
202 T getBoostVariantValue(const ast::variant_t& val, int datatype) const {
203 T value;
204 try {
205 switch (datatype) {
206 case ast::FLOAT:
207 value = std::get<float>(val);
208 break;
209 case ast::DOUBLE:
210 value = std::get<double>(val);
211 break;
212 case ast::SHORT:
213 value = std::get<short>(val);
214 break;
215 case ast::LONG:
216 value = std::get<long>(val);
217 break;
218 default:
220 "SDDSParser::getBoostVariantValue",
221 "can't convert value to type T");
222 }
223 } catch (...) {
225 "SDDSParser::getBoostVariantValue", "can't convert value");
226 }
227 return value;
228 }
229
230 private:
231 int getColumnIndex(std::string col_name) const;
232 };
233
235} // namespace SDDS
236
237#endif
double T
Definition OPALTypes.h:8
std::map< std::string, int > columnNameToID_m
mapping from column name to ID in columns_m
Definition SDDSParser.h:56
void getParameterValue(std::string parameter_name, T &nval)
Definition SDDSParser.h:184
std::string readFile()
ast::columnData_t getColumnData(const std::string &columnName)
ast::datatype getColumnType(const std::string &col_name)
Definition SDDSParser.h:69
std::string sddsFileName_m
Definition SDDSParser.h:51
T getBoostVariantValue(const ast::variant_t &val, int datatype) const
Convert value from std::variant (only numeric types) to a value of type T.
Definition SDDSParser.h:202
void getInterpolatedValue(std::string ref_name, double ref_val, std::string col_name, T &nval)
Definition SDDSParser.h:110
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:83
static std::string fixCaseSensitivity(const std::string &for_string)
Definition SDDSParser.h:46
void getInterpolatedValue(double spos, std::string col_name, T &nval)
Definition SDDSParser.h:172
SDDS::file sddsData_m
Definition SDDSParser.h:58
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:54
std::vector< variant_t > columnData_t
Definition ast.hpp:36
@ DOUBLE
Definition ast.hpp:26
@ LONG
Definition ast.hpp:26
@ FLOAT
Definition ast.hpp:26
@ SHORT
Definition ast.hpp:26
std::variant< float, double, short, long, char, std::string > variant_t
Definition ast.hpp:34
columnList sddsColumns_m
Definition file.hpp:39
parameterList sddsParameters_m
Definition file.hpp:38