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/GlobalSystemOfUnits.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  fEnMax = pgun_params.getParameter<double>("EnMax");
30  fEnMin = pgun_params.getParameter<double>("EnMin");
31  if (fEnMin < 1)
32  LogError("CloseByParticleGunProducer") << " Please choose a minimum energy greater than 1 GeV, otherwise time "
33  "information may be invalid or not reliable";
34 
35  fMaxEnSpread = pgun_params.getParameter<bool>("MaxEnSpread");
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");
54  fRandomShoot = pgun_params.getParameter<bool>("RandomShoot");
55  fNParticles = pgun_params.getParameter<int>("NParticles");
56  fPartIDs = pgun_params.getParameter<vector<int>>("PartID");
57 
58  // set dt between particles
59  fUseDeltaT = pgun_params.getParameter<bool>("UseDeltaT");
60  fTMax = pgun_params.getParameter<double>("TMax");
61  fTMin = pgun_params.getParameter<double>("TMin");
62  if (fTMax <= fTMin)
63  LogError("CloseByParticleGunProducer") << " Please fix TMin and TMax values in the configuration";
64  // set a fixed time offset for the particles
65  fOffsetFirst = pgun_params.getParameter<double>("OffsetFirst");
66 
67  produces<HepMCProduct>("unsmeared");
68  produces<GenEventInfoProduct>();
69 }
70 
72  // no need to cleanup GenEvent memory - done in HepMCProduct
73 }
74 
77  desc.add<bool>("AddAntiParticle", false);
78  {
80  psd0.add<bool>("ControlledByEta", false);
81  psd0.add<double>("Delta", 10);
82  psd0.add<double>("EnMax", 200.0);
83  psd0.add<double>("EnMin", 25.0);
84  psd0.add<bool>("MaxEnSpread", false);
85  psd0.add<double>("MaxEta", 2.7);
86  psd0.add<double>("MaxPhi", 3.14159265359);
87  psd0.add<double>("MinEta", 1.7);
88  psd0.add<double>("MinPhi", -3.14159265359);
89  psd0.add<int>("NParticles", 2);
90  psd0.add<bool>("Overlapping", false);
91  psd0.add<std::vector<int>>("PartID",
92  {
93  22,
94  });
95  psd0.add<bool>("Pointing", true);
96  psd0.add<double>("RMax", 120);
97  psd0.add<double>("RMin", 60);
98  psd0.add<bool>("RandomShoot", false);
99  psd0.add<double>("ZMax", 321);
100  psd0.add<double>("ZMin", 320);
101  psd0.add<bool>("UseDeltaT", false);
102  psd0.add<double>("TMin", 0.);
103  psd0.add<double>("TMax", 0.05);
104  psd0.add<double>("OffsetFirst", 0.);
105  desc.add<edm::ParameterSetDescription>("PGunParameters", psd0);
106  }
107  desc.addUntracked<int>("Verbosity", 0);
108  desc.addUntracked<unsigned int>("firstRun", 1);
109  desc.add<std::string>("psethack", "random particles in phi and r windows");
110  descriptions.add("CloseByParticleGunProducer", desc);
111 }
112 
115  CLHEP::HepRandomEngine* engine = &rng->getEngine(e.streamID());
116 
117  if (fVerbosity > 0) {
118  LogDebug("CloseByParticleGunProducer") << " CloseByParticleGunProducer : Begin New Event Generation" << endl;
119  }
120  fEvt = new HepMC::GenEvent();
121 
122  auto const& field = es.getData(m_fieldToken);
123 
124  int barcode = 1;
125  unsigned int numParticles = fRandomShoot ? CLHEP::RandFlat::shoot(engine, 1, fNParticles) : fNParticles;
126 
127  double phi = CLHEP::RandFlat::shoot(engine, fPhiMin, fPhiMax);
128  double fZ = CLHEP::RandFlat::shoot(engine, fZMin, fZMax);
129  double fR;
130  double fT;
131 
132  if (!fControlledByEta) {
133  fR = CLHEP::RandFlat::shoot(engine, fRMin, fRMax);
134  } else {
135  double fEta = CLHEP::RandFlat::shoot(engine, fEtaMin, fEtaMax);
136  fR = (fZ / sinh(fEta));
137  }
138 
139  if (fUseDeltaT) {
140  fT = CLHEP::RandFlat::shoot(engine, fTMin, fTMax);
141  } else {
142  fT = 0.;
143  }
144 
145  double tmpPhi = phi;
146  double tmpR = fR;
147 
148  // Loop over particles
149  for (unsigned int ip = 0; ip < numParticles; ++ip) {
150  if (fOverlapping) {
151  fR = CLHEP::RandFlat::shoot(engine, tmpR - fDelta, tmpR + fDelta);
152  phi = CLHEP::RandFlat::shoot(engine, tmpPhi - fDelta / fR, tmpPhi + fDelta / fR);
153  } else
154  phi += fDelta / fR;
155 
156  double fEn;
157  if (numParticles > 1 && fMaxEnSpread)
158  fEn = fEnMin + ip * (fEnMax - fEnMin) / (numParticles - 1);
159  else
160  fEn = CLHEP::RandFlat::shoot(engine, fEnMin, fEnMax);
161 
162  int partIdx = CLHEP::RandFlat::shoot(engine, 0, fPartIDs.size());
163  int PartID = fPartIDs[partIdx];
164  const HepPDT::ParticleData* PData = fPDGTable->particle(HepPDT::ParticleID(abs(PartID)));
165  double mass = PData->mass().value();
166  double mom2 = fEn * fEn - mass * mass;
167  double mom = 0.;
168  if (mom2 > 0.) {
169  mom = sqrt(mom2);
170  }
171  double px = 0.;
172  double py = 0.;
173  double pz = mom;
174  double energy = fEn;
175 
176  // Compute Vertex Position
177  double x = fR * cos(phi);
178  double y = fR * sin(phi);
179 
180  HepMC::FourVector p(px, py, pz, energy);
181  // If we are requested to be pointing to (0,0,0), correct the momentum direction
182  if (fPointing) {
183  math::XYZVector direction(x, y, fZ);
184  math::XYZVector momentum = direction.unit() * mom;
185  p.setX(momentum.x());
186  p.setY(momentum.y());
187  p.setZ(momentum.z());
188  }
189 
190  // compute correct path assuming uniform magnetic field in CMS
191  double pathLength = 0.;
192  const double speed = p.pz() / p.e() * c_light / cm;
193  if (PData->charge()) {
194  // Radius [cm] = P[GeV/c] * 10^9 / (c[mm/ns] * 10^6 * q[C] * B[T]) * 100[cm/m]
195  const double radius = std::sqrt(p.px() * p.px() + p.py() * p.py()) * std::pow(10, 5) /
196  (c_light * field.inTesla({0.f, 0.f, 0.f}).z()); // cm
197  const double arc = 2 * asinf(std::sqrt(x * x + y * y) / (2 * radius)) * radius;
198  pathLength = std::sqrt(arc * arc + fZ * fZ);
199  } else {
200  pathLength = std::sqrt(x * x + y * y + fZ * fZ);
201  }
202 
203  // if not pointing time doesn't mean a lot, keep the old way
204  const double pathTime = fPointing ? (pathLength / speed) : (std::sqrt(x * x + y * y + fZ * fZ) / speed);
205  double timeOffset = fOffsetFirst + (pathTime + ip * fT) * ns * c_light;
206 
207  HepMC::GenVertex* Vtx = new HepMC::GenVertex(HepMC::FourVector(x * cm, y * cm, fZ * cm, timeOffset));
208 
210  Part->suggest_barcode(barcode);
211  barcode++;
212 
213  Vtx->add_particle_out(Part);
214 
215  if (fVerbosity > 0) {
216  Vtx->print();
217  Part->print();
218  }
219  fEvt->add_vertex(Vtx);
220  }
221 
222  fEvt->set_event_number(e.id().event());
223  fEvt->set_signal_process_id(20);
224 
225  if (fVerbosity > 0) {
226  fEvt->print();
227  }
228 
229  unique_ptr<HepMCProduct> BProduct(new HepMCProduct());
230  BProduct->addHepMCData(fEvt);
231  e.put(std::move(BProduct), "unsmeared");
232 
233  unique_ptr<GenEventInfoProduct> genEventInfo(new GenEventInfoProduct(fEvt));
234  e.put(std::move(genEventInfo));
235 
236  if (fVerbosity > 0) {
237  LogDebug("CloseByParticleGunProducer") << " CloseByParticleGunProducer : Event Generation Done " << endl;
238  }
239 }
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
constexpr int pow(int x)
Definition: conifer.h:24
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:19
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
def move(src, dest)
Definition: eostools.py:511
#define LogDebug(id)