33#include <unordered_map>
35namespace marley_utils {
38 constexpr int PHOTON = 22;
39 constexpr int ELECTRON = 11;
40 constexpr int POSITRON = -11;
41 constexpr int ELECTRON_NEUTRINO = 12;
42 constexpr int ELECTRON_ANTINEUTRINO = -12;
43 constexpr int MUON = 13;
44 constexpr int MUON_NEUTRINO = 14;
45 constexpr int MUON_ANTINEUTRINO = -14;
46 constexpr int TAU = 15;
47 constexpr int TAU_NEUTRINO = 16;
48 constexpr int TAU_ANTINEUTRINO = -16;
49 constexpr int NEUTRON = 2112;
50 constexpr int PROTON = 2212;
51 constexpr int DEUTERON = 1000010020;
52 constexpr int TRITON = 1000010030;
53 constexpr int HELION = 1000020030;
54 constexpr int ALPHA = 1000020040;
59 constexpr double UNKNOWN_MAX = std::numeric_limits<double>::infinity();
63 constexpr int LARGE_NUMBER_OF_ITERATIONS = 100000;
66 constexpr double GF = 1.16637e-11;
68 constexpr double GF2 = GF * GF;
72 constexpr double Vud = 0.97427;
74 constexpr double Vud2 = Vud * Vud;
79 constexpr double sin2thetaw = 0.23155;
83 constexpr double MeV = 1e-3;
87 constexpr double micro_amu = 0.000931494061;
90 constexpr double infinity = std::numeric_limits<double>::max();
91 constexpr double minus_infinity = -infinity;
94 constexpr double m_mu = 113428.9267;
97 constexpr double pi = M_PI;
98 constexpr double two_pi = 2.*pi;
99 const double sqrt_two_pi = std::sqrt( two_pi );
100 constexpr double half_pi = pi/2.0;
103 constexpr std::complex<double> i(0, 1);
106 const double log_2 = std::log(2);
114 constexpr double alpha = 7.2973525698e-3;
117 constexpr double hbar_c = 197.3269718;
118 constexpr double hbar_c2 = hbar_c * hbar_c;
121 constexpr double hbar = 6.58211951e-22;
124 constexpr double m_e = 0.510998928;
126 constexpr double m_p = 938.27208816;
128 constexpr double m_n = 939.5654205;
130 constexpr double m_nucleon = 0.5 * (m_p + m_n);
132 constexpr double m_nucleon2 = m_nucleon * m_nucleon;
134 constexpr double m_pion = 139.57039;
136 constexpr double mu_p = 2.79284734463;
138 constexpr double mu_n = -1.9130427;
141 constexpr double g_V = 1.0;
142 constexpr double g_V2 = g_V * g_V;
145 constexpr double g_A = 1.262;
146 constexpr double g_A2 = g_A * g_A;
149 constexpr double M_V = 0.84 * 1e3;
152 constexpr double M_A = 1.032 * 1e3;
155 constexpr double mb = 1/3.89379338e5;
157 constexpr double fm2_to_minus40_cm2 = 1e14;
159 constexpr double fm2_to_picobarn = 1e10;
161 constexpr double fm_to_cm = 1e-13;
163 constexpr double e2 = hbar_c * alpha;
167 constexpr double r0 = 1.2;
169 constexpr double ONE_HALF = 1.0/2.0;
170 constexpr double ONE_THIRD = 1.0/3.0;
173 extern std::string latex_table_1, latex_table_2, latex_table_3, latex_table_4;
177 std::string nuc_id(
int Z,
int A);
181 inline int get_nucleus_pid(
int Z,
int A) {
182 if (Z == 0 && A == 1)
return NEUTRON;
183 else if (Z == 1 && A == 1)
return PROTON;
184 else return 10000*Z + 10*A + 1000000000;
187 inline int get_particle_Z(
int pid) {
188 if (pid == marley_utils::PROTON)
return 1;
189 else if (pid == marley_utils::NEUTRON)
return 0;
191 else if (pid > 1000000000)
return (pid % 10000000)/10000;
196 inline int get_particle_A(
int pid) {
197 if (pid == marley_utils::PROTON)
return 1;
198 else if (pid == marley_utils::NEUTRON)
return 1;
200 else if (pid > 1000000000)
return (pid % 10000)/10;
209 bool string_to_neutrino_pdg(
const std::string& str,
int& pdg);
214 std::string neutrino_pdg_to_string(
int pdg);
219 inline bool is_lepton(
int pdg ) {
220 int abs_pdg = std::abs( pdg );
221 bool is_a_lepton = ( abs_pdg >= ELECTRON && abs_pdg <= TAU_NEUTRINO );
226 int get_particle_helicity(
const int pdg );
233 inline bool is_ion(
int pdg ) {
234 bool is_an_ion = ( pdg > 1000000000 && pdg < 2000000000 );
240 double real_sqrt(
double num);
247 template <
typename T>
constexpr T ipow(T num,
unsigned int pow)
249 return ( pow >=
sizeof(
unsigned int)*8 ) ? 0 :
250 pow == 0 ? 1 : num * ipow(num, pow - 1);
254 std::complex<double> gamma(std::complex<double> z);
257 double num_integrate(
const std::function<
double(
double)> &f,
262 double minimize(
const std::function<
double(
double)> f,
double leftEnd,
263 double rightEnd,
double epsilon,
double& minLoc);
265 double maximize(
const std::function<
double(
double)> f,
double leftEnd,
266 double rightEnd,
double epsilon,
double& maxLoc);
270 void solve_quadratic_equation(
double A,
double B,
271 double C,
double &solPlus,
double &solMinus);
274 std::string get_file_contents(std::string filename);
278 std::string get_next_line(std::ifstream &file_in,
const std::regex &rx,
281 std::string get_next_line(std::ifstream &file_in,
const std::regex &rx,
282 bool match,
int& num_lines);
287 const std::string whitespace =
" \f\n\r\t\v";
291 inline double str_to_double(
const std::string& s) {
292 size_t endpos = s.find_last_not_of(whitespace);
293 if (endpos == std::string::npos) {
303 inline std::string to_lowercase(
const std::string& s) {
304 std::string new_s = s;
305 std::transform(new_s.begin(), new_s.end(), new_s.begin(), ::tolower);
312 inline std::string& to_lowercase_inplace(std::string& s) {
313 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
320 inline std::string& to_uppercase_inplace(std::string& s) {
321 std::transform(s.begin(), s.end(), s.begin(), ::toupper);
328 inline std::string& pad_left_inplace(std::string &str,
329 const size_t len,
const char pad_char =
' ')
332 str.insert(0, len - str.size(), pad_char);
336 inline std::string& pad_right_inplace(std::string &str,
337 const size_t len,
const char pad_char =
' ')
340 str.append(len - str.size(), pad_char);
349 inline std::string trim_right_copy(
const std::string& s,
350 const std::string& delimiters = whitespace)
352 size_t endpos = s.find_last_not_of(delimiters);
353 return (endpos == std::string::npos) ?
"" : s.substr(0, endpos + 1);
356 inline std::string trim_left_copy(
const std::string& s,
357 const std::string& delimiters = whitespace)
359 size_t startpos = s.find_first_not_of(delimiters);
360 return (startpos == std::string::npos) ?
"" : s.substr(startpos);
363 inline std::string trim_copy(
const std::string& s,
364 const std::string& delimiters = whitespace)
366 return trim_left_copy(trim_right_copy(s, delimiters), delimiters);
371 inline std::string& trim_right_inplace(std::string& s,
372 const std::string& delimiters = whitespace)
374 size_t endpos = s.find_last_not_of(delimiters);
375 if (endpos == std::string::npos) {
384 inline std::string& trim_left_inplace(std::string& s,
385 const std::string& delimiters = whitespace)
387 size_t startpos = s.find_first_not_of(delimiters);
388 if (startpos == std::string::npos) {
392 s.erase(0, startpos);
397 inline std::string& trim_inplace(std::string& s,
398 const std::string& delimiters = whitespace)
400 return trim_left_inplace(trim_right_inplace(s,delimiters), delimiters);
406 inline std::vector<std::string> split_string(
const std::string& str,
409 std::vector<std::string> vec;
410 std::stringstream ss( str );
412 while ( std::getline(ss, token, delim) ) {
413 vec.push_back( token );
420 std::string num_bytes_to_string(
double bytes,
unsigned precision = 3);
425 std::string nucid_to_symbol(std::string nucid);
429 int nucid_to_Z(std::string nucid);
432 template <
typename repType>
using
433 seconds = std::chrono::duration< repType >;
434 template <
typename repType>
using
435 minutes = std::chrono::duration< repType, std::ratio<60> >;
436 template <
typename repType>
using
437 hours = std::chrono::duration< repType, std::ratio<3600> >;
438 template <
typename repType>
using
439 days = std::chrono::duration< repType, std::ratio<86400> >;
446 template <
typename repType,
typename periodType = std::ratio<1>> std::string duration_to_string(
447 std::chrono::duration<repType, periodType> duration)
449 int day_count =
static_cast<int>(std::chrono::duration_cast
450 <marley_utils::days<repType>>(duration) / (marley_utils::days<repType>(1)));
451 duration -= marley_utils::days<repType>(day_count);
453 int hour_count =
static_cast<int>(std::chrono::duration_cast
454 <marley_utils::hours<repType>>(duration) / (marley_utils::hours<repType>(1)));
455 duration -= marley_utils::hours<repType>(hour_count);
457 int minute_count =
static_cast<int>(std::chrono::duration_cast
458 <marley_utils::minutes<repType>>(duration) / (marley_utils::minutes<repType>(1)));
459 duration -= marley_utils::minutes<repType>(minute_count);
461 int second_count =
static_cast<int>(std::chrono::duration_cast
462 <marley_utils::seconds<repType>>(duration) / (marley_utils::seconds<repType>(1)));
463 duration -= marley_utils::seconds<repType>(second_count);
465 std::ostringstream out;
467 out << day_count <<
" days ";
469 if (day_count == 1) {
470 out << day_count <<
" day ";
472 if (hour_count < 10) out <<
"0";
473 out << hour_count <<
":";
474 if (minute_count < 10) out <<
"0";
475 out << minute_count <<
":";
476 if (second_count < 10) out <<
"0";
482 template <
typename durationType> std::string duration_to_string(
483 durationType duration)
485 return duration_to_string<
typename durationType::rep,
486 typename durationType::period>(duration);
492 std::string elapsed_time_string(
493 std::chrono::system_clock::time_point &start_time,
494 std::chrono::system_clock::time_point &end_time);
498 const std::unordered_map<int, std::string> particle_symbols = {
519 std::string get_particle_symbol(
int pid,
bool excited =
false );
523 const std::unordered_map<int, int> particle_electric_charges = {
537 inline int get_particle_charge(
int pid) {
540 if (pid > 1000000000)
return (pid % 10000000)/10000;
542 int charge = particle_electric_charges.at( std::abs(pid) );
545 if ( pid < 0 ) charge *= -1;
550 bool prompt_yes_no(
const std::string& message);
555 extern const std::unordered_map<int, std::string> element_symbols;
560 extern const std::unordered_map<std::string, int> atomic_numbers;
562 extern const std::string marley_logo;
564 extern const std::string marley_pic;