30#include "marley/marley_utils.hh"
31#include "marley/Integrator.hh"
32#include "marley/Error.hh"
35std::string marley_utils::latex_table_1 =
"\\documentclass[12pt]{article}\n"
37 "\\usepackage{amsmath}\n"
38 "\\usepackage{booktabs}\n"
39 "\\usepackage[justification=justified,\n"
40 "width=\\textwidth,\n"
41 "labelformat=empty]{caption}\n"
42 "\\usepackage[top=1in, bottom=1in, left=0.25in, right=0.25in]{geometry}\n"
43 "\\usepackage{isotope}\n"
44 "\\usepackage{longtable}\n"
45 "\\usepackage{multirow}\n"
46 "\\usepackage{siunitx}\n"
48 "\\newcommand{\\ExtraRowSpace}{1cm}\n"
52 "\\begin{longtable}{\n"
53 "S[table-number-alignment = center,\n"
54 " table-text-alignment = center]\n"
56 "S[table-number-alignment = center,\n"
57 " table-text-alignment = center]\n"
58 "% table-column-width = 2cm]\n"
59 "S[table-number-alignment = center,\n"
60 " table-text-alignment = center]\n"
61 "S[table-number-alignment = center,\n"
62 " table-text-alignment = center]\n"
66std::string marley_utils::latex_table_2 =
"\\toprule\n"
67 "%{\\centering\\textbf{Level Energy (keV)}}\n"
68 "%& {\\centering\\textbf{Spin-Parity}}\n"
69 "%& {\\centering\\textbf{$\\boldsymbol{\\gamma}$ Energy (keV)}}\n"
70 "%& {\\centering\\textbf{$\\boldsymbol{\\gamma}$ RI}}\n"
71 "%& {\\centering\\textbf{Final Energy (keV)}} \\\\\n"
72 "{\\multirow{3}{2cm}{\\centering\\textbf{Level Energy (keV)}}}\n"
73 "& {\\multirow{3}{2cm}{\\centering\\textbf{Spin-Parity}}}\n"
74 "& {\\multirow{3}{2cm}{\\centering\\textbf{$\\boldsymbol{\\gamma}$ Energy (keV)}}}\n"
75 "& {\\multirow{3}{2cm}{\\centering\\textbf{$\\boldsymbol{\\gamma}$ RI}}}\n"
76 "& {\\multirow{3}{2.5cm}{\\centering\\textbf{Final Level Energy (keV)}}} \\\\\n"
83std::string marley_utils::latex_table_3 =
"\\toprule\n"
84 "%{\\centering\\textbf{Level Energy (keV)}}\n"
85 "%& {\\centering\\textbf{Spin-Parity}}\n"
86 "%& {\\centering\\textbf{$\\boldsymbol{\\gamma}$ Energy (keV)}}\n"
87 "%& {\\centering\\textbf{$\\boldsymbol{\\gamma}$ RI}}\n"
88 "%& {\\centering\\textbf{Final Energy (keV)}} \\\\\n"
89 "{\\multirow{3}{2cm}{\\centering\\textbf{Level Energy (keV)}}}\n"
90 "& {\\multirow{3}{2cm}{\\centering\\textbf{Spin-Parity}}}\n"
91 "& {\\multirow{3}{2cm}{\\centering\\textbf{$\\boldsymbol{\\gamma}$ Energy (keV)}}}\n"
92 "& {\\multirow{3}{2cm}{\\centering\\textbf{$\\boldsymbol{\\gamma}$ RI}}}\n"
93 "& {\\multirow{3}{2.5cm}{\\centering\\textbf{Final Level Energy (keV)}}} \\\\\n"
97 "\\noalign{\\vspace{-\\ExtraRowSpace}}\n"
99 "\\bottomrule \\multicolumn{4}{r}{\\textit{Continued on next page}} \\\\\n"
106std::string marley_utils::latex_table_4 =
"\\end{longtable}\n"
115std::complex<double> marley_utils::gamma(std::complex<double> z)
120 static const int g=7;
121 static const double pi =
122 3.1415926535897932384626433832795028841972;
123 static const double p[g+2] = {0.99999999999980993, 676.5203681218851,
124 -1259.1392167224028, 771.32342877765313, -176.61502916214059,
125 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6,
126 1.5056327351493116e-7};
128 if (std::real(z) < 0.5) {
129 return pi / (std::sin(pi*z)*gamma(1.0-z));
134 std::complex<double> x = p[0];
136 for (
int j = 1; j < g + 2; ++j) {
137 x += p[j]/(z+std::complex<double>(j,0));
140 std::complex<double> t = z + (g + 0.5);
142 return std::sqrt(2*pi) * std::pow(t, z + 0.5) * std::exp(-t) * x;
153double marley_utils::minimize(
const std::function<
double(
double)> f,
159 double d, e, m, p, q, r, tol, t2, u, v, w, fu, fv, fw, fx;
160 static const double c = 0.5*(3.0 - std::sqrt(5.0));
161 static const double SQRT_DBL_EPSILON = std::sqrt(DBL_EPSILON);
164 double& b = rightEnd;
167 v = w = x = a + c*(b - a);
172 while (m = 0.5*(a + b),
173 tol = SQRT_DBL_EPSILON*fabs(x) + epsilon,
175 fabs(x - m) > t2 - 0.5*(b - a))
181 r = (x - w)*(fx - fv);
182 q = (x - v)*(fx - fw);
183 p = (x - v)*q - (x - w)*r;
185 (q > 0.0) ? p = -p : q = -q;
188 if (fabs(p) < fabs(0.5*q*r) && p < q*(a - x) && p < q*(b - x))
194 if (u - a < t2 || b - u < t2)
195 d = (x < m) ? tol : -tol;
215 (u < x) ? b = x : a = x;
222 (u < x) ? a = u : b = u;
223 if (fu <= fw || w == x)
228 else if (fu <= fv || v == x || v == w)
239double marley_utils::maximize(
const std::function<
double(
double)> f,
245 double result = minimize([&f](
double x) ->
double {
return -1.0*f(x); },
246 leftEnd, rightEnd, epsilon, maxLoc);
253double marley_utils::num_integrate(
const std::function<
double(
double)> &f,
259 return integrator.num_integrate(f, a, b);
268void marley_utils::solve_quadratic_equation(
double A,
double B,
269 double C,
double &solPlus,
double &solMinus) {
276 double discr = b*b - c;
284 solMinus = -b - marley_utils::real_sqrt(discr);
285 solPlus = c/solMinus;
289 solPlus = -b + marley_utils::real_sqrt(discr);
290 solMinus = c/solPlus;
301double marley_utils::real_sqrt(
double num) {
306 return std::sqrt(num);
312bool marley_utils::prompt_yes_no(
const std::string& message) {
314 std::string response;
315 while (std::cout << message <<
" [y/n]? "
316 && std::getline(std::cin, response)
317 && !(response ==
"y" || response ==
"n" || response ==
"Y"
318 || response ==
"N"));
319 if (response ==
"y" || response ==
"Y")
return true;
324std::string marley_utils::nuc_id(
int Z,
int A) {
327 std::string(
"The atomic number Z = ") + std::to_string(Z)
328 +
" and the mass number A = " + std::to_string(A)
329 +
" do not correspond to a valid ENSDF nucid.");
332 std::string atomic_mass_number;
334 atomic_mass_number =
" " + std::to_string(A);
337 atomic_mass_number =
" " + std::to_string(A);
340 atomic_mass_number = std::to_string(A);
344 std::string symbol = element_symbols.at(Z);
347 to_uppercase_inplace(symbol);
351 if (symbol.length() == 1) symbol +=
" ";
353 return atomic_mass_number + symbol;
358std::string marley_utils::num_bytes_to_string(
double bytes,
362 std::string SI_prefix;
364 if (bytes < 1e3)
return std::to_string(
static_cast<int>(bytes)) +
" B";
365 else if (bytes < 1e6) {
369 else if (bytes < 1e9) {
373 else if (bytes < 1e12) {
382 std::ostringstream out;
384 out.precision(precision);
385 out << bytes/divisor <<
" " << SI_prefix <<
"B";
397std::string marley_utils::elapsed_time_string(
398 std::chrono::system_clock::time_point &start_time,
399 std::chrono::system_clock::time_point &end_time)
401 std::chrono::system_clock::duration time_elapsed
402 = end_time - start_time;
404 return marley_utils::duration_to_string
405 <std::chrono::system_clock::duration>(time_elapsed);
411std::string marley_utils::get_file_contents(std::string filename) {
414 std::ifstream in(filename.c_str(), std::ios::in | std::ios::binary);
417 std::string contents;
422 in.seekg(0, std::ios::end);
423 contents.resize(in.tellg());
424 in.seekg(0, std::ios::beg);
427 in.read(&contents[0], contents.size());
436std::string marley_utils::get_next_line(std::ifstream &file_in,
437 const std::regex &rx,
bool match)
441 while (!file_in.eof() && file_in.good()) {
443 std::getline(file_in, line);
446 if (std::regex_match(line, rx) == match) {
455 return std::string(
"");
460std::string marley_utils::get_next_line(std::ifstream &file_in,
461 const std::regex &rx,
bool match,
int& num_lines)
467 while (!file_in.eof() && file_in.good()) {
469 std::getline(file_in, line);
474 if (std::regex_match(line, rx) == match) {
483 return std::string(
"");
490bool marley_utils::string_to_neutrino_pdg(
const std::string& str,
int& pdg) {
491 if (str ==
"ve") pdg = marley_utils::ELECTRON_NEUTRINO;
492 else if (str ==
"vebar") pdg = marley_utils::ELECTRON_ANTINEUTRINO;
493 else if (str ==
"vu") pdg = marley_utils::MUON_NEUTRINO;
494 else if (str ==
"vubar") pdg = marley_utils::MUON_ANTINEUTRINO;
495 else if (str ==
"vt") pdg = marley_utils::TAU_NEUTRINO;
496 else if (str ==
"vtbar") pdg = marley_utils::TAU_ANTINEUTRINO;
504std::string marley_utils::neutrino_pdg_to_string(
int pdg) {
505 if (pdg == marley_utils::ELECTRON_NEUTRINO)
506 return std::string(
"ve");
507 else if (pdg == marley_utils::ELECTRON_ANTINEUTRINO)
508 return std::string(
"vebar");
509 else if (pdg == marley_utils::MUON_NEUTRINO)
510 return std::string(
"vu");
511 else if (pdg == marley_utils::MUON_ANTINEUTRINO)
512 return std::string(
"vubar");
513 else if (pdg == marley_utils::TAU_NEUTRINO)
514 return std::string(
"vt");
515 else if (pdg == marley_utils::TAU_ANTINEUTRINO)
516 return std::string(
"vtbar");
517 else return std::string(
"?");
523std::string marley_utils::nucid_to_symbol(std::string nucid) {
524 if (nucid.length() != 5) {
527 std::regex_search(nucid, m, std::regex(
"[0-9]+"));
528 std::string z_str = m.str();
529 std::string e_str = m.suffix().str();
533 if (e_str.length() > 1)
534 e_str.back() = tolower(e_str.back());
535 return z_str + e_str;
539 nucid.back() = tolower(nucid.back());
540 return marley_utils::trim_copy(nucid);
544int marley_utils::get_particle_helicity(
const int pdg ) {
547 constexpr int DUMMY_HELICITY = 0;
549 constexpr int RIGHT_HANDED = 1;
551 constexpr int LEFT_HANDED = -1;
553 if ( pdg == marley_utils::ELECTRON_NEUTRINO
554 || pdg == marley_utils::MUON_NEUTRINO
555 || pdg == marley_utils::TAU_NEUTRINO )
560 else if ( pdg == marley_utils::ELECTRON_ANTINEUTRINO
561 || pdg == marley_utils::MUON_ANTINEUTRINO
562 || pdg == marley_utils::TAU_ANTINEUTRINO )
567 else throw marley::Error(
"Handling of particles with PDG code = "
568 + std::to_string(pdg) +
" is unimplemented in marley_utils::"
569 "get_particle_helicity()" );
571 return DUMMY_HELICITY;
574std::string marley_utils::get_particle_symbol(
int pid,
bool excited ) {
577 auto iter = particle_symbols.find( std::abs(pid) );
581 if ( iter != particle_symbols.end() ) {
582 result = iter->second;
585 if ( is_lepton(pid) ) {
586 int charge = get_particle_charge( pid );
587 if ( charge < 0 ) result +=
"-";
588 else if ( charge > 0 ) result +=
"+";
589 else if ( pid < 0 ) {
590 static const std::string COMBINING_MACRON(
"̄" );
591 result = result.substr( 0, 2 ) + COMBINING_MACRON + result.back();
597 else if ( marley_utils::is_ion(pid) ) {
598 result = std::to_string( get_particle_A(pid) );
599 int Z = get_particle_Z( pid );
600 auto el_iter = marley_utils::element_symbols.find( Z );
601 if ( el_iter != element_symbols.end() ) {
602 result += el_iter->second;
603 if ( excited ) result +=
'*';
608 + std::to_string( Z ) +
" encountered in marley_utils::"
609 "get_particle_symbol()" );
612 else throw marley::Error(
"Unrecognized PDG code " + std::to_string(pid) );
615 if ( excited && !is_ion(pid) ) {
617 + std::to_string( pid ) +
" in marley_utils::get_particle_symbol()" );
625int marley_utils::nucid_to_Z(std::string nucid) {
629 if (nucid.length() != 5) {
632 std::regex_search(nucid, m, std::regex(
"[0-9]+"));
633 e_str = m.suffix().str();
637 if (e_str.length() > 1)
638 e_str.back() = tolower(e_str.back());
643 nucid.back() = tolower(nucid.back());
644 e_str = nucid.substr(nucid.size() - 2);
645 marley_utils::trim_right_inplace(e_str);
647 return atomic_numbers.at(e_str);
653 const std::unordered_map<int, std::string> marley_utils::element_symbols = {
777 const std::unordered_map<std::string, int> marley_utils::atomic_numbers = {
899 const std::string marley_utils::marley_logo =
"╔╦╗╔═╗╦═╗╦ ╔═╗╦ ╦\n"
900 "║║║╠═╣╠╦╝║ ║╣ ╚╦╝\n"
901 "╩ ╩╩ ╩╩╚═╩═╝╚═╝ ╩\n";
903 const std::string marley_utils::marley_pic =
904 "ZZ77I\?I7777\?\?+I\?\?+=====~=~~~:+=+7I$I$Z$$O"
905 "Z77Z$O\?\?=\?\?$Z$Z=$=~=~,:::~~:=~===+=+=II\n"
906 "Z$7IIIIII+I=++=+==+~=~~~~~===\?ZIZ$OOZZOOI8$ZZ"
907 "O8Z8O$ZOO7Z+:,:::,::~:::::~+~:~=~=+\n"
908 "$77I$II\?+I\?+++=+=+====+\?=~=I$7O7$OOZ$8OO8DO"
909 "O8888O8ZOZZ8Z7I~:::::::::::~~:~==~==~\n"
910 "I7I$I7++\?+++=+=++===~~++I\?OO$I$ZOZDO8O888D88"
911 "8OO8888888ZOO$\?I::~,::,::::~:~~=~~==\n"
912 "IIII+\?\?I\?=\?+=+=====~~=$$Z$$Z8IOZOZOD888D$="
913 ":::,,,,,:Z88888ZZ$=\?:,~::::~~:~,:~~~:~\n"
914 "77I$\?\?\?+\?+\?=+=~=~~~=7Z87ZZ$OIZZOO8888DD\?"
915 "::::,,::::,,::O88O8ZZ=:=:::,::::::::=~:=\n"
916 "II+\?+\?\?++++======++7Z8I7OO$$DO$8Z888DZ\?~~:"
917 ",,,,,,,,,:,:~:$O8ZOZ\?=~,:,,:,:::::~~~:\n"
918 "$+I\?+\?+=+===+=+\?+IZ8$DDDIZO8OOD8D88D87+:::="
919 "7ZI7~,,,,:::::~8O8ZZ7+~::,:,::,:,:::~\n"
920 "7+\?+\?+\?+======\?$OO$IOD8OD88O8OD7D8DD8I:~77"
921 "$7ZZ$$O+::,:::~~=8O78OI\?~:,:,::,,,::~:\n"
922 "I\?+++=\?+=~++$$ZZODZ88ZDDOZZDOZD8DDDD7~~Z\?=~"
923 "==~Z88O+~,::::~~=88OO8$+~=:,,::,,,:,:\n"
924 "+++++==++I$$ZO8$$O8DNDNDOZ8O88O8DDD$+\?$$8O$88"
925 "8O8O$7:~~:~,,~~O8888OO$~,:,,:::,:,:\n"
926 "+\?++====\?\?$O88Z88ODD$ZOZ$$OOOOODDD\?~~::~=$"
927 "Z~Z7887I~::$Z$O\?::I888ZO8$\?~:,,::~::,,\n"
928 "\?+++====\?$88DDZ$88OZDDD8$O88O88D8\?:::,:,,:+"
929 "8OO+7$~,,,O8OOOZ==8888888O\?=~::::::,,\n"
930 "++=====+\?OODZ$$DD8DDD8ZZ$$ODO8DD=::~,,:::,,,,"
931 ":,,,,:,,:OI~:ZOZ88D8$8OO7+:,::::~::\n"
932 "+++=+=\?\?8D87DZ8DDDDZ888O88OO88ZD\?\?\?:::~::"
933 ":~=I::,,,:~,,88D:,7Z8D88O88O+=:,,,:~::,\n"
934 "+=+=++78Z7OZZ8DDDD8DDD8$+78$8D8D7I~:~I\?II7$I\?"
935 "ZI$DD8I\?+==~88II8DD8O88OZ~:,,:::,:,\n"
936 "++===+ID$ODDDDNDDDDD7=$O\?$88NDD8I\?++I\?+77\?"
937 "~~~:=\?IOZ$OO7O8787$8D88$88ZO=~::,:::::\n"
938 "=+===+I$8D8=8NDDND=OZZD$\?7ODO8D87=\?++II+Z++\?"
939 "I\?Z7$Z$I$D8~::~Z7DDD87O$OZ++,,,::::,\n"
940 "===~+\?8DZ8N8DNDNNDD+I=77I7D8DDDOZ++==\?I8\?\?"
941 "$8ZO$7=\?$\?Z$==::,:8DDD8888O$$~,,:::::,\n"
942 "====$8OOODN\?DDNDNNDI=+ZIIZD8DDD$7+I+==IZ8Z~~\?"
943 "~O8$7\?=ZI+$:::~DDDD8O88$87~,::::::,\n"
944 "==+8$8O88N8ODNNNDNDND7Z=ZDD8NDNO+7+=\?+\?~Z\?,"
945 ":,,+,+DDZ7Z+7~~,~DDDD888O8$$\?:,,,:::,\n"
946 "+~=+ZO88DD8DNNDNDDND78DI\?O8DDDDZ\?7I=\?==~~ZD"
947 "DDDO,:,=D87+I==~=DDDD8DDOO$I=::,::::,\n"
948 "+=+\?8I8DDNO8NNNNDNNDDD\?IDON8DDD$7$I\?7=~=~~~"
949 ":~8DDD.~888O7I\?\?8DDD88OD8O$~:::,,:,:,\n"
950 "=~\?8$O8DDDZDNDNNDNDNDD78DDNNDDDZI+\?\?7~=+:=="
951 "77~~:ZO,DOOZZ7$ZDDDD8D8D888$::::,::,,\n"
952 "+=\?8IDDNDDODNNNNNNNN$D$DDDNDDDDO$=7=+=~\?+==\?"
953 "+7Z7I7$I\?Z$$ODDDDD88DDDD88I\?,,::,:,:\n"
954 "=\?$OI8NDND8DNNDNNNDD7788DNDD8DDNZ$I+\?~~~==+="
955 "$$$II$I~ZIOO8DDDDD8D8D8DDO7=::,:,,:,\n"
956 "I$8888DDNDDDNN8NNNNN7Z88NNDDNNDDD8ZO7I=~~:~\?="
957 "77II\?\?7O$ZODDDDD8DDD8O88Z\?:,:::,::,\n"
958 "$DDZ8DDNND8DNDNNNNND7$8ODN8DNND888D8$$ZI$$\?I~"
959 "=+I\?+7Z7$ODDDNDD88888OODO:::,,,,:::\n"
960 "8DDOD8DDNN$ND7NNNNND8I88NN8DDNDDDZDD$ZZIZ88ZO7"
961 "\?==78$IZDDDDDDDOD888DD8Z,::,,,,::,\n"
962 "DD8DDDDDDNNNO\?NNNNN\?878NNNZOZDDD8ZDNDD888O8D"
963 "OD87ZOI\?O8DDDDDDDODO$D7OO~:::,:,::::\n"
964 "8NZOO8D8NDNNN7D88NNIOID8ND88$NDD8O$DDDDDN88Z8D"
965 "8DD8Z7D8DDDDDDDOD8\?8OO=::,:::,:,,,\n"
966 "DOZ8ZD8DDDNDDDN$8ONDNI88NNZD7DND$$8DNDNND8DNOO"
967 "$NODODDDNDDDNDDD887IOO=:::::::,,,:\n"
968 "NID8ND8DDNN+DNN$DID8D=ODDNZD\?8DN8ODZDDDN8NDOD"
969 "8DDD8DDDDDDDDNDDD8~IDOO~:::,:,:,:,:\n"
970 "IDODDDNDNDNZNNNI77D8+IZDN888=O8DD8DDNDNNNN8ODD"
971 "DDN8DDDDDDDDDZDZI77+OO$I~:::::,:,:\n"
972 "7NODDDD8NNDDN\?I7$INO++ODDI8D+7O8$88NNNDDNNDDD"
973 "D8D8O$DDDDDND88O$$887$\?OZZ:::,,::,,\n"
974 "NNDODDNDDNDNO$7I\?+NZ\?7DD$88=+\?ZZ$OIDDNNDND8"
975 "DODND8$=DDDNDD8OOI$O87$O8Z8\?+:~::,,::\n"
976 "NNNDZD$DN+DNOZZ\?==D7=IDN$DNI=I$ZZZ7$Z$DDNN8D8"
977 "O$8$::DDNN8D8D8I8O8Z88DD8I\?+:::,,::\n"
978 "NNNZ$DDNNZ7NOII+==D8+ZO=8D\?++I$$Z$88O8OZ8OZOI"
979 "Z8$::NNDNDOD88$$ZIIIZOD88I8O+:::,,,\n"
980 "NNNZ8DDND8ON7ZI==~DOZ88OO7$I\?\?7+I$\?$Z8$$Z$Z"
981 "ZZD+::ODNZOD8=7I$D8Z$~I8DDD888+~~,,,,\n"
982 "NNN$DD8NDDNN+7I==~7\?+7ZZ8I7I\?7\?77I7+ZZZ$$7Z"
983 "NI~::~88O8DD+O$$DODZZZZDDODOO+:$\?:~,,\n"
984 "NNDD8DNN8ZDN8I\?~~=~Z\?$I8D$7I=\?ZZ77\?\?$II$Z"
985 "DZ=~::8D8ODZINZO$ODDI78=8DD8D+\?Z$$Z\?::,\n"
986 "NN\?\?NNNDD8DD$\?7=NN=OZD8ODZ\?I=7ZI$I7O$$OO$="
987 "DDI:~\?7OOIDD8\?$DDDO\?Z\?OZ87I8~OZ888Z+~:\n"
988 "NNIO8NND88NN8IIND87ZDDO8$I\?7$ZIII7\?\?Z8:=\?+"
989 "OZD:IIDIODND7\?O$NDOOI7::O$\?77DZO$D8ZI~\n"
990 "NNI7DDNNDONNO\?O$ONDNI\?DN$+\?ZIZ$7I778=++==++"
991 "ID\?Z$O$ZDD\?\?7$DDO\?$$O~:8+~OO8$\?888OZ=\n"
992 "NNO78NNN78NNDDZ7DN$8DZ78$I7I+$I7\?\?Z~+++=++\?"
993 "II$OOIIZDDD87ODD\?ZO8Z:8Z$7ODDZ78D8O$\?\n"
994 "NN=ZONNDDODD77$ZN7D8D=NOO$$I$7I77$8+\?++\?=+\?"
995 "$7I\?DO7DDDD87ND8Z8$8~:=OO7Z$OI+8DDZZ\?\n"
996 "NDOO8NND$ON87NDD\?7\?$D7N8Z7II8ZI+Z8~\?==+==I\?"
997 "DZID$=ZDD8ZIZNODOZ8D~:~ZD$\?\?\?D7O8DOI\?\n"
998 "NNIODNNNDNNI$NO\?+DDNDD8ZZ$78OO$ID~\?+\?=++=IZ"
999 "$OO8OI$N$$Z8NDZZO$D::~=$OZI+=$$$+O8Z+\n"
1000 "NI\?O8NNNDD\?ODD8=$$887DOZZ$I7\?\?\?$~+\?=+~=\?"
1001 "\?~O\?ZZN\?I7\?OZ8NDOOIDZI:~==+$OI~~~ZI~78ZI\n"
1002 "NZ7DNNNNN8DNNOD\?78N8N8$\?7I\?\?++7==+\?\?~~=+"
1003 "+Z~OZD7Z=DO7NND7$78DO=~====O$+:~=OZ=\?$O+\n"
1004 "N8OZDNNNNZNMN7$\?8OO\?OZ\?7$7III7$+++=====++=8"
1005 "+$ZI7\?$7$8D$D\?ODD8O==~=IO8\?\?+=D$I=7I=\n"
1006 "ND88ODN8NNNNN7\?Z7ZN=D8I$\?\?\?I+7~\?\?=++===+"
1007 "Z8\?+I$\?O\?DD8+8\?DOO8DN7I+==+=Z8=Z~$Z7+\?7\?\n";
Base class for all exceptions thrown by MARLEY functions.
Numerical integrator that uses Clenshaw-Curtis quadrature