GENIEGenerator
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
gBeamHNLParticleGun.cxx
Go to the documentation of this file.
1 //________________________________________________________________________________________
2 /*!
3 
4 \program gevgen_pghnl
5 
6 \brief A particle gun for long-lived HNL.
7 
8  *** Synopsis :
9 
10  gevgen_pghnl [-h]
11  [-r run#]
12  -n n_of_events
13  [-m decay_mode]
14  [-g geometry (ROOT file)]
15  [-L geometry_length_units]
16  [-t geometry_top_volume_name]
17  [-o output_event_file_prefix]
18  [--seed random_number_seed]
19  [--message-thresholds xml_file]
20  [--event-record-print-level level]
21  [--mc-job-status-refresh-rate rate]
22 
23  *** Options :
24 
25  [] Denotes an optional argument
26 
27  -h
28  Prints out the gevgen_pghnl syntax and exits.
29  -r
30  Specifies the MC run number [default: 1000].
31  -n
32  Specifies how many events to generate.
33  -m
34  HNL decay mode ID:
35  -g
36  Input detector geometry.
37  If a geometry is specified, HNL decay vertices will be distributed
38  in the desired detector volume.
39  Using this argument, you can pass a ROOT file containing your
40  detector geometry description.
41  -L
42  Input geometry length units, eg 'm', 'cm', 'mm', ...
43  [default: 'mm']
44  -o
45  Sets the prefix of the output event file.
46  The output filename is built as:
47  [prefix].[run_number].[event_tree_format].[file_format]
48  The default output filename is:
49  gntp.[run_number].ghep.root
50  This cmd line arguments lets you override 'gntp'
51  --seed
52  Random number seed.
53 
54 \author Costas Andreopoulos <c.andreopoulos \at cern.ch>
55  University of Liverpool
56  John Plows <komninos-john.plows \at physics.ox.ac.uk>
57  University of Oxford
58 
59 \created May 27th, 2022
60 
61 \cpright Copyright (c) 2003-2024, The GENIE Collaboration
62  For the full text of the license visit http://copyright.genie-mc.org
63 
64 */
65 //_________________________________________________________________________________________
66 
67 #include <cassert>
68 #include <cstdlib>
69 #include <string>
70 #include <vector>
71 #include <sstream>
72 
73 #include <TSystem.h>
74 
98 #include "Framework/Utils/RunOpt.h"
100 
101 using std::string;
102 using std::vector;
103 using std::ostringstream;
104 
105 using namespace genie;
106 using namespace genie::hnl;
107 using namespace genie::hnl::enums;
108 
109 #ifdef __GENIE_GEOM_DRIVERS_ENABLED__
110 #define __CAN_USE_ROOT_GEOM__
111 #include <TGeoVolume.h>
112 #include <TGeoManager.h>
113 #include <TGeoShape.h>
114 #include <TGeoBBox.h>
115 #endif // #ifdef __GENIE_GEOM_DRIVERS_ENABLED__
116 
117 // function prototypes
118 void GetCommandLineArgs (int argc, char ** argv);
119 void PrintSyntax (void);
120 
121 int SelectDecayMode (std::vector<HNLDecayMode_t> *intChannels, SimpleHNL sh);
122 const EventRecordVisitorI * HNLGenerator(void);
123 
124 TLorentzVector * GenerateOriginPosition( GHepRecord * event );
125 TLorentzVector * GenerateOriginMomentum( GHepRecord * event );
126 
127 TLorentzVector GeneratePosition( GHepRecord * event );
128 #ifdef __CAN_USE_ROOT_GEOM__
129 void InitBoundingBox (void);
130 #endif // #ifdef __CAN_USE_ROOT_GEOM__
131 
132 //
133 string kDefOptGeomLUnits = "mm"; // default geometry length units
134 string kDefOptGeomDUnits = "g_cm3"; // default geometry density units
135 NtpMCFormat_t kDefOptNtpFormat = kNFGHEP; // default event tree format
136 string kDefOptEvFilePrefix = "gntp";
137 
138 string kDefOptSName = "genie::EventGenerator";
139 string kDefOptSConfig = "BeamHNL";
140 string kDefOptSTune = "GHNL20_00a_00_000";
141 
142 //
143 Long_t gOptRunNu = 1000; // run number
144 int gOptNev = 10; // number of events to generate
145 
146 double gOptEnergyHNL = -1; // HNL energy
147 double gOptMassHNL = -1; // HNL mass
148 double gOptECoupling = -1; // |U_e4|^2
149 double gOptMCoupling = -1; // |U_m4|^2
150 double gOptTCoupling = -1; // |U_t4|^2
151 
152 bool gOptIsMajorana = false; // is this Majorana?
153 int gOptHNLKind = -1; // 0 = nu, 1 = nubar, 2 = mix
154 
156 std::vector< HNLDecayMode_t > gOptIntChannels; // decays to un-inhibit
157 
158 string gOptEvFilePrefix = kDefOptEvFilePrefix; // event file prefix
159 bool gOptUsingRootGeom = false; // using root geom or target mix?
160 string gOptRootGeom; // input ROOT file with realistic detector geometry
161 
162 #ifdef __CAN_USE_ROOT_GEOM__
163 TGeoManager * gOptRootGeoManager = 0; // the workhorse geometry manager
164 TGeoVolume * gOptRootGeoVolume = 0;
165 #endif // #ifdef __CAN_USE_ROOT_GEOM__
166 
167 string gOptRootGeomTopVol = ""; // input geometry top event generation volume
168 double gOptGeomLUnits = 0; // input geometry length units
169 long int gOptRanSeed = -1; // random number seed
170 
171 // Geometry bounding box and origin - read from the input geometry file (if any)
172 double fdx = 0; // half-length - x
173 double fdy = 0; // half-length - y
174 double fdz = 0; // half-length - z
175 double fox = 0; // origin - x
176 double foy = 0; // origin - y
177 double foz = 0; // origin - z
178 
179 double NTP_IS_E = 0., NTP_IS_PX = 0., NTP_IS_PY = 0., NTP_IS_PZ = 0.;
180 double NTP_FS0_E = 0., NTP_FS0_PX = 0., NTP_FS0_PY = 0., NTP_FS0_PZ = 0.;
181 double NTP_FS1_E = 0., NTP_FS1_PX = 0., NTP_FS1_PY = 0., NTP_FS1_PZ = 0.;
182 double NTP_FS2_E = 0., NTP_FS2_PX = 0., NTP_FS2_PY = 0., NTP_FS2_PZ = 0.;
184 
185 //Decayer * hnlgen = 0;
186 // HNL lifetime in rest frame
187 double CoMLifetime = -1.0; // GeV^{-1}
188 // an array to keep production vertex
189 double evProdVtx[3] = {0.0, 0.0, 0.0}; // mm
190 // event weight
191 double evWeight = 1.0;
192 
193 //_________________________________________________________________________________________
194 int main(int argc, char ** argv)
195 {
196  // suppress ROOT Info messages
197  gErrorIgnoreLevel = kWarning;
198 
199  // Parse command line arguments
200  GetCommandLineArgs(argc,argv);
201 
202  // Init messenger and random number seed
203  utils::app_init::MesgThresholds(RunOpt::Instance()->MesgThresholdFiles());
205 
206  __attribute__((unused)) RandomGen * rnd = RandomGen::Instance();
207 
208  // Get the HNL generator first to load config
209  // config loaded upon instantiation of HNLGenerator algorithm
210  // ==> Decayer::LoadConfig()
211  __attribute__((unused)) const EventRecordVisitorI * mcgen = HNLGenerator();
212  const Algorithm * algHNLGen = AlgFactory::Instance()->GetAlgorithm("genie::hnl::Decayer", "Default");
213  const Algorithm * algVtxGen = AlgFactory::Instance()->GetAlgorithm("genie::hnl::VertexGenerator", "Default");
214 
215  const Decayer * hnlgen = dynamic_cast< const Decayer * >( algHNLGen );
216  const VertexGenerator * vtxGen = dynamic_cast< const VertexGenerator * >( algVtxGen );
217 
218  bool geom_is_accessible = ! (gSystem->AccessPathName(gOptRootGeom.c_str()));
219  if (!geom_is_accessible) {
220  LOG("gevgen_pghnl", pFATAL)
221  << "The specified ROOT geometry doesn't exist! Initialization failed!";
222  exit(1);
223  }
224  vtxGen->SetGeomFile( gOptRootGeom );
225 
226  if( !gOptRootGeoManager ) gOptRootGeoManager = TGeoManager::Import(gOptRootGeom.c_str());
227 
228  TGeoVolume * top_volume = gOptRootGeoManager->GetTopVolume();
229  assert( top_volume );
230  __attribute__((unused)) TGeoShape * ts = top_volume->GetShape();
231 
232  //TGeoBBox * box = (TGeoBBox *)ts;
233 
234  string confString = kDefOptSName + kDefOptSConfig;
235 
236  CoMLifetime = hnlgen->GetHNLLifetime();
237 
238  gOptMassHNL = hnlgen->GetHNLMass();
239  std::vector< double > U4l2s = hnlgen->GetHNLCouplings();
240  gOptECoupling = U4l2s.at(0);
241  gOptMCoupling = U4l2s.at(1);
242  gOptTCoupling = U4l2s.at(2);
243  gOptIsMajorana = hnlgen->IsHNLMajorana();
244 
245  std::string stIntChannels = hnlgen->GetHNLInterestingChannels(); int iChan = -1;
246  if( gOptIntChannels.size() > 0 ) gOptIntChannels.clear();
247  while( stIntChannels.size() > 0 ){ // read channels from right (lowest mass) to left (highest mass)
248  iChan++;
249  HNLDecayMode_t md = static_cast< HNLDecayMode_t >( iChan );
250  std::string tmpSt = stIntChannels.substr( stIntChannels.size()-1, stIntChannels.size() );
251  if( std::strcmp( tmpSt.c_str(), "1" ) == 0 )
252  gOptIntChannels.emplace_back( md );
253 
254  stIntChannels.erase( stIntChannels.end()-1, stIntChannels.end() );
255  }
256 
257  assert( gOptECoupling >= 0.0 && gOptMCoupling >= 0.0 && gOptTCoupling >= 0.0 );
258 
259  // Initialize an Ntuple Writer to save GHEP records into a TTree
262  ntpw.Initialize();
263 
264  LOG("gevgen_pghnl", pNOTICE)
265  << "Initialised Ntuple Writer";
266 
267  // add another few branches to tree.
268  ntpw.EventTree()->Branch("hnl_mass", &gOptMassHNL, "gOptMassHNL/D");
269  ntpw.EventTree()->Branch("hnl_coup_e", &gOptECoupling, "gOptECoupling/D");
270  ntpw.EventTree()->Branch("hnl_coup_m", &gOptMCoupling, "gOptMCoupling/D");
271  ntpw.EventTree()->Branch("hnl_coup_t", &gOptTCoupling, "gOptTCoupling/D");
272  ntpw.EventTree()->Branch("hnl_ismaj", &gOptIsMajorana, "gOptIsMajorana/I");
273 
274  // let's make HNL-specific FS branches until we get gntpc sorted out
275  ntpw.EventTree()->Branch("hnl_IS_E", &NTP_IS_E, "NTP_IS_E/D");
276  ntpw.EventTree()->Branch("hnl_IS_PX", &NTP_IS_PX, "NTP_IS_PX/D");
277  ntpw.EventTree()->Branch("hnl_IS_PY", &NTP_IS_PY, "NTP_IS_PY/D");
278  ntpw.EventTree()->Branch("hnl_IS_PZ", &NTP_IS_PZ, "NTP_IS_PZ/D");
279  ntpw.EventTree()->Branch("hnl_FS0_PDG", &NTP_FS0_PDG, "NTP_FS0_PDG/I");
280  ntpw.EventTree()->Branch("hnl_FS0_E", &NTP_FS0_E, "NTP_FS0_E/D");
281  ntpw.EventTree()->Branch("hnl_FS0_PX", &NTP_FS0_PX, "NTP_FS0_PX/D");
282  ntpw.EventTree()->Branch("hnl_FS0_PY", &NTP_FS0_PY, "NTP_FS0_PY/D");
283  ntpw.EventTree()->Branch("hnl_FS0_PZ", &NTP_FS0_PZ, "NTP_FS0_PZ/D");
284  ntpw.EventTree()->Branch("hnl_FS1_PDG", &NTP_FS1_PDG, "NTP_FS1_PDG/I");
285  ntpw.EventTree()->Branch("hnl_FS1_E", &NTP_FS1_E, "NTP_FS1_E/D");
286  ntpw.EventTree()->Branch("hnl_FS1_PX", &NTP_FS1_PX, "NTP_FS1_PX/D");
287  ntpw.EventTree()->Branch("hnl_FS1_PY", &NTP_FS1_PY, "NTP_FS1_PY/D");
288  ntpw.EventTree()->Branch("hnl_FS1_PZ", &NTP_FS1_PZ, "NTP_FS1_PZ/D");
289  ntpw.EventTree()->Branch("hnl_FS2_PDG", &NTP_FS2_PDG, "NTP_FS2_PDG/I");
290  ntpw.EventTree()->Branch("hnl_FS2_E", &NTP_FS2_E, "NTP_FS2_E/D");
291  ntpw.EventTree()->Branch("hnl_FS2_PX", &NTP_FS2_PX, "NTP_FS2_PX/D");
292  ntpw.EventTree()->Branch("hnl_FS2_PY", &NTP_FS2_PY, "NTP_FS2_PY/D");
293  ntpw.EventTree()->Branch("hnl_FS2_PZ", &NTP_FS2_PZ, "NTP_FS2_PZ/D");
294 
295  // Create a MC job monitor for a periodically updated status file
296  GMCJMonitor mcjmonitor(gOptRunNu);
297  mcjmonitor.SetRefreshRate(RunOpt::Instance()->MCJobStatusRefreshRate());
298 
299  LOG("gevgen_pghnl", pNOTICE)
300  << "Initialised MC job monitor";
301 
302  // Set GHEP print level
303  GHepRecord::SetPrintLevel(RunOpt::Instance()->EventRecordPrintLevel());
304 
305 #ifdef __CAN_USE_ROOT_GEOM__
306  // Read geometry bounding box - for vertex position generation
307  if( gOptUsingRootGeom ){
308  InitBoundingBox();
309  }
310 #endif // #ifdef __CAN_USE_ROOT_GEOM__
311 
312  // read in energy. This is always constant
313  //gOptEnergyHNL = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-Energy" );
314  gOptEnergyHNL = hnlgen->GetPGunEnergy();
315  if( gOptEnergyHNL <= gOptMassHNL ){
316  LOG( "gevgen_pghnl", pFATAL )
317  << "\nInsufficient energy " << gOptEnergyHNL << " GeV for HNL of mass " << gOptMassHNL << " GeV. Exiting."
318  << "\nPlease check ${GENIE}/config/CommonHNL.xml sections \"ParamSpace\" and \"ParticleGun\"";
319  exit(1);
320  }
321  assert( gOptEnergyHNL > gOptMassHNL );
322 
323  // Event loop
324  int ievent = 0;
325 
326  while (1)
327  {
328  if( gOptNev >= 10000 ){
329  if( ievent % (gOptNev / 1000 ) == 0 ){
330  int irat = ievent / ( gOptNev / 1000 );
331  std::cerr << 0.1 * irat << " % " << " ( " << ievent
332  << " / " << gOptNev << " ) \r" << std::flush;
333  }
334  } else if( gOptNev >= 100 ){
335  if( ievent % (gOptNev / 10 ) == 0 ){
336  int irat = ievent / ( gOptNev / 10 );
337  std::cerr << 10.0 * irat << " % " << " ( " << ievent
338  << " / " << gOptNev << " ) \r" << std::flush;
339  }
340  }
341 
342  if((ievent) == gOptNev) break;
343 
344  LOG("gevgen_pghnl", pNOTICE)
345  << " *** Generating event............ " << ievent;
346 
347  int hpdg = genie::kPdgHNL;
348  EventRecord * event = new EventRecord;
349 
350  event->SetProbability( CoMLifetime );
351 
352  int decay = (int) gOptDecayMode;
353 
354  SimpleHNL sh( "HNL", ievent, hpdg, genie::kPdgKP,
356 
357  const std::map< HNLDecayMode_t, double > gammaMap = sh.GetValidChannels();
359 
360  if( gOptDecayMode == kHNLDcyNull ){ // select from available modes
361  LOG("gevgen_pghnl", pNOTICE)
362  << "No decay mode specified - sampling from all available modes.";
363 
364  std::vector< HNLDecayMode_t > * intChannels = &gOptIntChannels;
365 
366  decay = SelectDecayMode( intChannels, sh );
367  }
368 
369  Interaction * interaction = Interaction::HNL(genie::kPdgHNL, gOptEnergyHNL, decay);
370  event->AttachSummary(interaction);
371 
372  // generate origin position and momentum direction for this HNL
373  TLorentzVector * x4orig = GenerateOriginPosition( event );
374  TLorentzVector * p4HNL = GenerateOriginMomentum( event );
375 
376  // and add as Particle(0)
377  GHepParticle ptHNL( kPdgHNL, kIStInitialState, -1, -1, -1, -1, *p4HNL, *x4orig );
378  event->AddParticle( ptHNL );
379 
380  LOG("gevgen_pghnl", pDEBUG)
381  << "Note decay mode is " << utils::hnl::AsString(gOptDecayMode);
382 
383  // Simulate decay
384  hnlgen->ProcessEventRecord(event);
385  vtxGen->ProcessEventRecord(event);
386 
387  // add the FS 4-momenta to special branches
388  // Quite inelegant. Gets the job done, though
389  NTP_FS0_PDG = (event->Particle(1))->Pdg();
390  NTP_FS0_E = ((event->Particle(1))->P4())->E();
391  NTP_FS0_PX = ((event->Particle(1))->P4())->Px();
392  NTP_FS0_PY = ((event->Particle(1))->P4())->Py();
393  NTP_FS0_PZ = ((event->Particle(1))->P4())->Pz();
394  NTP_FS1_PDG = (event->Particle(2))->Pdg();
395  NTP_FS1_E = ((event->Particle(2))->P4())->E();
396  NTP_FS1_PX = ((event->Particle(2))->P4())->Px();
397  NTP_FS1_PY = ((event->Particle(2))->P4())->Py();
398  NTP_FS1_PZ = ((event->Particle(2))->P4())->Pz();
399  if( event->Particle(3) ){
400  NTP_FS2_PDG = (event->Particle(3))->Pdg();
401  NTP_FS2_E = ((event->Particle(3))->P4())->E();
402  NTP_FS2_PX = ((event->Particle(3))->P4())->Px();
403  NTP_FS2_PY = ((event->Particle(3))->P4())->Py();
404  NTP_FS2_PZ = ((event->Particle(3))->P4())->Pz();
405  }
406  else{
407  NTP_FS2_PDG = 0;
408  NTP_FS2_E = 0.0;
409  NTP_FS2_PX = 0.0;
410  NTP_FS2_PY = 0.0;
411  NTP_FS2_PZ = 0.0;
412  }
413 
414  // Generate (or read) a position for the decay vertex
415  // also currently handles the event weight
416  TLorentzVector x4mm = GeneratePosition( event );
417  event->SetWeight( evWeight );
418 
419  // why does InitState show the wrong p4 here?
420  interaction->InitStatePtr()->SetProbeP4( *(event->Particle(0)->P4()) );
421 
422  LOG("gevgen_pghnl", pINFO)
423  << "Generated event: " << *event;
424 
425  // Add event at the output ntuple, refresh the mc job monitor & clean-up
426  ntpw.AddEventRecord(ievent, event);
427  mcjmonitor.Update(ievent,event);
428  delete event;
429 
430  ievent++;
431  } // event loop
432 
433  // Save the generated event tree & close the output file
434  ntpw.Save();
435 
436  LOG("gevgen_pghnl", pNOTICE) << "Done!";
437 
438  return 0;
439 }
440 //_________________________________________________________________________________________
441 //............................................................................
442 #ifdef __CAN_USE_ROOT_GEOM__
443 void InitBoundingBox(void)
444 {
445 // Initialise geometry bounding box, used for generating HNL vertex positions
446 
447  LOG("gevgen_pghnl", pINFO)
448  << "Initialising geometry bounding box.";
449 
450  fdx = 0; // half-length - x
451  fdy = 0; // half-length - y
452  fdz = 0; // half-length - z
453  fox = 0; // origin - x
454  foy = 0; // origin - y
455  foz = 0; // origin - z
456 
457  if(!gOptUsingRootGeom) return;
458 
459  bool geom_is_accessible = ! (gSystem->AccessPathName(gOptRootGeom.c_str()));
460  if (!geom_is_accessible) {
461  LOG("gevgen_pghnl", pFATAL)
462  << "The specified ROOT geometry doesn't exist! Initialization failed!";
463  exit(1);
464  }
465 
466  if( !gOptRootGeoManager ) gOptRootGeoManager = TGeoManager::Import(gOptRootGeom.c_str());
467 
468  TGeoVolume * top_volume = gOptRootGeoManager->GetTopVolume();
469  assert( top_volume );
470  TGeoShape * ts = top_volume->GetShape();
471 
472  TGeoBBox * box = (TGeoBBox *)ts;
473 
474  //const Algorithm * algVtxGen = AlgFactory::Instance()->GetAlgorithm("genie::hnl::VertexGenerator", "Default");
475 
476  //const VertexGenerator * vtxGen = dynamic_cast< const VertexGenerator * >( algVtxGen );
477 
478  //get box origin and dimensions (in the same units as the geometry)
479  fdx = box->GetDX();
480  fdy = box->GetDY();
481  fdz = box->GetDZ();
482  fox = (box->GetOrigin())[0];
483  foy = (box->GetOrigin())[1];
484  foz = (box->GetOrigin())[2];
485 
486  LOG("gevgen_pghnl", pINFO)
487  << "Before conversion the bounding box has:"
488  << "\nOrigin = ( " << fox << " , " << foy << " , " << foz << " )"
489  << "\nDimensions = " << fdx << " x " << fdy << " x " << fdz
490  << "\n1cm = 1.0 unit";
491 
492  // Convert from local to SI units
493  fdx *= gOptGeomLUnits;
494  fdy *= gOptGeomLUnits;
495  fdz *= gOptGeomLUnits;
496  fox *= gOptGeomLUnits;
497  foy *= gOptGeomLUnits;
498  foz *= gOptGeomLUnits;
499 
500  LOG("gevgen_pghnl", pINFO)
501  << "Initialised bounding box successfully.";
502 
503 }
504 #endif // #ifdef __CAN_USE_ROOT_GEOM__
505 //............................................................................
506 //_________________________________________________________________________________________
507 TLorentzVector * GenerateOriginMomentum( GHepRecord * event )
508 {
509  double E = gOptEnergyHNL;
510  double M = gOptMassHNL;
511  double pMag = std::sqrt( E*E - M*M );
512 
513  const Algorithm * algHNLGen = AlgFactory::Instance()->GetAlgorithm("genie::hnl::Decayer", "Default");
514  const Decayer * hnlgen = dynamic_cast< const Decayer * >( algHNLGen );
515 
516  // first map directional cosines to unit sphere
517  /*
518  double cx = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-cx" );
519  double cy = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-cy" );
520  double cz = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-cz" );
521  */
522  std::vector< double > PGDirection = hnlgen->GetPGunDirection();
523  double cx = PGDirection.at(0), cy = PGDirection.at(1), cz = PGDirection.at(2);
524  double c2 = std::sqrt( cx*cx + cy*cy + cz*cz );
525  assert( c2 > 0.0 );
526 
527  cx *= 1.0 / c2; cy *= 1.0 / c2; cz *= 1.0 / c2;
528 
529  double theta = TMath::ACos( cz / c2 );
530  double phi = ( TMath::Sin( theta ) != 0.0 ) ? TMath::ACos( cx / ( c2 * TMath::Sin( theta ) ) ) : 0.0;
531 
532  // apply uniform random deviation
533  std::vector< double > PGunDeviation = hnlgen->GetPGunDeviation();
534  /*
535  double dthetaDeg = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-DTheta" );
536  double dphiDeg = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-DPhi" );
537  */
538  double dthetaDeg = PGunDeviation.at(0), dphiDeg = PGunDeviation.at(1);
539  double dThetaMax = dthetaDeg * constants::kPi / 180.0;
540  double dPhiMax = dphiDeg * constants::kPi / 180.0;
541 
542  RandomGen * rng = RandomGen::Instance();
543  double dTheta = rng->RndGen().Uniform( -dThetaMax, dThetaMax );
544  double dPhi = rng->RndGen().Uniform( -dPhiMax, dPhiMax );
545 
546  std::ostringstream asts;
547  asts
548  << "Output details for the momentum:"
549  << "\nDirectional cosines: ( " << cx << ", " << cy << ", " << cz << " )"
550  << "\nMapped to ( " << theta * 180.0 / constants::kPi
551  << ", " << phi * 180.0 / constants::kPi << " ) [deg] on unit sphere"
552  << "\nApplied deviation: dTheta = " << dTheta * 180.0 / constants::kPi
553  << ", dPhi = " << dPhi * 180.0 / constants::kPi << " [deg]";
554 
555  // make momentum
556  theta += dTheta; phi += dPhi;
557  TLorentzVector * p4HNL = new TLorentzVector();
558  p4HNL->SetPxPyPzE( pMag * TMath::Sin( theta ) * TMath::Cos( phi ),
559  pMag * TMath::Sin( theta ) * TMath::Sin( phi ),
560  pMag * TMath::Cos( theta ), E );
561 
562  asts << "\nMomentum = " << utils::print::P4AsString( p4HNL );
563 
564  Interaction * interaction = event->Summary();
565  interaction->InitStatePtr()->SetProbeP4( *p4HNL );
566 
567  LOG( "gevgen_pghnl", pDEBUG ) << asts.str();
568 
569  //delete rng;
570  return p4HNL;
571 }
572 //_________________________________________________________________________________________
573 TLorentzVector * GenerateOriginPosition( GHepRecord * event )
574 {
575  const Algorithm * algHNLGen = AlgFactory::Instance()->GetAlgorithm("genie::hnl::Decayer", "Default");
576  const Decayer * hnlgen = dynamic_cast< const Decayer * >( algHNLGen );
577 
578  // get centre of box from config
579  std::vector< double > PGOrigin = hnlgen->GetPGunOrigin();
580  /*
581  double ox = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-OriginX" );
582  double oy = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-OriginY" );
583  double oz = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-OriginZ" );
584  */
585  double ox = PGOrigin.at(0), oy = PGOrigin.at(1), oz = PGOrigin.at(2);
586 
587  // allow uniform deviation
588  std::vector< double > PGDOrigin = hnlgen->GetPGunDOrigin();
589  /*
590  double Dxmax = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-OriginDX" );
591  double Dymax = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-OriginDY" );
592  double Dzmax = utils::hnl::GetCfgDouble( "HNL", "ParticleGun", "PG-OriginDZ" );
593  */
594  double Dxmax = PGDOrigin.at(0), Dymax = PGDOrigin.at(1), Dzmax = PGDOrigin.at(2);
595 
596  RandomGen * rng = RandomGen::Instance();
597  double dx = rng->RndGen().Uniform( -Dxmax, Dxmax );
598  double dy = rng->RndGen().Uniform( -Dymax, Dymax );
599  double dz = rng->RndGen().Uniform( -Dzmax, Dzmax );
600 
601  // make position
602  ox += dx; oy += dy; oz += dz;
603  TLorentzVector * x4HNL = new TLorentzVector();
604  x4HNL->SetXYZT( ox, oy, oz, 0.0 );
605 
606  event->SetVertex( *x4HNL );
607  //delete rng;
608  return x4HNL;
609 }
610 //_________________________________________________________________________________________
611 TLorentzVector GeneratePosition( GHepRecord * event )
612 {
613  if( gOptUsingRootGeom ){
614 
615  const Algorithm * algVtxGen = AlgFactory::Instance()->GetAlgorithm("genie::hnl::VertexGenerator", "Default");
616 
617  const VertexGenerator * vtxGen = dynamic_cast< const VertexGenerator * >( algVtxGen );
618  vtxGen->ProcessEventRecord( event );
619 
620  TLorentzVector x4 = *(event->Vertex());
621  return x4;
622  }
623  else{
624  __attribute__((unused)) RandomGen * rnd = RandomGen::Instance();
625  TRandom3 & rnd_geo = rnd->RndGeom();
626 
627  double rndx = 2 * (rnd_geo.Rndm() - 0.5); // [-1,1]
628  double rndy = 2 * (rnd_geo.Rndm() - 0.5); // [-1,1]
629  double rndz = 2 * (rnd_geo.Rndm() - 0.5); // [-1,1]
630 
631  double t_gen = 0;
632  double x_gen = fox + rndx * fdx;
633  double y_gen = foy + rndy * fdy;
634  double z_gen = foz + rndz * fdz;
635 
636  TLorentzVector pos(x_gen, y_gen, z_gen, t_gen);
637  return pos;
638  }
639 
640  return TLorentzVector( 0, 0, 0, 0);
641 }
642 //_________________________________________________________________________________________
643 const EventRecordVisitorI * HNLGenerator(void)
644 {
645  //string sname = "genie::EventGenerator";
646  //string sconfig = "BeamHNL";
647  AlgFactory * algf = AlgFactory::Instance();
648 
649  LOG("gevgen_pghnl", pINFO)
650  << "Instantiating HNL generator.";
651 
652  const Algorithm * algmcgen = algf->GetAlgorithm(kDefOptSName, kDefOptSConfig);
653  LOG("gevgen_pghnl", pDEBUG)
654  << "Got algorithm " << kDefOptSName.c_str() << "/" << kDefOptSConfig.c_str();;
655 
656  const EventRecordVisitorI * mcgen =
657  dynamic_cast< const EventRecordVisitorI * >( algmcgen );
658  if(!mcgen) {
659  LOG("gevgen_pghnl", pFATAL) << "Couldn't instantiate the HNL generator";
660  gAbortingInErr = true;
661  exit(1);
662  }
663 
664  LOG("gevgen_pghnl", pINFO)
665  << "HNL generator instantiated successfully.";
666 
667  return mcgen;
668 }
669 //_________________________________________________________________________________________
670 int SelectDecayMode( std::vector< HNLDecayMode_t > * intChannels, SimpleHNL sh )
671 {
672  const std::map< HNLDecayMode_t, double > gammaMap = sh.GetValidChannels();
673 
674  // set CoM lifetime now if unset
675  if( CoMLifetime < 0.0 ){
677  LOG( "gevgen_pghnl", pDEBUG )
678  << "Rest frame CoMLifetime = " << CoMLifetime << " [GeV^{-1}]";
679  }
680 
681  for( std::vector< HNLDecayMode_t >::iterator it = intChannels->begin(); it != intChannels->end(); ++it ){
682  HNLDecayMode_t mode = *it;
683  auto mapG = gammaMap.find( mode );
684  double theGamma = mapG->second;
685  LOG("gevgen_pghnl", pDEBUG)
686  << "For mode " << utils::hnl::AsString( mode ) << " gamma = " << theGamma;
687  }
688 
689  std::map< HNLDecayMode_t, double > intMap =
690  selector::SetInterestingChannels( (*intChannels), gammaMap );
691 
692  sh.SetInterestingChannels( intMap );
693 
694  // get probability that channels in intChannels will be selected
695  std::map< HNLDecayMode_t, double > PMap =
696  selector::GetProbabilities( intMap );
697 
698  // now do a random throw
699  RandomGen * rnd = RandomGen::Instance();
700  double ranThrow = rnd->RndGen().Uniform( 0., 1. ); // HNL's fate is sealed.
701 
702  HNLDecayMode_t selectedDecayChan =
703  selector::SelectChannelInclusive( PMap, ranThrow );
704 
705  int decay = ( int ) selectedDecayChan;
706  return decay;
707 }
708 //_________________________________________________________________________________________
709 void GetCommandLineArgs(int argc, char ** argv)
710 {
711  LOG("gevgen_pghnl", pINFO) << "Parsing command line arguments";
712 
713  // Parse run options for this app
714 
715  CmdLnArgParser parser(argc,argv);
716 
717  // help?
718  bool help = parser.OptionExists('h');
719  if(help) {
720  PrintSyntax();
721  exit(0);
722  }
723 
724  // force the app to look at HNL tune by default
725  // if user passes --tune argument, look at the user input tune instead
726  char * expargv[ argc + 2 ];
727  bool didFindUserInputTune = false;
728  std::string stExtraTuneBit = kDefOptSTune;
729 
730  if( parser.OptionExists("tune") ){
731  didFindUserInputTune = true;
732  stExtraTuneBit = parser.ArgAsString("tune");
733  LOG( "gevgen_hnl", pWARN )
734  << "Using input HNL tune " << parser.ArgAsString("tune");
735  } else {
736  LOG( "gevgen_hnl", pWARN )
737  << "Using default HNL tune " << kDefOptSTune;
738  }
739  // append this to argv
740  for( int iArg = 0; iArg < argc; iArg++ ){
741  expargv[iArg] = argv[iArg];
742  }
743  if( !didFindUserInputTune ){
744  char * chBit = const_cast< char * >( stExtraTuneBit.c_str() ); // ugh. Ugly.
745  std::string stune("--tune"); char * tBit = const_cast< char * >( stune.c_str() );
746  expargv[argc] = tBit;
747  expargv[argc+1] = chBit;
748  }
749 
750  // Common run options.
751  int expargc = ( didFindUserInputTune ) ? argc : argc+2;
752  std::string stnull(""); char * nBit = const_cast< char * >( stnull.c_str() );
753  expargv[expargc] = nBit;
754 
755  RunOpt::Instance()->ReadFromCommandLine(expargc,expargv);
756 
757  // run number
758  if( parser.OptionExists('r') ) {
759  LOG("gevgen_pghnl", pDEBUG) << "Reading MC run number";
760  gOptRunNu = parser.ArgAsLong('r');
761  } else {
762  LOG("gevgen_pghnl", pDEBUG) << "Unspecified run number - Using default";
763  gOptRunNu = 1000;
764  } //-r
765 
766  // number of events
767  if( parser.OptionExists('n') ) {
768  LOG("gevgen_pghnl", pDEBUG)
769  << "Reading number of events to generate";
770  gOptNev = parser.ArgAsInt('n');
771  } else {
772  LOG("gevgen_pghnl", pFATAL)
773  << "You need to specify the number of events";
774  PrintSyntax();
775  exit(0);
776  } //-n
777 
778  // get HNL mass
779  const Algorithm * algHNLGen = AlgFactory::Instance()->GetAlgorithm("genie::hnl::Decayer", "Default");
780  const Decayer * hnlgen = dynamic_cast< const Decayer * >( algHNLGen );
781  gOptMassHNL = hnlgen->GetHNLMass();
782 
783  // HNL decay mode
784  int mode = -1;
785  if( parser.OptionExists('m') ) {
786  LOG("gevgen_pghnl", pDEBUG)
787  << "Reading HNL decay mode";
788  mode = parser.ArgAsInt('m');
789  } else {
790  LOG("gevgen_pghnl", pINFO)
791  << "No decay mode specified - will sample from allowed decay modes";
792  } //-m
793  gOptDecayMode = (HNLDecayMode_t) mode;
794 
796  if(!allowed) {
797  LOG("gevgen_pghnl", pFATAL)
798  << "Specified decay is not allowed kinematically for the given HNL mass";
799  PrintSyntax();
800  exit(0);
801  }
802 
803  //
804  // geometry
805  //
806 
807  string geom = "";
808  string lunits;
809 #ifdef __CAN_USE_ROOT_GEOM__
810  // string dunits;
811  if( parser.OptionExists('g') ) {
812  LOG("gevgen_pghnl", pDEBUG) << "Getting input geometry";
813  geom = parser.ArgAsString('g');
814 
815  // is it a ROOT file that contains a ROOT geometry?
816  bool accessible_geom_file =
817  ! (gSystem->AccessPathName(geom.c_str()));
818  if (accessible_geom_file) {
819  gOptRootGeom = geom;
820  gOptUsingRootGeom = true;
821  } else {
822  LOG("gevgen_pghnl", pFATAL)
823  << "Geometry option is not a ROOT file. Please use ROOT geom.";
824  PrintSyntax();
825  exit(1);
826  }
827  } else {
828  // LOG("gevgen_pghnl", pFATAL)
829  // << "No geometry option specified - Exiting";
830  // PrintSyntax();
831  // exit(1);
832  } //-g
833 
834  if(gOptUsingRootGeom) {
835  // using a ROOT geometry - get requested geometry units
836 
837  // length units:
838  if( parser.OptionExists('L') ) {
839  LOG("gevgen_pghnl", pDEBUG)
840  << "Checking for input geometry length units";
841  lunits = parser.ArgAsString('L');
842  } else {
843  LOG("gevgen_pghnl", pDEBUG) << "Using default geometry length units";
844  lunits = kDefOptGeomLUnits;
845  } // -L
846  // // density units:
847  // if( parser.OptionExists('D') ) {
848  // LOG("gevgen_pghnl", pDEBUG)
849  // << "Checking for input geometry density units";
850  // dunits = parser.ArgAsString('D');
851  // } else {
852  // LOG("gevgen_pghnl", pDEBUG) << "Using default geometry density units";
853  // dunits = kDefOptGeomDUnits;
854  // } // -D
856  // gOptGeomDUnits = utils::units::UnitFromString(dunits);
857 
858  } // using root geom?
859 #endif // #ifdef __CAN_USE_ROOT_GEOM__
860 
861  // event file prefix
862  if( parser.OptionExists('o') ) {
863  LOG("gevgen_pghnl", pDEBUG) << "Reading the event filename prefix";
864  gOptEvFilePrefix = parser.ArgAsString('o');
865  } else {
866  LOG("gevgen_pghnl", pDEBUG)
867  << "Will set the default event filename prefix";
869  } //-o
870 
871  // random number seed
872  if( parser.OptionExists("seed") ) {
873  LOG("gevgen_pghnl", pINFO) << "Reading random number seed";
874  gOptRanSeed = parser.ArgAsLong("seed");
875  } else {
876  LOG("gevgen_pghnl", pINFO) << "Unspecified random number seed - Using default";
877  gOptRanSeed = -1;
878  }
879 
880  //
881  // >>> print the command line options
882  //
883 
884  ostringstream gminfo;
885  if (gOptUsingRootGeom) {
886  gminfo << "Using ROOT geometry - file: " << gOptRootGeom
887  << ", top volume: "
888  << ((gOptRootGeomTopVol.size()==0) ? "<master volume>" : gOptRootGeomTopVol)
889  << ", length units: " << lunits;
890  // << ", density units: " << dunits;
891  }
892 
893  LOG("gevgen_pghnl", pNOTICE)
894  << "\n\n"
895  << utils::print::PrintFramedMesg("gevgen_pghnl job configuration");
896 
897  LOG("gevgen_pghnl", pNOTICE)
898  << "\n @@ Run number : " << gOptRunNu
899  << "\n @@ Random seed : " << gOptRanSeed
900  << "\n @@ Decay channel : " << utils::hnl::AsString(gOptDecayMode)
901  << "\n @@ Geometry : " << gminfo.str()
902  << "\n @@ Statistics : " << gOptNev << " events";
903 }
904 //_________________________________________________________________________________________
905 void PrintSyntax(void)
906 {
907  LOG("gevgen_pghnl", pFATAL)
908  << "\n **Syntax**"
909  << "\n gevgen_pghnl [-h] "
910  << "\n [-r run#]"
911  << "\n -n n_of_events"
912  << "\n [-m decay_mode]"
913  << "\n [-g geometry (ROOT file)]"
914  << "\n [-L length_units_at_geom]"
915  << "\n [-o output_event_file_prefix]"
916  << "\n [--seed random_number_seed]"
917  << "\n [--message-thresholds xml_file]"
918  << "\n [--event-record-print-level level]"
919  << "\n [--mc-job-status-refresh-rate rate]"
920  << "\n"
921  << " Please also read the detailed documentation at http://www.genie-mc.org"
922  << " or look at the source code: $GENIE/src/Apps/gBeamHNLParticleGun.cxx"
923  << "\n";
924 }
925 //_________________________________________________________________________________________
bool IsHNLMajorana() const
Definition: HNLDecayer.cxx:722
void RandGen(long int seed)
Definition: AppInit.cxx:30
static void SetPrintLevel(int print_level)
Definition: GHepRecord.cxx:956
double NTP_IS_PX
HNLDecayMode_t gOptDecayMode
double CoMLifetime
TLorentzVector GeneratePosition(GHepRecord *event)
string kDefOptSTune
Heavy Neutral Lepton final-state product generator.
Definition: HNLDecayer.h:41
double evProdVtx[3]
Heavy Neutral Lepton decay vertex generator given production vertex and momentum ***.
double NTP_FS1_PX
string gOptEvFilePrefix
Definition: gAtmoEvGen.cxx:310
void SetProbeP4(const TLorentzVector &P4)
static RandomGen * Instance()
Access instance.
Definition: RandomGen.cxx:71
string AsString(genie::hnl::HNLDecayMode_t hnldm)
Defines the EventRecordVisitorI interface. Concrete implementations of this interface use the &#39;Visito...
double gOptECoupling
void ReadFromCommandLine(int argc, char **argv)
Definition: RunOpt.cxx:99
double foy
virtual void SetProbability(double prob)
Definition: GHepRecord.h:131
#define pFATAL
Definition: Messenger.h:56
HNL object.
Definition: SimpleHNL.h:36
string P4AsString(const TLorentzVector *p)
Definition: PrintUtils.cxx:27
void Update(int iev, const EventRecord *event)
Definition: GMCJMonitor.cxx:48
Algorithm abstract base class.
Definition: Algorithm.h:54
double GetCoMLifetime()
Definition: SimpleHNL.h:96
TLorentzVector * GenerateOriginPosition(GHepRecord *event)
int NTP_FS0_PDG
A singleton holding random number generator classes. All random number generation in GENIE should tak...
Definition: RandomGen.h:29
double NTP_FS0_PX
bool gOptIsMajorana
double NTP_IS_E
double evWeight
int main(int argc, char **argv)
Definition: gAtmoEvGen.cxx:327
std::map< genie::hnl::HNLDecayMode_t, double > SetInterestingChannels(std::vector< genie::hnl::HNLDecayMode_t > intChannels, std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
double GetHNLMass() const
Definition: HNLDecayer.cxx:710
void SetRefreshRate(int rate)
Definition: GMCJMonitor.cxx:43
string kDefOptEvFilePrefix
Definition: gAtmoEvGen.cxx:320
Summary information for an interaction.
Definition: Interaction.h:56
string lunits
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
double GetPGunEnergy() const
Definition: HNLDecayer.cxx:750
double fox
double NTP_IS_PY
TTree * EventTree(void)
Definition: NtpWriter.h:55
double fdy
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE...
Definition: Messenger.h:96
string gOptRootGeomTopVol
Definition: gAtmoEvGen.cxx:301
void ProcessEventRecord(GHepRecord *event_rec) const
double NTP_FS2_PY
double gOptEnergyHNL
std::vector< double > GetPGunDirection() const
Definition: HNLDecayer.cxx:755
double GetHNLLifetime() const
Definition: HNLDecayer.cxx:705
string geom
double UnitFromString(string u)
Definition: UnitUtils.cxx:18
double NTP_FS2_PX
string kDefOptSName
const Algorithm * GetAlgorithm(const AlgId &algid)
Definition: AlgFactory.cxx:75
int gOptNev
Definition: gAtmoEvGen.cxx:305
const int kPdgKP
Definition: PDGCodes.h:172
const int kPdgHNL
Definition: PDGCodes.h:224
std::map< genie::hnl::HNLDecayMode_t, double > GetValidChannels()
Definition: SimpleHNL.h:154
enum genie::hnl::EHNLDecayMode HNLDecayMode_t
void Save(void)
get the even tree
Definition: NtpWriter.cxx:225
#define pINFO
Definition: Messenger.h:62
void SetInterestingChannels(const std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
Definition: SimpleHNL.h:276
double NTP_IS_PZ
TLorentzVector * GenerateOriginMomentum(GHepRecord *event)
void AddEventRecord(int ievent, const EventRecord *ev_rec)
save the event tree
Definition: NtpWriter.cxx:57
double NTP_FS0_PY
std::vector< double > GetPGunOrigin() const
Definition: HNLDecayer.cxx:736
std::vector< double > GetPGunDeviation() const
Definition: HNLDecayer.cxx:762
string gOptRootGeom
Definition: gAtmoEvGen.cxx:300
std::vector< double > GetPGunDOrigin() const
Definition: HNLDecayer.cxx:743
#define pWARN
Definition: Messenger.h:60
Long_t gOptRunNu
Definition: gAtmoEvGen.cxx:295
std::string GetHNLInterestingChannels() const
Definition: HNLDecayer.cxx:727
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
Definition: EventRecord.h:37
void CustomizeFilenamePrefix(string prefix)
Definition: NtpWriter.cxx:133
double gOptTCoupling
void Initialize(void)
add event
Definition: NtpWriter.cxx:83
string kDefOptGeomLUnits
Definition: gAtmoEvGen.cxx:321
double NTP_FS2_PZ
static RunOpt * Instance(void)
Definition: RunOpt.cxx:54
static AlgFactory * Instance()
Definition: AlgFactory.cxx:64
A utility class to facilitate creating the GENIE MC Ntuple from the output GENIE GHEP event records...
Definition: NtpWriter.h:39
static __attribute__((unused)) double fDecayGammas[]
std::map< genie::hnl::HNLDecayMode_t, double > GetProbabilities(std::map< genie::hnl::HNLDecayMode_t, double > gammaMap)
double NTP_FS2_E
double gOptMCoupling
TRandom3 & RndGen(void) const
rnd number generator for generic usage
Definition: RandomGen.h:80
double NTP_FS0_E
double NTP_FS1_PY
std::vector< double > GetHNLCouplings() const
Definition: HNLDecayer.cxx:715
double NTP_FS1_E
double fdx
string kDefOptSConfig
NtpMCFormat_t kDefOptNtpFormat
Definition: gAtmoEvGen.cxx:319
InitialState * InitStatePtr(void) const
Definition: Interaction.h:74
string PrintFramedMesg(string mesg, unsigned int nl=1, const char f='*')
Definition: PrintUtils.cxx:164
int SelectDecayMode(std::vector< HNLDecayMode_t > *intChannels, SimpleHNL sh)
void MesgThresholds(string inpfile)
Definition: AppInit.cxx:99
double foz
const EventRecordVisitorI * HNLGenerator(void)
Command line argument parser.
enum genie::ENtpMCFormat NtpMCFormat_t
genie::hnl::HNLDecayMode_t SelectChannelInclusive(std::map< genie::hnl::HNLDecayMode_t, double > Pmap, double ranThrow)
#define pNOTICE
Definition: Messenger.h:61
void GetCommandLineArgs(int argc, char **argv)
Definition: gAtmoEvGen.cxx:563
The GENIE Algorithm Factory.
Definition: AlgFactory.h:39
void ProcessEventRecord(GHepRecord *event) const
Definition: HNLDecayer.cxx:54
double NTP_FS1_PZ
string kDefOptGeomDUnits
Definition: gAtmoEvGen.cxx:322
void SetGeomFile(std::string geomfile) const
bool gAbortingInErr
Definition: Messenger.cxx:34
GENIE&#39;s GHEP MC event record.
Definition: GHepRecord.h:45
double gOptGeomLUnits
Definition: gAtmoEvGen.cxx:302
int NTP_FS1_PDG
int NTP_FS2_PDG
Most commonly used PDG codes. A set of utility functions to handle PDG codes is provided in PDGUtils...
STDHEP-like event record entry that can fit a particle or a nucleus.
Definition: GHepParticle.h:39
double gOptMassHNL
void PrintSyntax(void)
bool IsKinematicallyAllowed(genie::hnl::HNLDecayMode_t hnldm, double Mhnl)
double NTP_FS0_PZ
std::vector< HNLDecayMode_t > gOptIntChannels
bool gOptUsingRootGeom
Definition: gAtmoEvGen.cxx:298
int gOptHNLKind
double fdz
#define pDEBUG
Definition: Messenger.h:63
static Interaction * HNL(int probe, double E=0, int decayed_mode=-1)
long int gOptRanSeed
Definition: gAtmoEvGen.cxx:312