OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Util.cpp
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#include "Utilities/Util.h"
19#include "Physics/Physics.h"
20#include "OPALrevision.h"
21
22#include <boost/filesystem.hpp>
23#include <boost/regex.hpp>
24
25#include <cctype>
26#include <fstream>
27#include <iostream>
28#include <iterator>
29#include <queue>
30
31namespace Util {
32 std::string getGitRevision() {
33 return std::string(GIT_VERSION);
34 }
35
36#define erfinv_a3 -0.140543331
37#define erfinv_a2 0.914624893
38#define erfinv_a1 -1.645349621
39#define erfinv_a0 0.886226899
40
41#define erfinv_b4 0.012229801
42#define erfinv_b3 -0.329097515
43#define erfinv_b2 1.442710462
44#define erfinv_b1 -2.118377725
45#define erfinv_b0 1
46
47#define erfinv_c3 1.641345311
48#define erfinv_c2 3.429567803
49#define erfinv_c1 -1.62490649
50#define erfinv_c0 -1.970840454
51
52#define erfinv_d2 1.637067800
53#define erfinv_d1 3.543889200
54#define erfinv_d0 1
55
56 double erfinv (double x) // inverse error function
57 {
58 double r;
59 int sign_x;
60
61 if (x < -1 || x > 1)
62 return NAN;
63
64 if (x == 0)
65 return 0;
66
67 if (x > 0)
68 sign_x = 1;
69 else {
70 sign_x = -1;
71 x = -x;
72 }
73
74 if (x <= 0.7) {
75 double x2 = x * x;
76 r =
77 x * (((erfinv_a3 * x2 + erfinv_a2) * x2 + erfinv_a1) * x2 + erfinv_a0);
78 r /= (((erfinv_b4 * x2 + erfinv_b3) * x2 + erfinv_b2) * x2 +
79 erfinv_b1) * x2 + erfinv_b0;
80 }
81 else {
82 double y = std::sqrt (-std::log ((1 - x) / 2));
83 r = (((erfinv_c3 * y + erfinv_c2) * y + erfinv_c1) * y + erfinv_c0);
84 r /= ((erfinv_d2 * y + erfinv_d1) * y + erfinv_d0);
85 }
86
87 r = r * sign_x;
88 x = x * sign_x;
89
90 r -= (std::erf (r) - x) / (2 / std::sqrt (M_PI) * std::exp (-r * r));
91 r -= (std::erf (r) - x) / (2 / std::sqrt (M_PI) * std::exp (-r * r));
92
93 return r;
94 }
95
96#undef erfinv_a3
97#undef erfinv_a2
98#undef erfinv_a1
99#undef erfinv_a0
100
101#undef erfinv_b4
102#undef erfinv_b3
103#undef erfinv_b2
104#undef erfinv_b1
105#undef erfinv_b0
106
107#undef erfinv_c3
108#undef erfinv_c2
109#undef erfinv_c1
110#undef erfinv_c0
111
112#undef erfinv_d2
113#undef erfinv_d1
114#undef erfinv_d0
115
116 Vector_t getTaitBryantAngles(Quaternion rotation, const std::string& /*elementName*/) {
117 Quaternion rotationBAK = rotation;
118
119 // y axis
120 Vector_t tmp = rotation.rotate(Vector_t(0, 0, 1));
121 tmp(1) = 0.0;
122 // tmp /= euclidean_norm(tmp);
123 double theta = std::fmod(std::atan2(tmp(0), tmp(2)) + Physics::two_pi, Physics::two_pi);
124
125 Quaternion rotTheta(std::cos(0.5 * theta), 0, std::sin(0.5 * theta), 0);
126 rotation = rotTheta.conjugate() * rotation;
127
128 // x axis
129 tmp = rotation.rotate(Vector_t(0, 0, 1));
130 tmp(0) = 0.0;
131 tmp /= euclidean_norm(tmp);
132 double phi = std::fmod(std::atan2(-tmp(1), tmp(2)) + Physics::two_pi, Physics::two_pi);
133
134 Quaternion rotPhi(std::cos(0.5 * phi), std::sin(0.5 * phi), 0, 0);
135 rotation = rotPhi.conjugate() * rotation;
136
137 // z axis
138 tmp = rotation.rotate(Vector_t(1, 0, 0));
139 tmp(2) = 0.0;
140 tmp /= euclidean_norm(tmp);
141 double psi = std::fmod(std::atan2(tmp(1), tmp(0)) + Physics::two_pi, Physics::two_pi);
142
143 return Vector_t(theta, phi, psi);
144 }
145
146 std::string toUpper(const std::string& str) {
147 std::string output = str;
148 std::transform(output.begin(), output.end(), output.begin(), [](const char c) { return std::toupper(c);});
149
150 return output;
151 }
152
153 std::string boolToUpperString(const bool& b) {
154 std::ostringstream valueStream;
155 valueStream << std::boolalpha << b;
156 std::string output = Util::toUpper(valueStream.str());
157 return output;
158 }
159
160 std::string boolVectorToUpperString(const std::vector<bool>& b) {
161 std::ostringstream output;
162 if (b.size() > 1) {
163 output << "(";
164 }
165 for (size_t i = 0; i < b.size(); ++i) {
166 output << std::boolalpha << boolToUpperString(b[i]);
167 if (b.size() > 1) {
168 (i < (b.size()-1)) ? (output << ", ") : (output << ")");
169 }
170 }
171
172 return output.str();
173 }
174
175 std::string doubleVectorToString(const std::vector<double>& v) {
176 std::vector<std::string> stringVec;
177 stringVec.reserve(v.size());
178 Util::toString(std::begin(v), std::end(v), std::back_inserter(stringVec));
179
180 std::ostringstream output;
181 if (v.size() > 1) {
182 output << "(";
183 }
184 unsigned int i = 0;
185 for (auto& s: stringVec) {
186 ++i;
187 output << s;
188 if (v.size() > 1) {
189 (i < stringVec.size()) ? (output << ", ") : (output << ")");
190 }
191 }
192
193 return output.str();
194 }
195
196 std::string combineFilePath(std::initializer_list<std::string> ilist) {
197 boost::filesystem::path path;
198 for (auto entry : ilist) {
199 path /= entry;
200 }
201 return path.string();
202 }
203
205 sum(0.0),
206 correction(0.0)
207 { }
208
210 long double y = value - this->correction;
211 long double t = this->sum + y;
212 this->correction = (t - this->sum) - y;
213 this->sum = t;
214 return *this;
215 }
216
220 unsigned int rewindLinesSDDS(const std::string& fileName, double maxSPos, bool checkForTime) {
221 if (Ippl::myNode() > 0) return 0;
222
223 std::fstream fs(fileName.c_str(), std::fstream::in);
224 if (!fs.is_open()) return 0;
225
226 std::string line;
227 std::queue<std::string> allLines;
228 unsigned int numParameters = 0;
229 unsigned int numColumns = 0;
230 unsigned int sposColumnNr = 0;
231 unsigned int timeColumnNr = 0;
232 double spos, time = 0.0;
233 double lastTime = -1.0;
234
235 boost::regex parameters("&parameter");
236 boost::regex column("&column");
237 boost::regex data("&data");
238 boost::regex end("&end");
239 boost::regex name("name=([a-zA-Z0-9\\$_]+)");
240 boost::smatch match;
241
242 std::istringstream linestream;
243
244 while (std::getline(fs, line)) {
245 allLines.push(line);
246 }
247 fs.close();
248
249 fs.open (fileName.c_str(), std::fstream::out);
250
251 if (!fs.is_open()) return 0;
252
253 do {
254 line = allLines.front();
255 allLines.pop();
256 fs << line << "\n";
257 if (boost::regex_search(line, match, parameters)) {
258 ++numParameters;
259 while (!boost::regex_search(line, match, end)) {
260 line = allLines.front();
261 allLines.pop();
262 fs << line << "\n";
263 }
264 } else if (boost::regex_search(line, match, column)) {
265 ++numColumns;
266 while (!boost::regex_search(line, match, name)) {
267 line = allLines.front();
268 allLines.pop();
269 fs << line << "\n";
270 }
271 if (match[1] == "s") {
272 sposColumnNr = numColumns;
273 }
274 if (match[1] == "t") {
275 timeColumnNr = numColumns;
276 }
277 while (!boost::regex_search(line, match, end)) {
278 line = allLines.front();
279 allLines.pop();
280 fs << line << "\n";
281 }
282 }
283 } while (!boost::regex_search(line, match, data));
284
285 while (!boost::regex_search(line, match, end)) {
286 line = allLines.front();
287 allLines.pop();
288 fs << line << "\n";
289 }
290
291 for (unsigned int i = 0; i < numParameters; ++ i) {
292 fs << allLines.front() << "\n";
293 allLines.pop();
294 }
295
296 while (!allLines.empty()) {
297 line = allLines.front();
298
299 linestream.str(line);
300 if (checkForTime) {
301 for (unsigned int i = 0; i < timeColumnNr; ++ i) {
302 linestream >> time;
303 }
304 }
305
306 linestream.str(line);
307 for (unsigned int i = 0; i < sposColumnNr; ++ i) {
308 linestream >> spos;
309 }
310
311 if ((spos - maxSPos) > 1e-20 * Physics::c) break;
312
313 allLines.pop();
314
315 if (!checkForTime || (time - lastTime) > 1e-20)
316 fs << line << "\n";
317
318 lastTime = time;
319 }
320
321 fs.close();
322
323 if (!allLines.empty())
324 INFOMSG(level2 << "rewind " + fileName + " to " + std::to_string(maxSPos) << " m" << endl);
325
326 return allLines.size();
327 }
328
329 /*
330 base64.cpp and base64.h
331
332 Copyright (C) 2004-2008 René Nyffenegger
333
334 This source code is provided 'as-is', without any express or implied
335 warranty. In no event will the author be held liable for any damages
336 arising from the use of this software.
337
338 Permission is granted to anyone to use this software for any purpose,
339 including commercial applications, and to alter it and redistribute it
340 freely, subject to the following restrictions:
341
342 1. The origin of this source code must not be misrepresented; you must not
343 claim that you wrote the original source code. If you use this source code
344 in a product, an acknowledgment in the product documentation would be
345 appreciated but is not required.
346
347 2. Altered source versions must be plainly marked as such, and must not be
348 misrepresented as being the original source code.
349
350 3. This notice may not be removed or altered from any source distribution.
351
352 René Nyffenegger rene.nyffenegger@adp-gmbh.ch
353
354 */
355
356 static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
357 "abcdefghijklmnopqrstuvwxyz"
358 "0123456789+/";
359
360 static inline bool is_base64(unsigned char c) {
361 return (std::isalnum(c) || (c == '+') || (c == '/'));
362 }
363
364 std::string base64_encode(const std::string& string_to_encode) {
365 const char* bytes_to_encode = string_to_encode.c_str();
366 unsigned int in_len = string_to_encode.size();
367 std::string ret;
368 int i = 0;
369 int j = 0;
370 unsigned char char_array_3[3];
371 unsigned char char_array_4[4];
372
373 while (in_len--) {
374 char_array_3[i++] = *(bytes_to_encode++);
375 if (i == 3) {
376 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
377 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
378 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
379 char_array_4[3] = char_array_3[2] & 0x3f;
380
381 for (i = 0; (i <4) ; i++)
382 ret += base64_chars[char_array_4[i]];
383 i = 0;
384 }
385 }
386
387 if (i)
388 {
389 for (j = i; j < 3; j++)
390 char_array_3[j] = '\0';
391
392 char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
393 char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
394 char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
395 char_array_4[3] = char_array_3[2] & 0x3f;
396
397 for (j = 0; (j < i + 1); j++)
398 ret += base64_chars[char_array_4[j]];
399
400 while((i++ < 3))
401 ret += '=';
402
403 }
404
405 return ret;
406 }
407
408 std::string base64_decode(std::string const& encoded_string) {
409 int in_len = encoded_string.size();
410 int i = 0;
411 int j = 0;
412 int in_ = 0;
413 unsigned char char_array_4[4], char_array_3[3];
414 std::string ret;
415
416 while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
417 char_array_4[i++] = encoded_string[in_]; in_++;
418 if (i ==4) {
419 for (i = 0; i <4; i++)
420 char_array_4[i] = base64_chars.find(char_array_4[i]);
421
422 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
423 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
424 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
425
426 for (i = 0; (i < 3); i++)
427 ret += char_array_3[i];
428 i = 0;
429 }
430 }
431
432 if (i) {
433 for (j = i; j <4; j++)
434 char_array_4[j] = 0;
435
436 for (j = 0; j <4; j++)
437 char_array_4[j] = base64_chars.find(char_array_4[j]);
438
439 char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
440 char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
441 char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
442
443 for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
444 }
445
446 return ret;
447 }
448}
FTps< T, N > erf(const FTps< T, N > &x, int trunc=(FTps< T, N >::EXACT))
Error function.
Definition: FTpsMath.h:385
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
#define erfinv_c1
Definition: Util.cpp:49
#define erfinv_d0
Definition: Util.cpp:54
#define erfinv_a0
Definition: Util.cpp:39
#define erfinv_b2
Definition: Util.cpp:43
#define erfinv_b1
Definition: Util.cpp:44
#define erfinv_a2
Definition: Util.cpp:37
#define erfinv_c2
Definition: Util.cpp:48
#define erfinv_c3
Definition: Util.cpp:47
#define erfinv_d1
Definition: Util.cpp:53
#define erfinv_a1
Definition: Util.cpp:38
#define erfinv_a3
Definition: Util.cpp:36
#define erfinv_b4
Definition: Util.cpp:41
#define erfinv_d2
Definition: Util.cpp:52
#define erfinv_b0
Definition: Util.cpp:45
#define erfinv_b3
Definition: Util.cpp:42
#define erfinv_c0
Definition: Util.cpp:50
Tps< T > log(const Tps< T > &x)
Natural logarithm.
Definition: TpsMath.h:182
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > exp(const Tps< T > &x)
Exponential.
Definition: TpsMath.h:165
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition: Vector.h:243
#define GIT_VERSION
Definition: OPALrevision.h:1
T::PETE_Expr_t::PETE_Return_t sum(const PETE_Expr< T > &expr)
Definition: PETE.h:1111
PETE_TBTree< FnFmod, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > fmod(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
Inform & level2(Inform &inf)
Definition: Inform.cpp:46
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define INFOMSG(msg)
Definition: IpplInfo.h:348
const std::string name
constexpr double two_pi
The value of.
Definition: Physics.h:33
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double c
The velocity of light in m/s.
Definition: Physics.h:45
Definition: Util.cpp:31
std::string combineFilePath(std::initializer_list< std::string > ilist)
Definition: Util.cpp:196
std::string doubleVectorToString(const std::vector< double > &v)
Definition: Util.cpp:175
Vector_t getTaitBryantAngles(Quaternion rotation, const std::string &)
Definition: Util.cpp:116
std::string boolVectorToUpperString(const std::vector< bool > &b)
Definition: Util.cpp:160
void toString(IteratorIn first, IteratorIn last, IteratorOut out)
Definition: Util.h:268
std::string toUpper(const std::string &str)
Definition: Util.cpp:146
double erfinv(double x)
Definition: Util.cpp:56
std::string base64_decode(std::string const &encoded_string)
Definition: Util.cpp:408
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:220
std::string getGitRevision()
Definition: Util.cpp:32
std::string base64_encode(const std::string &string_to_encode)
Definition: Util.cpp:364
std::string boolToUpperString(const bool &b)
Definition: Util.cpp:153
FRONT * fs
Definition: hypervolume.cpp:59
Vector_t rotate(const Vector_t &) const
Definition: Quaternion.cpp:122
Quaternion conjugate() const
Definition: Quaternion.h:105
long double sum
Definition: Util.h:214
long double correction
Definition: Util.h:215
KahanAccumulation & operator+=(double value)
Definition: Util.cpp:209
static int myNode()
Definition: IpplInfo.cpp:691
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6