LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
EventGenerator_module.cc
Go to the documentation of this file.
1 //
2 // Generate a very simple event; add it to the event as a data product of type
3 // GenParticleCollection.
4 //
5 
7 
11 
12 #include "CLHEP/Random/RandGaussQ.h"
13 
14 #include <cmath>
15 #include <memory>
16 #include <vector>
17 
18 namespace artg4tk {
19 
21 
22  public:
23  explicit EventGenerator(fhicl::ParameterSet const& pset);
24  virtual ~EventGenerator();
25 
26  void produce(art::Event& event) override;
27 
28  private:
30  int fPDG;
31  double fMass;
32  CLHEP::Hep3Vector fMomentum;
33  CLHEP::Hep3Vector fMomentumSig;
34  CLHEP::Hep3Vector fVertex;
35 
36  CLHEP::RandGaussQ* fRandom;
37  };
38 
39 }
40 
42  : EDProducer{pset}
43  , _nparticles(pset.get<int>("nparticles", 1))
44  , fPDG(pset.get<int>("pdgcode", 2212))
45  , fMass(pset.get<double>("mass", 0.938272))
46  , // mass in GeV !!!
47  fMomentumSig(CLHEP::Hep3Vector(0., 0., 0.))
48  , fVertex(CLHEP::Hep3Vector(0., 0., 0.))
49  , fRandom(0)
50 {
51 
52  std::vector<double> mom = pset.get<std::vector<double>>("momentum");
53  //
54  fMomentum.setX(mom[0]); //*GeV;
55  fMomentum.setY(mom[1]); //*GeV;
56  fMomentum.setZ(mom[2]); //*GeV;
57 
58  std::vector<double> momsig =
59  pset.get<std::vector<double>>("momentum_sigma", std::vector<double>());
60  if (!momsig.empty())
61  fMomentumSig.setX(momsig[0]);
62  if (momsig.size() >= 2)
63  fMomentumSig.setY(momsig[1]);
64  if (momsig.size() >= 3)
65  fMomentumSig.setZ(momsig[2]);
66 
67  std::vector<double> vtx = pset.get<std::vector<double>>("vertex", std::vector<double>());
68  if (!vtx.empty())
69  fVertex.setX(vtx[0]); // in cm
70  if (vtx.size() >= 2)
71  fVertex.setY(vtx[1]); // in cm
72  if (vtx.size() >= 3)
73  fVertex.setZ(vtx[2]); // in cm
74 
75  long seed = pset.get<long>("RNDMSeed", -1);
76  if (seed == -1) {
77  // Construct seed from time and pid. (default behavior if
78  // no seed is provided by the fcl file)
79  // Note: According to Kevin Lynch, the two lines below are not portable.
80  seed = time(0) + getpid();
81  seed =
82  ((seed & 0xFFFF0000) >> 16) | ((seed & 0x0000FFFF) << 16); // exchange upper and lower word
83  seed = seed % 900000000; // ensure the seed is in the correct range for engine
84  }
85 
86  fRandom = new CLHEP::RandGaussQ(
87  createEngine(seed)); // create_engine is inherited from "EngineCreator" base class
88 
89  produces<GenParticleCollection>();
90 }
91 
93 {
94  if (fRandom)
95  delete fRandom;
96 }
97 
98 void
100 {
101  std::unique_ptr<GenParticleCollection> gens(new GenParticleCollection());
102  gens->reserve(_nparticles);
103 
104  if (fPDG == PDGCode::invalid)
105  return;
106 
107  // Apply momentum spread (assume gauss)
108  double tmpx = std::max(0., (fMomentumSig.x() * fRandom->fire() + std::fabs(fMomentum.x())));
109  double tmpy = std::max(0., (fMomentumSig.y() * fRandom->fire() + std::fabs(fMomentum.y())));
110  double tmpz = std::max(0., (fMomentumSig.z() * fRandom->fire() + std::fabs(fMomentum.z())));
111  if (fMomentum.x() < 0.)
112  tmpx *= -1.;
113  if (fMomentum.y() < 0.)
114  tmpy *= -1.;
115  if (fMomentum.z() < 0.)
116  tmpz *= -1.;
117  CLHEP::Hep3Vector tmp(tmpx, tmpy, tmpz);
118 
119  double e = std::sqrt(tmp.mag2() + fMass * fMass);
120  CLHEP::HepLorentzVector mom4(tmp, e);
121  PDGCode::type code = static_cast<PDGCode::type>(fPDG);
122  gens->push_back(GenParticle(code, art::Ptr<GenParticle>(), fVertex, mom4, GenParticle::alive));
123 
124  // Put the output collection into the event.
125  event.put(std::move(gens));
126 }
127 
base_engine_t & createEngine(seed_t seed)
EventGenerator(fhicl::ParameterSet const &pset)
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
Float_t tmp
Definition: plot.C:35
std::vector< GenParticle > GenParticleCollection
void produce(art::Event &event) override
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
long seed
Definition: chem4.cc:67
Float_t e
Definition: plot.C:35
Definition: fwd.h:26
Event finding and building.