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