MARLEY (Model of Argon Reaction Low Energy Yields) v2.0.0
A Monte Carlo event generator for tens-of-MeV neutrino interactions
Loading...
Searching...
No Matches
cmd_xsec.cc
1
4//
5// This file is part of MARLEY (Model of Argon Reaction Low Energy Yields)
6//
7// MARLEY is free software: you can redistribute it and/or modify it under the
8// terms of version 3 of the GNU General Public License as published by the
9// Free Software Foundation.
10//
11// For the full text of the license please see COPYING or
12// visit http://opensource.org/licenses/GPL-3.0
13//
14// Please respect the MCnet academic usage guidelines. See GUIDELINES
15// or visit https://www.montecarlonet.org/GUIDELINES for details.
16
17// Standard library includes
18#include <fstream>
19#include <iostream>
20#include <string>
21
22// MARLEY includes
23#include "marley/CommandHandler.hh"
24#include "marley/Generator.hh"
25#include "marley/JSON.hh"
26#include "marley/JSONConfig.hh"
27#include "marley/Logger.hh"
28#include "marley/marley_utils.hh"
29
30namespace {
31
32 constexpr double DEFAULT_KE_MIN = 0.;
33 constexpr double DEFAULT_KE_MAX = 100.;
34 constexpr int DEFAULT_NUM_STEPS = 10000;
35 constexpr int DEFAULT_PDG = marley_utils::ELECTRON_NEUTRINO;
36
37}
38
39bool marley::CommandHandler::cmd_xsec( std::deque< std::string >& args ) {
40
41 std::string output_path;
42 std::string config_file_path;
43 bool force = false;
44
45 while ( !args.empty() ) {
46 std::string arg = args.front();
47 args.pop_front();
48
49 if ( arg == "-o" || arg == "--output" ) {
50 if ( args.empty() ) {
51 std::cerr << "marley xsec: missing argument after '" << arg << "'\n";
52 return false;
53 }
54 output_path = args.front();
55 args.pop_front();
56 }
57 else if ( arg == "-f" || arg == "--force" ) {
58 force = true;
59 }
60 else if ( arg == "-h" || arg == "--help" ) {
61 args.clear();
62 args.push_front( "xsec" );
64 }
65 else if ( arg.front() == '-' ) {
66 std::cerr << "marley xsec: unrecognized option '" << arg << "'\n";
67 return false;
68 }
69 else if ( config_file_path.empty() ) {
70 config_file_path = arg;
71 }
72 else {
73 std::cerr << "marley xsec: unexpected extra argument '"
74 << arg << "'\n";
75 return false;
76 }
77 }
78
79 if ( output_path.empty() ) {
80 std::cerr << "marley xsec: missing required output file\n";
81 args.push_front( "xsec" );
83 return false;
84 }
85
86 if ( config_file_path.empty() ) {
87 std::cerr << "marley xsec: missing required configuration file\n";
88 args.push_front( "xsec" );
90 return false;
91 }
92
93 if ( !force ) {
94 std::ifstream temp_stream( output_path );
95 if ( temp_stream ) {
96 bool overwrite = marley_utils::prompt_yes_no(
97 "Really overwrite " + output_path + '?');
98 if ( !overwrite ) {
99 std::cout << "Total cross section dump aborted.\n";
100 return true;
101 }
102 }
103 }
104
105 std::ofstream out_file( output_path );
106
107 marley::JSONConfig config( config_file_path );
108 marley::Generator gen = config.create_generator();
109
110 double KEmin = DEFAULT_KE_MIN;
111 double KEmax = DEFAULT_KE_MAX;
112 int num_steps = DEFAULT_NUM_STEPS;
113 int projectile_pdg = DEFAULT_PDG;
114
115 const marley::JSON& json = config.get_json();
116
117 if ( json.has_key("xsec") ) {
118 const marley::JSON& xsec_settings = json.at( "xsec" );
119
120 if ( xsec_settings.has_key("KEmin") ) {
121 bool ok = false;
122 KEmin = xsec_settings.at("KEmin").to_double( ok );
123 if ( !ok ) throw marley::Error("Unrecognized KEmin value "
124 + xsec_settings.at("KEmin").to_string() + " encountered in the"
125 " \"xsec\" section of the job configuration file.");
126 }
127
128 if ( xsec_settings.has_key("KEmax") ) {
129 bool ok = false;
130 KEmax = xsec_settings.at("KEmax").to_double( ok );
131 if ( !ok ) throw marley::Error("Unrecognized KEmax value "
132 + xsec_settings.at("KEmax").to_string() + " encountered in the"
133 " \"xsec\" section of the job configuration file.");
134 }
135
136 if ( xsec_settings.has_key("steps") ) {
137 bool ok = false;
138 num_steps = xsec_settings.at("steps").to_long( ok );
139 if ( !ok ) throw marley::Error("Unrecognized steps value "
140 + xsec_settings.at("steps").to_string() + " encountered in the"
141 " \"xsec\" section of the job configuration file.");
142 }
143
144 if ( xsec_settings.has_key("pdg") ) {
145 bool ok = false;
146 projectile_pdg = xsec_settings.at("pdg").to_long( ok );
147 if ( !ok ) throw marley::Error("Unrecognized pdg value "
148 + xsec_settings.at("pdg").to_string() + " encountered in the"
149 " \"xsec\" section of the job configuration file.");
150 }
151 }
152
153 double KE = KEmin;
154 int steps = num_steps;
155
156 if ( steps <= 1 ) {
157 double xsec = gen.total_xs( projectile_pdg, KE );
158 xsec *= marley_utils::hbar_c2 * marley_utils::fm2_to_minus40_cm2 * 1e2;
159
160 out_file << KE << ' ' << xsec << '\n';
161
162 MARLEY_LOG( INFO, "app" ) << "KE = " << KE
163 << " MeV, abundance-weighted total xsec = "
164 << xsec << " × 10^{-42} cm^2 / atom";
165 }
166 else {
167 double delta = ( KEmax - KEmin ) / ( steps - 1 );
168 for ( int s = 0; s < steps; ++s ) {
169 KE = KEmin + s * delta;
170 double xsec = gen.total_xs( projectile_pdg, KE );
171 xsec *= marley_utils::hbar_c2 * marley_utils::fm2_to_minus40_cm2 * 1e2;
172
173 out_file << KE << ' ' << xsec << '\n';
174
175 MARLEY_LOG( INFO, "app" ) << "KE = " << KE
176 << " MeV, abundance-weighted total xsec = "
177 << xsec << " × 10^{-42} cm^2 / atom";
178 }
179 }
180
181 return true;
182}
static bool cmd_help(std::deque< std::string > &args)
Display top-level or command-specific help messages.
Definition cmd_help.cc:24
static bool cmd_xsec(std::deque< std::string > &args)
Tabulate energy-dependent total cross section values.
Definition cmd_xsec.cc:39
Base class for all exceptions thrown by MARLEY functions.
Definition Error.hh:26
The MARLEY Event generator.
Definition Generator.hh:54
double total_xs(int pdg_a, double KEa, int pdg_atom) const
Computes the total cross section at fixed energy for all configured reactions involving a particular ...
Definition Generator.cc:629