CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
VertexClassifier.cc
Go to the documentation of this file.
1 /*
2  * VertexClassifier.C
3  */
4 
5 #include <math.h>
6 #include <cstdlib>
7 #include <iostream>
8 
9 #include "HepPDT/ParticleID.hh"
10 
12 
13 
14 #define update(a, b) do { (a) = (a) | (b); } while(0)
15 
16 
18  hepMCLabel_( config.getUntrackedParameter<edm::InputTag>("hepMC") )
19 {
20  // Set the history depth after hadronization
21  tracer_.depth(-2);
22 
23  // Set the minimum decay length for detecting long decays
24  longLivedDecayLength_ = config.getUntrackedParameter<double>("longLivedDecayLength");
25 
26  // Set the distance for clustering vertices
27  vertexClusteringDistance_ = config.getUntrackedParameter<double>("vertexClusteringDistance");
28 }
29 
30 
32 {
33  // Get the new event information for the tracer
34  tracer_.newEvent(event, setup);
35 
36  // Get hepmc of the event
37  event.getByLabel(hepMCLabel_, mcInformation_);
38 
39  // Get the partivle data table
41 
42  // Create the list of primary vertices associated to the event
44 }
45 
46 
48 {
49  // Initializing the category vector
50  reset();
51 
52  // Associate and evaluate the vertex history (check for fakes)
53  if ( tracer_.evaluate(vertex) )
54  {
55  // Get all the information related to the simulation details
57 
58  // Get all the information related to decay process
60 
61  // Get information about conversion and other interactions
63 
64  // Get geometrical information about the vertices
66 
67  // Check for unkown classification
68  unknownVertex();
69  }
70  else
71  flags_[Fake] = true;
72 
73  return *this;
74 }
75 
76 
78 {
79  // Initializing the category vector
80  reset();
81 
82  // Trace the history for the given TP
83  tracer_.evaluate(vertex);
84 
85  // Check for a reconstructed track
86  if ( tracer_.recoVertex().isNonnull() )
87  flags_[Reconstructed] = true;
88  else
89  flags_[Reconstructed] = false;
90 
91  // Get all the information related to the simulation details
93 
94  // Get all the information related to decay process
96 
97  // Get information about conversion and other interactions
99 
100  // Get geometrical information about the vertices
102 
103  // Check for unkown classification
104  unknownVertex();
105 
106  return *this;
107 }
108 
109 
111 {
112  // Get the event id for the initial TP.
113  EncodedEventId eventId = tracer_.simVertex()->eventId();
114  // Check for signal events
115  flags_[SignalEvent] = !eventId.bunchCrossing() && !eventId.event();
116 }
117 
118 
120 {
121  // Get the generated vetices from track history
122  VertexHistory::GenVertexTrail const & genVertexTrail = tracer_.genVertexTrail();
123 
124  // Loop over the generated vertices
125  for (
126  VertexHistory::GenVertexTrail::const_iterator ivertex = genVertexTrail.begin();
127  ivertex != genVertexTrail.end();
128  ++ivertex
129  )
130  {
131  // Get the pointer to the vertex by removing the const-ness (no const methos in HepMC::GenVertex)
132  HepMC::GenVertex * vertex = const_cast<HepMC::GenVertex *>(*ivertex);
133 
134  // Loop over the sources looking for specific decays
135  for (
136  HepMC::GenVertex::particle_iterator iparent = vertex->particles_begin(HepMC::parents);
137  iparent != vertex->particles_end(HepMC::parents);
138  ++iparent
139  )
140  {
141  // Collect the pdgid of the parent
142  int pdgid = std::abs((*iparent)->pdg_id());
143  // Get particle type
144  HepPDT::ParticleID particleID(pdgid);
145 
146  // Check if the particle type is valid one
147  if (particleID.isValid())
148  {
149  // Get particle data
150  ParticleData const * particleData = particleDataTable_->particle(particleID);
151  // Check if the particle exist in the table
152  if (particleData)
153  {
154  // Check if their life time is bigger than longLivedDecayLength_
155  if ( particleData->lifetime() > longLivedDecayLength_ )
156  {
157  // Check for B, C weak decays and long lived decays
158  update(flags_[BWeakDecay], particleID.hasBottom());
159  update(flags_[CWeakDecay], particleID.hasCharm());
160  update(flags_[LongLivedDecay], true);
161  }
162  // Check Tau, Ks and Lambda decay
163  update(flags_[TauDecay], pdgid == 15);
164  update(flags_[KsDecay], pdgid == 310);
165  update(flags_[LambdaDecay], pdgid == 3122);
166  update(flags_[JpsiDecay], pdgid == 443);
167  update(flags_[XiDecay], pdgid == 3312);
168  update(flags_[OmegaDecay], pdgid == 3334);
169  update(flags_[SigmaPlusDecay], pdgid == 3222);
170  update(flags_[SigmaMinusDecay], pdgid == 3112);
171  }
172  }
173  }
174  }
175 }
176 
177 
179 {
180  VertexHistory::SimVertexTrail const & simVertexTrail = tracer_.simVertexTrail();
181 
182  for (
183  VertexHistory::SimVertexTrail::const_iterator ivertex = simVertexTrail.begin();
184  ivertex != simVertexTrail.end();
185  ++ivertex
186  )
187  {
188  // pdgid of the real source parent vertex
189  int pdgid = 0;
190 
191  // select the original source in case of combined vertices
192  bool flag = false;
194 
195  for (its = (*ivertex)->sourceTracks_begin(); its != (*ivertex)->sourceTracks_end(); ++its)
196  {
197  for (itd = (*ivertex)->daughterTracks_begin(); itd != (*ivertex)->daughterTracks_end(); ++itd)
198  if (itd != its)
199  {
200  flag = true;
201  break;
202  }
203  if (flag)
204  break;
205  }
206  // Collect the pdgid of the original source track
207  if ( its != (*ivertex)->sourceTracks_end() )
208  pdgid = std::abs((*its)->pdgId());
209  else
210  pdgid = 0;
211 
212  // Loop over the simulated particles
213  for (
214  TrackingVertex::tp_iterator iparticle = (*ivertex)->daughterTracks_begin();
215  iparticle != (*ivertex)->daughterTracks_end();
216  ++iparticle
217  )
218  {
219 
220  if ( (*iparticle)->matchedHit() )
221  {
222  // Collect the G4 process of the first psimhit (it should be the same for all of them)
223  unsigned short process = (*iparticle)->pSimHit_begin()->processType();
224 
225  // Flagging all the different processes
226 
227  update(
229  process != G4::Undefined &&
230  process != G4::Unknown &&
231  process != G4::Primary
232  );
233 
235  update(flags_[UnknownProcess], process == G4::Unknown);
236  update(flags_[PrimaryProcess], process == G4::Primary);
238  update(flags_[DecayProcess], process == G4::Decay);
239  update(flags_[ComptonProcess], process == G4::Compton);
241  update(flags_[EIoniProcess], process == G4::EIoni);
242  update(flags_[HIoniProcess], process == G4::HIoni);
243  update(flags_[MuIoniProcess], process == G4::MuIoni);
244  update(flags_[PhotonProcess], process == G4::Photon);
247  update(flags_[EBremProcess], process == G4::EBrem);
249  update(flags_[MuBremProcess], process == G4::MuBrem);
250  update(flags_[MuNuclProcess], process == G4::MuNucl);
251 
252  // Special treatment for decays
253  if (process == G4::Decay)
254  {
255  // Get particle type
256  HepPDT::ParticleID particleID(pdgid);
257  // Check if the particle type is valid one
258  if (particleID.isValid())
259  {
260  // Get particle data
261  ParticleData const * particleData = particleDataTable_->particle(particleID);
262  // Check if the particle exist in the table
263  if (particleData)
264  {
265  // Check if their life time is bigger than 1e-14
266  if ( particleDataTable_->particle(particleID)->lifetime() > longLivedDecayLength_ )
267  {
268  // Check for B, C weak decays and long lived decays
269  update(flags_[BWeakDecay], particleID.hasBottom());
270  update(flags_[CWeakDecay], particleID.hasCharm());
271  update(flags_[LongLivedDecay], true);
272  }
273  // Check Tau, Ks and Lambda decay
274  update(flags_[TauDecay], pdgid == 15);
275  update(flags_[KsDecay], pdgid == 310);
276  update(flags_[LambdaDecay], pdgid == 3122);
277  update(flags_[JpsiDecay], pdgid == 443);
278  update(flags_[XiDecay], pdgid == 3312);
279  update(flags_[OmegaDecay], pdgid == 3334);
280  update(flags_[SigmaPlusDecay], pdgid == 3222);
281  update(flags_[SigmaMinusDecay], pdgid == 3112);
282  }
283  }
284  }
285  }
286  }
287  }
288 }
289 
290 
292 {
293  // Helper class for clusterization
294  typedef std::multimap<double, HepMC::ThreeVector> Clusters;
295  typedef std::pair<double, HepMC::ThreeVector> ClusterPair;
296 
297  Clusters clusters;
298 
299  // Get the main primary vertex from the list
300  GeneratedPrimaryVertex const & genpv = genpvs_.back();
301 
302  // Get the generated history of the tracks
304 
305  // Unit transformation from mm to cm
306  double const mm = 0.1;
307 
308  // Loop over the generated vertexes
309  for (
310  VertexHistory::GenVertexTrail::const_iterator ivertex = genVertexTrail.begin();
311  ivertex != genVertexTrail.end();
312  ++ivertex
313  )
314  {
315  // Check vertex exist
316  if (*ivertex)
317  {
318  // Measure the distance2 respecto the primary vertex
319  HepMC::ThreeVector p = (*ivertex)->point3d();
320  double distance = sqrt( pow(p.x() * mm - genpv.x, 2) + pow(p.y() * mm - genpv.y, 2) + pow(p.z() * mm - genpv.z, 2) );
321 
322  // If there is not any clusters add the first vertex.
323  if ( clusters.empty() )
324  {
325  clusters.insert( ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)) );
326  continue;
327  }
328 
329  // Check if there is already a cluster in the given distance from primary vertex
330  Clusters::const_iterator icluster = clusters.lower_bound(distance - vertexClusteringDistance_);
331 
332  if ( icluster == clusters.upper_bound(distance + vertexClusteringDistance_) )
333  {
334  clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)) );
335  continue;
336  }
337 
338  bool cluster = false;
339 
340  // Looping over the vertex clusters of a given distance from primary vertex
341  for (;
342  icluster != clusters.upper_bound(distance + vertexClusteringDistance_);
343  ++icluster
344  )
345  {
346  double difference = sqrt (
347  pow(p.x() * mm - icluster->second.x(), 2) +
348  pow(p.y() * mm - icluster->second.y(), 2) +
349  pow(p.z() * mm - icluster->second.z(), 2)
350  );
351 
352  if ( difference < vertexClusteringDistance_ )
353  {
354  cluster = true;
355  break;
356  }
357  }
358 
359  if (!cluster) clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x() * mm, p.y() * mm, p.z() * mm)) );
360  }
361  }
362 
364 
365  // Loop over the generated particles
366  for (
367  VertexHistory::SimVertexTrail::reverse_iterator ivertex = simVertexTrail.rbegin();
368  ivertex != simVertexTrail.rend();
369  ++ivertex
370  )
371  {
372  // Look for those with production vertex
373  TrackingVertex::LorentzVector p = (*ivertex)->position();
374 
375  double distance = sqrt( pow(p.x() - genpv.x, 2) + pow(p.y() - genpv.y, 2) + pow(p.z() - genpv.z, 2) );
376 
377  // If there is not any clusters add the first vertex.
378  if ( clusters.empty() )
379  {
380  clusters.insert( ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())) );
381  continue;
382  }
383 
384  // Check if there is already a cluster in the given distance from primary vertex
385  Clusters::const_iterator icluster = clusters.lower_bound(distance - vertexClusteringDistance_);
386 
387  if ( icluster == clusters.upper_bound(distance + vertexClusteringDistance_) )
388  {
389  clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())) );
390  continue;
391  }
392 
393  bool cluster = false;
394 
395  // Looping over the vertex clusters of a given distance from primary vertex
396  for (;
397  icluster != clusters.upper_bound(distance + vertexClusteringDistance_);
398  ++icluster
399  )
400  {
401  double difference = sqrt (
402  pow(p.x() - icluster->second.x(), 2) +
403  pow(p.y() - icluster->second.y(), 2) +
404  pow(p.z() - icluster->second.z(), 2)
405  );
406 
407  if ( difference < vertexClusteringDistance_ )
408  {
409  cluster = true;
410  break;
411  }
412  }
413 
414  if (!cluster) clusters.insert ( ClusterPair(distance, HepMC::ThreeVector(p.x(), p.y(), p.z())) );
415  }
416 
417  if ( clusters.size() == 1 )
418  flags_[PrimaryVertex] = true;
419  else if ( clusters.size() == 2 )
420  flags_[SecondaryVertex] = true;
421  else
422  flags_[TertiaryVertex] = true;
423 }
424 
425 
427 {
428  return !p->end_vertex() && p->status() == 1;
429 }
430 
431 
433 {
434  const ParticleData * part = particleDataTable_->particle( p->pdg_id() );
435  if (part)
436  return part->charge()!=0;
437  else
438  {
439  // the new/improved particle table doesn't know anti-particles
440  return particleDataTable_->particle( -p->pdg_id() ) != 0;
441  }
442 }
443 
444 
446 {
447  genpvs_.clear();
448 
449  const HepMC::GenEvent * event = mcInformation_->GetEvent();
450 
451  if (event)
452  {
453  int idx = 0;
454 
455  // Loop over the different GenVertex
456  for ( HepMC::GenEvent::vertex_const_iterator ivertex = event->vertices_begin(); ivertex != event->vertices_end(); ++ivertex )
457  {
458  bool hasParentVertex = false;
459 
460  // Loop over the parents looking to see if they are coming from a production vertex
461  for (
462  HepMC::GenVertex::particle_iterator iparent = (*ivertex)->particles_begin(HepMC::parents);
463  iparent != (*ivertex)->particles_end(HepMC::parents);
464  ++iparent
465  )
466  if ( (*iparent)->production_vertex() )
467  {
468  hasParentVertex = true;
469  break;
470  }
471 
472  // Reject those vertices with parent vertices
473  if (hasParentVertex) continue;
474 
475  // Get the position of the vertex
476  HepMC::FourVector pos = (*ivertex)->position();
477 
478  double const mm = 0.1;
479 
480  GeneratedPrimaryVertex pv(pos.x()*mm, pos.y()*mm, pos.z()*mm);
481 
482  std::vector<GeneratedPrimaryVertex>::iterator ientry = genpvs_.begin();
483 
484  // Search for a VERY close vertex in the list
485  for (; ientry != genpvs_.end(); ++ientry)
486  {
487  double distance = sqrt( pow(pv.x - ientry->x, 2) + pow(pv.y - ientry->y, 2) + pow(pv.z - ientry->z, 2) );
488  if ( distance < vertexClusteringDistance_ )
489  break;
490  }
491 
492  // Check if there is not a VERY close vertex and added to the list
493  if (ientry == genpvs_.end())
494  ientry = genpvs_.insert(ientry,pv);
495 
496  // Add the vertex barcodes to the new or existent vertices
497  ientry->genVertex.push_back((*ivertex)->barcode());
498 
499  // Collect final state descendants
500  for (
501  HepMC::GenVertex::particle_iterator idecendants = (*ivertex)->particles_begin(HepMC::descendants);
502  idecendants != (*ivertex)->particles_end(HepMC::descendants);
503  ++idecendants
504  )
505  {
506  if (isFinalstateParticle(*idecendants))
507  if ( find(ientry->finalstateParticles.begin(), ientry->finalstateParticles.end(), (*idecendants)->barcode()) == ientry->finalstateParticles.end() )
508  {
509  ientry->finalstateParticles.push_back((*idecendants)->barcode());
510  HepMC::FourVector m = (*idecendants)->momentum();
511 
512  ientry->ptot.setPx(ientry->ptot.px() + m.px());
513  ientry->ptot.setPy(ientry->ptot.py() + m.py());
514  ientry->ptot.setPz(ientry->ptot.pz() + m.pz());
515  ientry->ptot.setE(ientry->ptot.e() + m.e());
516  ientry->ptsq += m.perp() * m.perp();
517 
518  if ( m.perp() > 0.8 && std::abs(m.pseudoRapidity()) < 2.5 && isCharged(*idecendants) ) ientry->nGenTrk++;
519  }
520  }
521  idx++;
522  }
523  }
524 
525  std::sort(genpvs_.begin(), genpvs_.end());
526 }
edm::Handle< edm::HepMCProduct > mcInformation_
T getUntrackedParameter(std::string const &, T const &) const
VertexHistory tracer_
long int flag
Definition: mlp_lapack.h:47
int event() const
get the contents of the subdetector field (should be protected?)
TPRegexp parents
Definition: eve_filter.cc:24
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_
const edm::InputTag hepMCLabel_
SimVertexTrail const & simVertexTrail() const
Return all the simulated vertices in the history.
Definition: HistoryBase.h:53
bool isCharged(const HepMC::GenParticle *)
#define abs(x)
Definition: mlp_lapack.h:159
Get track history and classify it in function of their .
void reset()
Reset the categories flags.
const reco::VertexBaseRef & recoVertex() const
Return a reference to the reconstructed track.
Definition: VertexHistory.h:62
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:7
void getData(T &iHolder) const
Definition: EventSetup.h:67
math::XYZTLorentzVectorD LorentzVector
bool evaluate(TrackingVertexRef tvr)
Evaluate track history using a TrackingParticleRef.
Definition: VertexHistory.h:40
VertexClassifier(edm::ParameterSet const &pset)
Constructor by ParameterSet.
Flags flags_
Flag containers.
T sqrt(T t)
Definition: SSEVec.h:46
int bunchCrossing() const
get the detector field from this detid
double longLivedDecayLength_
std::vector< const HepMC::GenVertex * > GenVertexTrail
GenVertex trail type.
Definition: HistoryBase.h:21
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
edm::ESHandle< ParticleDataTable > particleDataTable_
HepPDT::ParticleData ParticleData
const TrackingVertexRef & simVertex() const
Return the initial tracking vertex from the history.
Definition: HistoryBase.h:83
part
Definition: HCALResponse.h:21
void processesAtGenerator()
Get all the information related to decay process.
VertexClassifier const & evaluate(reco::VertexBaseRef const &)
Classify the RecoVertex in categories.
void depth(int d)
Set the depth of the history.
Definition: HistoryBase.h:47
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.
GenVertexTrail const & genVertexTrail() const
Return all generated vertex in the history.
Definition: HistoryBase.h:65
tuple process
Definition: LaserDQM_cfg.py:3
#define update(a, b)
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:279
std::vector< TrackingVertexRef > SimVertexTrail
SimVertex trail type.
Definition: HistoryBase.h:30
Auxiliary class holding simulated primary vertices.
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
void simulationInformation()
Get all the information related to the simulation details.