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