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_summarize.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 <algorithm>
19#include <fstream>
20#include <iostream>
21#include <string>
22#include <vector>
23
24// HepMC3 includes
25#include "HepMC3/FourVector.h"
26#include "HepMC3/GenEvent.h"
27#include "HepMC3/GenParticle.h"
28#include "HepMC3/GenVertex.h"
29
30#ifdef USE_ROOT
31// ROOT includes
32#include "TFile.h"
33#include "TTree.h"
34#endif
35
36// MARLEY includes
37#include "cmd_helpers.hh"
38#include "marley/CommandHandler.hh"
39#include "marley/Error.hh"
40#include "marley/EventFileReader.hh"
41#include "marley/hepmc3_utils.hh"
42#include "marley/marley_utils.hh"
43
44#ifndef USE_ROOT
45
47 std::deque< std::string >& /*args*/ )
48{
49 std::cerr << "marley: the 'summarize' command requires linking to ROOT.";
50 std::cerr << "Please rebuild MARLEY against ROOT and try again.\n";
51 return false;
52}
53
54#else
55
56bool marley::CommandHandler::cmd_summarize( std::deque< std::string >& args ) {
57
58 std::string output_path;
59 bool force = false;
60 std::vector< std::string > input_files;
61
62 while ( !args.empty() ) {
63 std::string arg = args.front();
64 args.pop_front();
65
66 if ( arg == "-o" || arg == "--output" ) {
67 if ( args.empty() ) {
68 std::cerr << "marley summarize: missing argument after '"
69 << arg << "'\n";
70 return false;
71 }
72 output_path = args.front();
73 args.pop_front();
74 }
75 else if ( arg == "-f" || arg == "--force" ) {
76 force = true;
77 }
78 else if ( arg == "-h" || arg == "--help" ) {
79 args.clear();
80 args.push_front( "summarize" );
82 }
83 else if ( arg.front() == '-' ) {
84 std::cerr << "marley summarize: unrecognized option '" << arg << "'\n";
85 return false;
86 }
87 else if ( output_path.empty() ) {
88 output_path = arg;
89 }
90 else {
91 input_files.push_back( arg );
92 }
93 }
94
95 if ( output_path.empty() ) {
96 std::cerr << "marley summarize: missing required output file\n";
97 args.push_front( "summarize" );
99 return false;
100 }
101
102 if ( input_files.empty() ) {
103 std::cerr << "marley summarize: no input files specified\n";
104 args.push_front( "summarize" );
106 return false;
107 }
108
109 if ( !force ) {
110 std::ifstream test( output_path );
111 if ( test ) {
112 bool overwrite = marley_utils::prompt_yes_no(
113 "Really overwrite " + output_path + "?" );
114 if ( !overwrite ) {
115 std::cout << "Action aborted.\n";
116 return true;
117 }
118 }
119 }
120
121 double flux_avg_tot_xsec;
122 int proc_type;
123
124 double Ev, KEv, pxv, pyv, pzv;
125 double Mt;
126 double El, KEl, pxl, pyl, pzl;
127 double Er = 0., KEr = 0., pxr = 0., pyr = 0., pzr = 0.;
128 int pdgv, pdgt, pdgl, pdgr = 0;
129 int np;
130
131 std::vector< int > PDGs;
132 std::vector< double > Es, KEs, pXs, pYs, pZs, Ts;
133
134 double Ex = 0.;
135 int twoJ = 0;
136 int par = 0;
137
138 double cv_weight;
139 std::vector< double > other_weights;
140
141 TFile out_tfile( output_path.c_str(), "recreate" );
142 TTree* out_tree = new TTree( "mst", "MARLEY summary tree" );
143
144 out_tree->Branch( "pdgv", &pdgv, "pdgv/I" );
145 out_tree->Branch( "Ev", &Ev, "Ev/D" );
146 out_tree->Branch( "KEv", &KEv, "KEv/D" );
147 out_tree->Branch( "pxv", &pxv, "pxv/D" );
148 out_tree->Branch( "pyv", &pyv, "pyv/D" );
149 out_tree->Branch( "pzv", &pzv, "pzv/D" );
150
151 out_tree->Branch( "pdgt", &pdgt, "pdgt/I" );
152 out_tree->Branch( "Mt", &Mt, "Mt/D" );
153
154 out_tree->Branch( "pdgl", &pdgl, "pdgl/I" );
155 out_tree->Branch( "El", &El, "El/D" );
156 out_tree->Branch( "KEl", &KEl, "KEl/D" );
157 out_tree->Branch( "pxl", &pxl, "pxl/D" );
158 out_tree->Branch( "pyl", &pyl, "pyl/D" );
159 out_tree->Branch( "pzl", &pzl, "pzl/D" );
160
161 out_tree->Branch( "pdgr", &pdgr, "pdgr/I" );
162 out_tree->Branch( "Er", &Er, "Er/D" );
163 out_tree->Branch( "KEr", &KEr, "KEr/D" );
164 out_tree->Branch( "pxr", &pxr, "pxr/D" );
165 out_tree->Branch( "pyr", &pyr, "pyr/D" );
166 out_tree->Branch( "pzr", &pzr, "pzr/D" );
167
168 out_tree->Branch( "Ex", &Ex, "Ex/D" );
169 out_tree->Branch( "twoJ", &twoJ, "twoJ/I" );
170 out_tree->Branch( "parity", &par, "parity/I" );
171
172 out_tree->Branch( "np", &np, "np/I" );
173 out_tree->Branch( "pdgp", &PDGs );
174 out_tree->Branch( "Ep", &Es );
175 out_tree->Branch( "KEp", &KEs );
176 out_tree->Branch( "pxp", &pXs );
177 out_tree->Branch( "pyp", &pYs );
178 out_tree->Branch( "pzp", &pZs );
179 out_tree->Branch( "tp", &Ts );
180
181 out_tree->Branch( "xsec", &flux_avg_tot_xsec, "xsec/D" );
182 out_tree->Branch( "proc", &proc_type, "proc/I" );
183
184 out_tree->Branch( "cv_weight", &cv_weight, "cv_weight/D" );
185 out_tree->Branch( "other_weights", &other_weights );
186
187 constexpr double XSEC_CONV = marley_utils::hbar_c2
188 * marley_utils::fm2_to_minus40_cm2 * 1e2;
189
190 bool weight_names_written = false;
191 long event_count = 0;
192
193 for_each_event( input_files,
194 [ & ]( HepMC3::GenEvent& ev, bool first_event, double xsec_natural,
195 const auto& first_info )
196 {
197 if ( first_event && !weight_names_written ) {
198 auto wgt_names = first_info->weight_names();
199 wgt_names.erase( wgt_names.begin() );
200 out_tfile.WriteObject( &wgt_names,
201 "MARLEY_other_weight_names", "WriteDelete" );
202 weight_names_written = true;
203 }
204
205 if ( event_count % 1000 == 0 ) {
206 std::cout << "Event " << event_count << '\n';
207 }
208
209 PDGs.clear();
210 Es.clear();
211 KEs.clear();
212 pXs.clear();
213 pYs.clear();
214 pZs.clear();
215 Ts.clear();
216
217 auto projectile = marley_hepmc3::get_projectile( ev );
218 pdgv = projectile->pid();
219
220 double mv = projectile->generated_mass();
221 const HepMC3::FourVector& p4v = projectile->momentum();
222
223 Ev = p4v.e();
224 KEv = std::max( 0., Ev - mv );
225 pxv = p4v.px();
226 pyv = p4v.py();
227 pzv = p4v.pz();
228
229 auto target = marley_hepmc3::get_target( ev );
230 pdgt = target->pid();
231 Mt = target->generated_mass();
232
233 auto ejectile = marley_hepmc3::get_ejectile( ev );
234 pdgl = ejectile->pid();
235
236 int ej_id = ejectile->id();
237
238 double ml = ejectile->generated_mass();
239 const HepMC3::FourVector& p4l = ejectile->momentum();
240
241 El = p4l.e();
242 KEl = std::max( 0., El - ml );
243 pxl = p4l.px();
244 pyl = p4l.py();
245 pzl = p4l.pz();
246
247 auto residue = marley_hepmc3::get_residue( ev );
248 if ( residue ) {
249 pdgr = residue->pid();
250
251 double mr = residue->generated_mass();
252 const HepMC3::FourVector& p4r = residue->momentum();
253
254 Er = p4r.e();
255 KEr = std::max( 0., Er - mr );
256 pxr = p4r.px();
257 pyr = p4r.py();
258 pzr = p4r.pz();
259
260 auto Ex_attr = residue->attribute< HepMC3::DoubleAttribute >( "Ex" );
261 Ex = Ex_attr->value();
262
263 auto twoJ_attr = residue->attribute< HepMC3::IntAttribute >( "twoJ" );
264 twoJ = twoJ_attr->value();
265
266 auto parity_attr = residue->attribute< HepMC3::IntAttribute >( "parity" );
267 par = parity_attr->value();
268 }
269
270 flux_avg_tot_xsec = xsec_natural * XSEC_CONV;
271
272 auto proc_type_attr = ev.attribute< HepMC3::IntAttribute >(
273 "signal_process_id" );
274 proc_type = proc_type_attr->value();
275
276 np = 0;
277 const auto& particles = ev.particles();
278 for ( const auto& p : particles ) {
279 if ( p->status() != marley_hepmc3::NUHEPMC_FINAL_STATE_STATUS ) {
280 continue;
281 }
282
283 if ( p->id() == ej_id ) continue;
284
285 ++np;
286
287 PDGs.push_back( p->pid() );
288
289 double mp = p->generated_mass();
290 const HepMC3::FourVector& p4p = p->momentum();
291
292 double Ep = p4p.e();
293 Es.push_back( Ep );
294
295 double KEp = std::max( 0., Ep - mp );
296 KEs.push_back( KEp );
297
298 pXs.push_back( p4p.px() );
299 pYs.push_back( p4p.py() );
300 pZs.push_back( p4p.pz() );
301
302 const HepMC3::FourVector& pos4_p = p->production_vertex()->position();
303 double tp = pos4_p.t();
304 tp *= marley_utils::hbar / marley_utils::hbar_c
305 / marley_utils::fm_to_cm;
306 Ts.push_back( tp );
307 }
308
309 other_weights = ev.weights();
310 cv_weight = other_weights.front();
311 other_weights.erase( other_weights.begin() );
312
313 out_tree->Fill();
314 ++event_count;
315 } );
316
317 out_tfile.cd();
318 out_tree->Write();
319 out_tfile.Close();
320 return true;
321}
322
323#endif
double t() const
Time component of position/displacement.
Definition FourVector.h:106
double px() const
x-component of momentum
Definition FourVector.h:114
double py() const
y-component of momentum
Definition FourVector.h:121
double pz() const
z-component of momentum
Definition FourVector.h:128
double e() const
Energy component of momentum.
Definition FourVector.h:135
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
const std::vector< double > & weights() const
Get event weight values as a vector.
Definition GenEvent.h:105
std::shared_ptr< T > attribute(const std::string &name, const int &id=0) const
Get attribute of type T.
Definition GenEvent.h:418
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_summarize(std::deque< std::string > &args)
Summarize an existing sample of MARLEY events as a ROOT TTree.