GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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 :
19 Syntax:
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-2024, 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"
181 #include "Framework/Utils/AppInit.h"
182 #include "Framework/Utils/RunOpt.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 
199 using std::string;
200 using std::vector;
201 using std::map;
202 using std::ostringstream;
203 
204 using namespace genie;
205 using namespace genie::controls;
206 
207 void GetCommandLineArgs (int argc, char ** argv);
208 void Initialize (void);
209 void PrintSyntax (void);
210 
211 #ifdef __CAN_GENERATE_EVENTS_USING_A_FLUX_OR_TGTMIX__
212 void GenerateEventsUsingFluxOrTgtMix();
213 GeomAnalyzerI * GeomDriver (void);
214 GFluxI * FluxDriver (void);
215 GFluxI * MonoEnergeticFluxDriver (void);
216 GFluxI * PowerLawFluxDriver (void);
217 GFluxI * TH1FluxDriver (void);
218 #endif
219 
221 
222 //Default options (override them using the command line arguments):
223 int kDefOptNevents = 0; // n-events to generate
225 Long_t kDefOptRunNu = 0; // default run number
226 
227 //User-specified options:
228 int gOptNevents; // n-events to generate
229 double gOptNuEnergy; // neutrino E, or min neutrino energy in spectrum
230 double gOptNuEnergyRange;// energy range in input spectrum
231 int gOptNuPdgCode; // neutrino PDG code
232 map<int,double> gOptTgtMix; // target mix (each with its relative weight)
233 Long_t gOptRunNu; // run number
234 string gOptFlux; //
235 string gOptFluxFactors; //
236 bool gOptWeighted; //
237 bool gOptForceInt; //
239 long int gOptRanSeed; // random number seed
240 string gOptInpXSecFile; // cross-section splines
241 string gOptOutFileName; // Optional outfile name
242 string gOptStatFileName; // Status file name, set if gOptOutFileName was set.
243 
244 //____________________________________________________________________________
245 int 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 //____________________________________________________________________________
273 void Initialize()
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 //............................................................................
365 void 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 //____________________________________________________________________________
430 GeomAnalyzerI * GeomDriver(void)
431 {
432 // create a trivial point geometry with the specified target or target mix
433 
435  return geom_driver;
436 }
437 //____________________________________________________________________________
438 GFluxI * 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 //____________________________________________________________________________
451 GFluxI * MonoEnergeticFluxDriver(void)
452 {
453 //
454 //
455  flux::GMonoEnergeticFlux * flux =
457  GFluxI * flux_driver = dynamic_cast<GFluxI *>(flux);
458  return flux_driver;
459 }
460 //____________________________________________________________________________
461 GFluxI * 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 
470  flux::GPowerLawFlux * flux =
472  GFluxI * flux_driver = dynamic_cast<GFluxI *>(flux);
473  return flux_driver;
474 }
475 //____________________________________________________________________________
476 GFluxI * 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 //____________________________________________________________________________
644 void 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";
741  gOptNuEnergyRange = -1;
742  }
743  } else {
744  gOptNuEnergy = atof(nue.c_str());
745  gOptNuEnergyRange = -1;
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 //____________________________________________________________________________
874 void 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 //____________________________________________________________________________
void RandGen(long int seed)
Definition: AppInit.cxx:30
static void SetPrintLevel(int print_level)
Definition: GHepRecord.cxx:956
void XSecTable(string inpfile, bool require_table)
Definition: AppInit.cxx:38
void SetUnphysEventMask(const TBits &mask)
Definition: GMCJDriver.cxx:74
void ForceInteraction(void)
Definition: GMCJDriver.cxx:162
Long_t kDefOptRunNu
Definition: gEvGen.cxx:225
#define pERROR
Definition: Messenger.h:59
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:71
void SetEventGeneratorList(string listname)
Definition: GMCJDriver.cxx:66
void CustomizeFilename(string filename)
Definition: NtpWriter.cxx:128
bool gOptForceInt
Definition: gEvGen.cxx:237
void ReadFromCommandLine(int argc, char **argv)
Definition: RunOpt.cxx:99
A numeric analysis tool class for interpolating 1-D functions.
Definition: Spline.h:58
#define pFATAL
Definition: Messenger.h:56
int gOptNuPdgCode
Definition: gEvGen.cxx:231
void Update(int iev, const EventRecord *event)
Definition: GMCJMonitor.cxx:48
void CustomizeFilename(string filename)
Definition: GMCJMonitor.cxx:97
int gOptNevents
Definition: gEvGen.cxx:228
string gOptStatFileName
Definition: gEvGen.cxx:242
map< int, double > gOptTgtMix
Definition: gAtmoEvGen.cxx:299
double Evaluate(double x) const
Definition: Spline.cxx:363
double gOptNuEnergyRange
Definition: gEvGen.cxx:230
A simple GENIE flux driver for neutrinos following a power law spectrum. Can handle a mix of neutrino...
Definition: GPowerLawFlux.h:36
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:29
int main(int argc, char **argv)
Definition: gAtmoEvGen.cxx:327
void SetRefreshRate(int rate)
Definition: GMCJMonitor.cxx:43
void UseFluxDriver(GFluxI *flux)
Definition: GMCJDriver.cxx:83
Simple class to create &amp; update MC job status files and env. vars. This is used to be able to keep tr...
Definition: GMCJMonitor.h:31
A GENIE `MC Job Driver&#39;. Can be used for setting up complicated event generation cases involving deta...
Definition: GMCJDriver.h:46
const double e
string gOptInpXSecFile
Definition: gAtmoEvGen.cxx:313
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
double gOptNuEnergy
Definition: gEvGen.cxx:229
void SetEventGeneratorList(string listname)
Definition: GEVGDriver.cxx:348
bool gOptWeighted
Definition: gEvGen.cxx:236
void ForceSingleProbScale(void)
Definition: GMCJDriver.cxx:172
A generic GENIE flux driver. Generates a &#39;cylindrical&#39; neutrino beam along the input direction...
static std::string RunOptSyntaxString(bool include_generator_specific)
Definition: RunOpt.cxx:157
A simple GENIE flux driver for monoenergetic neutrinos along the z direction. Can handle a mix of neu...
void Configure(bool calc_prob_scales=true)
Definition: GMCJDriver.cxx:399
void Initialize(void)
void Save(void)
get the even tree
Definition: NtpWriter.cxx:225
GENIE Event Generation Driver. A minimalist user interface object for generating neutrino interaction...
Definition: GEVGDriver.h:54
#define pINFO
Definition: Messenger.h:62
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
Definition: NtpWriter.cxx:57
void SetTransverseRadius(double Rt)
void SetNuDirection(const TVector3 &direction)
void BuildTune()
build tune and inform XSecSplineList
Definition: RunOpt.cxx:92
#define pWARN
Definition: Messenger.h:60
EventRecord * GenerateEvent(void)
Definition: GMCJDriver.cxx:815
Long_t gOptRunNu
Definition: gAtmoEvGen.cxx:295
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
Definition: EventRecord.h:37
string gOptFlux
Definition: gEvGen.cxx:234
int kDefOptNevents
Definition: gEvGen.cxx:223
string gOptFluxFactors
Definition: gEvGen.cxx:235
void Initialize(void)
add event
Definition: NtpWriter.cxx:83
static RunOpt * Instance(void)
Definition: RunOpt.cxx:54
vector< string > Split(string input, string delim)
Definition: StringUtils.cxx:36
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records...
Definition: NtpWriter.h:39
bool gOptUsingFluxOrTgtMix
Definition: gEvGen.cxx:238
TRandom3 & RndGen(void) const
rnd number generator for generic usage
Definition: RandomGen.h:80
string gOptOutFileName
Definition: gEvGen.cxx:241
void Configure(int nu_pdgc, int Z, int A)
Definition: GEVGDriver.cxx:137
NtpMCFormat_t kDefOptNtpFormat
Definition: gAtmoEvGen.cxx:319
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
Definition: PrintUtils.cxx:164
A vector of EventGeneratorI objects.
void GenerateEventsAtFixedInitState(void)
Definition: gEvGen.cxx:293
void SetBeamSpot(const TVector3 &spot)
void MesgThresholds(string inpfile)
Definition: AppInit.cxx:99
void AddEnergySpectrum(int nu_pdgc, TH1D *spectrum)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
#define pNOTICE
Definition: Messenger.h:61
void GetCommandLineArgs(int argc, char **argv)
Definition: gAtmoEvGen.cxx:563
Defines the GENIE Geometry Analyzer Interface.
Definition: GeomAnalyzerI.h:29
static const unsigned int kRjMaxIterations
Definition: Controls.h:26
void SetUnphysEventMask(const TBits &mask)
Definition: GEVGDriver.cxx:219
bool gAbortingInErr
Definition: Messenger.cxx:34
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
void UseGeomAnalyzer(GeomAnalyzerI *geom)
Definition: GMCJDriver.cxx:88
void UseSplines(bool useLogE=true)
Definition: GMCJDriver.cxx:93
The PointGeomAnalyzer class is the simplest implementation of the GeomAnalyserI interface and defines...
void PrintSyntax(void)
void CacheFile(string inpfile)
Definition: AppInit.cxx:117
void EnableBareXSecPreCalc(bool flag)
Definition: RunOpt.h:62
Initial State information.
Definition: InitialState.h:48
GENIE Interface for user-defined flux classes.
Definition: GFluxI.h:29
EventRecord * GenerateEvent(const TLorentzVector &nu4p)
Definition: GEVGDriver.cxx:228
long int gOptRanSeed
Definition: gAtmoEvGen.cxx:312