GENIEGen_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 //
4 // GENIE neutrino event generator
5 //
6 // brebel@fnal.gov
7 //
8 ////////////////////////////////////////////////////////////////////////
9 
10 #include <cstdlib>
11 #include <string>
12 #include <iostream>
13 #include <iomanip>
14 #include <memory>
15 
16 // ROOT includes
17 #include "TH1.h"
18 #include "TH2.h"
19 #include "TDatabasePDG.h"
20 #include "TStopwatch.h"
21 
22 // Framework includes
26 #include "fhiclcpp/ParameterSet.h"
28 #include "art_root_io/TFileService.h"
33 
34 // art extensions
35 #include "nurandom/RandomUtils/NuRandomService.h"
36 
37 // LArSoft includes
38 #include "lardataalg/MCDumpers/MCDumpers.h" // sim::dump namespace
46 #include "nugen/EventGeneratorBase/GENIE/GENIEHelper.h"
47 
48 ///Event Generation using GENIE, cosmics or single particles
49 namespace evgen {
50  /**
51  * @brief A module to check the results from the Monte Carlo generator
52  *
53  * Note on random number generator
54  * --------------------------------
55  *
56  * GENIE uses a TRandom generator for its purposes.
57  * Since art's RandomNumberGenerator service only provides
58  * `CLHEP::HepRandomEngine`, the standard LArSoft/art mechanism for handling
59  * the random stream can't be used.
60  * GENIEHelper, interface to GENIE provided by nugen, creates a TRandom
61  * that GENIE can use. It initializes it with a random seed read from
62  * *RandomSeed* configuration parameter. This and all the other parameters
63  * are inherited from the art module (that is, `GENIEGen`) configuration.
64  * LArSoft meddles with this mechanism to provide support for the standard
65  * "Seed" parameter and NuRandomService service.
66  *
67  * Configuration parameters
68  * -------------------------
69  *
70  * - *RandomSeed* (integer, optional): if specified, this value is used as
71  * seed for GENIE random number generator engine
72  * - *Seed* (unsigned integer, optional): if specified, this value is used as
73  * seed for GENIE random number generator engine; if *RandomSeed* is also
74  * specified, this value is ignored (but in the future this could turn into
75  * a configuration error)
76  *
77  * As custom, if the random seed is not provided by the configuration, one is
78  * fetched from `NuRandomService` (if available), with the behaviour in
79  * lar::util::FetchRandomSeed().
80  */
81  class GENIEGen : public art::EDProducer {
82  public:
83  explicit GENIEGen(fhicl::ParameterSet const &pset);
84  virtual ~GENIEGen();
85 
86  void produce(art::Event& evt);
87  void beginJob();
88  void beginRun(art::Run& run);
89  void beginSubRun(art::SubRun& sr);
90  void endSubRun(art::SubRun& sr);
91 
92  private:
93 
94  std::string ParticleStatus(int StatusCode);
95  std::string ReactionChannel(int ccnc,int mode);
96 
98 
99  evgb::GENIEHelper *fGENIEHelp; ///< GENIEHelper object
100  bool fDefinedVtxHistRange;///use defined hist range; it is useful to have for asymmetric ranges like in DP FD.
101  std::vector< double > fVtxPosHistRange;
102 
103  int fPassEmptySpills; ///< whether or not to kill evnets with no interactions
104  TStopwatch fStopwatch; ///keep track of how long it takes to run the job
105 
106  double fGlobalTimeOffset; /// The start of a simulated "beam gate".
107  double fRandomTimeOffset; /// The width of a simulated "beam gate".
108  ::sim::BeamType_t fBeamType; /// The type of beam
109 
110  double fPrevTotPOT; ///< Total POT from subruns previous to current subrun
111  double fPrevTotGoodPOT; ///< Total good POT from subruns previous to current subrun
112 
113  TH1F* fGenerated[6]; ///< Spectra as generated
114 
115  TH1F* fVertexX; ///< vertex location of generated events in x
116  TH1F* fVertexY; ///< vertex location of generated events in y
117  TH1F* fVertexZ; ///< vertex location of generated events in z
118 
119  TH2F* fVertexXY; ///< vertex location in xy
120  TH2F* fVertexXZ; ///< vertex location in xz
121  TH2F* fVertexYZ; ///< vertex location in yz
122 
123  TH1F* fDCosX; ///< direction cosine in x
124  TH1F* fDCosY; ///< direction cosine in y
125  TH1F* fDCosZ; ///< direction cosine in z
126 
127  TH1F* fMuMomentum; ///< momentum of outgoing muons
128  TH1F* fMuDCosX; ///< direction cosine of outgoing mu in x
129  TH1F* fMuDCosY; ///< direction cosine of outgoing mu in y
130  TH1F* fMuDCosZ; ///< direction cosine of outgoing mu in z
131 
132  TH1F* fEMomentum; ///< momentum of outgoing electrons
133  TH1F* fEDCosX; ///< direction cosine of outgoing e in x
134  TH1F* fEDCosY; ///< direction cosine of outgoing e in y
135  TH1F* fEDCosZ; ///< direction cosine of outgoing e in z
136 
137  TH1F* fCCMode; ///< CC interaction mode
138  TH1F* fNCMode; ///< CC interaction mode
139 
140  TH1F* fDeltaE; ///< difference in neutrino energy from MCTruth::Enu() vs TParticle
141  TH1F* fECons; ///< histogram to determine if energy is conserved in the event
142 
143  };
144 }
145 
146 namespace evgen{
147 
148  //____________________________________________________________________________
150  : EDProducer{pset}
151  , fGENIEHelp(0)
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.)) // BNB default value
157  , fBeamType(::sim::kBNB)
158  {
159  fStopwatch.Start();
160 
161  produces< std::vector<simb::MCTruth> >();
162  produces< std::vector<simb::MCFlux> >();
163  produces< std::vector<simb::GTruth> >();
164  produces< sumdata::RunData, art::InRun >();
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> >();
169 
170  std::string beam_type_name = pset.get<std::string>("BeamName");
171 
172  if(beam_type_name == "numi")
173 
175 
176  else if(beam_type_name == "booster")
177 
179 
180  else
181 
183 
185 
186  signed int temp_seed; // the seed read by GENIEHelper is a signed integer...
187  fhicl::ParameterSet GENIEconfig(pset);
188  if (!GENIEconfig.get_if_present("RandomSeed", temp_seed)) { // TODO use has_key() when it becomes available
189  // no RandomSeed specified; check for the LArSoft-style "Seed" instead:
190  // obtain the random seed from a service,
191  // unless overridden in configuration with key "Seed"
192  unsigned int seed;
193  if (!GENIEconfig.get_if_present("Seed", seed))
194  seed = art::ServiceHandle<rndm::NuRandomService>()->getSeed();
195 
196  // The seed is not passed to RandomNumberGenerator,
197  // since GENIE uses a TRandom generator that is owned by the GENIEHelper.
198  // Instead, we explicitly configure the random seed for GENIEHelper:
199  GENIEconfig.put("RandomSeed", seed);
200  } // if no RandomSeed present
201 
202  fGENIEHelp = new evgb::GENIEHelper(GENIEconfig,
203  geo->ROOTGeoManager(),
204  geo->ROOTFile(),
205  geo->TotalMass(pset.get< std::string>("TopVolume").c_str()));
206 
207  }
208 
209  //____________________________________________________________________________
211  {
212  if(fGENIEHelp) delete fGENIEHelp;
213  fStopwatch.Stop();
214  mf::LogInfo("GENIEProductionTime") << "real time to produce file: " << fStopwatch.RealTime();
215  }
216 
217  //____________________________________________________________________________
219  fGENIEHelp->Initialize();
220 
221  fPrevTotPOT = 0.;
222  fPrevTotGoodPOT = 0.;
223 
224  // Get access to the TFile service.
226 
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);
233 
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.);
237 
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.);
242 
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.);
247 
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();
254 
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();
261 
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.);
264 
266  double x = 2.1*geo->DetHalfWidth();
267  double y = 2.1*geo->DetHalfHeight();
268  double z = 2.*geo->DetLength();
269  int xdiv = TMath::Nint(2*x/5.);
270  int ydiv = TMath::Nint(2*y/5.);
271  int zdiv = TMath::Nint(2*z/5.);
272 
273  if (fDefinedVtxHistRange == false)
274  {
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);
278 
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);
282  }
283  else
284  {
285  fVertexX = tfs->make<TH1F>("fVertexX", ";x (cm)", xdiv, fVtxPosHistRange[0], fVtxPosHistRange[1]);
286  fVertexY = tfs->make<TH1F>("fVertexY", ";y (cm)", ydiv, fVtxPosHistRange[2], fVtxPosHistRange[3]);
287  fVertexZ = tfs->make<TH1F>("fVertexZ", ";z (cm)", zdiv, fVtxPosHistRange[4], fVtxPosHistRange[5]);
288 
289  fVertexXY = tfs->make<TH2F>("fVertexXY", ";x (cm);y (cm)", xdiv, fVtxPosHistRange[0], fVtxPosHistRange[1], ydiv, fVtxPosHistRange[2], fVtxPosHistRange[3]);
290  fVertexXZ = tfs->make<TH2F>("fVertexXZ", ";z (cm);x (cm)", zdiv, fVtxPosHistRange[4], fVtxPosHistRange[5], xdiv, fVtxPosHistRange[0], fVtxPosHistRange[1]);
291  fVertexYZ = tfs->make<TH2F>("fVertexYZ", ";z (cm);y (cm)", zdiv, fVtxPosHistRange[4], fVtxPosHistRange[5], ydiv, fVtxPosHistRange[2], fVtxPosHistRange[3]);
292  }
293 
294  }
295 
296  //____________________________________________________________________________
298  {
300  run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
301  }
302 
303  //____________________________________________________________________________
305  {
306 
307  fPrevTotPOT = fGENIEHelp->TotalExposure();
308  fPrevTotGoodPOT = fGENIEHelp->TotalExposure();
309 
310  return;
311  }
312 
313  //____________________________________________________________________________
315  {
316 
317  auto p = std::make_unique<sumdata::POTSummary>();
318 
319  p->totpot = fGENIEHelp->TotalExposure() - fPrevTotPOT;
320  p->totgoodpot = fGENIEHelp->TotalExposure() - fPrevTotGoodPOT;
321 
322  sr.put(std::move(p));
323 
324  return;
325  }
326 
327  //____________________________________________________________________________
329  {
330  std::unique_ptr< std::vector<simb::MCTruth> > truthcol (new std::vector<simb::MCTruth>);
331  std::unique_ptr< std::vector<simb::MCFlux> > fluxcol (new std::vector<simb::MCFlux >);
332  std::unique_ptr< std::vector<simb::GTruth> > gtruthcol (new std::vector<simb::GTruth >);
333  std::unique_ptr< art::Assns<simb::MCTruth, simb::MCFlux> > tfassn(new art::Assns<simb::MCTruth, simb::MCFlux>);
334  std::unique_ptr< art::Assns<simb::MCTruth, simb::GTruth> > tgtassn(new art::Assns<simb::MCTruth, simb::GTruth>);
335  std::unique_ptr< std::vector<sim::BeamGateInfo> > gateCollection(new std::vector<sim::BeamGateInfo>);
336 
337  while(truthcol->size() < 1){
338  while(!fGENIEHelp->Stop()){
339 
340  simb::MCTruth truth;
341  simb::MCFlux flux;
342  simb::GTruth gTruth;
343 
344  // GENIEHelper returns a false in the sample method if
345  // either no neutrino was generated, or the interaction
346  // occurred beyond the detector's z extent - ie something we
347  // would never see anyway.
348  if(fGENIEHelp->Sample(truth, flux, gTruth)){
349 
350  truthcol ->push_back(truth);
351  fluxcol ->push_back(flux);
352  gtruthcol->push_back(gTruth);
353  auto const truthPtr = art::PtrMaker<simb::MCTruth>{evt}(truthcol->size() - 1);
354  tfassn->addSingle(truthPtr, art::PtrMaker<simb::MCFlux>{evt}(fluxcol->size() - 1));
355  tgtassn->addSingle(truthPtr, art::PtrMaker<simb::GTruth>{evt}(gtruthcol->size() - 1));
356 
357  FillHistograms(truth);
358 
359  // check that the process code is not unsupported by GENIE
360  // (see issue #18025 for reference);
361  // if it is, print all the information we can about this truth record
362  if (truth.NeutrinoSet() && (truth.GetNeutrino().InteractionType() == simb::kNuanceOffset)) {
363  mf::LogWarning log("GENIEmissingProcessMapping");
364  log << "Found an interaction that is not represented by the interaction type code in GENIE:"
365  "\nMCTruth record:"
366  "\n"
367  ;
368  sim::dump::DumpMCTruth(log, truth, 2U); // 2 trajectory points per line
369  log <<
370  "\nGENIE truth record:"
371  "\n"
372  ;
373  sim::dump::DumpGTruth(log, gTruth);
374  } // if
375 
376  }// end if genie was able to make an event
377 
378  }// end event generation loop
379 
380  // check to see if we are to pass empty spills
381  if(truthcol->size() < 1 && fPassEmptySpills){
382  MF_LOG_DEBUG("GENIEGen") << "no events made for this spill but "
383  << "passing it on and ending the event anyway";
384  break;
385  }
386 
387  }// end loop while no interactions are made
388 
389  // Create a simulated "beam gate" for these neutrino events.
390  // We're creating a vector of these because, in a
391  // distant-but-possible future, we may be generating more than one
392  // beam gate within a simulated time window.
393  gateCollection->push_back(sim::BeamGateInfo( fGlobalTimeOffset, fRandomTimeOffset, fBeamType ));
394 
395  // put the collections in the event
396  evt.put(std::move(truthcol));
397  evt.put(std::move(fluxcol));
398  evt.put(std::move(gtruthcol));
399  evt.put(std::move(tfassn));
400  evt.put(std::move(tgtassn));
401  evt.put(std::move(gateCollection));
402 
403  return;
404  }
405 
406  //......................................................................
408  {
409  int code = StatusCode;
411 
412  switch(code)
413  {
414  case -1:
415  ParticleStatusName = "kIStUndefined";
416  break;
417  case 0:
418  ParticleStatusName = "kIStInitialState";
419  break;
420  case 1:
421  ParticleStatusName = "kIStStableFinalState";
422  break;
423  case 2:
424  ParticleStatusName = "kIStIntermediateState";
425  break;
426  case 3:
427  ParticleStatusName = "kIStDecayedState";
428  break;
429  case 11:
430  ParticleStatusName = "kIStNucleonTarget";
431  break;
432  case 12:
433  ParticleStatusName = "kIStDISPreFragmHadronicState";
434  break;
435  case 13:
436  ParticleStatusName = "kIStPreDecayResonantState";
437  break;
438  case 14:
439  ParticleStatusName = "kIStHadronInTheNucleus";
440  break;
441  case 15:
442  ParticleStatusName = "kIStFinalStateNuclearRemnant";
443  break;
444  case 16:
445  ParticleStatusName = "kIStNucleonClusterTarget";
446  break;
447  default:
448  ParticleStatusName = "Status Unknown";
449  }
450  return ParticleStatusName;
451  }
452 
453  //......................................................................
455  {
456  std::string ReactionChannelName=" ";
457 
458  if(ccnc==0)
459  ReactionChannelName = "kCC";
460  else if(ccnc==1)
461  ReactionChannelName = "kNC";
462  else std::cout<<"Current mode unknown!! "<<std::endl;
463 
464  if(mode==0)
465  ReactionChannelName += "_kQE";
466  else if(mode==1)
467  ReactionChannelName += "_kRes";
468  else if(mode==2)
469  ReactionChannelName += "_kDIS";
470  else if(mode==3)
471  ReactionChannelName += "_kCoh";
472  else std::cout<<"interaction mode unknown!! "<<std::endl;
473 
474  return ReactionChannelName;
475  }
476 
477  //......................................................................
479  {
480  // Decide which histograms to put the spectrum in
481  int id = -1;
482  if (mc.GetNeutrino().CCNC()==simb::kCC) {
483  fCCMode->Fill(mc.GetNeutrino().Mode());
484  if (mc.GetNeutrino().Nu().PdgCode() == 12) id = 0;
485  else if (mc.GetNeutrino().Nu().PdgCode() == -12) id = 1;
486  else if (mc.GetNeutrino().Nu().PdgCode() == 14) id = 2;
487  else if (mc.GetNeutrino().Nu().PdgCode() == -14) id = 3;
488  else return;
489  }
490  else {
491  fNCMode->Fill(mc.GetNeutrino().Mode());
492  if (mc.GetNeutrino().Nu().PdgCode() > 0) id = 4;
493  else id = 5;
494  }
495  if (id==-1) abort();
496 
497  // Fill the specta histograms
498  fGenerated[id]->Fill(mc.GetNeutrino().Nu().E() );
499 
500  ///< fill the vertex histograms from the neutrino - that is always
501  ///< particle 0 in the list
502  simb::MCNeutrino mcnu = mc.GetNeutrino();
503  const simb::MCParticle nu = mcnu.Nu();
504 
505  fVertexX->Fill(nu.Vx());
506  fVertexY->Fill(nu.Vy());
507  fVertexZ->Fill(nu.Vz());
508 
509  fVertexXY->Fill(nu.Vx(), nu.Vy());
510  fVertexXZ->Fill(nu.Vz(), nu.Vx());
511  fVertexYZ->Fill(nu.Vz(), nu.Vy());
512 
513  double mom = nu.P();
514  if(std::abs(mom) > 0.){
515  fDCosX->Fill(nu.Px()/mom);
516  fDCosY->Fill(nu.Py()/mom);
517  fDCosZ->Fill(nu.Pz()/mom);
518  }
519 
520 
521  MF_LOG_DEBUG("GENIEInteractionInformation")
522  << std::endl
523  << "REACTION: " << ReactionChannel(mc.GetNeutrino().CCNC(),mc.GetNeutrino().Mode())
524  << std::endl
525  << "-----------> Particles in the Stack = " << mc.NParticles() << std::endl
526  << std::setiosflags(std::ios::left)
527  << std::setw(20) << "PARTICLE"
528  << std::setiosflags(std::ios::left)
529  << std::setw(32) << "STATUS"
530  << std::setw(18) << "E (GeV)"
531  << std::setw(18) << "m (GeV/c2)"
532  << std::setw(18) << "Ek (GeV)"
533  << std::endl << std::endl;
534 
535  const TDatabasePDG* databasePDG = TDatabasePDG::Instance();
536 
537  // Loop over the particle stack for this event
538  for(int i = 0; i < mc.NParticles(); ++i){
539  simb::MCParticle part(mc.GetParticle(i));
540  std::string name = databasePDG->GetParticle(part.PdgCode())->GetName();
541  int code = part.StatusCode();
543  double mass = part.Mass();
544  double energy = part.E();
545  double Ek = (energy-mass); // Kinetic Energy (GeV)
546  if(status=="kIStStableFinalState"||status=="kIStHadronInTheNucleus")
547  MF_LOG_DEBUG("GENIEFinalState")
548  << std::setiosflags(std::ios::left) << std::setw(20) << name
549  << std::setiosflags(std::ios::left) << std::setw(32) <<status
550  << std::setw(18)<< energy
551  << std::setw(18)<< mass
552  << std::setw(18)<< Ek <<std::endl;
553  else
554  MF_LOG_DEBUG("GENIEFinalState")
555  << std::setiosflags(std::ios::left) << std::setw(20) << name
556  << std::setiosflags(std::ios::left) << std::setw(32) << status
557  << std::setw(18) << energy
558  << std::setw(18) << mass <<std::endl;
559  }
560 
561 
562  if(mc.GetNeutrino().CCNC() == simb::kCC){
563 
564  ///look for the outgoing lepton in the particle stack
565  ///just interested in the first one
566  for(int i = 0; i < mc.NParticles(); ++i){
567  simb::MCParticle part(mc.GetParticle(i));
568  if(abs(part.PdgCode()) == 11){
569  fEMomentum->Fill(part.P());
570  fEDCosX->Fill(part.Px()/part.P());
571  fEDCosY->Fill(part.Py()/part.P());
572  fEDCosZ->Fill(part.Pz()/part.P());
573  fECons->Fill(nu.E() - part.E());
574  break;
575  }
576  else if(abs(part.PdgCode()) == 13){
577  fMuMomentum->Fill(part.P());
578  fMuDCosX->Fill(part.Px()/part.P());
579  fMuDCosY->Fill(part.Py()/part.P());
580  fMuDCosZ->Fill(part.Pz()/part.P());
581  fECons->Fill(nu.E() - part.E());
582  break;
583  }
584  }// end loop over particles
585  }//end if CC interaction
586 
587  return;
588  }
589 
590 }
591 
592 namespace evgen{
593 
595 
596 }
TH1F * fVertexX
vertex location of generated events in x
std::string ParticleStatus(int StatusCode)
static QCString name
Definition: declinfo.cpp:673
double E(const int i=0) const
Definition: MCParticle.h:233
TH1F * fMuDCosZ
direction cosine of outgoing mu in z
TH2F * fVertexXZ
vertex location in xz
int PdgCode() const
Definition: MCParticle.h:212
int CCNC() const
Definition: MCNeutrino.h:148
const simb::MCNeutrino & GetNeutrino() const
Definition: MCTruth.h:77
double Py(const int i=0) const
Definition: MCParticle.h:231
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
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.
Definition: MCDumpers.h:378
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)
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
void beginRun(art::Run &run)
TH1F * fMuDCosY
direction cosine of outgoing mu in y
const simb::MCParticle & Nu() const
Definition: MCNeutrino.h:146
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
double Px(const int i=0) const
Definition: MCParticle.h:230
offset to account for adding in Nuance codes to this enum
Definition: MCNeutrino.h:95
void endSubRun(art::SubRun &sr)
int NParticles() const
Definition: MCTruth.h:75
TGeoManager * ROOTGeoManager() const
Access to the ROOT geometry description manager.
Utility functions to print MC truth information.
TH1F * fNCMode
CC interaction mode.
object containing MC flux information
art framework interface to geometry description
std::string ROOTFile() const
Returns the full directory path to the geometry file source.
Definition: Run.h:17
::sim::BeamType_t fBeamType
The width of a simulated "beam gate".
double TotalMass() const
Returns the total mass [kg] of the specified volume (default: world).
TH1F * fDCosZ
direction cosine in z
int InteractionType() const
Definition: MCNeutrino.h:150
T abs(T value)
void produce(art::Event &evt)
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
TH1F * fEDCosY
direction cosine of outgoing e in y
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
GENIEGen(fhicl::ParameterSet const &pset)
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
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.
def move(depos, offset)
Definition: depos.py:107
double P(const int i=0) const
Definition: MCParticle.h:234
double fGlobalTimeOffset
keep track of how long it takes to run the job
TH1F * fEDCosX
direction cosine of outgoing e in x
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.
Definition: MCDumpers.h:345
p
Definition: test.py:223
TH1F * fGenerated[6]
Spectra as generated.
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
CodeOutputInterface * code
double fPrevTotPOT
The type of beam.
TH1F * fDCosY
direction cosine in y
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
const simb::MCParticle & GetParticle(int i) const
Definition: MCTruth.h:76
double Vx(const int i=0) const
Definition: MCParticle.h:221
TH1F * fEMomentum
momentum of outgoing electrons
BNB.
Definition: BeamTypes.h:11
TH2F * fVertexYZ
vertex location in yz
TH1F * fECons
histogram to determine if energy is conserved in the event
std::optional< T > get_if_present(std::string const &key) const
Definition: ParameterSet.h:224
#define MF_LOG_DEBUG(id)
double Pz(const int i=0) const
Definition: MCParticle.h:232
double Vz(const int i=0) const
Definition: MCParticle.h:223
TH1F * fEDCosZ
direction cosine of outgoing e in z
TH1F * fDCosX
direction cosine in x
list x
Definition: train.py:276
bool NeutrinoSet() const
Definition: MCTruth.h:78
TCEvent evt
Definition: DataStructs.cxx:7
Event generator information.
Definition: MCTruth.h:32
TStopwatch fStopwatch
static constexpr double sr
Definition: Units.h:166
Event generator information.
Definition: MCNeutrino.h:18
LArSoft geometry interface.
Definition: ChannelGeo.h:16
TH1F * fMuMomentum
momentum of outgoing muons
int Mode() const
Definition: MCNeutrino.h:149
Event Generation using GENIE, cosmics or single particles.
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.
Definition: BeamTypes.h:9
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
double Vy(const int i=0) const
Definition: MCParticle.h:222
void put(std::string const &key)
A module to check the results from the Monte Carlo generator.
QTextStream & endl(QTextStream &s)
double fRandomTimeOffset
The start of a simulated "beam gate".