OPAL (Object Oriented Parallel Accelerator Library)  2024.1
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"
22 #include "Algorithms/Quaternion.h"
23 #include "Physics/Physics.h"
24 
25 #include <algorithm>
26 #include <cmath>
27 #include <cstring>
28 #include <functional>
29 #include <initializer_list>
30 #include <limits>
31 #include <sstream>
32 #include <string>
33 #include <type_traits>
34 
35 // ------- DON'T DELETE: start --------
36 #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
37 #define __DBGMSG__ __FILENAME__ << ": " << __LINE__ << "\t"
38 // ------- DON'T DELETE: end --------
39 
40 namespace Util {
41  std::string getGitRevision();
42 
43  double erfinv(double x);
44 
45  inline
46  double getGamma(Vector_t p) {
47  return std::sqrt(dot(p, p) + 1.0);
48  }
49 
50  inline
52  return p / getGamma(p);
53  }
54 
55  inline
56  double getKineticEnergy(Vector_t p, double mass) {
57  return (getGamma(p) - 1.0) * mass;
58  }
59 
60  inline
61  double getBetaGamma(double Ekin, double mass) {
62  double value = std::sqrt(std::pow(Ekin / mass + 1.0, 2) - 1.0);
63  if (value < std::numeric_limits<double>::epsilon())
64  value = std::sqrt(2 * Ekin / mass);
65  return value;
66  }
67 
68  inline
69  double convertMomentumEVoverCToBetaGamma(double p, double mass) {
70  return p / mass;
71  }
72 
73  inline
74  std::string getTimeString(double time, unsigned int precision = 3) {
75  std::string timeUnit(" [ps]");
76 
77  time *= 1e12;
78  if (std::abs(time) > 1000) {
79  time /= 1000;
80  timeUnit = std::string(" [ns]");
81 
82  if (std::abs(time) > 1000) {
83  time /= 1000;
84  timeUnit = std::string(" [ms]");
85  }
86  } else if (std::abs(time) < 1.0) {
87  time *= 1000;
88  timeUnit = std::string(" [fs]");
89  }
90 
91  std::stringstream timeOutput;
92  timeOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << time << timeUnit;
93  return timeOutput.str();
94  }
95 
96  inline
97  std::string getLengthString(double spos, unsigned int precision = 3) {
98  std::string sposUnit(" [m]");
99 
100  if (std::abs(spos) < 1.0) {
101  spos *= 1000.0;
102  sposUnit = std::string(" [mm]");
103  }
104 
105  if (std::abs(spos) < 1.0) {
106  spos *= 1000.0;
107  sposUnit = std::string(" [um]");
108  }
109 
110  std::stringstream positionOutput;
111  positionOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << spos << sposUnit;
112  return positionOutput.str();
113  }
114 
115  inline
116  std::string getLengthString(Vector_t spos, unsigned int precision = 3) {
117  std::string sposUnit(" [m]");
118  double maxPos = std::abs(spos(0));
119  for (unsigned int i = 1; i < 3u; ++ i) {
120  maxPos = std::max(maxPos, std::abs(spos(i)));
121  }
122 
123  std::stringstream positionOutput;
124 
125  if (maxPos < 1.0) {
126  maxPos *= 1000.0;
127  spos *= 1000.0;
128  sposUnit = std::string(" [mm]");
129  }
130 
131  if (maxPos < 1.0) {
132  maxPos *= 1000.0;
133  spos *= 1000.0;
134  sposUnit = std::string(" [um]");
135  }
136 
137  positionOutput << std::fixed << std::setprecision(precision)
138  << "( "
139  << std::setw(precision + 7) << spos(0) << " , "
140  << std::setw(precision + 7) << spos(1) << " , "
141  << std::setw(precision + 7) << spos(2)
142  << " )" << sposUnit;
143  return positionOutput.str();
144  }
145 
146  inline
147  std::string getEnergyString(double energyInMeV, unsigned int precision = 3) {
148  std::string energyUnit(" [MeV]");
149  double energy = energyInMeV;
150 
151  if (energy > 1000.0) {
152  energy /= 1000.0;
153  energyUnit = std::string(" [GeV]");
154  } else if (energy < 1.0) {
155  energy *= 1000.0;
156  energyUnit = std::string(" [keV]");
157  if (energy < 1.0) {
158  energy *= 1000.0;
159  energyUnit = std::string(" [eV]");
160  }
161  }
162 
163  std::stringstream energyOutput;
164  energyOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << energy << energyUnit;
165 
166  return energyOutput.str();
167  }
168 
169  inline
170  std::string getChargeString(double charge, unsigned int precision = 3) {
171  std::string chargeUnit(" [fC]");
172 
173  charge *= 1e15;
174 
175  if (std::abs(charge) > 1000.0) {
176  charge /= 1000.0;
177  chargeUnit = std::string(" [pC]");
178  }
179 
180  if (std::abs(charge) > 1000.0) {
181  charge /= 1000.0;
182  chargeUnit = std::string(" [nC]");
183  }
184 
185  if (std::abs(charge) > 1000.0) {
186  charge /= 1000.0;
187  chargeUnit = std::string(" [uC]");
188  }
189 
190  std::stringstream chargeOutput;
191  chargeOutput << std::fixed << std::setw(precision + 2) << std::setprecision(precision) << charge << chargeUnit;
192 
193  return chargeOutput.str();
194  }
195 
196  Vector_t getTaitBryantAngles(Quaternion rotation, const std::string& elementName = "");
197 
199  inline double angle_0to2pi(double angle) {
200  // converts angle to range [-2*pi, 2*pi)
201  angle = std::fmod(angle, Physics::two_pi);
202  if (angle >= 0.0) return angle;
203  else return angle + Physics::two_pi;
204  }
206  inline bool angleBetweenAngles(const double angle, const double min, const double max) {
207  if (min <= max) return (angle >= min && angle <= max);
208  else return (angle >= min || angle <= max);
209  }
210 
211  std::string toUpper(const std::string& str);
212 
213  std::string boolToUpperString(const bool& b);
214 
215  std::string boolVectorToUpperString(const std::vector<bool>& b);
216 
217  std::string doubleVectorToString(const std::vector<double>& v);
218 
219  std::string combineFilePath(std::initializer_list<std::string>);
220 
221  void checkInt(double real, std::string name, double tolerance = 1e-9);
222 
225  bool isAllDigits(const std::string& str);
226 
227  template<class IteratorIn, class IteratorOut>
228  void toString(IteratorIn first, IteratorIn last, IteratorOut out);
229 
230  template <typename T>
231  std::string toStringWithThousandSep(T value, char sep = '\'');
232 
234  long double sum;
235  long double correction;
237 
238  KahanAccumulation& operator+=(double value);
239  };
240 
241  unsigned int rewindLinesSDDS(const std::string& fileName, double maxSPos, bool checkForTime = true);
242 
243  std::string base64_encode(const std::string& string_to_encode);//unsigned char const* , unsigned int len);
244  std::string base64_decode(std::string const& s);
245 
246  template<typename T, typename A>
247  T* c_data(std::vector<T,A>& v) { return v.empty() ? static_cast<T*>(0) : &(v[0]); }
248 
249  template<typename T, typename A>
250  T const* c_data(std::vector<T,A> const& v) { return v.empty() ? static_cast<T const*>(0) : &(v[0]); }
251 }
252 
253 template <typename T>
254 std::string Util::toStringWithThousandSep(T value, char sep) {
255  static_assert(std::is_integral<T>::value, "Util::toStringWithThousandSep: T must be of integer type");
256 
257  unsigned int powers = std::floor(std::max(0.0,
258  std::log(std::abs((double)value)) / std::log(10.0))
259  );
260  powers -= powers % 3u;
261 
262  std::ostringstream ret;
263  unsigned int i = 0;
264  while (powers >= 3u) {
265  T multiplicator = std::pow(T(10), powers);
266  T pre = value / multiplicator;
267  if (i > 0) {
268  ret << std::setw(3) << std::setfill('0') << pre << sep;
269  } else {
270  ret << pre << sep;
271  }
272  value -= pre * multiplicator;
273 
274  powers -= 3;
275  ++ i;
276  }
277 
278  if (i > 0) {
279  ret << std::setw(3) << std::setfill('0') << value;
280  } else {
281  ret << value;
282  }
283 
284  return ret.str();
285 }
286 
287 template<class IteratorIn, class IteratorOut>
288 void Util::toString(IteratorIn first, IteratorIn last, IteratorOut out) {
289  std::transform(first, last, out, [](auto d) {
290  std::ostringstream stm;
291  stm << d;
292  return stm.str();
293  } );
294 }
295 
296 #endif
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
double angle_0to2pi(double angle)
convert angle (in rad) to [0,2pi) range, from https://stackoverflow.com/a/29721295 ...
Definition: Util.h:199
double convertMomentumEVoverCToBetaGamma(double p, double mass)
Definition: Util.h:69
std::string boolVectorToUpperString(const std::vector< bool > &b)
Definition: Util.cpp:161
Vector_t getTaitBryantAngles(Quaternion rotation, const std::string &)
Definition: Util.cpp:117
item[EANGLE] Entrance edge angle(radians).\item[ROTATION] Rotation of the magnet about its central axis(radians
constexpr double two_pi
The value of .
Definition: Physics.h:33
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
long double correction
Definition: Util.h:235
std::string boolToUpperString(const bool &b)
Definition: Util.cpp:154
std::string getGitRevision()
Definition: Util.cpp:33
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:206
Definition: TSVMeta.h:24
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:240
std::string base64_encode(const std::string &string_to_encode)
Definition: Util.cpp:384
T * c_data(std::vector< T, A > &v)
Definition: Util.h:247
std::string toUpper(const std::string &str)
Definition: Util.cpp:147
T::PETE_Expr_t::PETE_Return_t min(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:76
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
std::string getTimeString(double time, unsigned int precision=3)
Definition: Util.h:74
long double sum
Definition: Util.h:234
bool isAllDigits(const std::string &str)
Definition: Util.cpp:218
std::string toStringWithThousandSep(T value, char sep= '\'')
Definition: Util.h:254
Vector_t getBeta(Vector_t p)
Definition: Util.h:51
double getKineticEnergy(Vector_t p, double mass)
Definition: Util.h:56
std::string getEnergyString(double energyInMeV, unsigned int precision=3)
Definition: Util.h:147
double getGamma(Vector_t p)
Definition: Util.h:46
double erfinv(double x)
Definition: Util.cpp:57
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
const std::string name
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition: Util.cpp:197
std::string getChargeString(double charge, unsigned int precision=3)
Definition: Util.h:170
std::string doubleVectorToString(const std::vector< double > &v)
Definition: Util.cpp:176
constexpr double e
The value of .
Definition: Physics.h:39
std::string getLengthString(double spos, unsigned int precision=3)
Definition: Util.h:97
Tps< T > pow(const Tps< T > &x, int y)
Integer power.
Definition: TpsMath.h:76
void checkInt(double real, std::string name, double tolerance)
Definition: Util.cpp:205
PETE_TUTree< FnFloor, typename T::PETE_Expr_t > floor(const PETE_Expr< T > &l)
Definition: PETE.h:733
std::string base64_decode(std::string const &encoded_string)
Definition: Util.cpp:428
FLieGenerator< T, N > real(const FLieGenerator< std::complex< T >, N > &)
Take real part of a complex generator.
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition: Vector3D.cpp:118
double getBetaGamma(double Ekin, double mass)
Definition: Util.h:61
void toString(IteratorIn first, IteratorIn last, IteratorOut out)
Definition: Util.h:288
KahanAccumulation & operator+=(double value)
Definition: Util.cpp:229