26 #include "Conventions/GVersion.h" 27 #include "Ntuple/NtpMCEventRecord.h" 28 #include "Ntuple/NtpMCTreeHeader.h" 29 #include "PDG/PDGLibrary.h" 32 #include "GHEP/GHepRecord.h" 33 #include "GHEP/GHepParticle.h" 35 #include "FluxDrivers/GNuMIFlux.h" 36 #include "FluxDrivers/GSimpleNtpFlux.h" 38 #include "GENIE/Framework/Conventions/GVersion.h" 39 #include "GENIE/Framework/GHEP/GHepRecord.h" 40 #include "GENIE/Framework/GHEP/GHepParticle.h" 41 #include "GENIE/Framework/Ntuple/NtpMCFormat.h" 42 #include "GENIE/Framework/Ntuple/NtpWriter.h" 43 #include "GENIE/Framework/Ntuple/NtpMCEventRecord.h" 45 #include "GENIE/Framework/Messenger/Messenger.h" 48 #include "GENIE/Tools/Flux/GNuMIFlux.h" 49 #include "GENIE/Tools/Flux/GSimpleNtpFlux.h" 52 #include "dk2nu/tree/dk2nu.h" 53 #include "dk2nu/tree/NuChoice.h" 57 #include "TBranchElement.h" 58 #include "TBranchObject.h" 61 #include "CLHEP/Random/RandFlat.h" 62 #include "CLHEP/Random/RandPoissonT.h" 63 #include "CLHEP/Random/RandGauss.h" 95 Comment(
"list of input gntp.*.ghep.root files"),
100 Comment(
"how many events to pull \"<form>: <value> [<value>]\"" 101 " known functional forms:\n" 103 " \"flat: <nmin> <nmax>\"\n" 104 " \"poisson: <mean>\"\n" 105 " \"poisson-1: <mean>\" use Poisson, then subtract 1 (floor 0)\n" 106 " \"gauss: <mean> <rms>\" (floor 0)"),
110 Name(
"globalTimeOffset"),
111 Comment(
"fixed offset to add (in ns)"),
116 Comment(
"time distribution beyond globalTimeOffset (in ns)\n" 117 " e.g. \"flat: 1000\"\n" 119 " see: https://cdcvs.fnal.gov/redmine/projects/nutools/wiki/GENIEHelper#EvtTimeFNALBeam"),
132 Comment(
"allow module to offset global vertex (genie vtx units = m)")
136 Comment(
"attempt to fetch and fill MCFlux for each genie::EventRecord"),
140 Name(
"outputPrintLevel"),
141 Comment(
"print fetched genie::EventRecord -1=no, 13=max info\n" 142 "see GENIE manual for legal values"),
146 Name(
"outputDumpFileName"),
147 Comment(
"name of file to print to (if outputPrintLevel >= 0)\n" 148 "\"std::cout\" for standard out\n" 149 "otherwise string with %l replaced by module_label"),
150 "AddGenieEventsToArt_%l.txt" 153 Name(
"randomEntries"),
154 Comment(
"use random sets of entries from input files\n" 155 "rather than go through the files sequentially"),
159 Name(
"numberToSkip"),
160 Comment(
"Skip the first N entries, starting on the entry \n" 161 "specified in this variable"),
172 Name(
"inputGenieVersion"),
173 Comment(
"Version of GENIE used previously to generate the input events (default"),
178 Name(
"inputGenieTune"),
179 Comment(
"GENIE Comprehensive Model Configuration (CMC/'tune') used to generate the input events for GENIE 3.0+"),
184 Name(
"addGenieVtxTime"),
185 Comment(
"include GENIE's vertex time to MCTruth particle times"),
242 void ParseCountConfig();
243 size_t GetNumToAdd()
const;
244 void ParseTimeConfig();
245 void ParseVtxOffsetConfig();
302 , fGlobalTimeOffset(0)
304 , fXlo(0), fYlo(0), fZlo(0)
305 , fXhi(0), fYhi(0), fZhi(0)
307 , fRandomEntries(false)
308 , fOutputPrintLevel(-1)
312 , fRndDist(kUnknownDist)
315 , fGTreeChain(new TChain(
"gtree"))
316 , fMCRec(new
genie::NtpMCEventRecord)
319 , fGNuMIFluxPassThroughInfo(0)
320 , fGSimpleNtpEntry(0)
336 genie::PDGLibrary::Instance();
345 (*genie::Messenger::Instance())(
"GENIE") << log4cpp::Priority::INFO
346 <<
"Trigger GENIE banner";
353 <<
" ctor start " << fMyModuleLabel
365 produces< std::vector<simb::MCTruth> >();
366 produces< std::vector<simb::GTruth> >();
367 produces< art::Assns<simb::MCTruth, simb::GTruth> >();
369 produces< std::vector<simb::MCFlux> >();
371 produces< art::Assns<simb::MCTruth, simb::MCFlux> >();
378 std::string outFileList =
"adding file pattern: ";
379 for (
size_t i=0; i <
fFileList.size(); ++i) {
380 outFileList +=
"\n\t";
389 size_t skip =
fParams().numberToSkip();
409 TObjArray* blist =
fGTreeChain->GetListOfBranches();
412 while ( ( obj = next() ) ) {
413 std::string bname = obj->GetName();
416 const TBranchElement* belement =
dynamic_cast<const TBranchElement*
>(obj);
417 const TBranchObject* bobject =
dynamic_cast<const TBranchObject*
>(obj);
418 if ( ! belement && ! bobject ) {
419 std::string reallyIsA = obj->ClassName();
421 <<
"### supposed branch element '" << bname
422 <<
"' wasn't a TBranchElement/TBranchObject but instead a " 423 << reallyIsA << std::endl;
424 if ( bname ==
"gmcrec" ) {
426 <<
"### since this is '" << bname
427 <<
"' this is likely to end very badly badly" << std::endl;
431 std::string bclass = (belement) ? belement->GetClassName()
432 : bobject->GetClassName();
433 if ( bclass ==
"genie::NtpMCEventRecord" ) {
435 }
else if ( bclass ==
"genie::flux::GNuMIFluxPassThroughInfo" ) {
438 }
else if ( bclass ==
"genie::flux::GSimpleNtpEntry" ) {
441 }
else if ( bclass ==
"genie::flux::GSimpleNtpNuMI" ) {
444 }
else if ( bclass ==
"genie::flux::GSimpleNtpAux" ) {
447 }
else if ( bclass ==
"bsim::Dk2Nu" ) {
450 }
else if ( bclass ==
"bsim::NuChoice" ) {
455 <<
"### branch element '" << bname
456 <<
"' was unhandled '" << bclass <<
"' class" << std::endl;
463 <<
"chain has " <<
fNumMCRec <<
" entries" 467 <<
"input files have zero entries " 468 << __FILE__ <<
":" << __LINE__;
482 if ( posl != std::string::npos ) {
486 <<
"#### AddGenieEventsToArt::ctor open " 488 << std::endl << std::flush;
491 std::ios_base::trunc|std::ios_base::out);
502 std::ofstream* ofs =
dynamic_cast<std::ofstream*
>(
fOutputStream);
505 <<
"#### AddGenieEventsToArt::dtor close " 507 << std::endl << std::flush;
520 std::unique_ptr< std::vector<simb::MCTruth> >
521 mctruthcol(
new std::vector<simb::MCTruth>);
523 std::unique_ptr< std::vector<simb::GTruth> >
524 gtruthcol(
new std::vector<simb::GTruth>);
526 std::unique_ptr< std::vector<simb::MCFlux> >
527 mcfluxcol(
new std::vector<simb::MCFlux>);
529 std::unique_ptr< art::Assns<simb::MCTruth, simb::MCFlux> >
531 std::unique_ptr< art::Assns<simb::MCTruth, simb::GTruth> >
539 std::vector<size_t> entries;
543 mf::LogDebug(
"AddGeniEventsToArt") <<
"#### AddGenieEventsToArt::produce " 544 <<
"attempt to get " << n <<
" entries " 545 <<
"from " <<
fDistName <<
" distribution";
548 while ( entries.size() !=
n ) {
560 if ( std::find(entries.begin(),entries.end(),indx) != entries.end() ) {
564 entries.push_back(indx);
573 for (
size_t i=0; i<
n; ++i) {
578 size_t ientry = entries[i];
580 <<
"Event: " << i <<
" - Using entry " << ientry << std::endl;
584 genie::EventRecord* grec =
fMCRec->event;
589 if ( grec->GetEntries() == 1 ) {
590 genie::GHepParticle* p = grec->Particle(0);
591 if ( p && p->Pdg() == 0 ) {
610 #if __GENIE_RELEASE_CODE__ >= GRELCODE(3,0,2) 611 int plevel = genie::GHepRecord::GetPrintLevel();
619 #if __GENIE_RELEASE_CODE__ >= GRELCODE(3,0,2) 620 genie::GHepRecord::SetPrintLevel(plevel);
632 TLorentzVector vtxOffset(xoff,yoff,zoff,evtTimeOffset);
643 double dk2gen = -99999.;
651 static genie::flux::GSimpleNtpMeta* meta = 0;
653 meta =
new genie::flux::GSimpleNtpMeta;
657 meta->auxintname.push_back(
"tgen");
658 meta->auxdblname.push_back(
"fgXYWgt");
659 meta->auxdblname.push_back(
"nimpwt");
660 meta->auxdblname.push_back(
"muparpx");
661 meta->auxdblname.push_back(
"muparpy");
662 meta->auxdblname.push_back(
"muparpz");
663 meta->auxdblname.push_back(
"mupare");
664 meta->auxdblname.push_back(
"necm");
682 mctruthcol->push_back(mctruth);
683 gtruthcol->push_back(gtruth);
686 mcfluxcol->push_back(mcflux);
698 gtruthcol->size()-1, gtruthcol->size());
702 mcfluxcol->size()-1, mcfluxcol->size());
712 evt.
put(std::move(mctruthcol));
713 evt.
put(std::move(gtruthcol));
714 evt.
put(std::move(tgassn));
716 evt.
put(std::move(mcfluxcol));
717 evt.
put(std::move(tfassn));
734 std::string str =
fParams().countConfig();
737 std::transform(str.begin(),str.end(),str.begin(),::tolower);
739 if( str.find_first_not_of(
" \t\n") != 0)
740 str.erase( 0, str.find_first_not_of(
" \t\n") );
742 size_t i = str.find_first_of(
" \t\n");
751 if ( nf == 0 &&
fDistName.find(
"rootino") != 0 ) {
753 <<
"ParseCountConfig " << str
754 <<
" had " << nf <<
" args, expected something '" 755 << str <<
"'"<< std::endl;
757 << __FILE__ <<
":" << __LINE__
758 <<
" badDist '" << str <<
"'";
766 <<
" had 2 args, expected 1: '" 767 << str <<
"', ignoring 2nd" << std::endl;
769 }
else if (
fDistName.find(
"flat") == 0 ) {
775 }
else if (
fDistName.find(
"poiss") == 0 ) {
781 <<
" had 2 args, expected 1: '" 782 << str <<
"', ignoring 2nd" << std::endl;
784 }
else if (
fDistName.find(
"gaus") == 0 ) {
789 <<
" had " << nf <<
" args, expected 2: '" 790 << str <<
"'"<< std::endl;
792 << __FILE__ <<
":" << __LINE__
795 }
else if (
fDistName.find(
"rootino") == 0 ) {
801 <<
" 'distribution' is incompatible with randomEntries=true" 804 << __FILE__ <<
":" << __LINE__
805 <<
" badDist '" <<
fDistName <<
"' w/ randomEntries=true";
809 <<
"ParseCountConfig unknown fDistName " <<
fDistName 810 <<
" had' " << nf <<
" args '" 811 << str <<
"'"<< std::endl;
813 << __FILE__ <<
":" << __LINE__
819 <<
" fDistName='" <<
fDistName <<
"' (int)" 820 << (int)
fRndDist <<
"; cfgstr '" << str <<
"' --> " 826 static bool first =
true;
828 CLHEP::RandFlat flatTest(
fEngine);
830 for (
int rtest = 0; rtest < 5; ++rtest ) {
831 std::cout <<
" ======= testing CLHEP::RandFlat::fireInt(" 832 << rtest <<
") =======" << std::endl;
833 for (
int i=0; i<100; ++i)
834 std::cout <<
" " << flatTest.fireInt(rtest);
835 std::cout << std::endl;
865 nchosen =
fRndP1 + flat.fireInt(range);
871 CLHEP::RandPoisson poisson(
fEngine);
872 nchosen = poisson.fire(
fRndP1);
874 if ( nchosen > 0 ) --nchosen;
877 <<
"fRndDist[type=" << (int)
fRndDist 878 <<
"] '" <<
fParams().timeConfig() <<
"' " 879 <<
" nchosen " << nchosen
880 <<
" can't subtract 1 for kPoissonMinus1" 888 CLHEP::RandGauss gauss(
fEngine);
890 if ( tmp > 0 ) nchosen = (size_t)(tmp);
894 <<
"fRndDist[type=" << (int)
fRndDist 895 <<
"] '" <<
fParams().timeConfig() <<
"' " 897 <<
"; can't return < 0 for kGaussian, return 0" 911 <<
"fRndDist[type=" << (int)
fRndDist 912 <<
"] '" <<
fParams().timeConfig() <<
"' not handled" 930 std::string timeConfig =
fParams().timeConfig();
932 if( timeConfig.find_first_not_of(
" \t\n") != 0)
933 timeConfig.erase( 0, timeConfig.find_first_not_of(
" \t\n") );
935 size_t i = timeConfig.find_first_of(
": \t\n");
936 std::string timeName = timeConfig.substr(0,i);
937 timeConfig.erase(0,i);
941 <<
" name='" << timeName <<
"'" 942 <<
" cfg='" << timeConfig <<
"'" << std::endl;
943 if ( timeName ==
"none" ) timeName =
"evgb::EvtTimeNone";
944 if ( timeName ==
"flat" ) timeName =
"evgb::EvtTimeFlat";
945 if ( timeName ==
"numi" || timeName ==
"NuMI" ||
946 timeName ==
"fnal" || timeName ==
"FNAL" )
947 timeName =
"evgb::EvtTimeFNALBeam";
948 if ( timeName ==
"Booster" || timeName ==
"booster" )
949 timeName =
"evgb::EvtTimeFNALBeam Booster";
960 << __FILE__ <<
":" << __LINE__
961 <<
" unknown '" << timeName <<
"'";
979 <<
" x [" << std::setw(11) <<
fXlo <<
" " 980 << std::setw(11) <<
fXhi <<
" ]\n" 981 <<
" y [" << std::setw(11) <<
fYlo <<
" " 982 << std::setw(11) <<
fYhi <<
" ]\n" 983 <<
" z [" << std::setw(11) <<
fZlo <<
" " 984 << std::setw(11) <<
fZhi <<
" ]";
base_engine_t & createEngine(seed_t seed)
Atom< bool > addGenieVtxTime
Atom< std::string > timeConfig
void FillMCTruth(const genie::EventRecord *grec, double spillTime, simb::MCTruth &mctruth, const std::string &genieVersion="unknown", const std::string &genieTune="unknown", bool addGenieVtxTime=false, const std::unordered_map< std::string, std::string > genConfig={})
std::vector< std::string > fFileList
GENIE neutrino interaction simulation objects.
Atom< double > globalTimeOffset
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void FillMCFlux(genie::GFluxI *fdriver, simb::MCFlux &mcflux)
genie::flux::GSimpleNtpEntry * fGSimpleNtpEntry
enum evg::AddGenieEventsToArt::EDistrib RndDist_t
unsigned int GetRandomNumberSeed()
Sequence< std::string > fileList
Functions for transforming GENIE objects into ART objects (and back)
std::string fMyModuleType
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
evgb::EvtTimeShiftI * fTimeShifter
CLHEP::HepRandomEngine & fEngine
std::string fMyModuleLabel
void ParseVtxOffsetConfig()
object containing MC flux information
Atom< std::string > countConfig
interface for event time distribution
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
AddGenieEventsToArt(const Parameters &p)
size_t GetNumToAdd() const
genie::flux::GSimpleNtpAux * fGSimpleNtpAux
bsim::NuChoice * fNuChoice
#define DEFINE_ART_MODULE(klass)
Atom< std::string > inputGenieVersion
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.
virtual void PrintConfig(bool verbose=true)=0
provide a means of printing the configuration
auto const & get_PSet() const
std::ostream * fOutputStream
Atom< std::string > outputDumpFileName
Atom< bool > randomEntries
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
genie::NtpMCEventRecord * fMCRec
A class for generating concrete EvtTimeShiftI derived classes based on the factory pattern...
genie::flux::GSimpleNtpNuMI * fGSimpleNtpNuMI
static EvtTimeShiftFactory & Instance()
Table< VtxOffsets > vtxOffsets
Atom< std::string > inputGenieTune
virtual double TimeOffset()=0
void FillGTruth(const genie::EventRecord *grec, simb::GTruth >ruth)
Event generator information.
std::string fOutputDumpFileName
void produce(art::Event &e) override
genie::flux::GNuMIFluxPassThroughInfo * fGNuMIFluxPassThroughInfo
Atom< int > outputPrintLevel
cet::coded_exception< error, detail::translate > exception
evgb::EvtTimeShiftI * GetEvtTimeShift(const std::string &name, const std::string &config="") const