All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NucleonDecay_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: NucleonDecay
3 // Module Type: producer
4 // GENIE nucleon decay generator
5 //
6 // Converted from gNucleonDecayEvGen.cxx by
7 // tjyang@fnal.gov
8 //
9 // 2016 PDG numbering scheme in pp.8-10 of
10 // http://www-pdg.lbl.gov/2016/listings/rpp2016-list-p.pdf (tau1 through tau60)
11 //
12 ////////////////////////////////////////////////////////////////////////
13 
14 #include "art/Framework/Core/EDProducer.h"
15 #include "art/Framework/Core/ModuleMacros.h"
16 #include "art/Framework/Principal/Event.h"
17 #include "art/Framework/Principal/Run.h"
18 #include "art/Framework/Services/Registry/ServiceHandle.h"
19 #include "fhiclcpp/ParameterSet.h"
20 #include "messagefacility/MessageLogger/MessageLogger.h"
21 
22 // GENIE includes
23 #include "Framework/Algorithm/AlgFactory.h"
24 #include "Framework/EventGen/EventRecordVisitorI.h"
25 #include "Framework/EventGen/EventRecord.h"
26 #include "Physics/NucleonDecay/NucleonDecayMode.h"
27 #include "Physics/NucleonDecay/NucleonDecayUtils.h"
28 #include "Framework/ParticleData/PDGLibrary.h"
29 #include "Framework/GHEP/GHepParticle.h"
30 #include "Framework/Utils/AppInit.h"
31 
32 // larsoft includes
33 #include "nusimdata/SimulationBase/MCTruth.h"
34 #include "nusimdata/SimulationBase/MCParticle.h"
35 
36 #include "nugen/EventGeneratorBase/GENIE/GENIE2ART.h"
37 
40 #include "nurandom/RandomUtils/NuRandomService.h"
41 
42 // c++ includes
43 #include <memory>
44 #include <string>
45 
46 #include "CLHEP/Random/RandFlat.h"
47 
48 namespace evgen {
49  class NucleonDecay;
50 }
51 
52 class evgen::NucleonDecay : public art::EDProducer {
53 public:
54  explicit NucleonDecay(fhicl::ParameterSet const & p);
55  // The destructor generated by the compiler is fine for classes
56  // without bare pointers or other resource use.
57 
58  // Plugins should not be copied or assigned.
59  NucleonDecay(NucleonDecay const &) = delete;
60  NucleonDecay(NucleonDecay &&) = delete;
61  NucleonDecay & operator = (NucleonDecay const &) = delete;
62  NucleonDecay & operator = (NucleonDecay &&) = delete;
63 
64  // Required functions.
65  void produce(art::Event & e) override;
66 
67  // Selected optional functions.
68  void beginRun(art::Run& run) override;
69 
70 private:
71 
72  // Declare member data here.
73  const genie::EventRecordVisitorI * mcgen;
74  genie::NucleonDecayMode_t gOptDecayMode = genie::kNDNull; // nucleon decay mode
75  int dpdg = 0;
76  CLHEP::RandFlat flatDist;
77 };
78 
79 
80 evgen::NucleonDecay::NucleonDecay(fhicl::ParameterSet const & p)
81  : art::EDProducer{p}
82  // create a default random engine; obtain the random seed from NuRandomService,
83  // unless overridden in configuration with key "Seed"
84  , flatDist{art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*this, p, "Seed")}
85 {
86  genie::PDGLibrary::Instance(); //Ensure Messenger is started first in GENIE.
87 
88  string sname = "genie::EventGenerator";
89  string sconfig = "NucleonDecay";
90  // GENIE v3 needs a tune (even if irrelevant)
91  evgb::SetEventGeneratorListAndTune("Default","Default");
92 
93  genie::AlgFactory * algf = genie::AlgFactory::Instance();
95  dynamic_cast<const genie::EventRecordVisitorI *> (algf->GetAlgorithm(sname,sconfig));
96  if(!mcgen) {
97  throw cet::exception("NucleonDecay") << "Couldn't instantiate the nucleon decay generator";
98  }
99  int fDecayMode = p.get<int>("DecayMode");
100  gOptDecayMode = (genie::NucleonDecayMode_t) fDecayMode;
101 
102  if (p.get<int>("DecayedNucleon") > 0 ){
103  dpdg = p.get<int>("DecayedNucleon");
104  }
105  else{
106  dpdg = genie::utils::nucleon_decay::DecayedNucleonPdgCode(gOptDecayMode);
107  }
108 
109  produces< std::vector<simb::MCTruth> >();
111 
112  unsigned int seed = art::ServiceHandle<rndm::NuRandomService>()->getSeed();
113  genie::utils::app_init::RandGen(seed);
114 }
115 
116 void evgen::NucleonDecay::produce(art::Event & e)
117 {
118  // Implementation of required member function here.
119  genie::EventRecord * event = new genie::EventRecord;
120  int target = 1000180400; //Only use argon target
121  int decay = (int)gOptDecayMode;
122  genie::Interaction * interaction = genie::Interaction::NDecay(target,decay,dpdg);
123  event->AttachSummary(interaction);
124 
125  // Simulate decay
126  mcgen->ProcessEventRecord(event);
127 
128 // genie::Interaction *inter = event->Summary();
129 // const genie::InitialState &initState = inter->InitState();
130 // std::cout<<"initState = "<<initState.AsString()<<std::endl;
131 // const genie::ProcessInfo &procInfo = inter->ProcInfo();
132 // std::cout<<"procInfo = "<<procInfo.AsString()<<std::endl;
133  MF_LOG_DEBUG("NucleonDecay")
134  << "Generated event: " << *event;
135 
136  std::unique_ptr< std::vector<simb::MCTruth> > truthcol(new std::vector<simb::MCTruth>);
137  simb::MCTruth truth;
138 
139  art::ServiceHandle<geo::Geometry const> geo;
140 
141  // Find boundary of active volume
142  double minx = 1e9;
143  double maxx = -1e9;
144  double miny = 1e9;
145  double maxy = -1e9;
146  double minz = 1e9;
147  double maxz = -1e9;
148  for (size_t i = 0; i<geo->NTPC(); ++i){
149  const geo::TPCGeo &tpc = geo->TPC(i);
150  if (minx>tpc.MinX()) minx = tpc.MinX();
151  if (maxx<tpc.MaxX()) maxx = tpc.MaxX();
152  if (miny>tpc.MinY()) miny = tpc.MinY();
153  if (maxy<tpc.MaxY()) maxy = tpc.MaxY();
154  if (minz>tpc.MinZ()) minz = tpc.MinZ();
155  if (maxz<tpc.MaxZ()) maxz = tpc.MaxZ();
156  }
157 
158  // Assign vertice position
159  double X0 = flatDist.fire( minx, maxx );
160  double Y0 = flatDist.fire( miny, maxy );
161  double Z0 = flatDist.fire( minz, maxz );
162 
163  TIter partitr(event);
164  genie::GHepParticle *part = 0;
165  // GHepParticles return units of GeV/c for p. the V_i are all in fermis
166  // and are relative to the center of the struck nucleus.
167  // add the vertex X/Y/Z to the V_i for status codes 0 and 1
168  int trackid = 0;
169  std::string primary("primary");
170 
171  while( (part = dynamic_cast<genie::GHepParticle *>(partitr.Next())) ){
172 
173  simb::MCParticle tpart(trackid,
174  part->Pdg(),
175  primary,
176  part->FirstMother(),
177  part->Mass(),
178  part->Status());
179 
180  TLorentzVector pos(X0, Y0, Z0, 0);
181  TLorentzVector mom(part->Px(), part->Py(), part->Pz(), part->E());
182  tpart.AddTrajectoryPoint(pos,mom);
183  if(part->PolzIsSet()) {
184  TVector3 polz;
185  part->GetPolarization(polz);
186  tpart.SetPolarization(polz);
187  }
188  tpart.SetRescatter(part->RescatterCode());
189  truth.Add(tpart);
190 
191  ++trackid;
192  }// end loop to convert GHepParticles to MCParticles
193  truth.SetOrigin(simb::kUnknown);
194  truthcol->push_back(truth);
195  //FillHistograms(truth);
196  e.put(std::move(truthcol));
197 
198  delete event;
199 }
200 
201 void evgen::NucleonDecay::beginRun(art::Run& run)
202 {
203  art::ServiceHandle<geo::Geometry const> geo;
204  run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
205 }
206 
207 DEFINE_ART_MODULE(evgen::NucleonDecay)
genie::NucleonDecayMode_t gOptDecayMode
NucleonDecay(fhicl::ParameterSet const &p)
CLHEP::RandFlat flatDist
gOptDecayMode
process_name opdaq physics producers generator physics producers generator physics producers generator Z0
Definition: gen_protons.fcl:45
const genie::EventRecordVisitorI * mcgen
pdgs p
Definition: selectors.fcl:22
double MinX() const
Returns the world x coordinate of the start of the box.
Definition: BoxBoundedGeo.h:88
string sconfig
Geometry information for a single TPC.
Definition: TPCGeo.h:38
produces< sumdata::RunData, art::InRun >()
double MaxX() const
Returns the world x coordinate of the end of the box.
Definition: BoxBoundedGeo.h:91
process_name opdaq physics producers generator physics producers generator Y0
Definition: gen_protons.fcl:45
int fDecayMode
void beginRun(art::Run &run) override
standard_singlep gaussian distribution X0
Definition: multigen.fcl:8
double MinZ() const
Returns the world z coordinate of the start of the box.
unsigned int seed
string sname
void produce(art::Event &e) override
double MaxY() const
Returns the world y coordinate of the end of the box.
NucleonDecay & operator=(NucleonDecay const &)=delete
double MaxZ() const
Returns the world z coordinate of the end of the box.
genie::AlgFactory * algf
do i e
double MinY() const
Returns the world y coordinate of the start of the box.
art framework interface to geometry description