OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
Util.h
Go to the documentation of this file.
1//
2// Namespace Util
3// This namespace contains useful global methods.
4//
5// Copyright (c) 200x - 2022, Paul Scherrer Institut, Villigen PSI, Switzerland
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#ifndef USEFULFUNCTIONS
19#define USEFULFUNCTIONS
20
21#include "Algorithms/Vektor.h"
23#include "Physics/Physics.h"
24
25#include <algorithm>
26#include <array>
27#include <cmath>
28#include <cstring>
29#include <iomanip>
30#include <initializer_list>
31#include <limits>
32#include <sstream>
33#include <string>
34#include <string_view>
35#include <type_traits>
36#include <vector>
37
38// ------- DON'T DELETE: start --------
39#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
40#define __DBGMSG__ __FILENAME__ << ": " << __LINE__ << "\t"
41// ------- DON'T DELETE: end --------
42
43namespace Util {
44 std::string getGitRevision();
45
46 double erfinv(double x);
47
48 inline
49 double getGamma(Vector_t p) {
50 return std::sqrt(dot(p, p) + 1.0);
51 }
52
53 inline
55 return p / getGamma(p);
56 }
57
58 inline
59 double getKineticEnergy(Vector_t p, double mass) {
60 return (getGamma(p) - 1.0) * mass;
61 }
62
63 inline
64 double getBetaGamma(double Ekin, double mass) {
65 double value = std::sqrt(std::pow(Ekin / mass + 1.0, 2) - 1.0);
66 if (value < std::numeric_limits<double>::epsilon())
67 value = std::sqrt(2 * Ekin / mass);
68 return value;
69 }
70
71 inline
72 double convertMomentumEVoverCToBetaGamma(double p, double mass) {
73 return p / mass;
74 }
75
76 inline
77 std::string getTimeString(double time, unsigned int precision = 3) {
78 std::string timeUnit(" [ps]");
79
80 time *= 1e12;
81 if (std::abs(time) > 1000) {
82 time /= 1000;
83 timeUnit = std::string(" [ns]");
84
85 if (std::abs(time) > 1000) {
86 time /= 1000;
87 timeUnit = std::string(" [ms]");
88 }
89 } else if (std::abs(time) < 1.0) {
90 time *= 1000;
91 timeUnit = std::string(" [fs]");
92 }
93
94 std::stringstream timeOutput;
95 timeOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << time << timeUnit;
96 return timeOutput.str();
97 }
98
99 inline
100 std::string getLengthString(double spos, unsigned int precision = 3) {
101 std::string sposUnit(" [m]");
102
103 if (std::abs(spos) < 1.0) {
104 spos *= 1000.0;
105 sposUnit = std::string(" [mm]");
106 }
107
108 if (std::abs(spos) < 1.0) {
109 spos *= 1000.0;
110 sposUnit = std::string(" [um]");
111 }
112
113 std::stringstream positionOutput;
114 positionOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << spos << sposUnit;
115 return positionOutput.str();
116 }
117
118 inline
119 std::string getLengthString(Vector_t spos, unsigned int precision = 3) {
120 std::string sposUnit(" [m]");
121 double maxPos = std::abs(spos(0));
122 for (unsigned int i = 1; i < 3u; ++ i) {
123 maxPos = std::max(maxPos, std::abs(spos(i)));
124 }
125
126 std::stringstream positionOutput;
127
128 if (maxPos < 1.0) {
129 maxPos *= 1000.0;
130 spos *= 1000.0;
131 sposUnit = std::string(" [mm]");
132 }
133
134 if (maxPos < 1.0) {
135 maxPos *= 1000.0;
136 spos *= 1000.0;
137 sposUnit = std::string(" [um]");
138 }
139
140 positionOutput << std::fixed << std::setprecision(precision)
141 << "( "
142 << std::setw(precision + 7) << spos(0) << " , "
143 << std::setw(precision + 7) << spos(1) << " , "
144 << std::setw(precision + 7) << spos(2)
145 << " )" << sposUnit;
146 return positionOutput.str();
147 }
148
149 inline
150 std::string getEnergyString(double energyInMeV, unsigned int precision = 3) {
151 std::string energyUnit(" [MeV]");
152 double energy = energyInMeV;
153
154 if (energy > 1000.0) {
155 energy /= 1000.0;
156 energyUnit = std::string(" [GeV]");
157 } else if (energy < 1.0) {
158 energy *= 1000.0;
159 energyUnit = std::string(" [keV]");
160 if (energy < 1.0) {
161 energy *= 1000.0;
162 energyUnit = std::string(" [eV]");
163 }
164 }
165
166 std::stringstream energyOutput;
167 energyOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << energy << energyUnit;
168
169 return energyOutput.str();
170 }
171
172 inline
173 std::string getChargeString(double charge, unsigned int precision = 3) {
174 std::string chargeUnit(" [fC]");
175
176 charge *= 1e15;
177
178 if (std::abs(charge) > 1000.0) {
179 charge /= 1000.0;
180 chargeUnit = std::string(" [pC]");
181 }
182
183 if (std::abs(charge) > 1000.0) {
184 charge /= 1000.0;
185 chargeUnit = std::string(" [nC]");
186 }
187
188 if (std::abs(charge) > 1000.0) {
189 charge /= 1000.0;
190 chargeUnit = std::string(" [uC]");
191 }
192
193 std::stringstream chargeOutput;
194 chargeOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << charge << chargeUnit;
195
196 return chargeOutput.str();
197 }
198
199 Vector_t getTaitBryantAngles(Quaternion rotation, const std::string& elementName = "");
200
202 inline double angle_0to2pi(double angle) {
203 // converts angle to range [-2*pi, 2*pi)
204 angle = std::fmod(angle, Physics::two_pi);
205 if (angle >= 0.0) return angle;
206 else return angle + Physics::two_pi;
207 }
209 inline bool angleBetweenAngles(const double angle, const double min, const double max) {
210 if (min <= max) return (angle >= min && angle <= max);
211 else return (angle >= min || angle <= max);
212 }
213
214 std::string toUpper(const std::string& str);
215
216 std::string boolToUpperString(const bool& b);
217
218 std::string boolVectorToUpperString(const std::vector<bool>& b);
219
220 std::string doubleVectorToString(const std::vector<double>& v);
221
222 std::string combineFilePath(std::initializer_list<std::string>);
223
224 void checkInt(double real, const std::string& name, double tolerance = 1e-9);
225
228 bool isAllDigits(const std::string& str);
229
230 template<class IteratorIn, class IteratorOut>
231 void toString(IteratorIn first, IteratorIn last, IteratorOut out);
232
233 std::string compressString(const std::string& str);
234
235 std::string replaceAll(const std::string& str, const std::string& from, const std::string& to);
236
237 // Split string on any of the characters in 'delims'. If compress==true,
238 // consecutive delimiters are treated as one (no empty tokens).
239 std::vector<std::string> split_any_of(const std::string& s,
240 const std::string& delims,
241 bool compress = true);
242
243 // Trim characters on both ends that are present in 'chars'
244 inline
245 std::string trim_chars(const std::string& s, const std::string& chars) {
246 std::size_t first = 0;
247 while (first < s.size() && chars.find(s[first]) != std::string::npos)
248 ++first;
249
250 std::size_t last = s.size();
251 while (last > first && chars.find(s[last - 1]) != std::string::npos)
252 --last;
253
254 return s.substr(first, last - first);
255 }
256
257 template <typename T>
258 std::string toStringWithThousandSep(T value, char sep = '\'');
259
260 template<typename Enum, std::size_t N>
261 constexpr Enum stringToEnum(std::string_view str,
262 const std::array<std::pair<Enum, std::string_view>, N>& map,
263 Enum defaultEnum) noexcept {
264 for (const auto& [e, s] : map) {
265 if (s == str) return e;
266 }
267 return defaultEnum;
268 }
269
270 template<typename Enum, std::size_t N>
271 constexpr std::string_view enumToString(Enum e,
272 const std::array<std::pair<Enum, std::string_view>, N>& map,
273 std::string_view defaultStr) noexcept {
274 for (const auto& [key, s] : map) {
275 if (key == e) return s;
276 }
277 return defaultStr;
278 }
279
280 template <typename It>
281 std::string join(It begin, It end, const std::string& delimiter) {
282 std::string result;
283
284 if (begin == end) return result;
285
286 result += *begin;
287 ++begin;
288
289 while (begin != end) {
290 result += delimiter;
291 result += *begin;
292 ++begin;
293 }
294
295 return result;
296 }
297
298 template <typename Container>
299 std::string join(const Container& container, const std::string& delimiter) {
300 return join(std::begin(container), std::end(container), delimiter);
301 }
302
304 long double sum;
305 long double correction;
307
308 KahanAccumulation& operator+=(double value);
309 };
310
311 unsigned int rewindLinesSDDS(const std::string& fileName, double maxSPos, bool checkForTime = true);
312
313 std::string base64_encode(const std::string& string_to_encode);//unsigned char const* , unsigned int len);
314 std::string base64_decode(std::string const& s);
315
316 template<typename T, typename A>
317 T* c_data(std::vector<T,A>& v) { return v.empty() ? static_cast<T*>(0) : &(v[0]); }
318
319 template<typename T, typename A>
320 T const* c_data(std::vector<T,A> const& v) { return v.empty() ? static_cast<T const*>(0) : &(v[0]); }
321}
322
323template <typename T>
324std::string Util::toStringWithThousandSep(T value, char sep) {
325 static_assert(std::is_integral<T>::value, "Util::toStringWithThousandSep: T must be of integer type");
326
327 unsigned int powers = std::floor(std::max(0.0,
328 std::log(std::abs((double)value)) / std::log(10.0))
329 );
330 powers -= powers % 3u;
331
332 std::ostringstream ret;
333 unsigned int i = 0;
334 while (powers >= 3u) {
335 T multiplicator = std::pow(T(10), powers);
336 T pre = value / multiplicator;
337 if (i > 0) {
338 ret << std::setw(3) << std::setfill('0') << pre << sep;
339 } else {
340 ret << pre << sep;
341 }
342 value -= pre * multiplicator;
343
344 powers -= 3;
345 ++ i;
346 }
347
348 if (i > 0) {
349 ret << std::setw(3) << std::setfill('0') << value;
350 } else {
351 ret << value;
352 }
353
354 return ret.str();
355}
356
357template<class IteratorIn, class IteratorOut>
358void Util::toString(IteratorIn first, IteratorIn last, IteratorOut out) {
359 std::transform(first, last, out, [](auto d) {
360 std::ostringstream stm;
361 stm << d;
362 return stm.str();
363 } );
364}
365
366#endif
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:118
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
const std::string name
constexpr double two_pi
The value of.
Definition Physics.h:33
Definition Util.cpp:37
void checkInt(double real, const std::string &name, double tolerance)
Definition Util.cpp:212
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition Util.cpp:204
bool angleBetweenAngles(const double angle, const double min, const double max)
check if angle (in rad and in range [0,2pi]) is within [min, max]
Definition Util.h:209
std::string doubleVectorToString(const std::vector< double > &v)
Definition Util.cpp:183
std::string getChargeString(double charge, unsigned int precision=3)
Definition Util.h:173
Vector_t getTaitBryantAngles(Quaternion rotation, const std::string &)
Definition Util.cpp:122
std::string boolVectorToUpperString(const std::vector< bool > &b)
Definition Util.cpp:168
double getKineticEnergy(Vector_t p, double mass)
Definition Util.h:59
void toString(IteratorIn first, IteratorIn last, IteratorOut out)
Definition Util.h:358
double convertMomentumEVoverCToBetaGamma(double p, double mass)
Definition Util.h:72
double getBetaGamma(double Ekin, double mass)
Definition Util.h:64
std::string toUpper(const std::string &str)
Definition Util.cpp:152
double erfinv(double x)
Definition Util.cpp:62
T * c_data(std::vector< T, A > &v)
Definition Util.h:317
std::vector< std::string > split_any_of(const std::string &s, const std::string &delims, bool compress)
Definition Util.cpp:250
std::string base64_decode(std::string const &encoded_string)
Definition Util.cpp:493
std::string replaceAll(const std::string &str, const std::string &from, const std::string &to)
Definition Util.cpp:231
unsigned int rewindLinesSDDS(const std::string &fileName, double maxSPos, bool checkForTime)
rewind the SDDS file such that the spos of the last step is less or equal to maxSPos
Definition Util.cpp:305
constexpr Enum stringToEnum(std::string_view str, const std::array< std::pair< Enum, std::string_view >, N > &map, Enum defaultEnum) noexcept
Definition Util.h:261
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
Definition Util.h:150
constexpr std::string_view enumToString(Enum e, const std::array< std::pair< Enum, std::string_view >, N > &map, std::string_view defaultStr) noexcept
Definition Util.h:271
std::string trim_chars(const std::string &s, const std::string &chars)
Definition Util.h:245
std::string getTimeString(double time, unsigned int precision=3)
Definition Util.h:77
std::string getGitRevision()
Definition Util.cpp:38
std::string compressString(const std::string &str)
Definition Util.cpp:271
std::string base64_encode(const std::string &string_to_encode)
Definition Util.cpp:449
Vector_t getBeta(Vector_t p)
Definition Util.h:54
double getGamma(Vector_t p)
Definition Util.h:49
std::string boolToUpperString(const bool &b)
Definition Util.cpp:161
std::string getLengthString(double spos, unsigned int precision=3)
Definition Util.h:100
double angle_0to2pi(double angle)
convert angle (in rad) to [0,2pi) range, from https://stackoverflow.com/a/29721295
Definition Util.h:202
bool isAllDigits(const std::string &str)
Definition Util.cpp:225
std::string join(It begin, It end, const std::string &delimiter)
Definition Util.h:281
std::string toStringWithThousandSep(T value, char sep='\'')
Definition Util.h:324
long double sum
Definition Util.h:304
long double correction
Definition Util.h:305
KahanAccumulation & operator+=(double value)
Definition Util.cpp:294