GENIEGenerator
Loading...
Searching...
No Matches
gEvGenHadronNucleus.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*!
3
4\program gevgen_hadron
5
6\brief Generates hadron + nucleus interactions using GENIE's INTRANUKE
7 Similar to NEUGEN's pitest (S.Dytman & H.Gallagher)
8
9 Syntax :
10 gevgen_hadron [-n nev] -p probe -t tgt [-r run#] -k KE
11 [-f flux] [-o prefix] [-m mode]
12 [--seed random_number_seed]
13 [--message-thresholds xml_file]
14 [--event-record-print-level level]
15 [--mc-job-status-refresh-rate rate]
16
17 Options :
18 [] Denotes an optional argument
19 -n
20 Specifies the number of events to generate (default: 10000)
21 -p
22 Specifies the incoming hadron PDG code
23 -t
24 Specifies the nuclear target PDG code (10LZZZAAAI)
25 -r
26 Specifies the MC run number (default: 0)
27 -k
28 Specifies the incoming hadron's kinetic energy (in GeV).
29 The same option can be use to specify a kinetic energy range as
30 a comma-separated set of numbers (eg 0.1,1.2).
31 If no flux is specified then the hadrons will be fired with a
32 uniform kinetic energy distribution within the specified range.
33 If a kinetic energy spectrum is supplied then the hadrons will be
34 fired with a kinetic energy following the input spectrum within
35 the specified range.
36 -f
37 Specifies the incoming hadron's kinetic energy spectrum -
38 it can be either a function, eg 'x*x+4*exp(-x)' or a text file
39 containing 2 columns corresponding to (kinetic energy {GeV}, 'flux').
40 -o
41 Output filename prefix
42 -m
43 INTRANUKE mode <hA, hN> (default: hA)
44 --seed
45 Random number seed.
46 --message-thresholds
47 Allows users to customize the message stream thresholds.
48 The thresholds are specified using an XML file.
49 See $GENIE/config/Messenger.xml for the XML schema.
50 --event-record-print-level
51 Allows users to set the level of information shown when the event
52 record is printed in the screen. See GHepRecord::Print().
53 --mc-job-status-refresh-rate
54 Allows users to customize the refresh rate of the status file.
55
56 Examples:
57
58 (1) Generate 100k pi^{+}+Fe56 events with a pi^{+} kinetic energy
59 of 165 MeV:
60 % gevgen_hadron -n 100000 -p 211 -t 1000260560 -k 0.165
61
62 (2) Generate 100k pi^{+}+Fe56 events with the pi^{+} kinetic energy
63 distributed uniformly in the [165 MeV, 1200 MeV] range:
64 % gevgen_hadron -n 100000 -p 211 -t 1000260560 -k 0.165,1.200
65
66 (3) Generate 100k pi^{+}+Fe56 events with the pi^{+} kinetic energy
67 distributed as f(KE) = 1/KE in the [165 MeV, 1200 MeV] range:
68 % ghAevgen -n gevgen_hadron -p 211 -t 1000260560 -k 0.165,1.200 -f '1/x'
69
70\authors Steve Dytman, Minsuk Kim and Aaron Meyer
71 University of Pittsburgh
72
73 Costas Andreopoulos,
74 University of Liverpool
75
76\version 1.3
77
78\created May 1, 2007
79
80\cpright Copyright (c) 2003-2025, The GENIE Collaboration
81 For the full text of the license visit http://copyright.genie-mc.org
82
83*/
84//____________________________________________________________________________
85
86#include <cassert>
87#include <cstdlib>
88
89// ROOT
90#include "TSystem.h"
91#include "TFile.h"
92#include "TTree.h"
93#include "TH1D.h"
94#include "TF1.h"
95
96#include "Framework/Conventions/GBuild.h"
119
122
123using namespace genie;
124using namespace genie::controls;
125
126using namespace genie::utils::intranuke;
127
128// Function prototypes
129void GetCommandLineArgs (int argc, char ** argv);
130const EventRecordVisitorI * GetIntranuke (void);
131double GenProbeKineticEnergy (void);
133void BuildSpectrum (void);
134void PrintSyntax (void);
135
136// Default options
137int kDefOptNevents = 10000; // n-events to generate
138Long_t kDefOptRunNu = 0; // default run number
139string kDefOptEvFilePrefix = "gntp.inuke"; // default output file prefix
140string kDefOptMode = "hA"; // default mode
141
142// User-specified options:
143string gOptMode; // mode variable
144Long_t gOptRunNu; // run number
145int gOptNevents; // n-events to generate
146int gOptProbePdgCode; // probe PDG code
147int gOptTgtPdgCode; // target PDG code
148double gOptProbeKE; // incoming hadron kinetic enegy (GeV) - for monoenergetic probes
149double gOptProbeKEmin; // incoming hadron kinetic enegy (GeV) - if using flux
150double gOptProbeKEmax; // incoming hadron kinetic enegy (GeV) - if using flux
151string gOptFlux; // input flux (function or flux file)
152string gOptEvFilePrefix; // event file prefix
153bool gOptUsingFlux=false; // using kinetic energy distribution?
154long int gOptRanSeed ; // random number seed
155
156TH1D * gSpectrum = 0;
157
158//____________________________________________________________________________
159int main(int argc, char ** argv)
160{
161 // Parse command line arguments
162 GetCommandLineArgs(argc,argv);
163
164 if ( ! RunOpt::Instance()->Tune() ) {
165 LOG("gmkspl", pFATAL) << " No TuneId in RunOption";
166 exit(-1);
167 }
169
170 // Init random number generator generator with user-specified seed number,
171 // set user-specified mesg thresholds, set user-specified GHEP print-level
172 utils::app_init::MesgThresholds(RunOpt::Instance()->MesgThresholdFiles());
174 GHepRecord::SetPrintLevel(RunOpt::Instance()->EventRecordPrintLevel());
175
176 // Build the incident hadron kinetic energy spectrum, if required
178
179 LOG("gevgen_hadron",pNOTICE) << "finish setup";
180
181 // Get the specified INTRANUKE model
183
184 // Initialize an Ntuple Writer to save GHEP records into a ROOT tree
187 ntpw.Initialize();
188
189 // Create an MC job monitor
190 GMCJMonitor mcjmonitor(gOptRunNu);
191
192 LOG("gevgen_hadron",pNOTICE) << "ready to generate events";
193
194 //
195 // Generate events
196 //
197
198 int ievent = 0;
199 while (ievent < gOptNevents) {
200 LOG("gevgen_hadron", pNOTICE)
201 << " *** Generating event............ " << ievent;
202
203 // initialize
204 EventRecord * evrec = InitializeEvent();
205
206 // generate full h+A event
207 intranuke->ProcessEventRecord(evrec);
208
209 // print generated events
210 LOG("gevgen_hadron", pNOTICE ) << *evrec;
211
212 // add event at the output ntuple
213 ntpw.AddEventRecord(ievent, evrec);
214
215 // refresh the mc job monitor
216 mcjmonitor.Update(ievent,evrec);
217
218 ievent++;
219 delete evrec;
220
221 } // end loop events
222
223 // Save the generated MC events
224 ntpw.Save();
225
226 // Clean-up
227 if(gSpectrum) {
228 delete gSpectrum;
229 gSpectrum = 0;
230 }
231
232 return 0;
233}
234//____________________________________________________________________________
236{
237// get the requested INTRANUKE module
238
239 string sname = "";
240 string sconf = "";
241
242 if ( gOptMode.compare("hA") == 0 ) {
243 sname = "genie::HAIntranuke";
244 sconf = "Default";
245 } else if ( gOptMode.compare("hN") == 0 ) {
246 sname = "genie::HNIntranuke";
247 sconf = "Default";
248 } else if ( gOptMode.compare("hA2025") == 0 ) {
249 sname = "genie::HAIntranuke2025";
250 sconf = "Default";
251 } else if ( gOptMode.compare("hN2025") == 0 ) {
252 sname = "genie::HNIntranuke2025";
253 sconf = "Default";
254 } else if ( gOptMode.compare("hA2018") == 0 ) {
255 sname = "genie::HAIntranuke2018";
256 sconf = "Default";
257 } else if ( gOptMode.compare("hN2018") == 0 ) {
258 sname = "genie::HNIntranuke2018";
259 sconf = "Default";
260#ifdef __GENIE_INCL_ENABLED__
261 } else if ( gOptMode.compare("HINCL") == 0 ) {
262 sname = "genie::HINCLCascadeIntranuke";
263 sconf = "Default";
264#endif
265#ifdef __GENIE_GEANT4_INTERFACE_ENABLED__
266 } else if ( gOptMode.compare("HG4BertCasc") == 0 ) {
267 sname = "genie::HG4BertCascIntranuke";
268 sconf = "Default";
269#endif
270 } else {
271 LOG("gevgen_hadron", pFATAL) << "Invalid Intranuke mode - Exiting";
272 gAbortingInErr = true;
273 exit(1);
274 }
275
278 dynamic_cast<const EventRecordVisitorI *> (algf->GetAlgorithm(sname,sconf));
279 assert(intranuke);
280
281 return intranuke;
282}
283//____________________________________________________________________________
285{
286// Initialize event record. Inserting the probe and target particles.
287
288 EventRecord * evrec = new EventRecord();
289 Interaction * interaction = new Interaction;
290 evrec->AttachSummary(interaction);
291
292 // dummy vertex position
293 TLorentzVector x4null(0.,0.,0.,0.);
294
295 // incident hadron & target nucleon masses
296 PDGLibrary * pdglib = PDGLibrary::Instance();
297 double mh = pdglib -> Find (gOptProbePdgCode) -> Mass();
298 double M = pdglib -> Find (gOptTgtPdgCode ) -> Mass();
299
300 // incident hadron kinetic energy
301 double ke = GenProbeKineticEnergy();
302
303 // form incident hadron and target 4-momenta
304 double Eh = mh + ke;
305 double pzh = TMath::Sqrt(TMath::Max(0.,Eh*Eh-mh*mh));
306 TLorentzVector p4h (0.,0.,pzh,Eh);
307 TLorentzVector p4tgt (0.,0.,0., M);
308
309 // insert probe and target entries
311 evrec->AddParticle(gOptProbePdgCode, ist, -1,-1,-1,-1, p4h, x4null);
312 evrec->AddParticle(gOptTgtPdgCode, ist, -1,-1,-1,-1, p4tgt, x4null);
313
314 return evrec;
315}
316//____________________________________________________________________________
318{
319 if(gOptUsingFlux) return gSpectrum->GetRandom(); // spectrum
320 else return gOptProbeKE; // mono-energetic
321}
322//____________________________________________________________________________
324{
325// Create kinetic energy spectrum from input function
326//
327
328 if(!gOptUsingFlux) return;
329
330 if(gSpectrum) {
331 delete gSpectrum;
332 gSpectrum = 0;
333 }
334
335 LOG("gevgen_hadron", pNOTICE)
336 << "Generating a flux histogram ... ";
337
338 int flux_bins = 300;
339 int flux_entries = 1000000;
340 double ke_min = gOptProbeKEmin;
341 double ke_max = gOptProbeKEmax;
342 double dke = ke_max - ke_min;
343 assert(dke>0 && ke_min>=0.);
344
345 // kinetic energy spectrum
346 gSpectrum = new TH1D(
347 "spectrum","hadron kinetic energy spectrum", flux_bins, ke_min, ke_max);
348
349 // check whether the input flux is a file or a functional form
350 bool input_is_file = ! gSystem->AccessPathName(gOptFlux.c_str());
351 if(input_is_file) {
352 Spline * input_flux = new Spline(gOptFlux.c_str());
353
354 // generate the flux hisogram from the input flux file
355 int n = 100;
356 double ke_step = (ke_max-ke_min)/(n-1);
357 double ymax = -1, ry = -1, gy = -1, ke = -1;
358 for(int i=0; i<n; i++) {
359 ke = ke_min + i*ke_step;
360 ymax = TMath::Max(ymax, input_flux->Evaluate(ke));
361 }
362 ymax *= 1.3;
363
365
366 for(int ientry=0; ientry<flux_entries; ientry++) {
367 bool accept = false;
368 unsigned int iter=0;
369 while(!accept) {
370 iter++;
371 if(iter > kRjMaxIterations) {
372 LOG("gevgen_hadron", pFATAL)
373 << "Couldn't generate a flux histogram";
374 gAbortingInErr = true;
375 exit(1);
376 }
377 ke = ke_min + dke * r->RndGen().Rndm();
378 gy = ymax * r->RndGen().Rndm();
379 ry = input_flux->Evaluate(ke);
380 accept = gy < ry;
381 if(accept) gSpectrum->Fill(ke);
382 }
383 }
384 delete input_flux;
385
386 } else {
387 // generate the flux histogram from the input functional form
388 TF1 * input_func = new TF1("input_func", gOptFlux.c_str(), ke_min, ke_max);
389 gSpectrum->FillRandom("input_func", flux_entries);
390 delete input_func;
391 }
392 TFile f("./input-hadron-flux.root","recreate");
393 gSpectrum->Write();
394 f.Close();
395}
396//____________________________________________________________________________
397void GetCommandLineArgs(int argc, char ** argv)
398{
399 LOG("gevgen_hadron", pINFO) << "Parsing command line arguments";
400
401 // Common run options.
403
404 // Parse run options for this app
405
406 CmdLnArgParser parser(argc,argv);
407
408 // number of events
409 if( parser.OptionExists('n') ) {
410 LOG("gevgen_hadron", pINFO) << "Reading number of events to generate";
411 gOptNevents = parser.ArgAsInt('n');
412 } else {
413 LOG("gevgen_hadron", pINFO)
414 << "Unspecified number of events to generate - Using default";
416 }
417
418 // run number
419 if( parser.OptionExists('r') ) {
420 LOG("gevgen_hadron", pINFO) << "Reading MC run number";
421 gOptRunNu = parser.ArgAsLong('r');
422 } else {
423 LOG("gevgen_hadron", pINFO) << "Unspecified run number - Using default";
425 }
426
427 // incoming hadron PDG code
428 if( parser.OptionExists('p') ) {
429 LOG("gevgen_hadron", pINFO) << "Reading rescattering particle PDG code";
430 gOptProbePdgCode = parser.ArgAsInt('p');
431 } else {
432 LOG("gevgen_hadron", pFATAL) << "Unspecified PDG code - Exiting";
433 PrintSyntax();
434 gAbortingInErr = true;
435 exit(1);
436 }
437
438 // target PDG code
439 if( parser.OptionExists('t') ) {
440 LOG("gevgen_hadron", pINFO) << "Reading target PDG code";
441 gOptTgtPdgCode = parser.ArgAsInt('t');
442 } else {
443 LOG("gevgen_hadron", pFATAL) << "Unspecified target PDG code - Exiting";
444 PrintSyntax();
445 gAbortingInErr = true;
446 exit(1);
447 }
448
449 // target PDG code
450 if( parser.OptionExists('m') ) {
451 LOG("gevgen_hadron", pINFO) << "Reading mode";
452 gOptMode = parser.ArgAsString('m');
453 } else {
454 LOG("gevgen_hadron", pFATAL) << "Unspecified mode - Using default";
456 }
457
458 // flux functional form or flux file
459 if( parser.OptionExists('f') ) {
460 LOG("gevgen_hadron", pINFO) << "Reading hadron's kinetic energy spectrum";
461 gOptFlux = parser.ArgAsString('f');
462 gOptUsingFlux = true;
463 }
464
465 // incoming hadron kinetic energy (or kinetic energy range, if using flux)
466 if( parser.OptionExists('k') ) {
467 LOG("gevgen_hadron", pINFO) << "Reading probe kinetic energy";
468 string ke = parser.ArgAsString('k');
469 // is it just a value or a range (comma separated set of values)
470 if(ke.find(",") != string::npos) {
471 // split the comma separated list
472 vector<string> kerange = utils::str::Split(ke, ",");
473 assert(kerange.size() == 2);
474 double kemin = atof(kerange[0].c_str());
475 double kemax = atof(kerange[1].c_str());
476 assert(kemax>kemin && kemin>0);
477 gOptProbeKE = -1;
478 gOptProbeKEmin = kemin;
479 gOptProbeKEmax = kemax;
480 // if no flux was specified, generate uniformly within given range
481 if(!gOptUsingFlux) {
482 gOptFlux = "1";
483 gOptUsingFlux = true;
484 }
485 } else {
486 gOptProbeKE = atof(ke.c_str());
487 gOptProbeKEmin = -1;
488 gOptProbeKEmax = -1;
489 if(gOptUsingFlux) {
490 LOG("gevgen_hadron", pFATAL)
491 << "You specified an input flux without a kinetic energy range";
492 PrintSyntax();
493 gAbortingInErr = true;
494 exit(1);
495 }
496 }
497 } else {
498 LOG("gevgen_hadron", pFATAL) << "Unspecified kinetic energy - Exiting";
499 PrintSyntax();
500 gAbortingInErr = true;
501 exit(1);
502 }
503
504 // event file prefix
505 if( parser.OptionExists('o') ) {
506 LOG("gevgen_hadron", pINFO) << "Reading the event filename prefix";
507 gOptEvFilePrefix = parser.ArgAsString('o');
508 } else {
509 LOG("gevgen_hadron", pDEBUG)
510 << "Will set the default event filename prefix";
512 } //-o
513
514 // INTRANUKE mode
515 if( parser.OptionExists('m') ) {
516 LOG("gevgen_hadron", pINFO) << "Reading mode";
517 gOptMode = parser.ArgAsString('m');
518 } else {
519 LOG("gevgen_hadron", pDEBUG)
520 << "Unspecified mode - Using default";
522 }
523
524 // random number seed
525 if( parser.OptionExists("seed") ) {
526 LOG("gevgen_hadron", pINFO) << "Reading random number seed";
527 gOptRanSeed = parser.ArgAsLong("seed");
528 } else {
529 LOG("gevgen_hadron", pINFO) << "Unspecified random number seed - Using default";
530 gOptRanSeed = -1;
531 }
532
533
534 LOG("gevgen_hadron", pNOTICE)
535 << "\n"
536 << utils::print::PrintFramedMesg("gevgen_hadron job configuration");
537
538 LOG("gevgen_hadron", pNOTICE) << "MC Run Number = " << gOptRunNu;
539 LOG("gevgen_hadron", pNOTICE) << "Random number seed = " << gOptRanSeed;
540 LOG("gevgen_hadron", pNOTICE) << "Mode = " << gOptMode;
541 LOG("gevgen_hadron", pNOTICE) << "Number of events = " << gOptNevents;
542 LOG("gevgen_hadron", pNOTICE) << "Probe PDG code = " << gOptProbePdgCode;
543 LOG("gevgen_hadron", pNOTICE) << "Target PDG code = " << gOptTgtPdgCode;
544 if(gOptProbeKEmin<0 && gOptProbeKEmax<0) {
545 LOG("gevgen_hadron", pNOTICE)
546 << "Hadron input KE = " << gOptProbeKE;
547 } else {
548 LOG("gevgen_hadron", pNOTICE)
549 << "Hadron input KE range = ["
550 << gOptProbeKEmin << ", " << gOptProbeKEmax << "]";
551 }
552 if(gOptUsingFlux) {
553 LOG("gevgen_hadron", pNOTICE)
554 << "Input flux = "
555 << gOptFlux;
556 }
557
558 LOG("gevgen_hadron", pNOTICE) << "\n";
559 LOG("gevgen_hadron", pNOTICE) << *RunOpt::Instance();
560}
561//____________________________________________________________________________
562void PrintSyntax(void)
563{
564 LOG("gevgen_hadron", pNOTICE)
565 << "\n\n"
566 << "Syntax:" << "\n"
567 << " gevgen_hadron [-r run] [-n nev] -p hadron_pdg -t tgt_pdg -k KE [-m mode] "
568 << " [-f flux] "
569 << " [--seed random_number_seed]"
570 << " [--message-thresholds xml_file]"
571 << " [--event-record-print-level level]"
572 << " [--mc-job-status-refresh-rate rate]"
573 << "\n";
574}
575//____________________________________________________________________________
#define pNOTICE
Definition Messenger.h:61
#define pINFO
Definition Messenger.h:62
#define pFATAL
Definition Messenger.h:56
#define pDEBUG
Definition Messenger.h:63
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
int main()
The GENIE Algorithm Factory.
Definition AlgFactory.h:39
const Algorithm * GetAlgorithm(const AlgId &algid)
static AlgFactory * Instance()
Command line argument parser.
string ArgAsString(char opt)
bool OptionExists(char opt)
was option set?
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the 'Visito...
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
Definition EventRecord.h:37
virtual void AttachSummary(Interaction *interaction)
virtual void AddParticle(const GHepParticle &p)
static void SetPrintLevel(int print_level)
Simple class to create & update MC job status files and env. vars. This is used to be able to keep tr...
Definition GMCJMonitor.h:31
void Update(int iev, const EventRecord *event)
Summary information for an interaction.
Definition Interaction.h:56
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records.
Definition NtpWriter.h:39
void Initialize(void)
add event
Definition NtpWriter.cxx:83
void Save(void)
get the even tree
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
Definition NtpWriter.cxx:57
void CustomizeFilenamePrefix(string prefix)
Singleton class to load & serve a TDatabasePDG.
Definition PDGLibrary.h:36
static PDGLibrary * Instance(void)
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition RandomGen.h:29
static RandomGen * Instance()
Access instance.
Definition RandomGen.cxx:74
TRandom3 & RndGen(void) const
rnd number generator for generic usage
Definition RandomGen.h:80
void ReadFromCommandLine(int argc, char **argv)
Definition RunOpt.cxx:99
void BuildTune()
build tune and inform XSecSplineList
Definition RunOpt.cxx:92
static RunOpt * Instance(void)
Definition RunOpt.cxx:54
A numeric analysis tool class for interpolating 1-D functions.
Definition Spline.h:58
double Evaluate(double x) const
Definition Spline.cxx:363
long int gOptRanSeed
string kDefOptEvFilePrefix
Long_t gOptRunNu
string gOptEvFilePrefix
string kDefOptMode
string gOptMode
int gOptTgtPdgCode
TH1D * gSpectrum
double gOptProbeKE
void BuildSpectrum(void)
double gOptProbeKEmax
int gOptProbePdgCode
double GenProbeKineticEnergy(void)
void GetCommandLineArgs(int argc, char **argv)
void PrintSyntax(void)
EventRecord * InitializeEvent(void)
const EventRecordVisitorI * GetIntranuke(void)
bool gOptUsingFlux
double gOptProbeKEmin
string gOptFlux
Definition gEvGen.cxx:234
Long_t kDefOptRunNu
Definition gEvGen.cxx:225
int kDefOptNevents
Definition gEvGen.cxx:223
int gOptNevents
Definition gEvGen.cxx:228
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
Definition Controls.h:26
INTRANUKE utilities.
void RandGen(long int seed)
Definition AppInit.cxx:30
void MesgThresholds(string inpfile)
Definition AppInit.cxx:99
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f=' *')
vector< string > Split(string input, string delim)
THE MAIN GENIE PROJECT NAMESPACE
Definition AlgCmp.h:25
@ kIStInitialState
Definition GHepStatus.h:29
bool gAbortingInErr
Definition Messenger.cxx:34
enum genie::EGHepStatus GHepStatus_t
@ kNFGHEP
Definition NtpMCFormat.h:30