25#include "HepMC3/FourVector.h"
26#include "HepMC3/GenEvent.h"
27#include "HepMC3/GenParticle.h"
28#include "HepMC3/GenVertex.h"
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"
47 std::deque< std::string >& )
49 std::cerr <<
"marley: the 'summarize' command requires linking to ROOT.";
50 std::cerr <<
"Please rebuild MARLEY against ROOT and try again.\n";
58 std::string output_path;
60 std::vector< std::string > input_files;
62 while ( !args.empty() ) {
63 std::string arg = args.front();
66 if ( arg ==
"-o" || arg ==
"--output" ) {
68 std::cerr <<
"marley summarize: missing argument after '"
72 output_path = args.front();
75 else if ( arg ==
"-f" || arg ==
"--force" ) {
78 else if ( arg ==
"-h" || arg ==
"--help" ) {
80 args.push_front(
"summarize" );
83 else if ( arg.front() ==
'-' ) {
84 std::cerr <<
"marley summarize: unrecognized option '" << arg <<
"'\n";
87 else if ( output_path.empty() ) {
91 input_files.push_back( arg );
95 if ( output_path.empty() ) {
96 std::cerr <<
"marley summarize: missing required output file\n";
97 args.push_front(
"summarize" );
102 if ( input_files.empty() ) {
103 std::cerr <<
"marley summarize: no input files specified\n";
104 args.push_front(
"summarize" );
110 std::ifstream test( output_path );
112 bool overwrite = marley_utils::prompt_yes_no(
113 "Really overwrite " + output_path +
"?" );
115 std::cout <<
"Action aborted.\n";
121 double flux_avg_tot_xsec;
124 double Ev, KEv, pxv, pyv, pzv;
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;
131 std::vector< int > PDGs;
132 std::vector< double > Es, KEs, pXs, pYs, pZs, Ts;
139 std::vector< double > other_weights;
141 TFile out_tfile( output_path.c_str(),
"recreate" );
142 TTree* out_tree =
new TTree(
"mst",
"MARLEY summary tree" );
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" );
151 out_tree->Branch(
"pdgt", &pdgt,
"pdgt/I" );
152 out_tree->Branch(
"Mt", &Mt,
"Mt/D" );
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" );
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" );
168 out_tree->Branch(
"Ex", &Ex,
"Ex/D" );
169 out_tree->Branch(
"twoJ", &twoJ,
"twoJ/I" );
170 out_tree->Branch(
"parity", &par,
"parity/I" );
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 );
181 out_tree->Branch(
"xsec", &flux_avg_tot_xsec,
"xsec/D" );
182 out_tree->Branch(
"proc", &proc_type,
"proc/I" );
184 out_tree->Branch(
"cv_weight", &cv_weight,
"cv_weight/D" );
185 out_tree->Branch(
"other_weights", &other_weights );
187 constexpr double XSEC_CONV = marley_utils::hbar_c2
188 * marley_utils::fm2_to_minus40_cm2 * 1e2;
190 bool weight_names_written =
false;
191 long event_count = 0;
193 for_each_event( input_files,
194 [ & ]( HepMC3::GenEvent& ev,
bool first_event,
double xsec_natural,
195 const auto& first_info )
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;
205 if ( event_count % 1000 == 0 ) {
206 std::cout <<
"Event " << event_count <<
'\n';
217 auto projectile = marley_hepmc3::get_projectile( ev );
218 pdgv = projectile->pid();
220 double mv = projectile->generated_mass();
221 const HepMC3::FourVector& p4v = projectile->momentum();
224 KEv = std::max( 0., Ev - mv );
229 auto target = marley_hepmc3::get_target( ev );
230 pdgt = target->pid();
231 Mt = target->generated_mass();
233 auto ejectile = marley_hepmc3::get_ejectile( ev );
234 pdgl = ejectile->pid();
236 int ej_id = ejectile->id();
238 double ml = ejectile->generated_mass();
239 const HepMC3::FourVector& p4l = ejectile->momentum();
242 KEl = std::max( 0., El - ml );
247 auto residue = marley_hepmc3::get_residue( ev );
249 pdgr = residue->pid();
251 double mr = residue->generated_mass();
252 const HepMC3::FourVector& p4r = residue->momentum();
255 KEr = std::max( 0., Er - mr );
260 auto Ex_attr = residue->attribute< HepMC3::DoubleAttribute >(
"Ex" );
261 Ex = Ex_attr->value();
263 auto twoJ_attr = residue->attribute< HepMC3::IntAttribute >(
"twoJ" );
264 twoJ = twoJ_attr->value();
266 auto parity_attr = residue->attribute< HepMC3::IntAttribute >(
"parity" );
267 par = parity_attr->value();
270 flux_avg_tot_xsec = xsec_natural * XSEC_CONV;
272 auto proc_type_attr = ev.
attribute< HepMC3::IntAttribute >(
273 "signal_process_id" );
274 proc_type = proc_type_attr->value();
278 for (
const auto& p : particles ) {
279 if ( p->status() != marley_hepmc3::NUHEPMC_FINAL_STATE_STATUS ) {
283 if ( p->id() == ej_id )
continue;
287 PDGs.push_back( p->pid() );
289 double mp = p->generated_mass();
290 const HepMC3::FourVector& p4p = p->momentum();
295 double KEp = std::max( 0., Ep - mp );
296 KEs.push_back( KEp );
298 pXs.push_back( p4p.
px() );
299 pYs.push_back( p4p.
py() );
300 pZs.push_back( p4p.
pz() );
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;
310 cv_weight = other_weights.front();
311 other_weights.erase( other_weights.begin() );
double t() const
Time component of position/displacement.
double px() const
x-component of momentum
double py() const
y-component of momentum
double pz() const
z-component of momentum
double e() const
Energy component of momentum.
const std::vector< ConstGenParticlePtr > & particles() const
Get list of particles (const)
const std::vector< double > & weights() const
Get event weight values as a vector.
std::shared_ptr< T > attribute(const std::string &name, const int &id=0) const
Get attribute of type T.
static bool cmd_help(std::deque< std::string > &args)
Display top-level or command-specific help messages.
static bool cmd_summarize(std::deque< std::string > &args)
Summarize an existing sample of MARLEY events as a ROOT TTree.