33 #include <unordered_map>
35 namespace 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();
62 constexpr
double GF = 1.16637e-11;
64 constexpr
double GF2 = GF * GF;
68 constexpr
double Vud = 0.97427;
70 constexpr
double Vud2 = Vud * Vud;
75 constexpr
double sin2thetaw = 0.23155;
79 constexpr
double MeV = 1e-3;
83 constexpr
double micro_amu = 0.000931494061;
86 constexpr
double infinity = std::numeric_limits<double>::max();
87 constexpr
double minus_infinity = -infinity;
90 constexpr
double m_mu = 113428.9267;
93 constexpr
double pi = M_PI;
94 constexpr
double two_pi = 2.*pi;
95 const double sqrt_two_pi = std::sqrt(pi);
96 constexpr
double half_pi = pi/2.0;
99 constexpr std::complex<double> i(0, 1);
102 const double log_2 = std::log(2);
109 constexpr
double alpha = 7.2973525698e-3;
111 constexpr
double hbar_c = 197.3269718;
112 constexpr
double hbar_c2 = hbar_c * hbar_c;
114 constexpr
double m_e = 0.510998928;
116 constexpr
double mb = 1/3.89379338e5;
118 constexpr
double fm2_to_minus40_cm2 = 1e14;
120 constexpr
double e2 = hbar_c * alpha;
124 constexpr
double r0 = 1.2;
126 constexpr
double ONE_HALF = 1.0/2.0;
127 constexpr
double ONE_THIRD = 1.0/3.0;
130 extern std::string latex_table_1, latex_table_2, latex_table_3, latex_table_4;
134 std::string nuc_id(
int Z,
int A);
138 inline int get_nucleus_pid(
int Z,
int A) {
139 if (Z == 0 && A == 1)
return NEUTRON;
140 else if (Z == 1 && A == 1)
return PROTON;
141 else return 10000*Z + 10*A + 1000000000;
144 inline int get_particle_Z(
int pid) {
145 if (pid == marley_utils::PROTON)
return 1;
146 else if (pid == marley_utils::NEUTRON)
return 0;
148 else if (pid > 1000000000)
return (pid % 10000000)/10000;
153 inline int get_particle_A(
int pid) {
154 if (pid == marley_utils::PROTON)
return 1;
155 else if (pid == marley_utils::NEUTRON)
return 1;
157 else if (pid > 1000000000)
return (pid % 10000)/10;
166 bool string_to_neutrino_pdg(
const std::string& str,
int& pdg);
171 std::string neutrino_pdg_to_string(
int pdg);
176 inline bool is_lepton(
int pdg ) {
177 int abs_pdg = std::abs( pdg );
178 bool is_a_lepton = ( abs_pdg >= ELECTRON && abs_pdg <= TAU_NEUTRINO );
187 inline bool is_ion(
int pdg ) {
188 bool is_an_ion = ( pdg > 1000000000 && pdg < 2000000000 );
194 double real_sqrt(
double num);
201 template <
typename T> constexpr T ipow(T num,
unsigned int pow)
203 return ( pow >=
sizeof(
unsigned int)*8 ) ? 0 :
204 pow == 0 ? 1 : num * ipow(num, pow - 1);
208 std::complex<double> gamma(std::complex<double> z);
211 double num_integrate(
const std::function<
double(
double)> &f,
216 double minimize(
const std::function<
double(
double)> f,
double leftEnd,
217 double rightEnd,
double epsilon,
double& minLoc);
219 double maximize(
const std::function<
double(
double)> f,
double leftEnd,
220 double rightEnd,
double epsilon,
double& maxLoc);
224 void solve_quadratic_equation(
double A,
double B,
225 double C,
double &solPlus,
double &solMinus);
228 std::string get_file_contents(std::string filename);
232 std::string get_next_line(std::ifstream &file_in,
const std::regex &rx,
235 std::string get_next_line(std::ifstream &file_in,
const std::regex &rx,
236 bool match,
int& num_lines);
241 const std::string whitespace =
" \f\n\r\t\v";
245 inline double str_to_double(
const std::string& s) {
246 size_t endpos = s.find_last_not_of(whitespace);
247 if (endpos == std::string::npos) {
257 inline std::string to_lowercase(
const std::string& s) {
258 std::string new_s = s;
259 std::transform(new_s.begin(), new_s.end(), new_s.begin(), ::tolower);
266 inline std::string& to_lowercase_inplace(std::string& s) {
267 std::transform(s.begin(), s.end(), s.begin(), ::tolower);
274 inline std::string& to_uppercase_inplace(std::string& s) {
275 std::transform(s.begin(), s.end(), s.begin(), ::toupper);
282 inline std::string& pad_left_inplace(std::string &str,
283 const size_t len,
const char pad_char =
' ')
286 str.insert(0, len - str.size(), pad_char);
290 inline std::string& pad_right_inplace(std::string &str,
291 const size_t len,
const char pad_char =
' ')
294 str.append(len - str.size(), pad_char);
303 inline std::string trim_right_copy(
const std::string& s,
304 const std::string& delimiters = whitespace)
306 size_t endpos = s.find_last_not_of(delimiters);
307 return (endpos == std::string::npos) ?
"" : s.substr(0, endpos + 1);
310 inline std::string trim_left_copy(
const std::string& s,
311 const std::string& delimiters = whitespace)
313 size_t startpos = s.find_first_not_of(delimiters);
314 return (startpos == std::string::npos) ?
"" : s.substr(startpos);
317 inline std::string trim_copy(
const std::string& s,
318 const std::string& delimiters = whitespace)
320 return trim_left_copy(trim_right_copy(s, delimiters), delimiters);
325 inline std::string& trim_right_inplace(std::string& s,
326 const std::string& delimiters = whitespace)
328 size_t endpos = s.find_last_not_of(delimiters);
329 if (endpos == std::string::npos) {
338 inline std::string& trim_left_inplace(std::string& s,
339 const std::string& delimiters = whitespace)
341 size_t startpos = s.find_first_not_of(delimiters);
342 if (startpos == std::string::npos) {
346 s.erase(0, startpos);
351 inline std::string& trim_inplace(std::string& s,
352 const std::string& delimiters = whitespace)
354 return trim_left_inplace(trim_right_inplace(s,delimiters), delimiters);
360 inline std::vector<std::string> split_string(
const std::string& str,
363 std::vector<std::string> vec;
364 std::stringstream ss( str );
366 while ( std::getline(ss, token, delim) ) {
367 vec.push_back( token );
374 std::string num_bytes_to_string(
double bytes,
unsigned precision = 3);
379 std::string nucid_to_symbol(std::string nucid);
383 int nucid_to_Z(std::string nucid);
386 template <
typename repType>
using
387 seconds = std::chrono::duration< repType >;
388 template <
typename repType>
using
389 minutes = std::chrono::duration< repType, std::ratio<60> >;
390 template <
typename repType>
using
391 hours = std::chrono::duration< repType, std::ratio<3600> >;
392 template <
typename repType>
using
393 days = std::chrono::duration< repType, std::ratio<86400> >;
400 template <
typename repType,
typename periodType = std::ratio<1>> std::string duration_to_string(
401 std::chrono::duration<repType, periodType> duration)
403 int day_count =
static_cast<int>(std::chrono::duration_cast
404 <marley_utils::days<repType>>(duration) / (marley_utils::days<repType>(1)));
405 duration -= marley_utils::days<repType>(day_count);
407 int hour_count =
static_cast<int>(std::chrono::duration_cast
408 <marley_utils::hours<repType>>(duration) / (marley_utils::hours<repType>(1)));
409 duration -= marley_utils::hours<repType>(hour_count);
411 int minute_count =
static_cast<int>(std::chrono::duration_cast
412 <marley_utils::minutes<repType>>(duration) / (marley_utils::minutes<repType>(1)));
413 duration -= marley_utils::minutes<repType>(minute_count);
415 int second_count =
static_cast<int>(std::chrono::duration_cast
416 <marley_utils::seconds<repType>>(duration) / (marley_utils::seconds<repType>(1)));
417 duration -= marley_utils::seconds<repType>(second_count);
419 std::ostringstream out;
421 out << day_count <<
" days ";
423 if (day_count == 1) {
424 out << day_count <<
" day ";
426 if (hour_count < 10) out <<
"0";
427 out << hour_count <<
":";
428 if (minute_count < 10) out <<
"0";
429 out << minute_count <<
":";
430 if (second_count < 10) out <<
"0";
436 template <
typename durationType> std::string duration_to_string(
437 durationType duration)
439 return duration_to_string<
typename durationType::rep,
440 typename durationType::period>(duration);
446 std::string elapsed_time_string(
447 std::chrono::system_clock::time_point &start_time,
448 std::chrono::system_clock::time_point &end_time);
452 const std::unordered_map<int, std::string> particle_symbols = {
456 { 14,
"\u03BD\u03BC" },
458 { 16,
"\u03BD\u03C4" },
465 { 1000020040,
"\u03B1" },
470 const std::unordered_map<int, int> particle_electric_charges = {
483 inline int get_particle_charge(
int pid) {
486 if (pid > 1000000000)
return (pid % 10000000)/10000;
488 int charge = particle_electric_charges.at( std::abs(pid) );
491 if ( pid < 0 ) charge *= -1;
495 inline std::string get_particle_symbol(
int pid) {
496 int charge = get_particle_charge( pid );
497 std::string result = particle_symbols.at( std::abs(pid) );
498 if ( charge < 0 ) result +=
"\u207B";
499 else if ( charge > 0 ) result +=
"\u207A";
500 else if ( pid < 0 ) result =
"anti-" + result;
505 bool prompt_yes_no(
const std::string& message);
510 extern const std::unordered_map<int, std::string> element_symbols;
515 extern const std::unordered_map<std::string, int> atomic_numbers;
517 extern const std::string marley_logo;
519 extern const std::string marley_pic;