CMS 3D CMS Logo

VertexClassifier.cc
Go to the documentation of this file.
1 /*
2  * VertexClassifier.C
3  */
4 
5 #include <cmath>
6 #include <cstdlib>
7 #include <iostream>
8 
9 #include "HepPDT/ParticleID.hh"
10 
12 
13 #define update(a, b) \
14  do { \
15  (a) = (a) || (b); \
16  } while (0)
17 
19  : VertexCategories(),
20  tracer_(config, collector),
21  hepMCLabel_(config.getUntrackedParameter<edm::InputTag>("hepMC")),
22  particleDataTableToken_(collector.esConsumes()) {
24  // Set the history depth after hadronization
25  tracer_.depth(-2);
26 
27  // Set the minimum decay length for detecting long decays
28  longLivedDecayLength_ = config.getUntrackedParameter<double>("longLivedDecayLength");
29 
30  // Set the distance for clustering vertices
31  vertexClusteringDistance_ = config.getUntrackedParameter<double>("vertexClusteringDistance");
32 }
33 
35  // Get the new event information for the tracer
37 
38  // Get hepmc of the event
39  event.getByLabel(hepMCLabel_, mcInformation_);
40 
41  // Get the partivle data table
43 
44  // Create the list of primary vertices associated to the event
46 }
47 
49  // Initializing the category vector
50  reset();
51 
52  // Associate and evaluate the vertex history (check for fakes)
53  if (tracer_.evaluate(vertex)) {
54  // Get all the information related to the simulation details
56 
57  // Get all the information related to decay process
59 
60  // Get information about conversion and other interactions
62 
63  // Get geometrical information about the vertices
65 
66  // Check for unkown classification
67  unknownVertex();
68  } else
69  flags_[Fake] = true;
70 
71  return *this;
72 }
73 
75  // Initializing the category vector
76  reset();
77 
78  // Trace the history for the given TP
80 
81  // Check for a reconstructed track
83  flags_[Reconstructed] = true;
84  else
85  flags_[Reconstructed] = false;
86 
87  // Get all the information related to the simulation details
89 
90  // Get all the information related to decay process
92 
93  // Get information about conversion and other interactions
95 
96  // Get geometrical information about the vertices
98 
99  // Check for unkown classification
100  unknownVertex();
101 
102  return *this;
103 }
104 
106  // Get the event id for the initial TP.
107  EncodedEventId eventId = tracer_.simVertex()->eventId();
108  // Check for signal events
109  flags_[SignalEvent] = !eventId.bunchCrossing() && !eventId.event();
110 }
111 
113  // Get the generated vetices from track history
114  VertexHistory::GenVertexTrail const &genVertexTrail = tracer_.genVertexTrail();
115 
116  // Loop over the generated vertices
117  for (VertexHistory::GenVertexTrail::const_iterator ivertex = genVertexTrail.begin(); ivertex != genVertexTrail.end();
118  ++ivertex) {
119  // Get the pointer to the vertex by removing the const-ness (no const methos
120  // in HepMC::GenVertex)
121  HepMC::GenVertex *vertex = const_cast<HepMC::GenVertex *>(*ivertex);
122 
123  // Loop over the sources looking for specific decays
124  for (HepMC::GenVertex::particle_iterator iparent = vertex->particles_begin(HepMC::parents);
125  iparent != vertex->particles_end(HepMC::parents);
126  ++iparent) {
127  // Collect the pdgid of the parent
128  int pdgid = std::abs((*iparent)->pdg_id());
129  // Get particle type
131 
132  // Check if the particle type is valid one
133  if (particleID.isValid()) {
134  // Get particle data
135  ParticleData const *particleData = particleDataTable_->particle(particleID);
136  // Check if the particle exist in the table
137  if (particleData) {
138  // Check if their life time is bigger than longLivedDecayLength_
139  if (particleData->lifetime() > longLivedDecayLength_) {
140  // Check for B, C weak decays and long lived decays
141  update(flags_[BWeakDecay], particleID.hasBottom());
142  update(flags_[CWeakDecay], particleID.hasCharm());
143  update(flags_[LongLivedDecay], true);
144  }
145  // Check Tau, Ks and Lambda decay
146  update(flags_[TauDecay], pdgid == 15);
147  update(flags_[KsDecay], pdgid == 310);
148  update(flags_[LambdaDecay], pdgid == 3122);
149  update(flags_[JpsiDecay], pdgid == 443);
150  update(flags_[XiDecay], pdgid == 3312);
151  update(flags_[OmegaDecay], pdgid == 3334);
152  update(flags_[SigmaPlusDecay], pdgid == 3222);
153  update(flags_[SigmaMinusDecay], pdgid == 3112);
154  }
155  }
156  }
157  }
158 }
159 
161  VertexHistory::SimVertexTrail const &simVertexTrail = tracer_.simVertexTrail();
162 
163  for (VertexHistory::SimVertexTrail::const_iterator ivertex = simVertexTrail.begin(); ivertex != simVertexTrail.end();
164  ++ivertex) {
165  // pdgid of the real source parent vertex
166  int pdgid = 0;
167 
168  // select the original source in case of combined vertices
169  bool flag = false;
171 
172  for (its = (*ivertex)->sourceTracks_begin(); its != (*ivertex)->sourceTracks_end(); ++its) {
173  for (itd = (*ivertex)->daughterTracks_begin(); itd != (*ivertex)->daughterTracks_end(); ++itd)
174  if (itd != its) {
175  flag = true;
176  break;
177  }
178  if (flag)
179  break;
180  }
181  // Collect the pdgid of the original source track
182  if (its != (*ivertex)->sourceTracks_end())
183  pdgid = std::abs((*its)->pdgId());
184  else
185  pdgid = 0;
186 
187  // Geant4 process type is selected using first Geant4 vertex assigned to
188  // the TrackingVertex
189  unsigned int processG4 = 0;
190 
191  if ((*ivertex)->nG4Vertices() > 0) {
192  processG4 = (*(*ivertex)->g4Vertices_begin()).processType();
193  }
194 
195  unsigned int process = g4toCMSProcMap_.processId(processG4);
196 
197  // Flagging all the different processes
199 
217 
218  // Loop over the simulated particles
219  for (TrackingVertex::tp_iterator iparticle = (*ivertex)->daughterTracks_begin();
220  iparticle != (*ivertex)->daughterTracks_end();
221  ++iparticle) {
222  if ((*iparticle)->numberOfTrackerLayers()) {
223  // Special treatment for decays
224  if (process == CMS::Decay) {
225  // Get particle type
227  // Check if the particle type is valid one
228  if (particleID.isValid()) {
229  // Get particle data
230  ParticleData const *particleData = particleDataTable_->particle(particleID);
231  // Check if the particle exist in the table
232  if (particleData) {
233  // Check if their life time is bigger than 1e-14
234  if (particleDataTable_->particle(particleID)->lifetime() > longLivedDecayLength_) {
235  // Check for B, C weak decays and long lived decays
236  update(flags_[BWeakDecay], particleID.hasBottom());
237  update(flags_[CWeakDecay], particleID.hasCharm());
238  update(flags_[LongLivedDecay], true);
239  }
240  // Check Tau, Ks and Lambda decay
241  update(flags_[TauDecay], pdgid == 15);
242  update(flags_[KsDecay], pdgid == 310);
243  update(flags_[LambdaDecay], pdgid == 3122);
244  update(flags_[JpsiDecay], pdgid == 443);
245  update(flags_[XiDecay], pdgid == 3312);
246  update(flags_[OmegaDecay], pdgid == 3334);
247  update(flags_[SigmaPlusDecay], pdgid == 3222);
248  update(flags_[SigmaMinusDecay], pdgid == 3112);
249  }
250  }
251  }
252  }
253  }
254  }
255 }
256 
258  // Helper class for clusterization
259  typedef std::multimap<double, HepMC::ThreeVector> Clusters;
260  typedef std::pair<double, HepMC::ThreeVector> ClusterPair;
261 
263 
264  // Get the main primary vertex from the list
265  GeneratedPrimaryVertex const &genpv = genpvs_.back();
266 
267  // Get the generated history of the tracks
268  const VertexHistory::GenVertexTrail &genVertexTrail = tracer_.genVertexTrail();
269 
270  // Unit transformation from mm to cm
271  double const mm = 0.1;
272 
273  // Loop over the generated vertexes
274  for (VertexHistory::GenVertexTrail::const_iterator ivertex = genVertexTrail.begin(); ivertex != genVertexTrail.end();
275  ++ivertex) {
276  // Check vertex exist
277  if (*ivertex) {
278  // Measure the distance2 respecto the primary vertex
279  HepMC::ThreeVector p = (*ivertex)->point3d();
280  double distance =
281  sqrt(pow(p.x() * mm - genpv.x, 2) + pow(p.y() * mm - genpv.y, 2) + pow(p.z() * mm - genpv.z, 2));
282 
283  // If there is not any clusters add the first vertex.
284  if (clusters.empty()) {
285  clusters.insert(ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)));
286  continue;
287  }
288 
289  // Check if there is already a cluster in the given distance from primary
290  // vertex
291  Clusters::const_iterator icluster = clusters.lower_bound(distance - vertexClusteringDistance_);
292 
293  if (icluster == clusters.upper_bound(distance + vertexClusteringDistance_)) {
294  clusters.insert(ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)));
295  continue;
296  }
297 
298  bool cluster = false;
299 
300  // Looping over the vertex clusters of a given distance from primary
301  // vertex
302  for (; icluster != clusters.upper_bound(distance + vertexClusteringDistance_); ++icluster) {
303  double difference = sqrt(pow(p.x() * mm - icluster->second.x(), 2) + pow(p.y() * mm - icluster->second.y(), 2) +
304  pow(p.z() * mm - icluster->second.z(), 2));
305 
306  if (difference < vertexClusteringDistance_) {
307  cluster = true;
308  break;
309  }
310  }
311 
312  if (!cluster)
313  clusters.insert(ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)));
314  }
315  }
316 
317  const VertexHistory::SimVertexTrail &simVertexTrail = tracer_.simVertexTrail();
318 
319  // Loop over the generated particles
320  for (VertexHistory::SimVertexTrail::const_reverse_iterator ivertex = simVertexTrail.rbegin();
321  ivertex != simVertexTrail.rend();
322  ++ivertex) {
323  // Look for those with production vertex
324  TrackingVertex::LorentzVector p = (*ivertex)->position();
325 
326  double distance = sqrt(pow(p.x() - genpv.x, 2) + pow(p.y() - genpv.y, 2) + pow(p.z() - genpv.z, 2));
327 
328  // If there is not any clusters add the first vertex.
329  if (clusters.empty()) {
330  clusters.insert(ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())));
331  continue;
332  }
333 
334  // Check if there is already a cluster in the given distance from primary
335  // vertex
336  Clusters::const_iterator icluster = clusters.lower_bound(distance - vertexClusteringDistance_);
337 
338  if (icluster == clusters.upper_bound(distance + vertexClusteringDistance_)) {
339  clusters.insert(ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())));
340  continue;
341  }
342 
343  bool cluster = false;
344 
345  // Looping over the vertex clusters of a given distance from primary vertex
346  for (; icluster != clusters.upper_bound(distance + vertexClusteringDistance_); ++icluster) {
347  double difference = sqrt(pow(p.x() - icluster->second.x(), 2) + pow(p.y() - icluster->second.y(), 2) +
348  pow(p.z() - icluster->second.z(), 2));
349 
350  if (difference < vertexClusteringDistance_) {
351  cluster = true;
352  break;
353  }
354  }
355 
356  if (!cluster)
357  clusters.insert(ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())));
358  }
359 
360  if (clusters.size() == 1)
361  flags_[PrimaryVertex] = true;
362  else if (clusters.size() == 2)
363  flags_[SecondaryVertex] = true;
364  else
365  flags_[TertiaryVertex] = true;
366 }
367 
369  return !p->end_vertex() && p->status() == 1;
370 }
371 
373  const ParticleData *part = particleDataTable_->particle(p->pdg_id());
374  if (part)
375  return part->charge() != 0;
376  else {
377  // the new/improved particle table doesn't know anti-particles
378  return particleDataTable_->particle(-p->pdg_id()) != nullptr;
379  }
380 }
381 
383  genpvs_.clear();
384 
385  const HepMC::GenEvent *event = mcInformation_->GetEvent();
386 
387  if (event) {
388  int idx = 0;
389 
390  // Loop over the different GenVertex
391  for (HepMC::GenEvent::vertex_const_iterator ivertex = event->vertices_begin(); ivertex != event->vertices_end();
392  ++ivertex) {
393  bool hasParentVertex = false;
394 
395  // Loop over the parents looking to see if they are coming from a
396  // production vertex
397  for (HepMC::GenVertex::particle_iterator iparent = (*ivertex)->particles_begin(HepMC::parents);
398  iparent != (*ivertex)->particles_end(HepMC::parents);
399  ++iparent)
400  if ((*iparent)->production_vertex()) {
401  hasParentVertex = true;
402  break;
403  }
404 
405  // Reject those vertices with parent vertices
406  if (hasParentVertex)
407  continue;
408 
409  // Get the position of the vertex
410  HepMC::FourVector pos = (*ivertex)->position();
411 
412  double const mm = 0.1;
413 
414  GeneratedPrimaryVertex pv(pos.x() * mm, pos.y() * mm, pos.z() * mm);
415 
416  std::vector<GeneratedPrimaryVertex>::iterator ientry = genpvs_.begin();
417 
418  // Search for a VERY close vertex in the list
419  for (; ientry != genpvs_.end(); ++ientry) {
420  double distance = sqrt(pow(pv.x - ientry->x, 2) + pow(pv.y - ientry->y, 2) + pow(pv.z - ientry->z, 2));
422  break;
423  }
424 
425  // Check if there is not a VERY close vertex and added to the list
426  if (ientry == genpvs_.end())
427  ientry = genpvs_.insert(ientry, pv);
428 
429  // Add the vertex barcodes to the new or existent vertices
430  ientry->genVertex.push_back((*ivertex)->barcode());
431 
432  // Collect final state descendants
433  for (HepMC::GenVertex::particle_iterator idecendants = (*ivertex)->particles_begin(HepMC::descendants);
434  idecendants != (*ivertex)->particles_end(HepMC::descendants);
435  ++idecendants) {
436  if (isFinalstateParticle(*idecendants))
437  if (find(ientry->finalstateParticles.begin(), ientry->finalstateParticles.end(), (*idecendants)->barcode()) ==
438  ientry->finalstateParticles.end()) {
439  ientry->finalstateParticles.push_back((*idecendants)->barcode());
440  HepMC::FourVector m = (*idecendants)->momentum();
441 
442  ientry->ptot.setPx(ientry->ptot.px() + m.px());
443  ientry->ptot.setPy(ientry->ptot.py() + m.py());
444  ientry->ptot.setPz(ientry->ptot.pz() + m.pz());
445  ientry->ptot.setE(ientry->ptot.e() + m.e());
446  ientry->ptsq += m.perp() * m.perp();
447 
448  if (m.perp() > 0.8 && std::abs(m.pseudoRapidity()) < 2.5 && isCharged(*idecendants))
449  ientry->nGenTrk++;
450  }
451  }
452  idx++;
453  }
454  }
455 
456  std::sort(genpvs_.begin(), genpvs_.end());
457 }
edm::Handle< edm::HepMCProduct > mcInformation_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
edm::ESGetToken< ParticleDataTable, edm::DefaultRecord > particleDataTableToken_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
VertexHistory tracer_
const reco::VertexBaseRef & recoVertex() const
Return a reference to the reconstructed track.
Definition: VertexHistory.h:56
TPRegexp parents
Definition: eve_filter.cc:21
void newEvent(const edm::Event &, const edm::EventSetup &)
Pre-process event information (for accessing reconstruction information)
void vertexInformation()
Get geometrical information about the vertices.
std::vector< GeneratedPrimaryVertex > genpvs_
int event() const
get the contents of the subdetector field (should be protected?)
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:301
const edm::InputTag hepMCLabel_
GenVertexTrail const & genVertexTrail() const
Return all generated vertex in the history.
Definition: HistoryBase.h:58
bool isCharged(const HepMC::GenParticle *)
Get track history and classify it in function of their .
void reset()
Reset the categories flags.
SimVertexTrail const & simVertexTrail() const
Return all the simulated vertices in the history.
Definition: HistoryBase.h:52
Definition: config.py:1
bool isFinalstateParticle(const HepMC::GenParticle *)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
VertexClassifier(edm::ParameterSet const &pset, edm::ConsumesCollector)
Constructor by ParameterSet.
math::XYZTLorentzVectorD LorentzVector
bool evaluate(TrackingVertexRef tvr)
Evaluate track history using a TrackingParticleRef.
Definition: VertexHistory.h:38
const unsigned int processId(unsigned int g4ProcessId) const
Definition: Utils.cc:59
Flags flags_
Flag containers.
VertexClassifier const & evaluate(reco::VertexBaseRef const &)
Classify the RecoVertex in categories.
T sqrt(T t)
Definition: SSEVec.h:19
int bunchCrossing() const
get the detector field from this detid
double longLivedDecayLength_
def pv(vc)
Definition: MetAnalyzer.py:7
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< const HepMC::GenVertex * > GenVertexTrail
GenVertex trail type.
Definition: HistoryBase.h:24
edm::ESHandle< ParticleDataTable > particleDataTable_
const G4toCMSLegacyProcTypeMap g4toCMSProcMap_
HepPDT::ParticleData ParticleData
const HepMC::GenEvent * GetEvent() const
Definition: HepMCProduct.h:37
const TrackingVertexRef & simVertex() const
Return the initial tracking vertex from the history.
Definition: HistoryBase.h:70
part
Definition: HCALResponse.h:20
void processesAtGenerator()
Get all the information related to decay process.
HLT enums.
void depth(int d)
Set the depth of the history.
Definition: HistoryBase.h:49
double vertexClusteringDistance_
virtual void newEvent(edm::Event const &, edm::EventSetup const &)
Pre-process event information (for accessing reconstraction information)
void processesAtSimulation()
Get information about conversion and other interactions.
#define update(a, b)
std::vector< TrackingVertexRef > SimVertexTrail
SimVertex trail type.
Definition: HistoryBase.h:33
Auxiliary class holding simulated primary vertices.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
Definition: event.py:1
void simulationInformation()
Get all the information related to the simulation details.