GENIEGenerator
Loading...
Searching...
No Matches
gEvGen.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*!
3
4\program gevgen
5
6\brief A simple 'generic' GENIE v+A event generation driver (gevgen).
7
8 It handles:
9 a) event generation for a fixed init state (v+A) at fixed energy, or
10 b) event generation for simple fluxes (specified either via some
11 functional form, tabular text file or a ROOT histogram) and for
12 simple 'geometries' (a target mix with its corresponding weights)
13
14 See the GENIE manual for other apps handling experiment-specific
15 event generation cases using the outputs of detailed neutrino flux
16 simulations and realistic detector geometry descriptions.
17
18 Syntax :
19Syntax:
20
21 gevgen [-h]
22 [-r run#]
23 -n nev
24 -e energy (or energy range)
25 -p neutrino_pdg
26 -t target_pdg
27 [-f flux_description]
28 [-F flux_options]
29 [-o outfile_name]
30 [-w]
31 [--force-flux-ray-interaction]
32 [--seed random_number_seed]
33 [--cross-sections xml_file]
34
35 // command line args handled by RunOpt:
36 [--event-generator-list list_name] // default "Default"
37 [--tune tune_name] // default "G18_02a_00_000"
38 [--xml-path path]
39 [--message-thresholds xml_file]
40 [--event-record-print-level level]
41 [--mc-job-status-refresh-rate rate]
42 [--cache-file root_file]
43 [--enable-bare-xsec-pre-calc]
44 [--disable-bare-xsec-pre-calc]
45 [--unphysical-event-mask mask]
46
47 Options :
48 [] Denotes an optional argument.
49 -h
50 Prints-out help on using gevgen and exits.
51 -n
52 Specifies the number of events to generate.
53 -r
54 Specifies the MC run number.
55 -e
56 Specifies the neutrino energy.
57 If what follows the -e option is a comma separated pair of values
58 it will be interpreted as an energy range for the flux specified
59 via the -f option (see below).
60 -p
61 Specifies the neutrino PDG code.
62 -t
63 Specifies the target PDG code (pdg format: 10LZZZAAAI) _or_ a target
64 mix (pdg codes with corresponding weights) typed as a comma-separated
65 list of pdg codes with the corresponding weight fractions in brackets,
66 eg code1[fraction1],code2[fraction2],...
67 For example, to use a target mix of 95% O16 and 5% H type:
68 `-t 1000080160[0.95],1000010010[0.05]'.
69 -f
70 Specifies the neutrino flux spectrum.
71 It can be any of:
72 -- A function:
73 eg ` -f x*x+4*exp(-x)'
74 -- A vector file:
75 The vector file should contain 2 columns corresponding to
76 energy,flux (see $GENIE/data/flux/ for few examples).
77 -- A 1-D ROOT histogram (TH1D):
78 The general syntax is `-f /full/path/file.root,object_name<,[NO]WIDTH>'
79 by default variable bin histograms are multiplied by bin width
80 if ,NOWIDTH then they are not
81 if ,WIDTH then they are alway multiplied by bin width
82 -- A power law:
83 The general syntax is `-f POWERLAW:alpha'
84 and the spectrum will follow a E^{-alpha} distribution
85 -F
86 Specifies direction,size,start point of histogram flux
87 dircosx,dircosy,dircosz,Radius,spotx,spoty,spotz
88 -o
89 Specifies the name of the output file events will be saved in.
90 -w
91 Forces generation of weighted events.
92 This option is relevant only if a neutrino flux is specified.
93 Note that 'weighted' refers to the selection of the primary
94 flux neutrino + target that were forced to interact. A weighting
95 scheme for the generated kinematics of individual processes can
96 still be in effect if enabled..
97 ** Only use that option if you understand what it means **
98 --force-flux-ray-interaction
99 Forces the interaction of all flux rays.
100 This option is relevant only if a neutrino flux is specified.
101 Note that events will be weighted according to their
102 interaction probability
103 --seed
104 Random number seed.
105 --cross-sections
106 Name (incl. full path) of an XML file with pre-computed
107 cross-section values used for constructing splines.
108
109 --event-generator-list
110 List of event generators to load in event generation drivers.
111 [default: "Default"].
112 --tune
113 Specifies a GENIE comprehensive neutrino interaction model tune.
114 [default: "Default"].
115 --xml-path
116 A directory to load XML files from - overrides $GXMLPATH, and $GENIE/config
117 --message-thresholds
118 Allows users to customize the message stream thresholds.
119 The thresholds are specified using an XML file.
120 See $GENIE/config/Messenger.xml for the XML schema.
121 --event-record-print-level
122 Allows users to set the level of information shown when the event
123 record is printed in the screen. See GHepRecord::Print().
124 --mc-job-status-refresh-rate
125 Allows users to customize the refresh rate of the status file.
126 --cache-file
127 Allows users to specify a cache file so that the cache can be
128 re-used in subsequent MC jobs.
129 --unphysical-event-mask
130 Allows users to specify a 16-bit mask to allow certain types of
131 unphysical events to be written in the output file.
132 [default: all unphysical events are rejected]
133
134 *** See the User Manual for more details and examples. ***
135
136\author Costas Andreopoulos <c.andreopoulos \at cern.ch>
137 University of Liverpool
138
139\created October 05, 2004
140
141\cpright Copyright (c) 2003-2025, The GENIE Collaboration
142 For the full text of the license visit http://copyright.genie-mc.org
143
144*/
145//____________________________________________________________________________
146
147#include <cstdlib>
148#include <cassert>
149#include <sstream>
150#include <string>
151#include <vector>
152#include <map>
153
154#if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
155#include <fenv.h> // for `feenableexcept`
156#endif
157
158#include <TFile.h>
159#include <TTree.h>
160#include <TSystem.h>
161#include <TVector3.h>
162#include <TH1.h>
163#include <TF1.h>
164
166#include "Framework/Conventions/GBuild.h"
188
189#ifdef __GENIE_FLUX_DRIVERS_ENABLED__
190#ifdef __GENIE_GEOM_DRIVERS_ENABLED__
191#define __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
196#endif
197#endif
198
199using std::string;
200using std::vector;
201using std::map;
202using std::ostringstream;
203
204using namespace genie;
205using namespace genie::controls;
206
207void GetCommandLineArgs (int argc, char ** argv);
208void Initialize (void);
209void PrintSyntax (void);
210
211#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
212void GenerateEventsUsingFluxOrTgtMix();
213GeomAnalyzerI * GeomDriver (void);
214GFluxI * FluxDriver (void);
215GFluxI * MonoEnergeticFluxDriver (void);
216GFluxI * PowerLawFluxDriver (void);
217GFluxI * TH1FluxDriver (void);
218#endif
219
221
222//Default options (override them using the command line arguments):
223int kDefOptNevents = 0; // n-events to generate
225Long_t kDefOptRunNu = 0; // default run number
226
227//User-specified options:
228int gOptNevents; // n-events to generate
229double gOptNuEnergy; // neutrino E, or min neutrino energy in spectrum
230double gOptNuEnergyRange;// energy range in input spectrum
231int gOptNuPdgCode; // neutrino PDG code
232map<int,double> gOptTgtMix; // target mix (each with its relative weight)
233Long_t gOptRunNu; // run number
234string gOptFlux; //
239long int gOptRanSeed; // random number seed
240string gOptInpXSecFile; // cross-section splines
241string gOptOutFileName; // Optional outfile name
242string gOptStatFileName; // Status file name, set if gOptOutFileName was set.
243
244//____________________________________________________________________________
245int main(int argc, char ** argv)
246{
247 GetCommandLineArgs(argc,argv);
248 Initialize();
249
250 // throw on NaNs and Infs...
251#if defined(HAVE_FENV_H) && defined(HAVE_FEENABLEEXCEPT)
252 feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
253#endif
254 //
255 // Generate neutrino events
256 //
257
259#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
260 GenerateEventsUsingFluxOrTgtMix();
261#else
262 LOG("gevgen", pERROR)
263 << "\n To be able to generate neutrino events from a flux and/or a target mix"
264 << "\n you need to add the following config options at your GENIE installation:"
265 << "\n --enable-flux-drivers --enable-geom-drivers \n" ;
266#endif
267 } else {
269 }
270 return 0;
271}
272//____________________________________________________________________________
274{
275
276 if ( ! RunOpt::Instance()->Tune() ) {
277 LOG("gevgen", pFATAL) << " No TuneId in RunOption";
278 exit(-1);
279 }
281
282 // Initialization of random number generators, cross-section table,
283 // messenger thresholds, cache file
284 utils::app_init::MesgThresholds(RunOpt::Instance()->MesgThresholdFiles());
288
289 // Set GHEP print level
290 GHepRecord::SetPrintLevel(RunOpt::Instance()->EventRecordPrintLevel());
291}
292//____________________________________________________________________________
294{
295 int neutrino = gOptNuPdgCode;
296 int target = gOptTgtMix.begin()->first;
297 double Ev = gOptNuEnergy;
298 TLorentzVector nu_p4(0.,0.,Ev,Ev); // px,py,pz,E (GeV)
299
300 // Create init state
301 InitialState init_state(target, neutrino);
302
303 // Create/config event generation driver
304 GEVGDriver evg_driver;
306 evg_driver.SetUnphysEventMask(*RunOpt::Instance()->UnphysEventMask());
307 evg_driver.Configure(init_state);
308
309 // Initialize an Ntuple Writer
311
312 // If an output file name has been specified... use it
313 if (!gOptOutFileName.empty()){
315 }
316 ntpw.Initialize();
317
318
319 // Create an MC Job Monitor
320 GMCJMonitor mcjmonitor(gOptRunNu);
321 mcjmonitor.SetRefreshRate(RunOpt::Instance()->MCJobStatusRefreshRate());
322
323 // If a status file name has been given... use it
324 if (!gOptStatFileName.empty()){
326 }
327
328
329 LOG("gevgen", pNOTICE)
330 << "\n ** Will generate " << gOptNevents << " events for \n"
331 << init_state << " at Ev = " << Ev << " GeV";
332
333 // Generate events / print the GHEP record / add it to the ntuple
334 int ievent = 0;
335 while (ievent < gOptNevents) {
336 LOG("gevgen", pNOTICE)
337 << " *** Generating event............ " << ievent;
338
339 // generate a single event
340 EventRecord * event = evg_driver.GenerateEvent(nu_p4);
341
342 if(!event) {
343 LOG("gevgen", pNOTICE)
344 << "Last attempt failed. Re-trying....";
345 continue;
346 }
347
348 LOG("gevgen", pNOTICE)
349 << "Generated Event GHEP Record: " << *event;
350
351 // add event at the output ntuple, refresh the mc job monitor & clean up
352 ntpw.AddEventRecord(ievent, event);
353 mcjmonitor.Update(ievent,event);
354 ievent++;
355 delete event;
356 }
357
358 // Save the generated MC events
359 ntpw.Save();
360}
361//____________________________________________________________________________
362
363#ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
364//............................................................................
365void GenerateEventsUsingFluxOrTgtMix(void)
366{
367 // Get flux and geom drivers
368 GFluxI * flux_driver = FluxDriver();
369 GeomAnalyzerI * geom_driver = GeomDriver();
370
371 // Create the monte carlo job driver
372 GMCJDriver * mcj_driver = new GMCJDriver;
374 mcj_driver->SetUnphysEventMask(*RunOpt::Instance()->UnphysEventMask());
375 mcj_driver->UseFluxDriver(flux_driver);
376 mcj_driver->UseGeomAnalyzer(geom_driver);
377 if(gOptForceInt)
378 mcj_driver->ForceInteraction();
379 mcj_driver->Configure();
380 mcj_driver->UseSplines();
381 if(!gOptWeighted)
382 mcj_driver->ForceSingleProbScale();
383
384
385 // Initialize an Ntuple Writer to save GHEP records into a TTree
387
388 // If an output file name has been specified... use it
389 if (!gOptOutFileName.empty()){
390 ntpw.CustomizeFilename(gOptOutFileName);
391 }
392 ntpw.Initialize();
393
394 // Create an MC Job Monitor
395 GMCJMonitor mcjmonitor(gOptRunNu);
396 mcjmonitor.SetRefreshRate(RunOpt::Instance()->MCJobStatusRefreshRate());
397
398 // If a status file name has been given... use it
399 if (!gOptStatFileName.empty()){
400 mcjmonitor.CustomizeFilename(gOptStatFileName);
401 }
402
403
404 // Generate events / print the GHEP record / add it to the ntuple
405 int ievent = 0;
406 while ( ievent < gOptNevents) {
407
408 LOG("gevgen", pNOTICE) << " *** Generating event............ " << ievent;
409
410 // generate a single event for neutrinos coming from the specified flux
411 EventRecord * event = mcj_driver->GenerateEvent();
412
413 LOG("gevgen", pNOTICE) << "Generated Event GHEP Record: " << *event;
414
415 // add event at the output ntuple, refresh the mc job monitor & clean-up
416 ntpw.AddEventRecord(ievent, event);
417 mcjmonitor.Update(ievent,event);
418 ievent++;
419 delete event;
420 }
421
422 // Save the generated MC events
423 ntpw.Save();
424
425 delete flux_driver;
426 delete geom_driver;
427 delete mcj_driver;;
428}
429//____________________________________________________________________________
430GeomAnalyzerI * GeomDriver(void)
431{
432// create a trivial point geometry with the specified target or target mix
433
435 return geom_driver;
436}
437//____________________________________________________________________________
438GFluxI * FluxDriver(void)
439{
440// create & configure one of the generic flux drivers
441//
442 GFluxI * flux_driver = 0;
443
444 if(gOptNuEnergyRange<0) flux_driver = MonoEnergeticFluxDriver();
445 else if(gOptFlux.find("POWERLAW") != string::npos) flux_driver = PowerLawFluxDriver();
446 else flux_driver = TH1FluxDriver();
447
448 return flux_driver;
449}
450//____________________________________________________________________________
451GFluxI * MonoEnergeticFluxDriver(void)
452{
453//
454//
457 GFluxI * flux_driver = dynamic_cast<GFluxI *>(flux);
458 return flux_driver;
459}
460//____________________________________________________________________________
461GFluxI * PowerLawFluxDriver(void)
462{
463//
464//
465 vector<string> fv = utils::str::Split(gOptFlux,":");
466 assert(fv.size()==2);
467
468 double spectralindex = atof(fv[1].c_str());
469
472 GFluxI * flux_driver = dynamic_cast<GFluxI *>(flux);
473 return flux_driver;
474}
475//____________________________________________________________________________
476GFluxI * TH1FluxDriver(void)
477{
478//
479//
481 TH1D * spectrum = 0;
482
483 int flux_entries = 100000;
484
485 double emin = gOptNuEnergy;
486 double emax = gOptNuEnergy+gOptNuEnergyRange;
487 double de = gOptNuEnergyRange;
488
489 // check whether the input flux is a file or a functional form
490 //
491 bool input_is_text_file = ! gSystem->AccessPathName(gOptFlux.c_str());
492 bool input_is_root_file = gOptFlux.find(".root") != string::npos &&
493 gOptFlux.find(",") != string::npos;
494 if(input_is_text_file) {
495 //
496 // ** generate the flux histogram from the x,y pairs in the input text file
497 //
498 Spline * input_flux = new Spline(gOptFlux.c_str());
499 int n = 100;
500 double estep = (emax-emin)/(n-1);
501 double ymax = -1, ry = -1, gy = -1, e = -1;
502 for(int i=0; i<n; i++) {
503 e = emin + i*estep;
504 ymax = TMath::Max(ymax, input_flux->Evaluate(e));
505 }
506 ymax *= 1.3;
507
509 spectrum = new TH1D("spectrum","neutrino flux", 300, emin, emax);
510 spectrum->SetDirectory(0);
511
512 for(int ientry=0; ientry<flux_entries; ientry++) {
513 bool accept = false;
514 unsigned int iter=0;
515 while(!accept) {
516 iter++;
517 if(iter > kRjMaxIterations) {
518 LOG("gevgen", pFATAL) << "Couldn't generate a flux histogram";
519 exit(1);
520 }
521 e = emin + de * r->RndGen().Rndm();
522 gy = ymax * r->RndGen().Rndm();
523 ry = input_flux->Evaluate(e);
524 accept = gy < ry;
525 if(accept) spectrum->Fill(e);
526 }
527 }
528 delete input_flux;
529 }
530 else if(input_is_root_file) {
531 //
532 // ** extract specified flux histogram from the input root file
533 //
534 vector<string> fv = utils::str::Split(gOptFlux,",");
535 assert(fv.size()==2 || fv.size()==3);
536 assert( !gSystem->AccessPathName(fv[0].c_str()) );
537
538 LOG("gevgen", pNOTICE) << "Getting input flux from root file: " << fv[0];
539 TFile * flux_file = new TFile(fv[0].c_str(),"read");
540
541 LOG("gevgen", pNOTICE) << "Flux name: " << fv[1];
542 TH1D * hst = (TH1D *)flux_file->Get(fv[1].c_str());
543 if ( !hst ) {
544 LOG("gevgen", pFATAL) << "Could not load the flux histogram \"" << fv[1]
545 << "\" from the input ROOT file: " << fv[0];
546 std::exit(1);
547 }
548 assert(hst);
549 std::string extra = (fv.size()==3) ? fv[2] : "";
550 std::transform(extra.begin(),extra.end(),extra.begin(),::toupper);
551
552 LOG("gevgen", pNOTICE) << hst->GetEntries();
553
554 // Copy in the flux histogram from the root file and remove bins outside the emin,emax range
555 spectrum = (TH1D*)hst->Clone();
556 spectrum->SetNameTitle("spectrum","neutrino_flux");
557 spectrum->SetDirectory(0);
558 for(int ibin = 1; ibin <= hst->GetNbinsX(); ibin++) {
559 if(hst->GetBinLowEdge(ibin) + hst->GetBinWidth(ibin) > emax ||
560 hst->GetBinLowEdge(ibin) < emin) {
561 spectrum->SetBinContent(ibin, 0);
562 }
563 }
564 bool force_binwidth = false;
565#if ROOT_VERSION_CODE <= ROOT_VERSION(9,99,99)
566 // GetRandom() sampling on variable bin width histograms does not
567 // correctly account for bin widths for all versions of ROOT prior
568 // to (currently forever). At some point this might change and
569 // the necessity of this code snippet will go away
570 TAxis* xaxis = spectrum->GetXaxis();
571 if (xaxis->IsVariableBinSize()) force_binwidth = true;
572#endif
573 if ( extra == "WIDTH" ) force_binwidth = true;
574 if ( extra == "NOWIDTH" ) force_binwidth = false;
575 if ( force_binwidth ) {
576 LOG("gevgen", pNOTICE)
577 << "multiplying by bin width for histogram " << fv[1]
578 << " as " << spectrum->GetName()
579 << " from " << fv[0];
580 for(int ibin = 1; ibin <= spectrum->GetNbinsX(); ++ibin) {
581 double data = spectrum->GetBinContent(ibin);
582 double width = spectrum->GetBinWidth(ibin);
583 spectrum->SetBinContent(ibin,data*width);
584 }
585 }
586
587 LOG("gevgen", pNOTICE) << spectrum->GetEntries();
588
589 flux_file->Close();
590 delete flux_file;
591
592 LOG("gevgen", pNOTICE) << spectrum->GetEntries();
593
594 } else {
595 //
596 // ** generate the flux histogram from the input functional form
597 //
598 TF1 * input_func = new TF1("input_func", gOptFlux.c_str(), emin, emax);
599 spectrum = new TH1D("spectrum","neutrino flux", 300, emin, emax);
600 spectrum->SetDirectory(0);
601 spectrum->FillRandom("input_func", flux_entries);
602 delete input_func;
603 }
604 // save input flux
605
606 TFile f("./input-flux.root","recreate");
607 spectrum->Write();
608 f.Close();
609
610 TVector3 bdir (0,0,1);
611 double radius = -1;
612 TVector3 bspot(0,0,0);
613
614 // parse flux factors for direction, radius, spot
615 if ( gOptFluxFactors != "" ) {
616 vector<string> fv = utils::str::Split(gOptFluxFactors,",");
617 if ( fv.size() >= 3 ) {
618 bdir.SetX(atoi(fv[0].c_str()));
619 bdir.SetY(atoi(fv[1].c_str()));
620 bdir.SetZ(atoi(fv[2].c_str()));
621 if ( fv.size() >= 4 ) {
622 radius = atoi(fv[3].c_str());
623 if ( fv.size() >= 7 ) {
624 bspot.SetX(atoi(fv[4].c_str()));
625 bspot.SetY(atoi(fv[5].c_str()));
626 bspot.SetZ(atoi(fv[6].c_str()));
627 }
628 }
629 }
630 }
631
632 flux->SetNuDirection (bdir);
633 flux->SetTransverseRadius (radius);
634 flux->SetBeamSpot (bspot);
635 flux->AddEnergySpectrum (gOptNuPdgCode, spectrum);
636
637 GFluxI * flux_driver = dynamic_cast<GFluxI *>(flux);
638 return flux_driver;
639}
640//............................................................................
641#endif
642
643//____________________________________________________________________________
644void GetCommandLineArgs(int argc, char ** argv)
645{
646 LOG("gevgen", pINFO) << "Parsing command line arguments";
647
648 // Common run options. Set defaults and read.
651
652 // Parse run options for this app
653
654 CmdLnArgParser parser(argc,argv);
655
656 // help?
657 bool help = parser.OptionExists('h');
658 if(help) {
659 PrintSyntax();
660 exit(0);
661 }
662
663 // number of events
664 if( parser.OptionExists('n') ) {
665 LOG("gevgen", pINFO) << "Reading number of events to generate";
666 gOptNevents = parser.ArgAsInt('n');
667 } else {
668 LOG("gevgen", pINFO)
669 << "Unspecified number of events to generate - Using default";
671 }
672
673 // run number
674 if( parser.OptionExists('r') ) {
675 LOG("gevgen", pINFO) << "Reading MC run number";
676 gOptRunNu = parser.ArgAsLong('r');
677 } else {
678 LOG("gevgen", pINFO) << "Unspecified run number - Using default";
680 }
681
682 // Output file name
683 if( parser.OptionExists('o') ) {
684 LOG("gevgen", pINFO) << "Reading output file name";
685 gOptOutFileName = parser.ArgAsString('o');
686
688 // strip the output file format and replace with .status
689 if (gOptOutFileName.find_last_of(".") != string::npos)
691 gOptStatFileName.substr(0, gOptOutFileName.find_last_of("."));
692 gOptStatFileName .append(".status");
693 }
694
695 // flux functional form
696 bool using_flux = false;
697 if( parser.OptionExists('f') ) {
698 LOG("gevgen", pINFO) << "Reading flux function";
699 gOptFlux = parser.ArgAsString('f');
700 using_flux = true;
701 }
702 if (parser.OptionExists('F') ) {
703 LOG("gevgen", pINFO) << "Reading flux factors";
704 gOptFluxFactors = parser.ArgAsString('F');
705 }
706
707 if(parser.OptionExists('s')) {
708 LOG("gevgen", pWARN)
709 << "-s option no longer available. Please read the revised code documentation";
710 gAbortingInErr = true;
711 exit(1);
712 }
713
714
715 // generate weighted events option (only relevant if using a flux)
716 gOptWeighted = parser.OptionExists('w');
717
718 // force interaction of all injected events (only relevant if using a flux)
719 gOptForceInt = parser.OptionExists("force-flux-ray-interaction");
720
721 // neutrino energy
722 if( parser.OptionExists('e') ) {
723 LOG("gevgen", pINFO) << "Reading neutrino energy";
724 string nue = parser.ArgAsString('e');
725
726 // is it just a value or a range (comma separated set of values)
727 if(nue.find(",") != string::npos) {
728 // split the comma separated list
729 vector<string> nurange = utils::str::Split(nue, ",");
730 assert(nurange.size() == 2);
731 double emin = atof(nurange[0].c_str());
732 double emax = atof(nurange[1].c_str());
733 assert(emax>emin && emin>=0);
734 gOptNuEnergy = emin;
735 gOptNuEnergyRange = emax-emin;
736 if(!using_flux) {
737 LOG("gevgen", pWARN)
738 << "No flux was specified but an energy range was input!";
739 LOG("gevgen", pWARN)
740 << "Events will be generated at fixed E = " << gOptNuEnergy << " GeV";
742 }
743 } else {
744 gOptNuEnergy = atof(nue.c_str());
746 }
747 } else {
748 LOG("gevgen", pFATAL) << "Unspecified neutrino energy - Exiting";
749 PrintSyntax();
750 exit(1);
751 }
752
753 // neutrino PDG code
754 if( parser.OptionExists('p') ) {
755 LOG("gevgen", pINFO) << "Reading neutrino PDG code";
756 gOptNuPdgCode = parser.ArgAsInt('p');
757 } else {
758 LOG("gevgen", pFATAL) << "Unspecified neutrino PDG code - Exiting";
759 PrintSyntax();
760 exit(1);
761 }
762
763 // target mix (their PDG codes with their corresponding weights)
764 bool using_tgtmix = false;
765 if( parser.OptionExists('t') ) {
766 LOG("gevgen", pINFO) << "Reading target mix";
767 string stgtmix = parser.ArgAsString('t');
768 gOptTgtMix.clear();
769 vector<string> tgtmix = utils::str::Split(stgtmix,",");
770 if(tgtmix.size()==1) {
771 int pdg = atoi(tgtmix[0].c_str());
772 double wgt = 1.0;
773 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
774 } else {
775 using_tgtmix = true;
776 vector<string>::const_iterator tgtmix_iter = tgtmix.begin();
777 for( ; tgtmix_iter != tgtmix.end(); ++tgtmix_iter) {
778 string tgt_with_wgt = *tgtmix_iter;
779 string::size_type open_bracket = tgt_with_wgt.find("[");
780 string::size_type close_bracket = tgt_with_wgt.find("]");
781 string::size_type ibeg = 0;
782 string::size_type iend = open_bracket;
783 string::size_type jbeg = open_bracket+1;
784 string::size_type jend = close_bracket-1;
785 int pdg = atoi(tgt_with_wgt.substr(ibeg,iend).c_str());
786 double wgt = atof(tgt_with_wgt.substr(jbeg,jend).c_str());
787 LOG("Main", pNOTICE)
788 << "Adding to target mix: pdg = " << pdg << ", wgt = " << wgt;
789 gOptTgtMix.insert(map<int, double>::value_type(pdg, wgt));
790 }//tgtmix_iter
791 }//>1
792
793 } else {
794 LOG("gevgen", pFATAL) << "Unspecified target PDG code - Exiting";
795 PrintSyntax();
796 exit(1);
797 }
798
799 gOptUsingFluxOrTgtMix = using_flux || using_tgtmix;
800
801 // random number seed
802 if( parser.OptionExists("seed") ) {
803 LOG("gevgen", pINFO) << "Reading random number seed";
804 gOptRanSeed = parser.ArgAsLong("seed");
805 } else {
806 LOG("gevgen", pINFO) << "Unspecified random number seed - Using default";
807 gOptRanSeed = -1;
808 }
809
810 // input cross-section file
811 if( parser.OptionExists("cross-sections") ) {
812 LOG("gevgen", pINFO) << "Reading cross-section file";
813 gOptInpXSecFile = parser.ArgAsString("cross-sections");
814 } else {
815 LOG("gevgen", pINFO) << "Unspecified cross-section file";
816 gOptInpXSecFile = "";
817 }
818
819 //
820 // print-out the command line options
821 //
822 LOG("gevgen", pNOTICE)
823 << "\n"
824 << utils::print::PrintFramedMesg("gevgen job configuration");
825 LOG("gevgen", pNOTICE)
826 << "MC Run Number: " << gOptRunNu;
827 if(gOptRanSeed != -1) {
828 LOG("gevgen", pNOTICE)
829 << "Random number seed: " << gOptRanSeed;
830 } else {
831 LOG("gevgen", pNOTICE)
832 << "Random number seed was not set, using default";
833 }
834 LOG("gevgen", pNOTICE)
835 << "Number of events requested: " << gOptNevents;
836 if(gOptInpXSecFile.size() > 0) {
837 LOG("gevgen", pNOTICE)
838 << "Using cross-section splines read from: " << gOptInpXSecFile;
839 } else {
840 LOG("gevgen", pNOTICE)
841 << "No input cross-section spline file";
842 }
843 LOG("gevgen", pNOTICE)
844 << "Flux: " << gOptFlux << " factors " << gOptFluxFactors;
845 LOG("gevgen", pNOTICE)
846 << "Generate weighted events? " << gOptWeighted;
847 LOG("gevgen", pNOTICE)
848 << "Force interaction of all flux rays? " << gOptForceInt;
849 if(gOptNuEnergyRange>0) {
850 LOG("gevgen", pNOTICE)
851 << "Neutrino energy: ["
852 << gOptNuEnergy << ", " << gOptNuEnergy+gOptNuEnergyRange << "]";
853 } else {
854 LOG("gevgen", pNOTICE)
855 << "Neutrino energy: " << gOptNuEnergy;
856 }
857 LOG("gevgen", pNOTICE)
858 << "Neutrino code (PDG): " << gOptNuPdgCode;
859 LOG("gevgen", pNOTICE)
860 << "Target code (PDG) & weight fraction (in case of multiple targets): ";
861 map<int,double>::const_iterator iter;
862 for(iter = gOptTgtMix.begin(); iter != gOptTgtMix.end(); ++iter) {
863 int tgtpdgc = iter->first;
864 double wgt = iter->second;
865 LOG("gevgen", pNOTICE)
866 << " >> " << tgtpdgc << " (weight fraction = " << wgt << ")";
867 }
868 LOG("gevgen", pNOTICE) << "\n";
869
870 LOG("gevgen", pNOTICE) << *RunOpt::Instance();
871
872}
873//____________________________________________________________________________
874void PrintSyntax(void)
875{
876 LOG("gevgen", pNOTICE)
877 << "\n\n" << "Syntax:" << "\n"
878 << "\n gevgen [-h]"
879 << "\n [-r run#]"
880 << "\n -n nev"
881 << "\n -e energy (or energy range) "
882 << "\n -p neutrino_pdg"
883 << "\n -t target_pdg "
884 << "\n [-f flux_description]"
885 << "\n [-o outfile_name]"
886 << "\n [-w]"
887 << "\n [--force-flux-ray-interaction]"
888 << "\n [--seed random_number_seed]"
889 << "\n [--cross-sections xml_file]"
891 << "\n";
892
893}
894//____________________________________________________________________________
#define pNOTICE
Definition Messenger.h:61
#define pINFO
Definition Messenger.h:62
#define pERROR
Definition Messenger.h:59
#define pFATAL
Definition Messenger.h:56
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
#define pWARN
Definition Messenger.h:60
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils.
int main()
Command line argument parser.
string ArgAsString(char opt)
bool OptionExists(char opt)
was option set?
A vector of EventGeneratorI objects.
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
Definition EventRecord.h:37
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
Definition GEVGDriver.h:54
void SetUnphysEventMask(const TBits &mask)
void Configure(int nu_pdgc, int Z, int A)
EventRecord * GenerateEvent(const TLorentzVector &nu4p)
void SetEventGeneratorList(string listname)
GENIE Interface for user-defined flux classes.
Definition GFluxI.h:29
static void SetPrintLevel(int print_level)
A GENIE ‘MC Job Driver’. Can be used for setting up complicated event generation cases involving deta...
Definition GMCJDriver.h:46
void ForceSingleProbScale(void)
void UseFluxDriver(GFluxI *flux)
void UseGeomAnalyzer(GeomAnalyzerI *geom)
void Configure(bool calc_prob_scales=true)
void ForceInteraction(void)
void UseSplines(bool useLogE=true)
void SetUnphysEventMask(const TBits &mask)
void SetEventGeneratorList(string listname)
EventRecord * GenerateEvent(void)
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 CustomizeFilename(string filename)
void Update(int iev, const EventRecord *event)
void SetRefreshRate(int rate)
Defines the GENIE Geometry Analyzer Interface.
Initial State information.
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records.
Definition NtpWriter.h:39
void CustomizeFilename(string filename)
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
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
static std::string RunOptSyntaxString(bool include_generator_specific)
Definition RunOpt.cxx:157
void BuildTune()
build tune and inform XSecSplineList
Definition RunOpt.cxx:92
void EnableBareXSecPreCalc(bool flag)
Definition RunOpt.h:62
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
A generic GENIE flux driver. Generates a 'cylindrical' neutrino beam along the input direction,...
A simple GENIE flux driver for monoenergetic neutrinos along the z direction. Can handle a mix of neu...
A simple GENIE flux driver for neutrinos following a power law spectrum. Can handle a mix of neutrino...
The PointGeomAnalyzer class is the simplest implementation of the GeomAnalyserI interface and defines...
long int gOptRanSeed
NtpMCFormat_t kDefOptNtpFormat
Long_t gOptRunNu
map< int, double > gOptTgtMix
string gOptInpXSecFile
string gOptFlux
Definition gEvGen.cxx:234
bool gOptWeighted
Definition gEvGen.cxx:236
string gOptFluxFactors
Definition gEvGen.cxx:235
double gOptNuEnergyRange
Definition gEvGen.cxx:230
void GenerateEventsAtFixedInitState(void)
Definition gEvGen.cxx:293
void Initialize(void)
Definition gEvGen.cxx:273
bool gOptForceInt
Definition gEvGen.cxx:237
Long_t kDefOptRunNu
Definition gEvGen.cxx:225
int gOptNuPdgCode
Definition gEvGen.cxx:231
void GetCommandLineArgs(int argc, char **argv)
Definition gEvGen.cxx:644
bool gOptUsingFluxOrTgtMix
Definition gEvGen.cxx:238
void PrintSyntax(void)
Definition gEvGen.cxx:874
string gOptOutFileName
Definition gEvGen.cxx:241
int kDefOptNevents
Definition gEvGen.cxx:223
int gOptNevents
Definition gEvGen.cxx:228
double gOptNuEnergy
Definition gEvGen.cxx:229
string gOptStatFileName
Definition gEvGen.cxx:242
const double e
Misc GENIE control constants.
static const unsigned int kRjMaxIterations
Definition Controls.h:26
GENIE flux drivers.
Utilities for improving the code readability when using PDG codes.
void XSecTable(string inpfile, bool require_table)
Definition AppInit.cxx:38
void RandGen(long int seed)
Definition AppInit.cxx:30
void MesgThresholds(string inpfile)
Definition AppInit.cxx:99
void CacheFile(string inpfile)
Definition AppInit.cxx:117
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
bool gAbortingInErr
Definition Messenger.cxx:34
@ kNFGHEP
Definition NtpMCFormat.h:30
enum genie::ENtpMCFormat NtpMCFormat_t