19 #include "TDatabasePDG.h"
20 #include "TStopwatch.h"
23 #include "art/Framework/Core/ModuleMacros.h"
24 #include "art/Framework/Principal/Event.h"
25 #include "art/Framework/Principal/SubRun.h"
26 #include "fhiclcpp/ParameterSet.h"
27 #include "art/Framework/Services/Registry/ServiceHandle.h"
28 #include "art_root_io/TFileService.h"
29 #include "messagefacility/MessageLogger/MessageLogger.h"
30 #include "canvas/Persistency/Common/Assns.h"
31 #include "art/Framework/Core/EDProducer.h"
32 #include "art/Persistency/Common/PtrMaker.h"
35 #include "nurandom/RandomUtils/NuRandomService.h"
39 #include "nusimdata/SimulationBase/MCTruth.h"
40 #include "nusimdata/SimulationBase/MCFlux.h"
41 #include "nusimdata/SimulationBase/GTruth.h"
46 #include "nugen/EventGeneratorBase/GENIE/GENIEHelper.h"
83 explicit GENIEGen(fhicl::ParameterSet
const &pset);
152 , fDefinedVtxHistRange (pset.get<
bool >(
"DefinedVtxHistRange"))
153 , fVtxPosHistRange (pset.get< std::vector<double> >(
"VtxPosHistRange"))
154 , fPassEmptySpills (pset.get<
bool >(
"PassEmptySpills"))
155 , fGlobalTimeOffset(pset.get<
double >(
"GlobalTimeOffset",0))
156 , fRandomTimeOffset(pset.get<
double >(
"RandomTimeOffset",1600.))
161 produces< std::vector<simb::MCTruth> >();
162 produces< std::vector<simb::MCFlux> >();
163 produces< std::vector<simb::GTruth> >();
165 produces< sumdata::POTSummary, art::InSubRun >();
166 produces< art::Assns<simb::MCTruth, simb::MCFlux> >();
167 produces< art::Assns<simb::MCTruth, simb::GTruth> >();
168 produces< std::vector<sim::BeamGateInfo> >();
170 std::string beam_type_name = pset.get<std::string>(
"BeamName");
172 if(beam_type_name ==
"numi")
176 else if(beam_type_name ==
"booster")
182 fBeamType = ::sim::kUnknown;
184 art::ServiceHandle<geo::Geometry const> geo;
186 signed int temp_seed;
187 fhicl::ParameterSet GENIEconfig(pset);
188 if (!GENIEconfig.get_if_present(
"RandomSeed", temp_seed)) {
193 if (!GENIEconfig.get_if_present(
"Seed", seed))
194 seed = art::ServiceHandle<rndm::NuRandomService>()->getSeed();
199 GENIEconfig.put(
"RandomSeed", seed);
202 fGENIEHelp =
new evgb::GENIEHelper(GENIEconfig,
203 geo->ROOTGeoManager(),
205 geo->TotalMass(pset.get< std::string>(
"TopVolume").c_str()));
214 mf::LogInfo(
"GENIEProductionTime") <<
"real time to produce file: " <<
fStopwatch.RealTime();
225 art::ServiceHandle<art::TFileService const>
tfs;
227 fGenerated[0] = tfs->make<TH1F>(
"fGenerated_necc",
"", 100, 0.0, 20.0);
228 fGenerated[1] = tfs->make<TH1F>(
"fGenerated_nebcc",
"", 100, 0.0, 20.0);
229 fGenerated[2] = tfs->make<TH1F>(
"fGenerated_nmcc",
"", 100, 0.0, 20.0);
230 fGenerated[3] = tfs->make<TH1F>(
"fGenerated_nmbcc",
"", 100, 0.0, 20.0);
231 fGenerated[4] = tfs->make<TH1F>(
"fGenerated_nnc",
"", 100, 0.0, 20.0);
232 fGenerated[5] = tfs->make<TH1F>(
"fGenerated_nbnc",
"", 100, 0.0, 20.0);
234 fDCosX = tfs->make<TH1F>(
"fDCosX",
";dx/ds", 200, -1., 1.);
235 fDCosY = tfs->make<TH1F>(
"fDCosY",
";dy/ds", 200, -1., 1.);
236 fDCosZ = tfs->make<TH1F>(
"fDCosZ",
";dz/ds", 200, -1., 1.);
238 fMuMomentum = tfs->make<TH1F>(
"fMuMomentum",
";p_{#mu} (GeV/c)", 500, 0., 50.);
239 fMuDCosX = tfs->make<TH1F>(
"fMuDCosX",
";dx/ds;", 200, -1., 1.);
240 fMuDCosY = tfs->make<TH1F>(
"fMuDCosY",
";dy/ds;", 200, -1., 1.);
241 fMuDCosZ = tfs->make<TH1F>(
"fMuDCosZ",
";dz/ds;", 200, -1., 1.);
243 fEMomentum = tfs->make<TH1F>(
"fEMomentum",
";p_{e} (GeV/c)", 500, 0., 50.);
244 fEDCosX = tfs->make<TH1F>(
"fEDCosX",
";dx/ds;", 200, -1., 1.);
245 fEDCosY = tfs->make<TH1F>(
"fEDCosY",
";dy/ds;", 200, -1., 1.);
246 fEDCosZ = tfs->make<TH1F>(
"fEDCosZ",
";dz/ds;", 200, -1., 1.);
248 fCCMode = tfs->make<TH1F>(
"fCCMode",
";CC Interaction Mode;", 4, 0., 4.);
249 fCCMode->GetXaxis()->SetBinLabel(1,
"QE");
250 fCCMode->GetXaxis()->SetBinLabel(2,
"Res");
251 fCCMode->GetXaxis()->SetBinLabel(3,
"DIS");
252 fCCMode->GetXaxis()->SetBinLabel(4,
"Coh");
253 fCCMode->GetXaxis()->CenterLabels();
255 fNCMode = tfs->make<TH1F>(
"fNCMode",
";NC Interaction Mode;", 4, 0., 4.);
256 fNCMode->GetXaxis()->SetBinLabel(1,
"QE");
257 fNCMode->GetXaxis()->SetBinLabel(2,
"Res");
258 fNCMode->GetXaxis()->SetBinLabel(3,
"DIS");
259 fNCMode->GetXaxis()->SetBinLabel(4,
"Coh");
260 fNCMode->GetXaxis()->CenterLabels();
262 fDeltaE = tfs->make<TH1F>(
"fDeltaE",
";#Delta E_{#nu} (GeV);", 200, -1., 1.);
263 fECons = tfs->make<TH1F>(
"fECons",
";#Delta E(#nu,lepton);", 500, -5., 5.);
267 art::ServiceHandle<geo::Geometry const> geo;
268 double x = 2.1*geo->DetHalfWidth();
269 double y = 2.1*geo->DetHalfHeight();
270 double z = 2.*geo->DetLength();
271 int xdiv = TMath::Nint(2*x/5.);
272 int ydiv = TMath::Nint(2*y/5.);
273 int zdiv = TMath::Nint(2*z/5.);
275 fVertexX = tfs->make<TH1F>(
"fVertexX",
";x (cm)", xdiv, -0.1*
x,
x);
276 fVertexY = tfs->make<TH1F>(
"fVertexY",
";y (cm)", ydiv, -
y,
y);
277 fVertexZ = tfs->make<TH1F>(
"fVertexZ",
";z (cm)", zdiv, -0.1*
z,
z);
279 fVertexXY = tfs->make<TH2F>(
"fVertexXY",
";x (cm);y (cm)", xdiv, -0.1*
x,
x, ydiv, -
y,
y);
280 fVertexXZ = tfs->make<TH2F>(
"fVertexXZ",
";z (cm);x (cm)", zdiv, -0.2*
z,
z, xdiv, -0.1*
x,
x);
281 fVertexYZ = tfs->make<TH2F>(
"fVertexYZ",
";z (cm);y (cm)", zdiv, -0.2*
z,
z, ydiv, -
y,
y);
290 fVertexY = tfs->make<TH1F>(
"fVertexY",
";y (cm)", ydiv, fVtxPosHistRange[2], fVtxPosHistRange[3]);
291 fVertexZ = tfs->make<TH1F>(
"fVertexZ",
";z (cm)", zdiv, fVtxPosHistRange[4], fVtxPosHistRange[5]);
293 fVertexXY = tfs->make<TH2F>(
"fVertexXY",
";x (cm);y (cm)", xdiv, fVtxPosHistRange[0], fVtxPosHistRange[1], ydiv, fVtxPosHistRange[2], fVtxPosHistRange[3]);
294 fVertexXZ = tfs->make<TH2F>(
"fVertexXZ",
";z (cm);x (cm)", zdiv, fVtxPosHistRange[4], fVtxPosHistRange[5], xdiv, fVtxPosHistRange[0], fVtxPosHistRange[1]);
295 fVertexYZ = tfs->make<TH2F>(
"fVertexYZ",
";z (cm);y (cm)", zdiv, fVtxPosHistRange[4], fVtxPosHistRange[5], ydiv, fVtxPosHistRange[2], fVtxPosHistRange[3]);
303 art::ServiceHandle<geo::Geometry const> geo;
304 run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
321 auto p = std::make_unique<sumdata::POTSummary>();
326 sr.put(std::move(
p));
334 std::unique_ptr< std::vector<simb::MCTruth> > truthcol (
new std::vector<simb::MCTruth>);
335 std::unique_ptr< std::vector<simb::MCFlux> > fluxcol (
new std::vector<simb::MCFlux >);
336 std::unique_ptr< std::vector<simb::GTruth> > gtruthcol (
new std::vector<simb::GTruth >);
337 std::unique_ptr< art::Assns<simb::MCTruth, simb::MCFlux> > tfassn(
new art::Assns<simb::MCTruth, simb::MCFlux>);
338 std::unique_ptr< art::Assns<simb::MCTruth, simb::GTruth> > tgtassn(
new art::Assns<simb::MCTruth, simb::GTruth>);
339 std::unique_ptr< std::vector<sim::BeamGateInfo> > gateCollection(
new std::vector<sim::BeamGateInfo>);
341 while(truthcol->size() < 1){
354 truthcol ->push_back(truth);
355 fluxcol ->push_back(flux);
356 gtruthcol->push_back(gTruth);
357 auto const truthPtr = art::PtrMaker<simb::MCTruth>{evt}(truthcol->size() - 1);
358 tfassn->addSingle(truthPtr, art::PtrMaker<simb::MCFlux>{evt}(fluxcol->size() - 1));
359 tgtassn->addSingle(truthPtr, art::PtrMaker<simb::GTruth>{evt}(gtruthcol->size() - 1));
366 if (truth.NeutrinoSet() && (truth.GetNeutrino().InteractionType() ==
simb::kNuanceOffset)) {
367 mf::LogWarning log(
"GENIEmissingProcessMapping");
368 log <<
"Found an interaction that is not represented by the interaction type code in GENIE:"
374 "\nGENIE truth record:"
386 MF_LOG_DEBUG(
"GENIEGen") <<
"no events made for this spill but "
387 <<
"passing it on and ending the event anyway";
400 evt.put(std::move(truthcol));
401 evt.put(std::move(fluxcol));
402 evt.put(std::move(gtruthcol));
403 evt.put(std::move(tfassn));
404 evt.put(std::move(tgtassn));
405 evt.put(std::move(gateCollection));
413 int code = StatusCode;
419 ParticleStatusName =
"kIStUndefined";
422 ParticleStatusName =
"kIStInitialState";
425 ParticleStatusName =
"kIStStableFinalState";
428 ParticleStatusName =
"kIStIntermediateState";
431 ParticleStatusName =
"kIStDecayedState";
434 ParticleStatusName =
"kIStNucleonTarget";
437 ParticleStatusName =
"kIStDISPreFragmHadronicState";
440 ParticleStatusName =
"kIStPreDecayResonantState";
443 ParticleStatusName =
"kIStHadronInTheNucleus";
446 ParticleStatusName =
"kIStFinalStateNuclearRemnant";
449 ParticleStatusName =
"kIStNucleonClusterTarget";
452 ParticleStatusName =
"Status Unknown";
460 std::string ReactionChannelName=
" ";
463 ReactionChannelName =
"kCC";
465 ReactionChannelName =
"kNC";
466 else std::cout<<
"Current mode unknown!! "<<std::endl;
469 ReactionChannelName +=
"_kQE";
471 ReactionChannelName +=
"_kRes";
473 ReactionChannelName +=
"_kDIS";
475 ReactionChannelName +=
"_kCoh";
476 else std::cout<<
"interaction mode unknown!! "<<std::endl;
478 return ReactionChannelName;
486 if (mc.GetNeutrino().CCNC()==
simb::kCC) {
487 fCCMode->Fill(mc.GetNeutrino().Mode());
488 if (mc.GetNeutrino().Nu().PdgCode() == 12)
id = 0;
489 else if (mc.GetNeutrino().Nu().PdgCode() == -12)
id = 1;
490 else if (mc.GetNeutrino().Nu().PdgCode() == 14)
id = 2;
491 else if (mc.GetNeutrino().Nu().PdgCode() == -14)
id = 3;
495 fNCMode->Fill(mc.GetNeutrino().Mode());
496 if (mc.GetNeutrino().Nu().PdgCode() > 0)
id = 4;
502 fGenerated[id]->Fill(mc.GetNeutrino().Nu().E() );
506 simb::MCNeutrino mcnu = mc.GetNeutrino();
507 const simb::MCParticle
nu = mcnu.Nu();
519 fDCosX->Fill(nu.Px()/mom);
520 fDCosY->Fill(nu.Py()/mom);
521 fDCosZ->Fill(nu.Pz()/mom);
525 MF_LOG_DEBUG(
"GENIEInteractionInformation")
527 <<
"REACTION: " <<
ReactionChannel(mc.GetNeutrino().CCNC(),mc.GetNeutrino().Mode())
529 <<
"-----------> Particles in the Stack = " << mc.NParticles() << std::endl
531 << std::setw(20) <<
"PARTICLE"
533 << std::setw(32) <<
"STATUS"
534 << std::setw(18) <<
"E (GeV)"
535 << std::setw(18) <<
"m (GeV/c2)"
536 << std::setw(18) <<
"Ek (GeV)"
537 << std::endl << std::endl;
539 const TDatabasePDG* databasePDG = TDatabasePDG::Instance();
542 for(
int i = 0; i < mc.NParticles(); ++i){
543 simb::MCParticle part(mc.GetParticle(i));
544 std::string
name = databasePDG->GetParticle(part.PdgCode())->GetName();
545 int code = part.StatusCode();
547 double mass = part.Mass();
548 double energy = part.E();
549 double Ek = (energy-
mass);
550 if(status==
"kIStStableFinalState"||status==
"kIStHadronInTheNucleus")
551 MF_LOG_DEBUG(
"GENIEFinalState")
554 << std::setw(18)<< energy
555 << std::setw(18)<< mass
556 << std::setw(18)<< Ek <<std::endl;
558 MF_LOG_DEBUG(
"GENIEFinalState")
561 << std::setw(18) << energy
562 << std::setw(18) << mass <<std::endl;
566 if(mc.GetNeutrino().CCNC() ==
simb::kCC){
570 for(
int i = 0; i < mc.NParticles(); ++i){
571 simb::MCParticle part(mc.GetParticle(i));
572 if(
abs(part.PdgCode()) == 11){
574 fEDCosX->Fill(part.Px()/part.P());
575 fEDCosY->Fill(part.Py()/part.P());
576 fEDCosZ->Fill(part.Pz()/part.P());
577 fECons->Fill(nu.E() - part.E());
580 else if(
abs(part.PdgCode()) == 13){
585 fECons->Fill(nu.E() - part.E());
598 DEFINE_ART_MODULE(GENIEGen)
TH1F * fVertexX
vertex location of generated events in x
std::string ParticleStatus(int StatusCode)
TH1F * fMuDCosZ
direction cosine of outgoing mu in z
TH2F * fVertexXZ
vertex location in xz
process_name opflash particleana ie ie ie z
void DumpGTruth(Stream &&out, simb::GTruth const &truth, std::string indent, std::string firstIndent)
Dumps the content of the GENIE truth in the output stream.
offset to account for adding in Nuance codes to this enum
process_name opflash particleana ie x
TH1F * fDeltaE
difference in neutrino energy from MCTruth::Enu() vs TParticle
TH2F * fVertexXY
vertex location in xy
void beginSubRun(art::SubRun &sr)
std::string ReactionChannel(int ccnc, int mode)
void beginRun(art::Run &run)
TH1F * fMuDCosY
direction cosine of outgoing mu in y
void endSubRun(art::SubRun &sr)
produces< sumdata::RunData, art::InRun >()
TH1F * fNCMode
CC interaction mode.
::sim::BeamType_t fBeamType
The width of a simulated "beam gate".
TH1F * fDCosZ
direction cosine in z
Charged-current interactions.
void produce(art::Event &evt)
TH1F * fEDCosY
direction cosine of outgoing e in y
process_name opflash particleana ie ie y
Utility functions to print MC truth information.
GENIEGen(fhicl::ParameterSet const &pset)
int fPassEmptySpills
whether or not to kill evnets with no interactions
TH1F * fCCMode
CC interaction mode.
double fPrevTotGoodPOT
Total good POT from subruns previous to current subrun.
evgb::GENIEHelper * fGENIEHelp
GENIEHelper object.
double fGlobalTimeOffset
keep track of how long it takes to run the job
TH1F * fEDCosX
direction cosine of outgoing e in x
bool fDefinedVtxHistRange
TH1F * fMuDCosX
direction cosine of outgoing mu in x
void DumpMCTruth(Stream &&out, simb::MCTruth const &truth, unsigned int pointsPerLine, std::string indent, std::string firstIndent)
Dumps the content of the specified MC truth in the output stream.
TH1F * fGenerated[6]
Spectra as generated.
double fPrevTotPOT
The type of beam.
TH1F * fDCosY
direction cosine in y
TH1F * fEMomentum
momentum of outgoing electrons
TH2F * fVertexYZ
vertex location in yz
TH1F * fECons
histogram to determine if energy is conserved in the event
TH1F * fEDCosZ
direction cosine of outgoing e in z
TH1F * fDCosX
direction cosine in x
art::ServiceHandle< art::TFileService > tfs
TH1F * fMuMomentum
momentum of outgoing muons
std::string ParticleStatusName(int code)
Describes the status of a particle (simb::MCParticle::StatusCode()).
TH1F * fVertexY
vertex location of generated events in y
BeamType_t
Defines category of beams to be stored in sim::BeamGateInfo.
void FillHistograms(simb::MCTruth mc)
std::vector< double > fVtxPosHistRange
use defined hist range; it is useful to have for asymmetric ranges like in DP FD. ...
TH1F * fVertexZ
vertex location of generated events in z
art framework interface to geometry description
BEGIN_PROLOG could also be cout
A module to check the results from the Monte Carlo generator.
double fRandomTimeOffset
The start of a simulated "beam gate".