CMS 3D CMS Logo

CloseByParticleGunProducer.cc
Go to the documentation of this file.
1 #include <ostream>
2 #include <cmath>
3 
5 
8 
10 
16 
17 #include <CLHEP/Random/RandFlat.h>
18 #include <CLHEP/Units/SystemOfUnits.h>
19 #include <CLHEP/Units/GlobalPhysicalConstants.h>
20 #include <CLHEP/Random/RandFlat.h>
21 
22 using namespace edm;
23 using namespace std;
24 
26  : BaseFlatGunProducer(pset), m_fieldToken(esConsumes()) {
27  ParameterSet pgun_params = pset.getParameter<ParameterSet>("PGunParameters");
28  fControlledByEta = pgun_params.getParameter<bool>("ControlledByEta");
29  fVarMax = pgun_params.getParameter<double>("VarMax");
30  fVarMin = pgun_params.getParameter<double>("VarMin");
31  fMaxVarSpread = pgun_params.getParameter<bool>("MaxVarSpread");
32  fFlatPtGeneration = pgun_params.getParameter<bool>("FlatPtGeneration");
33  if (fVarMin < 1 && !fFlatPtGeneration)
34  LogError("CloseByParticleGunProducer") << " Please choose a minimum energy greater than 1 GeV, otherwise time "
35  "information may be invalid or not reliable";
36  if (fControlledByEta) {
37  fEtaMax = pgun_params.getParameter<double>("MaxEta");
38  fEtaMin = pgun_params.getParameter<double>("MinEta");
39  if (fEtaMax <= fEtaMin)
40  LogError("CloseByParticleGunProducer") << " Please fix MinEta and MaxEta values in the configuration";
41  } else {
42  fRMax = pgun_params.getParameter<double>("RMax");
43  fRMin = pgun_params.getParameter<double>("RMin");
44  if (fRMax <= fRMin)
45  LogError("CloseByParticleGunProducer") << " Please fix RMin and RMax values in the configuration";
46  }
47  fZMax = pgun_params.getParameter<double>("ZMax");
48  fZMin = pgun_params.getParameter<double>("ZMin");
49  fDelta = pgun_params.getParameter<double>("Delta");
50  fPhiMin = pgun_params.getParameter<double>("MinPhi");
51  fPhiMax = pgun_params.getParameter<double>("MaxPhi");
52  fPointing = pgun_params.getParameter<bool>("Pointing");
53  fOverlapping = pgun_params.getParameter<bool>("Overlapping");
55  LogError("CloseByParticleGunProducer")
56  << " Can't generate non pointing FlatPt samples; please disable FlatPt generation or generate pointing sample";
57  fRandomShoot = pgun_params.getParameter<bool>("RandomShoot");
58  fNParticles = pgun_params.getParameter<int>("NParticles");
59  fPartIDs = pgun_params.getParameter<vector<int>>("PartID");
60 
61  // set dt between particles
62  fUseDeltaT = pgun_params.getParameter<bool>("UseDeltaT");
63  fTMax = pgun_params.getParameter<double>("TMax");
64  fTMin = pgun_params.getParameter<double>("TMin");
65  if (fTMax <= fTMin)
66  LogError("CloseByParticleGunProducer") << " Please fix TMin and TMax values in the configuration";
67  // set a fixed time offset for the particles
68  fOffsetFirst = pgun_params.getParameter<double>("OffsetFirst");
69 
70  produces<HepMCProduct>("unsmeared");
71  produces<GenEventInfoProduct>();
72 }
73 
75  // no need to cleanup GenEvent memory - done in HepMCProduct
76 }
77 
80  desc.add<bool>("AddAntiParticle", false);
81  {
83  psd0.add<bool>("ControlledByEta", false);
84  psd0.add<double>("Delta", 10);
85  psd0.add<double>("VarMax", 200.0);
86  psd0.add<double>("VarMin", 25.0);
87  psd0.add<bool>("MaxVarSpread", false);
88  psd0.add<bool>("FlatPtGeneration", false);
89  psd0.add<double>("MaxEta", 2.7);
90  psd0.add<double>("MaxPhi", 3.14159265359);
91  psd0.add<double>("MinEta", 1.7);
92  psd0.add<double>("MinPhi", -3.14159265359);
93  psd0.add<int>("NParticles", 2);
94  psd0.add<bool>("Overlapping", false);
95  psd0.add<std::vector<int>>("PartID",
96  {
97  22,
98  });
99  psd0.add<bool>("Pointing", true);
100  psd0.add<double>("RMax", 120);
101  psd0.add<double>("RMin", 60);
102  psd0.add<bool>("RandomShoot", false);
103  psd0.add<double>("ZMax", 321);
104  psd0.add<double>("ZMin", 320);
105  psd0.add<bool>("UseDeltaT", false);
106  psd0.add<double>("TMin", 0.);
107  psd0.add<double>("TMax", 0.05);
108  psd0.add<double>("OffsetFirst", 0.);
109  desc.add<edm::ParameterSetDescription>("PGunParameters", psd0);
110  }
111  desc.addUntracked<int>("Verbosity", 0);
112  desc.addUntracked<unsigned int>("firstRun", 1);
113  desc.add<std::string>("psethack", "random particles in phi and r windows");
114  descriptions.add("CloseByParticleGunProducer", desc);
115 }
116 
119  CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
120 
121  if (fVerbosity > 0) {
122  LogDebug("CloseByParticleGunProducer") << " CloseByParticleGunProducer : Begin New Event Generation" << endl;
123  }
124  fEvt = new HepMC::GenEvent();
125 
126  auto const& field = es.getData(m_fieldToken);
127 
128  int barcode = 1;
129  unsigned int numParticles = fRandomShoot ? CLHEP::RandFlat::shoot(engine, 1, fNParticles) : fNParticles;
130 
131  double phi = CLHEP::RandFlat::shoot(engine, fPhiMin, fPhiMax);
132  double fZ = CLHEP::RandFlat::shoot(engine, fZMin, fZMax);
133  double fR, fEta;
134  double fT;
135 
136  if (!fControlledByEta) {
137  fR = CLHEP::RandFlat::shoot(engine, fRMin, fRMax);
138  fEta = asinh(fZ / fR);
139  } else {
140  fEta = CLHEP::RandFlat::shoot(engine, fEtaMin, fEtaMax);
141  fR = (fZ / sinh(fEta));
142  }
143 
144  if (fUseDeltaT) {
145  fT = CLHEP::RandFlat::shoot(engine, fTMin, fTMax);
146  } else {
147  fT = 0.;
148  }
149 
150  double tmpPhi = phi;
151  double tmpR = fR;
152 
153  // Loop over particles
154  for (unsigned int ip = 0; ip < numParticles; ++ip) {
155  if (fOverlapping) {
156  fR = CLHEP::RandFlat::shoot(engine, tmpR - fDelta, tmpR + fDelta);
157  phi = CLHEP::RandFlat::shoot(engine, tmpPhi - fDelta / fR, tmpPhi + fDelta / fR);
158  } else
159  phi += fDelta / fR;
160 
161  double fVar;
162  if (numParticles > 1 && fMaxVarSpread)
163  fVar = fVarMin + ip * (fVarMax - fVarMin) / (numParticles - 1);
164  else
165  fVar = CLHEP::RandFlat::shoot(engine, fVarMin, fVarMax);
166 
167  int partIdx = CLHEP::RandFlat::shoot(engine, 0, fPartIDs.size());
168  int PartID = fPartIDs[partIdx];
169  const HepPDT::ParticleData* PData = fPDGTable->particle(HepPDT::ParticleID(abs(PartID)));
170  double mass = PData->mass().value();
171 
172  double mom, px, py, pz;
173  double energy;
174 
175  if (!fFlatPtGeneration) {
176  double mom2 = fVar * fVar - mass * mass;
177  mom = 0.;
178  if (mom2 > 0.) {
179  mom = sqrt(mom2);
180  }
181  px = 0.;
182  py = 0.;
183  pz = mom;
184  energy = fVar;
185  } else {
186  double theta = 2. * atan(exp(-fEta));
187  mom = fVar / sin(theta);
188  px = fVar * cos(phi);
189  py = fVar * sin(phi);
190  pz = mom * cos(theta);
191  double energy2 = mom * mom + mass * mass;
192  energy = sqrt(energy2);
193  }
194  // Compute Vertex Position
195  double x = fR * cos(phi);
196  double y = fR * sin(phi);
197 
198  HepMC::FourVector p(px, py, pz, energy);
199  // If we are requested to be pointing to (0,0,0), correct the momentum direction
200  if (fPointing) {
201  math::XYZVector direction(x, y, fZ);
202  math::XYZVector momentum = direction.unit() * mom;
203  p.setX(momentum.x());
204  p.setY(momentum.y());
205  p.setZ(momentum.z());
206  }
207 
208  // compute correct path assuming uniform magnetic field in CMS
209  double pathLength = 0.;
210  const double speed = p.pz() / p.e() * c_light / CLHEP::cm;
211  if (PData->charge()) {
212  // Radius [cm] = P[GeV/c] * 10^9 / (c[mm/ns] * 10^6 * q[C] * B[T]) * 100[cm/m]
213  const double radius = std::sqrt(p.px() * p.px() + p.py() * p.py()) * std::pow(10, 5) /
214  (c_light * field.inTesla({0.f, 0.f, 0.f}).z()); // cm
215  const double arc = 2 * asinf(std::sqrt(x * x + y * y) / (2 * radius)) * radius;
216  pathLength = std::sqrt(arc * arc + fZ * fZ);
217  } else {
218  pathLength = std::sqrt(x * x + y * y + fZ * fZ);
219  }
220 
221  // if not pointing time doesn't mean a lot, keep the old way
222  const double pathTime = fPointing ? (pathLength / speed) : (std::sqrt(x * x + y * y + fZ * fZ) / speed);
223  double timeOffset = fOffsetFirst + (pathTime + ip * fT) * CLHEP::ns * c_light;
224 
225  HepMC::GenVertex* Vtx =
226  new HepMC::GenVertex(HepMC::FourVector(x * CLHEP::cm, y * CLHEP::cm, fZ * CLHEP::cm, timeOffset));
227 
229  Part->suggest_barcode(barcode);
230  barcode++;
231 
232  Vtx->add_particle_out(Part);
233 
234  if (fVerbosity > 0) {
235  Vtx->print();
236  Part->print();
237  }
238  fEvt->add_vertex(Vtx);
239  }
240 
241  fEvt->set_event_number(e.id().event());
242  fEvt->set_signal_process_id(20);
243 
244  if (fVerbosity > 0) {
245  fEvt->print();
246  }
247 
248  unique_ptr<HepMCProduct> BProduct(new HepMCProduct());
249  BProduct->addHepMCData(fEvt);
250  e.put(std::move(BProduct), "unsmeared");
251 
252  unique_ptr<GenEventInfoProduct> genEventInfo(new GenEventInfoProduct(fEvt));
253  e.put(std::move(genEventInfo));
254 
255  if (fVerbosity > 0) {
256  LogDebug("CloseByParticleGunProducer") << " CloseByParticleGunProducer : Event Generation Done " << endl;
257  }
258 }
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
static void fillDescriptions(ConfigurationDescriptions &descriptions)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
static unsigned int partIdx(const InputGenJetsParticleSelector::ParticleVector &p, const reco::Candidate *particle)
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Log< level::Error, false > LogError
virtual CLHEP::HepRandomEngine & getEngine(StreamID const &)=0
Use this engine in event methods.
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > m_fieldToken
ESHandle< HepPDT::ParticleDataTable > fPDGTable
T sqrt(T t)
Definition: SSEVec.h:23
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void produce(Event &e, const EventSetup &es) override
ParameterDescriptionBase * add(U const &iLabel, T const &value)
HepPDT::ParticleData ParticleData
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
void add(std::string const &label, ParameterSetDescription const &psetDescription)
HLT enums.
float x
Geom::Theta< T > theta() const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
def move(src, dest)
Definition: eostools.py:511
float fEta(int hwEta)
Definition: conversion.h:17
#define LogDebug(id)