AddGenieEventsToArt_module.cc
Go to the documentation of this file.
7 
9 
11 
13 
17 // for sim::GetRandomNumberSeed()
19 
20 #include "nutools/EventGeneratorBase/GENIE/GENIE2ART.h"
21 #include "nutools/EventGeneratorBase/GENIE/EvtTimeShiftI.h"
22 #include "nutools/EventGeneratorBase/GENIE/EvtTimeShiftFactory.h"
23 
24 // GENIE includes
25 #ifdef GENIE_PRE_R3
26  #include "Ntuple/NtpMCEventRecord.h"
27  #include "Ntuple/NtpMCTreeHeader.h"
28  #include "PDG/PDGLibrary.h"
29  // -- GENIE Messenger conflict LOG_INFO w/ ART messagefacility
30  //#include "Messenger/Messenger.h"
31  #include "GHEP/GHepRecord.h"
32 
33  #include "FluxDrivers/GNuMIFlux.h"
34  #include "FluxDrivers/GSimpleNtpFlux.h"
35 #else
36  #include "GENIE/Framework/ParticleData/PDGLibrary.h"
37  #include "GENIE/Framework/GHEP/GHepRecord.h"
38  #include "GENIE/Framework/Ntuple/NtpMCFormat.h"
39  #include "GENIE/Framework/Ntuple/NtpWriter.h"
40  #include "GENIE/Framework/Ntuple/NtpMCEventRecord.h"
41  // #include "GENIE/Framework/Ntuple/NtpMCTreeHeader.h"
42  // #include "GENIE/Framework/Messenger/Messenger.h" -- conflict LOG_INFO w/ messagefacility
43 
44  #include "GENIE/Tools/Flux/GNuMIFlux.h"
45  #include "GENIE/Tools/Flux/GSimpleNtpFlux.h"
46 #endif
47 
48 #include "dk2nu/tree/dk2nu.h"
49 #include "dk2nu/tree/NuChoice.h"
50 
51 // ROOT includes
52 #include "TChain.h"
53 #include "TBranchElement.h"
54 #include "TBranchObject.h"
55 
56 // CLHEP
57 #include "CLHEP/Random/RandFlat.h"
58 #include "CLHEP/Random/RandPoissonT.h"
59 #include "CLHEP/Random/RandGauss.h"
60 
61 #include <memory>
62 #include <vector>
63 #include <string>
64 #include <algorithm>
65 #include <utility>
66 
67 #include <fstream>
68 #include <cstdio>
69 #include <iomanip>
70 
71 #include "nutools/EventGeneratorBase/GENIE/EVGBAssociationUtil.h"
72 
73 namespace evg {
74  class AddGenieEventsToArt;
75 
77  // hold/document fcl parameters
78  template<class T> using Atom = fhicl::Atom<T>;
79  template<class T> using Sequence = fhicl::Sequence<T>;
80  template<class T> using Table = fhicl::Table<T>;
82  using Name = fhicl::Name;
83 
85  Name("fileList"),
86  Comment("list of input gntp.*.ghep.root files"),
87  // no default { " " } // no default
88  };
90  Name("countConfig"),
91  Comment("how many events to pull \"<form>: <value> [<value>]\""
92  " known functional forms:\n"
93  " \"fixed: <n>\"\n"
94  " \"flat: <nmin> <nmax>\"\n"
95  " \"poisson: <mean>\"\n"
96  " \"poisson-1: <mean>\" use Poisson, then subtract 1 (floor 0)\n"
97  " \"gauss: <mean> <rms>\" (floor 0)"),
98  "fixed: 1" // default
99  };
101  Name("globalTimeOffset"),
102  Comment("fixed offset to add (in ns)"),
103  0.0
104  };
106  Name("timeConfig"),
107  Comment("time distribution beyond globalTimeOffset (in ns)\n"
108  " e.g. \"flat: 1000\"\n"
109  " \"numi: \"\n"
110  "currently does not support modified numi parameters"),
111  "numi:"
112  };
113  struct VtxOffsets {
114  Atom<double> xlo { Name("xlo"), Comment("min x addition"), 0.0 };
115  Atom<double> ylo { Name("ylo"), Comment("min y addition"), 0.0 };
116  Atom<double> zlo { Name("zlo"), Comment("min z addition"), 0.0 };
117  Atom<double> xhi { Name("xhi"), Comment("max x addition"), 0.0 };
118  Atom<double> yhi { Name("yhi"), Comment("max y addition"), 0.0 };
119  Atom<double> zhi { Name("zhi"), Comment("max z addition"), 0.0 };
120  };
122  Name("vtxOffsets"),
123  Comment("allow module to offset global vertex (genie vtx units = m)")
124  };
126  Name("addMCFlux"),
127  Comment("attempt to fetch and fill MCFlux for each genie::EventRecord"),
128  true
129  };
131  Name("randomEntries"),
132  Comment("use random sets of entries from input files\n"
133  "rather than go through the files sequentially"),
134  true
135  };
137  Name("outputPrintLevel"),
138  Comment("print fetched genie::EventRecord -1=no, 13=max info\n"
139  "see GENIE manual for legal values"),
140  -1
141  };
143  Name("outputDumpFileName"),
144  Comment("name of file to print to (if outputPrintLevel >= 0)\n"
145  "\"std::cout\" for standard out\n"
146  "otherwise string with %l replaced by module_label"),
147  "AddGenieEventsToArt_%l.txt"
148  };
149  // want this to be optional ...
151  Name("seed"),
152  Comment("random number seed"),
153  0
154  };
155  }; // AddGenieEventsToArtParams
156 }
157 
159 public:
160 
161  // Allow 'art --print-description' to work
163 
164  //explicit AddGenieEventsToArt(fhicl::ParameterSet const & p);
165  explicit AddGenieEventsToArt(const Parameters & p);
166 
167  // The destructor generated by the compiler is fine for classes
168  // without bare pointers or other resource use.
170 
171  // Plugins should not be copied or assigned.
172  AddGenieEventsToArt(AddGenieEventsToArt const &) = delete;
174  AddGenieEventsToArt & operator = (AddGenieEventsToArt const &) = delete;
175  AddGenieEventsToArt & operator = (AddGenieEventsToArt &&) = delete;
176 
177  // Required functions.
178  void produce(art::Event & e) override;
179 
180  //void reconfigure(const Parameters & params) override;
181 
182  // Selected optional functions.
183  /*
184  void beginJob() override;
185  void beginRun(art::Run & r) override;
186  void beginSubRun(art::SubRun & sr) override;
187  void endJob() override;
188  void endRun(art::Run & r) override;
189  void endSubRun(art::SubRun & sr) override;
190  void respondToCloseInputFile(art::FileBlock const & fb) override;
191  void respondToCloseOutputFiles(art::FileBlock const & fb) override;
192  void respondToOpenInputFile(art::FileBlock const & fb) override;
193  void respondToOpenOutputFiles(art::FileBlock const & fb) override;
194  */
195 
196 private:
197 
198  typedef enum EDistrib { kUnknownDist,
203  kGaussian } RndDist_t;
204 
205  // Private member functions here.
206  void ParseCountConfig();
207  size_t GetNumToAdd() const;
208  void ParseTimeConfig();
209  void ParseVtxOffsetConfig();
210 
212 
213  // member data here.
214 
215  std::vector<std::string> fFileList;
218  double fXlo; // vtx offset ranges
219  double fYlo;
220  double fZlo;
221  double fXhi;
222  double fYhi;
223  double fZhi;
226 
231  //< use %l to substitute in module_label
232  //< use "", "--", "cout" or "std::cout" for using that instead of file
233  std::ostream* fOutputStream;
234 
235  // parsed NumToAddString parameters
236  RndDist_t fRndDist;
237  double fRndP1;
238  double fRndP2;
239 
240  TChain* fGTreeChain;
242  size_t fNumMCRec;
243  size_t fLastUsedMCRec; // if going sequentially
244 
245  // possible flux branches
246 
248 
252 
253  bsim::Dk2Nu* fDk2Nu;
254  bsim::NuChoice* fNuChoice;
255  unsigned int const fSeed;
256  CLHEP::HepRandomEngine& fEngine;
257 
258  // selection order - sequential-round, sequential-1time, random-1?
259 
260 };
261 
263  : EDProducer(params)
264  , fParams(params)
265  , fGlobalTimeOffset(0)
266  , fTimeShifter(0)
267  , fXlo(0), fYlo(0), fZlo(0)
268  , fXhi(0), fYhi(0), fZhi(0)
269  , fAddMCFlux(false)
270  , fRandomEntries(true)
271  , fOutputPrintLevel(-1)
272  , fOutputStream(0)
273  //
274  , fRndDist(kUnknownDist)
275  , fRndP1(-1)
276  , fRndP2(-1)
277  , fGTreeChain(new TChain("gtree"))
278  , fMCRec(new genie::NtpMCEventRecord)
279  , fNumMCRec(0)
280  , fLastUsedMCRec(0)
281  , fGNuMIFluxPassThroughInfo(0)
282  , fGSimpleNtpEntry(0)
283  , fGSimpleNtpNuMI(0)
284  , fGSimpleNtpAux(0)
285  , fDk2Nu(0)
286  , fNuChoice(0)
287  // get the random number seed, use a random default if not specified
288  // in the configuration file.
289  , fSeed{fParams().seed() == 0 ? evgb::GetRandomNumberSeed() : fParams().seed()}
290  // only need sub-label if using more than one engine for each
291  // instance of this module (already tagged by equiv of fMyModuleLabel)
292  , fEngine{createEngine(fSeed/*, "HepJamesRandom", sub-label*/)}
293 {
294  // trigger early initialization of PDG database & GENIE message service
295  // just to get it out of the way and not intermixed with other output
297 
298  fMyModuleType = fParams.get_PSet().get<std::string>("module_type");
299  fMyModuleLabel = fParams.get_PSet().get<std::string>("module_label");
300 
301  mf::LogInfo("AddGenieEventsToArt")
302  << " ctor start " << fMyModuleLabel
303  << " (" << fMyModuleType << ") " << std::endl << std::flush;
304 
305  fFileList = fParams().fileList();
306 
309  ParseTimeConfig();
310  fGlobalTimeOffset = fParams().globalTimeOffset();
311  fAddMCFlux = fParams().addMCFlux();
312  fRandomEntries = fParams().randomEntries();
313 
314  // Call appropriate produces<>() functions here.
315 
316  produces< std::vector<simb::MCTruth> >();
317  produces< std::vector<simb::GTruth> >();
318  produces< art::Assns<simb::MCTruth, simb::GTruth> >();
319  if ( fAddMCFlux ) {
320  produces< std::vector<simb::MCFlux> >();
321  // Associate every truth with the flux it came from
322  produces< art::Assns<simb::MCTruth, simb::MCFlux> >();
323  }
324 
325  //produces< sumdata::SpillData >();
326  //produces< sumdata::POTSum, art::InSubRun >();
327  //produces< sumdata::RunData, art::InRun >();
328 
329  std::string outFileList = "adding file pattern: ";
330  for (size_t i=0; i < fFileList.size(); ++i) {
331  outFileList += "\n";
332  outFileList += fFileList[i];
333  fGTreeChain->Add(fFileList[0].c_str());
334  }
335  mf::LogInfo("AddGenieEventsToArt") << outFileList;
336 
337  fNumMCRec = fGTreeChain->GetEntries();
339 
340  // attach flux branches ...
341  /**
342  gtree->GetBranch("flux")->GetClassName()
343  (const char* 0x31f41c0)"genie::flux::GNuMIFluxPassThroughInfo"
344 
345  gtree->GetBranch("simple")->GetClassName()
346  (const char* 0x2a2a8e0)"genie::flux::GSimpleNtpEntry"
347  gtree->GetBranch("numi")->GetClassName()
348  (const char* 0x2a33d40)"genie::flux::GSimpleNtpNuMI
349  gtree->GetBranch("aux")->GetClassName()
350  (const char* 0x2a35320)"genie::flux::GSimpleNtpAux"
351 
352  gtree->GetBranch("dk2nu")->GetClassName()
353  (const char* 0x3457d59)"bsim::Dk2Nu"
354  gtree->GetBranch("nuchoice")->GetClassName()
355  (const char* 0x3479329)"bsim::NuChoice"
356  **/
357  TObjArray* blist = fGTreeChain->GetListOfBranches();
358  TIter next(blist);
359  TObject* obj;
360  while ( ( obj = next() ) ) {
361  std::string bname = obj->GetName();
362  // should be a list of TBranchElement or TBranchObject items
363  // TBranchObject are ancient ... should have been replaced by Elements
364  const TBranchElement* belement = dynamic_cast<const TBranchElement*>(obj);
365  const TBranchObject* bobject = dynamic_cast<const TBranchObject*>(obj);
366  if ( ! belement && ! bobject ) {
367  std::string reallyIsA = obj->ClassName();
368  mf::LogError("AddGenieEventsToArt")
369  << "### supposed branch element '" << bname
370  << "' wasn't a TBranchElement/TBranchObject but instead a "
371  << reallyIsA << std::endl;
372  if ( bname == "gmcrec" ) {
373  mf::LogError("AddGenieEventsToArt")
374  << "### since this is '" << bname
375  << "' this is likely to end very badly badly" << std::endl;
376  }
377  continue;
378  }
379  std::string bclass = (belement) ? belement->GetClassName()
380  : bobject->GetClassName();
381  if ( bclass == "genie::NtpMCEventRecord" ) {
382  fGTreeChain->SetBranchAddress(bname.c_str(),&fMCRec);
383  } else if ( bclass == "genie::flux::GNuMIFluxPassThroughInfo" ) {
385  fGTreeChain->SetBranchAddress(bname.c_str(),&fGNuMIFluxPassThroughInfo);
386  } else if ( bclass == "genie::flux::GSimpleNtpEntry" ) {
388  fGTreeChain->SetBranchAddress(bname.c_str(),&fGSimpleNtpEntry);
389  } else if ( bclass == "genie::flux::GSimpleNtpNuMI" ) {
391  fGTreeChain->SetBranchAddress(bname.c_str(),&fGSimpleNtpNuMI);
392  } else if ( bclass == "genie::flux::GSimpleNtpAux" ) {
394  fGTreeChain->SetBranchAddress(bname.c_str(),&fGSimpleNtpAux);
395  } else if ( bclass == "bsim::Dk2Nu" ) {
396  fDk2Nu = new bsim::Dk2Nu;
397  fGTreeChain->SetBranchAddress(bname.c_str(),&fDk2Nu);
398  } else if ( bclass == "bsim::NuChoice" ) {
399  fNuChoice = new bsim::NuChoice;
400  fGTreeChain->SetBranchAddress(bname.c_str(),&fNuChoice);
401  } else {
402  mf::LogError("AddGenieEventsToArt")
403  << "### branch element '" << bname
404  << "' was unhandled '" << bclass << "' class" << std::endl;
405  }
406  } // while ( next )
407 
408  mf::LogInfo("AddGenieEventsToArt")
409  << "chain has " << fNumMCRec << " entries"
410  << std::endl;
411 
412  // setup to write out file, if requested
413  if ( fOutputPrintLevel > 0 ) {
414  if ( fOutputDumpFileName == "" ||
415  fOutputDumpFileName == "--" ||
416  fOutputDumpFileName == "cout" ||
417  fOutputDumpFileName == "std::cout" ) {
418  // standardize so we don't check all these again
419  fOutputDumpFileName = "std::cout";
420  fOutputStream = &(std::cout);
421  } else {
422  size_t posl = fOutputDumpFileName.find("%l");
423  if ( posl != std::string::npos ) {
424  fOutputDumpFileName.replace(posl,2,fMyModuleLabel);
425  }
426  mf::LogInfo("AddGenieEventToArt")
427  << "#### AddGenieEventsToArt::ctor open "
429  << std::endl << std::flush;
430  fOutputStream =
431  new std::ofstream(fOutputDumpFileName.c_str(),
432  std::ios_base::trunc|std::ios_base::out);
433  }
434  } // if ( fOutputPrintLevel > 0 )
435 
436 }
437 
439 {
440  // release resources
441  if ( fGTreeChain ) delete fGTreeChain;
442  if ( fOutputStream && ( fOutputDumpFileName != "std::cout" ) ) {
443  std::ofstream* ofs = dynamic_cast<std::ofstream*>(fOutputStream);
444  if ( ofs ) {
445  mf::LogInfo("AddGenieEventToArt")
446  << "#### AddGenieEventsToArt::dtor close "
448  << std::endl << std::flush;
449  ofs->flush();
450  ofs->close();
451  }
452  delete fOutputStream;
453  }
454 }
455 
457 {
458 
459  //std::cerr << "AddGenieEventsToArt::produce start" << std::endl << std::flush;
460 
461  std::unique_ptr< std::vector<simb::MCTruth> >
462  mctruthcol(new std::vector<simb::MCTruth>);
463 
464  std::unique_ptr< std::vector<simb::GTruth> >
465  gtruthcol(new std::vector<simb::GTruth>);
466 
467  std::unique_ptr< std::vector<simb::MCFlux> >
468  mcfluxcol(new std::vector<simb::MCFlux>);
469 
470  std::unique_ptr< art::Assns<simb::MCTruth, simb::MCFlux> >
472  std::unique_ptr< art::Assns<simb::MCTruth, simb::GTruth> >
474 
475  // number of interactions to add to _this_ record/"event"
476  size_t n = GetNumToAdd();
477  //std::cerr << "#### AddGenieEventsToArt::produce " << n
478  // << " MCTruth objects" << std::endl << std::flush;
479 
480  // make a list of entries in TChain to use for this overlay
481  // same entry should never be in the list twice ...
482  std::vector<size_t> entries;
483 
484  CLHEP::RandFlat flat(fEngine);
485 
486  //mf::LogInfo("AddGeniEventsToArt") << "attempt to get " << n << " entries";
487  while ( entries.size() != n ) {
488  if ( ! fRandomEntries ) {
489  // going through file sequentially
490  ++fLastUsedMCRec;
492  entries.push_back(fLastUsedMCRec);
493  // mf::LogInfo("AddGeniEventsToArt") << "adding " << fLastUsedMCRec;
494  } else {
495  size_t indx = flat.fireInt(fNumMCRec);
496  // ensure it isn't already there ..
497  if ( std::find(entries.begin(),entries.end(),indx) != entries.end() ) {
498  // mf::LogInfo("AddGeniEventsToArt") << "rejecting "
499  // << indx << " as already there";
500  } else {
501  entries.push_back(indx);
502  // mf::LogInfo("AddGeniEventsToArt") << "adding " << indx;
503  }
504  }
505  }
506  //mf::LogInfo("AddGeniEventsToArt") << "entries.size " << entries.size();
507 
508  for (size_t i=0; i<n; ++i) {
509  simb::MCTruth mctruth;
510  simb::GTruth gtruth;
511  simb::MCFlux mcflux;
512 
513  size_t ientry = entries[i];
514  // fetch a single entry from GENIE input file
515  fGTreeChain->GetEntry(ientry);
517 
518  /*
519  mf::LogInfo("AddGeniEventsToArt")
520  << "#### AddGenieEventsToArt::produce " << i+1 << " of " << n
521  << " using entry " << ientry
522  << std::endl;
523  */
524 
525  if ( fOutputStream ) {
526  // alas not currently able to get current setting
527  // int plevel = genie::GHepRecord::GetPrintLevel(); //
529  //std::cerr << "#### AddGenieEventsToArt::produce() writing to "
530  // << fOutputDumpFileName
531  // << std::endl << std::flush;
532  *fOutputStream << *fMCRec;
533  fOutputStream->flush();
534  }
535 
536  // generate offset in time
537  double evtTimeOffset = fGlobalTimeOffset + fTimeShifter->TimeOffset();
538 
539  // offset vertex position
540  double xoff = flat.fire(fXlo,fXhi);
541  double yoff = flat.fire(fYlo,fYhi);
542  double zoff = flat.fire(fZlo,fZhi);
543 
544  TLorentzVector vtxOffset(xoff,yoff,zoff,evtTimeOffset);
545 
546  // convert to simb:: ART objects using GENIE2ART functions
547  evgb::FillMCTruth(grec,vtxOffset,mctruth);
548  evgb::FillGTruth(grec,gtruth);
549 
550  if (fAddMCFlux) {
552  double dk2gen = -99999.;
554  } else if ( fGSimpleNtpEntry ) {
555  // cheat at meta data for now ...
556  // should be pulling this from input file ... no sure that
557  // it is being copied correctly
558  // (TChain isn't made of GSimpleNtpMeta objs ... )
559  // we need to know how to interpret the Aux variablees
560  static genie::flux::GSimpleNtpMeta* meta = 0;
561  if ( ! meta ) {
562  meta = new genie::flux::GSimpleNtpMeta;
563  // hopefully this is the layout
564  // aux ints: tgen
565  // aux doubles: fgXYWgt nimpwt muparpx muparpy muparpz mupare necm
566  meta->auxintname.push_back("tgen");
567  meta->auxdblname.push_back("fgXYWgt");
568  meta->auxdblname.push_back("nimpwt");
569  meta->auxdblname.push_back("muparpx");
570  meta->auxdblname.push_back("muparpy");
571  meta->auxdblname.push_back("muparpz");
572  meta->auxdblname.push_back("mupare");
573  meta->auxdblname.push_back("necm");
574  }
576  fGSimpleNtpAux,meta,mcflux);
577  } else if ( fDk2Nu ) {
579  }
580  }
581 
582  /*
583  genie::NtpMCRecHeader rec_header = fMCRec->hdr;
584  //LOG("gevdump", pNOTICE)
585  std::cout
586  << " ** Event: " << rec_header.ievent // implicit newline in print
587  << *grec;
588  // add to our collections
589  */
590 
591  mctruthcol->push_back(mctruth);
592  gtruthcol->push_back(gtruth);
593  if (fAddMCFlux) {
594  // deterimine if there is something to fetch
595  mcfluxcol->push_back(mcflux);
596  }
597 
598  // LArSoft #include "lardata/Utilities/AssociationUtil.h"
599  // NOVA #include "Utilities/AssociationUtil.h"
600  // these util::CreateAssn are taken from LArSoft's GENIEGen_module
601  // ~/Work/DUNE/code/larsim/larsim/EventGenerator/GENIE/GENIEGen_module.cc
602  // this seems to be MARK CreateAssn_07 ?? but that's one-to-many
603  // implicit in this is a indx=UNIT_MAX arg so this is only acting
604  // on the last element of truthcol
605 
606  evgb::util::CreateAssn(*this, evt, *mctruthcol, *gtruthcol, *tgassn,
607  gtruthcol->size()-1, gtruthcol->size());
608 
609  if (fAddMCFlux) {
610  evgb::util::CreateAssn(*this, evt, *mctruthcol, *mcfluxcol, *tfassn,
611  mcfluxcol->size()-1, mcfluxcol->size());
612  }
613  //
614 
615  } // done collecting input
616 
617  //std::cerr << "AddGenieEventsToArt::produce put into event"
618  // << std::endl << std::flush;
619 
620  // put the collections in the event
621  evt.put(std::move(mctruthcol));
622  evt.put(std::move(gtruthcol));
623  evt.put(std::move(tgassn));
624  if ( fAddMCFlux ) {
625  evt.put(std::move(mcfluxcol));
626  evt.put(std::move(tfassn));
627  }
628 
629 }
630 
631 //-------------------------------------------------------------------------
633 {
634  // Parse countConfig to get parameters on how many to add
635  // Should be one of these:
636  // "fixed:" <N>
637  // "flat: <Nmin> <Nmax>"
638  // "poisson: <Nmean>"
639  // "poisson-1: <Nmean>"
640  // "gauss: <mean> <rms>"
641 
642  std::string str = fParams().countConfig();
643 
644  // let user use whatever case they like
645  std::transform(str.begin(),str.end(),str.begin(),::tolower);
646  // trim any leading whitespace
647  if( str.find_first_not_of(" \t\n") != 0)
648  str.erase( 0, str.find_first_not_of(" \t\n") );
649 
650  size_t i = str.find_first_of(" \t\n");
651  std::string distName = str.substr(0,i);
652  str.erase(0,i);
653 
654  // now 'str' should have 1 or 2 numerical values
655 
656  int nf = sscanf(str.c_str(),"%lf %lf",&fRndP1,&fRndP2);
657 
658  if ( nf == 0 ) {
659  mf::LogError("AddGenieEventsToArt")
660  << "ParseCountConfig " << str
661  << " had " << nf << " args, expected something '"
662  << str << "'"<< std::endl;
663  throw cet::exception("badDist countConfig")
664  << __FILE__ << ":" << __LINE__
665  << " badDist '" << str << "'";
666  }
667 
668  if ( distName.find("fix") == 0 || distName == "n" || distName == "n:" ) {
669  fRndDist = kFixed;
670  if ( nf != 1 ) {
671  mf::LogError("AddGenieEventsToArt")
672  << "ParseCountConfig " << distName
673  << " had 2 args, expected 1: '"
674  << str << "', ignoring 2nd" << std::endl;
675  }
676  }
677  else if ( distName.find("flat") == 0 ) {
678  fRndDist = kFlat;
679  if ( nf == 1 ) fRndP2 = fRndP1;
680  // make sure they're ordered
681  if ( fRndP2 < fRndP1 ) std::swap(fRndP1,fRndP2);
682  }
683  else if ( distName.find("poiss") == 0 ) {
684  fRndDist = kPoisson;
685  if ( distName.find("-1") != std::string::npos ) fRndDist = kPoissonMinus1;
686  if ( nf != 1 ) {
687  mf::LogError("AddGenieEventsToArt")
688  << "ParseCountConfig " << distName
689  << " had 2 args, expected 1: '"
690  << str << "', ignoring 2nd" << std::endl;
691  }
692  }
693  else if ( distName.find("gaus") == 0 ) {
695  if ( nf != 2 ) {
696  mf::LogError("AddGenieEventsToArt")
697  << "ParseCountConfig " << distName
698  << " had " << nf << " args, expected 2: '"
699  << str << "'"<< std::endl;
700  throw cet::exception("badDist countConfig")
701  << __FILE__ << ":" << __LINE__
702  << " badDist '" << distName << "'";
703  }
704  } else {
705  mf::LogError("AddGenieEventsToArt")
706  << "ParseCountConfig unknown distName " << distName
707  << " had' " << nf << " args '"
708  << str << "'"<< std::endl;
709  throw cet::exception("unknownDist countConfig")
710  << __FILE__ << ":" << __LINE__
711  << " unknown '" << distName << "'";
712  }
713 
714  mf::LogInfo("AddGenieEventsToArt")
715  << "ParseCountConfig label='" << fMyModuleLabel << "'"
716  << " distName='" << distName << "' (int)"
717  << (int)fRndDist << "; cfgstr '" << str << "' --> "
718  << " p1 " << fRndP1 << " p2 " << fRndP2 << " nf " << nf
719  << std::endl;
720 
721 #if 0
722  // test how fireInt() works ...
723  static bool first = true;
724  if ( first ) {
725  CLHEP::RandFlat flatTest(fEngine); // pass by ref, doesn't own
726  first = false;
727  for (int rtest = 0; rtest < 5; ++rtest ) {
728  std::cout << " ======= testing CLHEP::RandFlat::fireInt("
729  << rtest << ") =======" << std::endl;
730  for (int i=0; i<100; ++i)
731  std::cout << " " << flatTest.fireInt(rtest);
732  std::cout << std::endl;
733  }
734  }
735 #endif
736 }
737 
739 {
740 
741  size_t nchosen = 0;
742 
743  switch ( fRndDist ) {
744  case kFixed:
745  {
746  nchosen = fRndP1; // nothing random about it
747  }
748  case kFlat:
749  {
750  CLHEP::RandFlat flat(fEngine); // pass by ref, doesn't own
751  // couldn't find good documentation on how this worked ... empirically
752  // fireInt(0) & fireInt(1) give 0 always
753  // fireInt(2) gives 0 or 1
754  // fireInt(3) gives 0, 1, 2
755  // fireInt(4) gives 0, 1, 2, 3
756  // ...
757  // so for p1=5, p2=7 we want 5 + [0:2] i.e 5+0=5, 5+1=6, 5+2=7
758  // and thus range should be 3
759  int range = (int)(fRndP2-fRndP1) + 1;
760  nchosen = fRndP1 + flat.fireInt(range);
761  }
762  break;
763  case kPoisson:
764  case kPoissonMinus1:
765  {
766  CLHEP::RandPoisson poisson(fEngine);
767  nchosen = poisson.fire(fRndP1);
768  if ( fRndDist == kPoissonMinus1 ) {
769  if ( nchosen > 0 ) --nchosen;
770  else {
771  mf::LogError("AddGenieEventsToArt")
772  << "fRndDist[type=" << (int)fRndDist
773  << "] '" << fParams().timeConfig() << "' "
774  << " nchosen " << nchosen
775  << " can't subtract 1 for kPoissonMinus1"
776  << std::endl;
777  }
778  }
779  }
780  break;
781  case kGaussian:
782  {
783  CLHEP::RandGauss gauss(fEngine);
784  double tmp = gauss.fire(fRndP1,fRndP2);
785  if ( tmp > 0 ) nchosen = (size_t)(tmp);
786  else {
787  nchosen = 0;
788  mf::LogError("AddGenieEventsToArt")
789  << "fRndDist[type=" << (int)fRndDist
790  << "] '" << fParams().timeConfig() << "' "
791  << " tmp " << tmp
792  << "; can't return < 0 for kGaussian, return 0"
793  << std::endl;
794  }
795  }
796  break;
797  default:
798  {
799  nchosen = 0;
800  mf::LogError("AddGenieEventsToArt")
801  << "fRndDist[type=" << (int)fRndDist
802  << "] '" << fParams().timeConfig() << "' not handled"
803  << std::endl;
804  }
805  }
806 
807  /*
808  mf::LogInfo("AddGenieEventsToArt")
809  << "fRndDist[type=" << (int)fRndDist
810  << "] '" << fParams().timeConfig() << "' "
811  << " nchosen " << nchosen << std::endl;
812  */
813 
814  return nchosen;
815 }
816 
817 //-------------------------------------------------------------------------
819 {
820  std::string timeConfig = fParams().timeConfig();
821  // trim any leading whitespace
822  if( timeConfig.find_first_not_of(" \t\n") != 0)
823  timeConfig.erase( 0, timeConfig.find_first_not_of(" \t\n") );
824 
825  size_t i = timeConfig.find_first_of(": \t\n");
826  std::string timeName = timeConfig.substr(0,i);
827  timeConfig.erase(0,i);
828 
829  mf::LogInfo("AddGenieEventsToArt")
830  << "ParseTimeConfig label='" << fMyModuleLabel << "'"
831  << " name='" << timeName << "'"
832  << " cfg='" << timeConfig << "'" << std::endl;
833  if ( timeName == "none" ) timeName = "evgb::EvtTimeNone";
834  if ( timeName == "flat" ) timeName = "evgb::EvtTimeFlat";
835  if ( timeName == "numi" || timeName == "NuMI"||
836  timeName == "fnal" || timeName == "FNAL" )
837  timeName = "evgb::EvtTimeFNALBeam";
838 
839  evgb::EvtTimeShiftFactory& timeFactory =
841  fTimeShifter = timeFactory.GetEvtTimeShift(timeName,timeConfig);
842 
843  if ( ! fTimeShifter ) {
844  timeFactory.Print();
845  throw cet::exception("BAD TimeShifter")
846  << __FILE__ << ":" << __LINE__
847  << " unknown '" << timeName << "'";
848  }
849 }
850 
851 //-------------------------------------------------------------------------
853 {
854  fXlo = fParams().vtxOffsets().xlo();
855  fYlo = fParams().vtxOffsets().ylo();
856  fZlo = fParams().vtxOffsets().zlo();
857  fXhi = fParams().vtxOffsets().xhi();
858  fYhi = fParams().vtxOffsets().yhi();
859  fZhi = fParams().vtxOffsets().zhi();
860 
861  if ( fXlo != 0 && fYlo != 0 && fZlo != 0 &&
862  fXhi != 0 && fYhi != 0 && fZhi != 0 ) {
863  mf::LogInfo("AddGenieEventsToArt")
864  << "ParseVtxOffsetConfig label='" << fMyModuleLabel << "' \n"
865  << " x [" << std::setw(11) << fXlo << " "
866  << std::setw(11) << fXhi << " ]\n"
867  << " y [" << std::setw(11) << fYlo << " "
868  << std::setw(11) << fYhi << " ]\n"
869  << " z [" << std::setw(11) << fZlo << " "
870  << std::setw(11) << fZhi << " ]";
871  }
872 
873 }
874 //-------------------------------------------------------------------------
875 
876 /*
877 void evg::AddGenieEventsToArt::reconfigure(const Parameters & params)
878 {
879  fParams = params;
880 }
881 */
882 
883 /*
884 void evg::AddGenieEventsToArt::beginJob()
885 {
886  // Implementation of optional member function here.
887 }
888 
889 void evg::AddGenieEventsToArt::beginRun(art::Run & r)
890 {
891  // Implementation of optional member function here.
892 }
893 
894 void evg::AddGenieEventsToArt::beginSubRun(art::SubRun & sr)
895 {
896  // Implementation of optional member function here.
897 }
898 
899 void evg::AddGenieEventsToArt::endJob()
900 {
901  // Implementation of optional member function here.
902 }
903 
904 void evg::AddGenieEventsToArt::endRun(art::Run & r)
905 {
906  // Implementation of optional member function here.
907 }
908 
909 void evg::AddGenieEventsToArt::endSubRun(art::SubRun & sr)
910 {
911  // Implementation of optional member function here.
912 }
913 
914 void evg::AddGenieEventsToArt::reconfigure(fhicl::ParameterSet const & p)
915 {
916  // Implementation of optional member function here.
917  std::cerr << "evg::AddGenieEventsToArt::reconfigure() not implemented"
918  << std::endl;
919  abort();
920 }
921 
922 void evg::AddGenieEventsToArt::respondToCloseInputFile(art::FileBlock const & fb)
923 {
924  // Implementation of optional member function here.
925 }
926 
927 void evg::AddGenieEventsToArt::respondToCloseOutputFiles(art::FileBlock const & fb)
928 {
929  // Implementation of optional member function here.
930 }
931 
932 void evg::AddGenieEventsToArt::respondToOpenInputFile(art::FileBlock const & fb)
933 {
934  // Implementation of optional member function here.
935 }
936 
937 void evg::AddGenieEventsToArt::respondToOpenOutputFiles(art::FileBlock const & fb)
938 {
939  // Implementation of optional member function here.
940 }
941 */
942 
static void SetPrintLevel(int print_level)
Definition: GHepRecord.cxx:992
base_engine_t & createEngine(seed_t seed)
std::vector< std::string > fFileList
THE MAIN GENIE PROJECT NAMESPACE
Definition: AlgCmp.h:26
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void FillMCFlux(genie::GFluxI *fdriver, simb::MCFlux &mcflux)
Definition: GENIE2ART.cxx:756
MINOS-style ntuple record. Each such ntuple record holds a generated EventRecord object. Ntuples of this type are intended for feeding GENIE events into other applications (for example the GEANT4 based MC generation framework of an experiment) if no direct interface exists.
genie::flux::GSimpleNtpEntry * fGSimpleNtpEntry
enum evg::AddGenieEventsToArt::EDistrib RndDist_t
unsigned int GetRandomNumberSeed()
Definition: evgenbase.h:22
std::vector< std::string > auxintname
tagname of aux ints associated w/ entry
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
CLHEP::HepRandomEngine & fEngine
object containing MC flux information
interface for event time distribution
Definition: EvtTimeShiftI.h:29
AddGenieEventsToArt(const Parameters &p)
genie::flux::GSimpleNtpAux * fGSimpleNtpAux
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:69
void swap(Handle< T > &a, Handle< T > &b)
std::void_t< T > n
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
def move(depos, offset)
Definition: depos.py:107
QTextStream & flush(QTextStream &s)
string tmp
Definition: languages.py:63
auto const & get_PSet() const
Definition: ProducerTable.h:47
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
Generated Event Record. It is a GHepRecord object that can accept / be visited by EventRecordVisitorI...
Definition: EventRecord.h:38
p
Definition: test.py:223
AdcCodeMitigator::Name Name
void FillMCTruth(const genie::EventRecord *grec, double spillTime, simb::MCTruth &mctruth)
Definition: GENIE2ART.cxx:181
static PDGLibrary * Instance(void)
Definition: PDGLibrary.cxx:43
#define Comment
genie::NtpMCEventRecord * fMCRec
genie::flux::GSimpleNtpNuMI * fGSimpleNtpNuMI
static EvtTimeShiftFactory & Instance()
virtual double TimeOffset()=0
void FillGTruth(const genie::EventRecord *grec, simb::GTruth &gtruth)
Definition: GENIE2ART.cxx:351
TCEvent evt
Definition: DataStructs.cxx:7
Event generator information.
Definition: MCTruth.h:32
ProductID put(std::unique_ptr< PROD > &&edp, FullSemantic< Level::Run > const semantic)
Definition: DataViewImpl.h:730
void produce(art::Event &e) override
genie::flux::GNuMIFluxPassThroughInfo * fGNuMIFluxPassThroughInfo
static QCString str
EventRecord * event
event
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
std::vector< std::string > auxdblname
tagname of aux doubles associated w/ entry
evgb::EvtTimeShiftI * GetEvtTimeShift(const std::string &name, const std::string &config="") const