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, 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 template <typename T>
234 std::string toStringWithThousandSep(T value, char sep = '\'');
235
236 template<typename Enum, std::size_t N>
237 constexpr Enum stringToEnum(std::string_view str,
238 const std::array<std::pair<Enum, std::string_view>, N>& map,
239 Enum defaultEnum) noexcept {
240 for (const auto& [e, s] : map) {
241 if (s == str) return e;
242 }
243 return defaultEnum;
244 }
245
246 template<typename Enum, std::size_t N>
247 constexpr std::string_view enumToString(Enum e,
248 const std::array<std::pair<Enum, std::string_view>, N>& map,
249 std::string_view defaultStr) noexcept {
250 for (const auto& [key, s] : map) {
251 if (key == e) return s;
252 }
253 return defaultStr;
254 }
255
257 long double sum;
258 long double correction;
260
261 KahanAccumulation& operator+=(double value);
262 };
263
264 unsigned int rewindLinesSDDS(const std::string& fileName, double maxSPos, bool checkForTime = true);
265
266 std::string base64_encode(const std::string& string_to_encode);//unsigned char const* , unsigned int len);
267 std::string base64_decode(std::string const& s);
268
269 template<typename T, typename A>
270 T* c_data(std::vector<T,A>& v) { return v.empty() ? static_cast<T*>(0) : &(v[0]); }
271
272 template<typename T, typename A>
273 T const* c_data(std::vector<T,A> const& v) { return v.empty() ? static_cast<T const*>(0) : &(v[0]); }
274}
275
276template <typename T>
277std::string Util::toStringWithThousandSep(T value, char sep) {
278 static_assert(std::is_integral<T>::value, "Util::toStringWithThousandSep: T must be of integer type");
279
280 unsigned int powers = std::floor(std::max(0.0,
281 std::log(std::abs((double)value)) / std::log(10.0))
282 );
283 powers -= powers % 3u;
284
285 std::ostringstream ret;
286 unsigned int i = 0;
287 while (powers >= 3u) {
288 T multiplicator = std::pow(T(10), powers);
289 T pre = value / multiplicator;
290 if (i > 0) {
291 ret << std::setw(3) << std::setfill('0') << pre << sep;
292 } else {
293 ret << pre << sep;
294 }
295 value -= pre * multiplicator;
296
297 powers -= 3;
298 ++ i;
299 }
300
301 if (i > 0) {
302 ret << std::setw(3) << std::setfill('0') << value;
303 } else {
304 ret << value;
305 }
306
307 return ret.str();
308}
309
310template<class IteratorIn, class IteratorOut>
311void Util::toString(IteratorIn first, IteratorIn last, IteratorOut out) {
312 std::transform(first, last, out, [](auto d) {
313 std::ostringstream stm;
314 stm << d;
315 return stm.str();
316 } );
317}
318
319#endif
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:118
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:35
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition Util.cpp:200
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:179
std::string getChargeString(double charge, unsigned int precision=3)
Definition Util.h:173
Vector_t getTaitBryantAngles(Quaternion rotation, const std::string &)
Definition Util.cpp:120
std::string boolVectorToUpperString(const std::vector< bool > &b)
Definition Util.cpp:164
double getKineticEnergy(Vector_t p, double mass)
Definition Util.h:59
void toString(IteratorIn first, IteratorIn last, IteratorOut out)
Definition Util.h:311
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:150
double erfinv(double x)
Definition Util.cpp:60
T * c_data(std::vector< T, A > &v)
Definition Util.h:270
std::string base64_decode(std::string const &encoded_string)
Definition Util.cpp:431
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:243
constexpr Enum stringToEnum(std::string_view str, const std::array< std::pair< Enum, std::string_view >, N > &map, Enum defaultEnum) noexcept
Definition Util.h:237
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:247
void checkInt(double real, std::string name, double tolerance)
Definition Util.cpp:208
std::string getTimeString(double time, unsigned int precision=3)
Definition Util.h:77
std::string getGitRevision()
Definition Util.cpp:36
std::string base64_encode(const std::string &string_to_encode)
Definition Util.cpp:387
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:157
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:221
std::string toStringWithThousandSep(T value, char sep='\'')
Definition Util.h:277
long double sum
Definition Util.h:257
long double correction
Definition Util.h:258
KahanAccumulation & operator+=(double value)
Definition Util.cpp:232