CMS 3D CMS Logo

PFDisplacedVertexFinder.cc
Go to the documentation of this file.
1 #include <memory>
2 
5 
7 
10 
14 
16 
19 
21 
22 #include "TMath.h"
23 
24 using namespace std;
25 using namespace reco;
26 
27 //for debug only
28 //#define PFLOW_DEBUG
29 
31  : displacedVertexCandidates_(nullptr),
32  displacedVertices_(new PFDisplacedVertexCollection),
33  transvSize_(0.0),
34  longSize_(0.0),
35  primaryVertexCut_(0.0),
36  tobCut_(0.0),
37  tecCut_(0.0),
38  minAdaptWeight_(2.0),
39  debug_(false) {}
40 
42 
44  const edm::Handle<reco::PFDisplacedVertexCandidateCollection>& displacedVertexCandidates) {
45  if (displacedVertexCandidates.isValid()) {
46  displacedVertexCandidates_ = displacedVertexCandidates.product();
47  } else {
49  }
50 }
51 
52 // -------- Main function which find vertices -------- //
53 
55  if (debug_)
56  cout << "========= Start Find Displaced Vertices =========" << endl;
57 
58  // The vertexCandidates have not been passed to the event
59  // So they need to be cleared is they are not empty
60  if (displacedVertices_.get())
61  displacedVertices_->clear();
62  else
63  displacedVertices_ = std::make_unique<PFDisplacedVertexCollection>();
64 
65  if (displacedVertexCandidates_ == nullptr) {
66  edm::LogInfo("EmptyVertexInput")
67  << "displacedVertexCandidates are not set or the setInput was called with invalid vertex";
68  return;
69  }
70 
71  // Prepare the collections
72  PFDisplacedVertexSeedCollection tempDisplacedVertexSeeds;
73  tempDisplacedVertexSeeds.reserve(4 * displacedVertexCandidates_->size());
74  PFDisplacedVertexCollection tempDisplacedVertices;
75  tempDisplacedVertices.reserve(4 * displacedVertexCandidates_->size());
76 
77  if (debug_)
78  cout << "1) Parsing displacedVertexCandidates into displacedVertexSeeds" << endl;
79 
80  // 1) Parsing displacedVertexCandidates into displacedVertexSeeds which would
81  // be later used for vertex fitting
82 
83  int i = -1;
84 
85  for (auto const& idvc : *displacedVertexCandidates_) {
86  i++;
87  if (debug_) {
88  cout << "Analyse Vertex Candidate " << i << endl;
89  }
90 
91  findSeedsFromCandidate(idvc, tempDisplacedVertexSeeds);
92  }
93 
94  if (debug_)
95  cout << "2) Merging Vertex Seeds" << endl;
96 
97  // 2) Some displacedVertexSeeds coming from different displacedVertexCandidates
98  // may be closed enough to be merged together. bLocked is an array which keeps the
99  // information about the seeds which are desabled.
100  vector<bool> bLockedSeeds;
101  bLockedSeeds.resize(tempDisplacedVertexSeeds.size());
102  mergeSeeds(tempDisplacedVertexSeeds, bLockedSeeds);
103 
104  if (debug_)
105  cout << "3) Fitting Vertices From Seeds" << endl;
106 
107  // 3) Fit displacedVertices from displacedVertexSeeds
108  for (unsigned idv = 0; idv < tempDisplacedVertexSeeds.size(); idv++) {
109  if (!tempDisplacedVertexSeeds[idv].isEmpty() && !bLockedSeeds[idv]) {
110  PFDisplacedVertex displacedVertex;
111  bLockedSeeds[idv] = fitVertexFromSeed(tempDisplacedVertexSeeds[idv], displacedVertex);
112  if (!bLockedSeeds[idv])
113  tempDisplacedVertices.emplace_back(displacedVertex);
114  }
115  }
116 
117  if (debug_)
118  cout << "4) Rejecting Bad Vertices and label them" << endl;
119 
120  // 4) Reject displaced vertices which may be considered as fakes
121  vector<bool> bLocked;
122  bLocked.resize(tempDisplacedVertices.size());
123  selectAndLabelVertices(tempDisplacedVertices, bLocked);
124 
125  if (debug_)
126  cout << "5) Fill the Displaced Vertices" << endl;
127 
128  // 5) Fill the displacedVertex_ which would be transfered to the producer
129  displacedVertices_->reserve(tempDisplacedVertices.size());
130 
131  for (unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
132  if (!bLocked[idv])
133  displacedVertices_->push_back(tempDisplacedVertices[idv]);
134 
135  if (debug_)
136  cout << "========= End Find Displaced Vertices =========" << endl;
137 }
138 
139 // -------- Different steps of the finder algorithm -------- //
140 
142  PFDisplacedVertexSeedCollection& tempDisplacedVertexSeeds) {
143  const PFDisplacedVertexCandidate::DistMap r2Map = vertexCandidate.r2Map();
144  bool bNeedNewCandidate = false;
145 
146  tempDisplacedVertexSeeds.push_back(PFDisplacedVertexSeed());
147 
148  IDVS idvc_current;
149 
150  for (PFDisplacedVertexCandidate::DistMap::const_iterator imap = r2Map.begin(); imap != r2Map.end(); imap++) {
151  unsigned ie1 = (*imap).second.first;
152  unsigned ie2 = (*imap).second.second;
153 
154  if (debug_)
155  cout << "ie1 = " << ie1 << " ie2 = " << ie2 << " radius = " << sqrt((*imap).first) << endl;
156 
157  GlobalPoint dcaPoint = vertexCandidate.dcaPoint(ie1, ie2);
158  if (fabs(dcaPoint.x()) > 1e9)
159  continue;
160 
161  bNeedNewCandidate = true;
162  for (idvc_current = tempDisplacedVertexSeeds.begin(); idvc_current != tempDisplacedVertexSeeds.end();
163  idvc_current++) {
164  if ((*idvc_current).isEmpty()) {
165  bNeedNewCandidate = false;
166  break;
167  }
168  const GlobalPoint vertexPoint = (*idvc_current).seedPoint();
169  std::pair<float, float> diffs = getTransvLongDiff(vertexPoint, dcaPoint);
170  if (diffs.second > longSize_)
171  continue;
172  if (diffs.first > transvSize_)
173  continue;
174  bNeedNewCandidate = false;
175  break;
176  }
177  if (bNeedNewCandidate) {
178  if (debug_)
179  cout << "create new displaced vertex" << endl;
180  tempDisplacedVertexSeeds.push_back(PFDisplacedVertexSeed());
181  idvc_current = tempDisplacedVertexSeeds.end();
182  idvc_current--;
183  }
184 
185  (*idvc_current).updateSeedPoint(dcaPoint, vertexCandidate.tref(ie1), vertexCandidate.tref(ie2));
186  }
187 }
188 
190  vector<bool>& bLocked) {
191  // loop over displaced vertex candidates
192  // and merge them if they are close to each other
193  for (unsigned idv_mother = 0; idv_mother < tempDisplacedVertexSeeds.size(); idv_mother++) {
194  if (!bLocked[idv_mother]) {
195  for (unsigned idv_daughter = idv_mother + 1; idv_daughter < tempDisplacedVertexSeeds.size(); idv_daughter++) {
196  if (!bLocked[idv_daughter]) {
197  if (isCloseTo(tempDisplacedVertexSeeds[idv_mother], tempDisplacedVertexSeeds[idv_daughter])) {
198  tempDisplacedVertexSeeds[idv_mother].mergeWith(tempDisplacedVertexSeeds[idv_daughter]);
199  bLocked[idv_daughter] = true;
200  if (debug_)
201  cout << "Seeds " << idv_mother << " and " << idv_daughter << " merged" << endl;
202  }
203  }
204  }
205  }
206  }
207 }
208 
210  PFDisplacedVertex& displacedVertex) {
211  if (debug_)
212  cout << "== Start vertexing procedure ==" << endl;
213 
214  // ---- Prepare transient track list ----
215 
216  auto const& tracksToFit = displacedVertexSeed.elements();
217  const GlobalPoint& seedPoint = displacedVertexSeed.seedPoint();
218 
219  vector<TransientTrack> transTracks;
220  vector<TransientTrack> transTracksRaw;
221  vector<TrackBaseRef> transTracksRef;
222 
223  transTracks.reserve(tracksToFit.size());
224  transTracksRaw.reserve(tracksToFit.size());
225  transTracksRef.reserve(tracksToFit.size());
226 
227  TransientVertex theVertexAdaptiveRaw;
228  TransientVertex theRecoVertex;
229 
230  // ---- 1) Clean for potentially poor seeds ------- //
231  // --------------------------------------------- //
232 
233  if (tracksToFit.size() < 2) {
234  if (debug_)
235  cout << "Only one to Fit Track" << endl;
236  return true;
237  }
238 
239  double rho = sqrt(seedPoint.x() * seedPoint.x() + seedPoint.y() * seedPoint.y());
240  double z = seedPoint.z();
241 
242  if (rho > tobCut_ || fabs(z) > tecCut_) {
243  if (debug_)
244  cout << "Seed Point out of the tracker rho = " << rho << " z = " << z << " nTracks = " << tracksToFit.size()
245  << endl;
246  return true;
247  }
248 
249  if (debug_)
250  displacedVertexSeed.Dump();
251 
252  int nStep45 = 0;
253  int nNotIterative = 0;
254 
255  // Fill vectors of TransientTracks and TrackRefs after applying preselection cuts.
256  for (auto const& ie : tracksToFit) {
257  TransientTrack tmpTk(*(ie.get()), magField_, globTkGeomHandle_);
258  transTracksRaw.emplace_back(tmpTk);
259  bool nonIt = PFTrackAlgoTools::nonIterative((ie)->algo());
260  bool step45 = PFTrackAlgoTools::step45((ie)->algo());
261  bool highQ = PFTrackAlgoTools::highQuality((ie)->algo());
262  if (step45)
263  nStep45++;
264  else if (nonIt)
265  nNotIterative++;
266  else if (!highQ) {
267  nNotIterative++;
268  nStep45++;
269  }
270  }
271 
272  if (rho > 25 && nStep45 + nNotIterative < 1) {
273  if (debug_)
274  cout << "Seed point at rho > 25 cm but no step 4-5 tracks" << endl;
275  return true;
276  }
277 
278  // ----------------------------------------------- //
279  // ---- PRESELECT GOOD TRACKS FOR FINAL VERTEX --- //
280  // ----------------------------------------------- //
281 
282  // 1)If only two track are found do not prefit
283 
284  if (transTracksRaw.size() == 2) {
285  if (debug_)
286  cout << "No raw fit done" << endl;
288  if (debug_)
289  cout << "Due to probably high pile-up conditions 2 track vertices switched off" << endl;
290  return true;
291  }
292  GlobalError globalError;
293 
294  theVertexAdaptiveRaw = TransientVertex(seedPoint, globalError, transTracksRaw, 1.);
295 
296  } else { //branch with transTracksRaw.size of at least 3
297 
298  if (debug_)
299  cout << "Raw fit done." << endl;
300 
306 
307  if (transTracksRaw.size() == 3) {
308  theVertexAdaptiveRaw = theAdaptiveFitterRaw.vertex(transTracksRaw, seedPoint);
309 
310  } else if (transTracksRaw.size() < 1000) {
313 
314  if (debug_)
315  cout << "First test with KFT" << endl;
316 
317  KalmanVertexFitter theKalmanFitter(true);
318  theVertexAdaptiveRaw = theKalmanFitter.vertex(transTracksRaw, seedPoint);
319 
320  if (!theVertexAdaptiveRaw.isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0.) {
321  if (debug_)
322  cout << "Prefit failed : valid? " << theVertexAdaptiveRaw.isValid()
323  << " totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
324  return true;
325  }
326 
327  if (debug_)
328  cout << "We use KFT instead of seed point to set up a point for AVF "
329  << " x = " << theVertexAdaptiveRaw.position().x() << " y = " << theVertexAdaptiveRaw.position().y()
330  << " z = " << theVertexAdaptiveRaw.position().z() << endl;
331 
332  // To save time: reject the Displaced vertex if it is too close to the beam pipe.
333  // Frequently it is very big vertices, with some dosens of tracks
334 
335  Vertex vtx = theVertexAdaptiveRaw;
336  rho = vtx.position().rho();
337 
338  // cout << "primary vertex cut = " << primaryVertexCut_ << endl;
339 
340  if (rho < primaryVertexCut_ || rho > 100) {
341  if (debug_)
342  cout << "KFT Vertex geometrically rejected with tracks #rho = " << rho << endl;
343  return true;
344  }
345 
346  // cout << "primary vertex cut = " << primaryVertexCut_ << " rho = " << rho << endl;
347 
348  theVertexAdaptiveRaw = theAdaptiveFitterRaw.vertex(transTracksRaw, theVertexAdaptiveRaw.position());
349 
350  } else {
351  edm::LogWarning("TooManyPFDVCandidates") << "gave up vertex reco for " << transTracksRaw.size() << " tracks";
352  }
353 
354  if (!theVertexAdaptiveRaw.isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0.) {
355  if (debug_)
356  cout << "Fit failed : valid? " << theVertexAdaptiveRaw.isValid()
357  << " totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
358  return true;
359  }
360 
361  // To save time: reject the Displaced vertex if it is too close to the beam pipe.
362  // Frequently it is very big vertices, with some dosens of tracks
363 
364  Vertex vtx = theVertexAdaptiveRaw;
365  rho = vtx.position().rho();
366 
367  if (rho < primaryVertexCut_) {
368  if (debug_)
369  cout << "Vertex "
370  << " geometrically rejected with " << transTracksRaw.size() << " tracks #rho = " << rho << endl;
371  return true;
372  }
373  }
374 
375  // ---- Remove tracks with small weight or
376  // big first (last) hit_to_vertex distance
377  // and then refit ---- //
378 
379  for (unsigned i = 0; i < transTracksRaw.size(); i++) {
380  if (debug_)
381  cout << "Raw Weight track " << i << " = " << theVertexAdaptiveRaw.trackWeight(transTracksRaw[i]) << endl;
382 
383  if (theVertexAdaptiveRaw.trackWeight(transTracksRaw[i]) > minAdaptWeight_) {
384  PFTrackHitFullInfo pattern = hitPattern_.analyze(tkerTopo_, tkerGeom_, tracksToFit[i], theVertexAdaptiveRaw);
385 
387 
388  if (vertexTrackType != PFDisplacedVertex::T_NOT_FROM_VERTEX) {
389  bool bGoodTrack = helper_.isTrackSelected(transTracksRaw[i].track(), vertexTrackType);
390 
391  if (bGoodTrack) {
392  transTracks.push_back(transTracksRaw[i]);
393  transTracksRef.push_back(tracksToFit[i]);
394  } else {
395  if (debug_)
396  cout << "Track rejected nChi2 = " << transTracksRaw[i].track().normalizedChi2()
397  << " pt = " << transTracksRaw[i].track().pt()
398  << " dxy (wrt (0,0,0)) = " << transTracksRaw[i].track().dxy()
399  << " nHits = " << transTracksRaw[i].track().numberOfValidHits() << " nOuterHits = "
400  << transTracksRaw[i].track().hitPattern().numberOfLostHits(HitPattern::MISSING_OUTER_HITS) << endl;
401  }
402  } else {
403  if (debug_) {
404  cout << "Remove track because too far away from the vertex:" << endl;
405  }
406  }
407  }
408  }
409 
410  if (debug_)
411  cout << "All Tracks " << transTracksRaw.size() << " with good weight " << transTracks.size() << endl;
412 
413  // ---- Refit ---- //
414  FitterType vtxFitter = F_NOTDEFINED;
415 
416  if (transTracks.size() < 2)
417  return true;
418  else if (transTracks.size() == 2) {
420  if (debug_)
421  cout << "Due to probably high pile-up conditions 2 track vertices switched off" << endl;
422  return true;
423  }
424  vtxFitter = F_KALMAN;
425  } else if (transTracks.size() > 2 && transTracksRaw.size() > transTracks.size())
426  vtxFitter = F_ADAPTIVE;
427  else if (transTracks.size() > 2 && transTracksRaw.size() == transTracks.size())
428  vtxFitter = F_DONOTREFIT;
429  else
430  return true;
431 
432  if (debug_)
433  cout << "Vertex Fitter " << vtxFitter << endl;
434 
435  if (vtxFitter == F_KALMAN) {
436  KalmanVertexFitter theKalmanFitter(true);
437  theRecoVertex = theKalmanFitter.vertex(transTracks, seedPoint);
438 
439  } else if (vtxFitter == F_ADAPTIVE) {
445 
446  theRecoVertex = theAdaptiveFitter.vertex(transTracks, seedPoint);
447 
448  } else if (vtxFitter == F_DONOTREFIT) {
449  theRecoVertex = theVertexAdaptiveRaw;
450  } else {
451  return true;
452  }
453 
454  // ---- Check if the fitted vertex is valid ---- //
455 
456  if (!theRecoVertex.isValid() || theRecoVertex.totalChiSquared() < 0.) {
457  if (debug_)
458  cout << "Refit failed : valid? " << theRecoVertex.isValid() << " totalChi2 = " << theRecoVertex.totalChiSquared()
459  << endl;
460  return true;
461  }
462 
463  // ---- Create vertex ---- //
464 
465  Vertex theRecoVtx = theRecoVertex;
466 
467  double chi2 = theRecoVtx.chi2();
468  double ndf = theRecoVtx.ndof();
469 
470  if (chi2 > TMath::ChisquareQuantile(0.95, ndf)) {
471  if (debug_)
472  cout << "Rejected because of chi2 = " << chi2 << " ndf = " << ndf
473  << " confid. level: " << TMath::ChisquareQuantile(0.95, ndf) << endl;
474  return true;
475  }
476 
477  // ---- Create and fill vector of refitted TransientTracks ---- //
478 
479  // -----------------------------------------------//
480  // ---- Prepare and Fill the Displaced Vertex ----//
481  // -----------------------------------------------//
482 
483  displacedVertex = theRecoVtx;
484  displacedVertex.removeTracks();
485 
486  for (unsigned i = 0; i < transTracks.size(); i++) {
487  PFTrackHitFullInfo pattern = hitPattern_.analyze(tkerTopo_, tkerGeom_, transTracksRef[i], theRecoVertex);
488 
490 
491  Track refittedTrack;
492  float weight = theRecoVertex.trackWeight(transTracks[i]);
493 
494  if (weight < minAdaptWeight_)
495  continue;
496 
497  try {
498  refittedTrack = theRecoVertex.refittedTrack(transTracks[i]).track();
499  } catch (cms::Exception& exception) {
500  continue;
501  }
502 
503  if (debug_) {
504  cout << "Vertex Track Type = " << vertexTrackType << endl;
505 
506  cout << "nHitBeforeVertex = " << pattern.first.first << " nHitAfterVertex = " << pattern.second.first
507  << " nMissHitBeforeVertex = " << pattern.first.second << " nMissHitAfterVertex = " << pattern.second.second
508  << " Weight = " << weight << endl;
509  }
510 
511  displacedVertex.addElement(transTracksRef[i], refittedTrack, pattern, vertexTrackType, weight);
512  }
513 
514  displacedVertex.setPrimaryDirection(helper_.primaryVertex());
515  displacedVertex.calcKinematics();
516 
517  if (debug_)
518  cout << "== End vertexing procedure ==" << endl;
519 
520  return false;
521 }
522 
524  vector<bool>& bLocked) {
525  if (debug_)
526  cout << " 4.1) Reject vertices " << endl;
527 
528  for (unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++) {
529  // ---- We accept a vertex only if it is not in TOB in the barrel
530  // and not in TEC in the end caps
531  // and not too much before the first pixel layer ---- //
532 
533  const float rho = tempDisplacedVertices[idv].position().rho();
534  const float z = tempDisplacedVertices[idv].position().z();
535 
536  if (rho > tobCut_ || rho < primaryVertexCut_ || fabs(z) > tecCut_) {
537  if (debug_)
538  cout << "Vertex " << idv << " geometrically rejected #rho = " << rho << " z = " << z << endl;
539 
540  bLocked[idv] = true;
541 
542  continue;
543  }
544 
545  unsigned nPrimary = tempDisplacedVertices[idv].nPrimaryTracks();
546  unsigned nMerged = tempDisplacedVertices[idv].nMergedTracks();
547  unsigned nSecondary = tempDisplacedVertices[idv].nSecondaryTracks();
548 
549  if (nPrimary + nMerged > 1) {
550  bLocked[idv] = true;
551  if (debug_)
552  cout << "Vertex " << idv << " rejected because two primary or merged tracks" << endl;
553  }
554 
555  if (nPrimary + nMerged + nSecondary < 2) {
556  bLocked[idv] = true;
557  if (debug_)
558  cout << "Vertex " << idv << " rejected because only one track related to the vertex" << endl;
559  }
560  }
561 
562  if (debug_)
563  cout << " 4.2) Check for common vertices" << endl;
564 
565  // ---- Among the remaining vertex we shall remove one
566  // of those which have two common tracks ---- //
567 
568  for (unsigned idv_mother = 0; idv_mother < tempDisplacedVertices.size(); idv_mother++) {
569  for (unsigned idv_daughter = idv_mother + 1; idv_daughter < tempDisplacedVertices.size(); idv_daughter++) {
570  if (!bLocked[idv_daughter] && !bLocked[idv_mother]) {
571  const unsigned commonTrks =
572  commonTracks(tempDisplacedVertices[idv_daughter], tempDisplacedVertices[idv_mother]);
573 
574  if (commonTrks > 1) {
575  if (debug_)
576  cout << "Vertices " << idv_daughter << " and " << idv_mother << " has many common tracks" << endl;
577 
578  // We keep the vertex vertex which contains the most of the tracks
579 
580  const int mother_size = tempDisplacedVertices[idv_mother].nTracks();
581  const int daughter_size = tempDisplacedVertices[idv_daughter].nTracks();
582 
583  if (mother_size > daughter_size)
584  bLocked[idv_daughter] = true;
585  else if (mother_size < daughter_size)
586  bLocked[idv_mother] = true;
587  else {
588  // If they have the same size we keep the vertex with the best normalised chi2
589 
590  const float mother_normChi2 = tempDisplacedVertices[idv_mother].normalizedChi2();
591  const float daughter_normChi2 = tempDisplacedVertices[idv_daughter].normalizedChi2();
592  if (mother_normChi2 < daughter_normChi2)
593  bLocked[idv_daughter] = true;
594  else
595  bLocked[idv_mother] = true;
596  }
597  }
598  }
599  }
600  }
601 
602  for (unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
603  if (!bLocked[idv])
604  bLocked[idv] = rejectAndLabelVertex(tempDisplacedVertices[idv]);
605 }
606 
609  dv.setVertexType(vertexType);
610 
611  return dv.isFake();
612 }
613 
615 
617  const GlobalPoint& vP1 = dv1.seedPoint();
618  const GlobalPoint& vP2 = dv2.seedPoint();
619 
620  std::pair<float, float> diffs = getTransvLongDiff(vP1, vP2);
621  if (diffs.second > longSize_)
622  return false;
623  if (diffs.first > transvSize_)
624  return false;
625  // if (Delta_Long < longSize_ && Delta_Transv < transvSize_) isCloseTo = true;
626 
627  return true;
628 }
629 
631  const GlobalPoint& ToProject) const {
632  const auto& vRef = Ref.basicVector();
633  const auto& vToProject = ToProject.basicVector();
634  float vRefMag2 = vRef.mag2();
635  float oneOverMag = 1.0f / sqrt(vRefMag2);
636 
637  return std::make_pair(fabs(vRef.cross(vToProject).mag() * oneOverMag),
638  fabs((vRef.dot(vToProject) - vRefMag2) * oneOverMag));
639 }
640 
642  PFTrackHitFullInfo& pairTrackHitInfo) const {
643  unsigned int nHitBeforeVertex = pairTrackHitInfo.first.first;
644  unsigned int nHitAfterVertex = pairTrackHitInfo.second.first;
645 
646  unsigned int nMissHitBeforeVertex = pairTrackHitInfo.first.second;
647  unsigned int nMissHitAfterVertex = pairTrackHitInfo.second.second;
648 
649  // For the moment those definitions are given apriori a more general study would be useful to refine those criteria
650 
651  if (nHitBeforeVertex <= 1 && nHitAfterVertex >= 3 && nMissHitAfterVertex <= 1)
652  return PFDisplacedVertex::T_FROM_VERTEX;
653  else if (nHitBeforeVertex >= 3 && nHitAfterVertex <= 1 && nMissHitBeforeVertex <= 1)
654  return PFDisplacedVertex::T_TO_VERTEX;
655  else if ((nHitBeforeVertex >= 2 && nHitAfterVertex >= 3) || (nHitBeforeVertex >= 3 && nHitAfterVertex >= 2))
656  return PFDisplacedVertex::T_MERGED;
657  else
658  return PFDisplacedVertex::T_NOT_FROM_VERTEX;
659 }
660 
662  vector<Track> vt1 = v1.refittedTracks();
663  vector<Track> vt2 = v2.refittedTracks();
664 
665  unsigned commonTracks = 0;
666 
667  for (unsigned il1 = 0; il1 < vt1.size(); il1++) {
668  unsigned il1_idx = v1.originalTrack(vt1[il1]).key();
669 
670  for (unsigned il2 = 0; il2 < vt2.size(); il2++)
671  if (il1_idx == v2.originalTrack(vt2[il2]).key()) {
672  commonTracks++;
673  break;
674  }
675  }
676 
677  return commonTracks;
678 }
679 
680 std::ostream& operator<<(std::ostream& out, const PFDisplacedVertexFinder& a) {
681  if (!out)
682  return out;
683  out << setprecision(3) << setw(5) << endl;
684  out << "" << endl;
685  out << " ====================================== " << endl;
686  out << " ====== Displaced Vertex Finder ======= " << endl;
687  out << " ====================================== " << endl;
688  out << " " << endl;
689 
690  a.helper_.Dump();
691  out << "" << endl
692  << " Adaptive Vertex Fitter parameters are :" << endl
693  << " sigmacut = " << a.sigmacut_ << " T_ini = " << a.t_ini_ << " ratio = " << a.ratio_ << endl
694  << endl;
695 
696  const std::unique_ptr<reco::PFDisplacedVertexCollection>& displacedVertices_ = std::move(a.displacedVertices());
697 
698  if (!displacedVertices_.get()) {
699  out << "displacedVertex already transfered" << endl;
700  } else {
701  out << "Number of displacedVertices found : " << displacedVertices_->size() << endl << endl;
702 
703  int i = -1;
704 
705  for (PFDisplacedVertexFinder::IDV idv = displacedVertices_->begin(); idv != displacedVertices_->end(); idv++) {
706  i++;
707  out << i << " ";
708  idv->Dump();
709  out << "" << endl;
710  }
711  }
712 
713  return out;
714 }
const Track & track() const
std::vector< PFDisplacedVertex > PFDisplacedVertexCollection
collection of PFDisplacedVertex objects
const GlobalPoint dcaPoint(unsigned ie1, unsigned ie2) const
float totalChiSquared() const
reco::TransientTrack refittedTrack(const reco::TransientTrack &track) const
GlobalPoint position() const
A block of tracks linked together.
void setPrimaryDirection(const math::XYZPoint &pvtx)
reco::PFDisplacedVertexSeedCollection::iterator IDVS
-----— Useful Types -----— ///
const GlobalPoint & seedPoint() const
T z() const
Definition: PV3DBase.h:61
edm::ESHandle< GlobalTrackingGeometry > globTkGeomHandle_
Tracker geometry for discerning hit positions.
reco::PFDisplacedVertex::VertexTrackType getVertexTrackType(PFTrackHitFullInfo &) const
bool isCloseTo(const reco::PFDisplacedVertexSeed &, const reco::PFDisplacedVertexSeed &) const
-----— Tools -----— ///
const TrackerTopology * tkerTopo_
doc?
T const * product() const
Definition: Handle.h:70
bool fitVertexFromSeed(const reco::PFDisplacedVertexSeed &, reco::PFDisplacedVertex &)
Fit one by one the vertex points with associated tracks to get displaced vertices.
bool rejectAndLabelVertex(reco::PFDisplacedVertex &dv)
Definition: weight.py:1
CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &) const override
void findDisplacedVertices()
-----— Main function which find vertices -----— ///
double ndof() const
Definition: Vertex.h:123
bool debug_
If true, debug printouts activated.
void Dump(std::ostream &out=std::cout) const
cout function
std::unique_ptr< reco::PFDisplacedVertexCollection > displacedVertices_
std::pair< PFTrackHitInfo, PFTrackHitInfo > PFTrackHitFullInfo
void mergeSeeds(reco::PFDisplacedVertexSeedCollection &, std::vector< bool > &bLocked)
Sometimes two vertex candidates can be quite close and coming from the same vertex.
CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &tracks) const override
const std::vector< TrackBaseRef > & elements() const
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
void addElement(const TrackBaseRef &r, const Track &refTrack, const PFTrackHitFullInfo &hitInfo, VertexTrackType trackType=T_NOT_FROM_VERTEX, float w=1.0)
Add a new track to the vertex.
PFTrackHitFullInfo analyze(const TrackerTopology *tkerTopo, const TrackerGeometry *tkerGeom, const reco::TrackBaseRef track, const TransientVertex &vert)
void setVertexType(VertexType vertexType)
Set the type of this vertex.
bool isValid() const
std::vector< PFDisplacedVertexSeed > PFDisplacedVertexSeedCollection
collection of PFDisplacedVertexSeed objects
T sqrt(T t)
Definition: SSEVec.h:19
reco::PFDisplacedVertexCandidateCollection const * displacedVertexCandidates_
-----— Members -----— ///
void findSeedsFromCandidate(const reco::PFDisplacedVertexCandidate &, reco::PFDisplacedVertexSeedCollection &)
--—— Different steps of the finder algorithm --—— ///
bool nonIterative(const reco::TrackBase::TrackAlgorithm &)
void selectAndLabelVertices(reco::PFDisplacedVertexCollection &, std::vector< bool > &)
Remove potentially fakes displaced vertices.
bool step45(const reco::TrackBase::TrackAlgorithm &)
bool highQuality(const reco::TrackBase::TrackAlgorithm &)
const MagneticField * magField_
to be able to extrapolate tracks f
void setInput(const edm::Handle< reco::PFDisplacedVertexCandidateCollection > &)
Set input collections of tracks.
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:53
math::XYZPoint primaryVertex() const
Set Vertex direction using the primary vertex.
Log< level::Info, false > LogInfo
size_t key() const
Definition: RefToBase.h:219
Block of elements.
double sigmacut_
Adaptive Vertex Fitter parameters.
unsigned commonTracks(const reco::PFDisplacedVertex &, const reco::PFDisplacedVertex &) const
const std::vector< Track > & refittedTracks() const
Returns the container of refitted tracks.
Definition: Vertex.h:196
reco::PFDisplacedVertexCollection::iterator IDV
bool isValid() const
Definition: HandleBase.h:70
double chi2() const
chi-squares
Definition: Vertex.h:116
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
fixed size matrix
double a
Definition: hdecay.h:119
const TrackBaseRef & tref(unsigned ie) const
float transvSize_
--—— Parameters --—— ///
float trackWeight(const reco::TransientTrack &track) const
std::pair< float, float > getTransvLongDiff(const GlobalPoint &, const GlobalPoint &) const
const TrackerGeometry * tkerGeom_
std::map< float, std::pair< int, int > > DistMap
void removeTracks()
Definition: Vertex.cc:75
Log< level::Warning, false > LogWarning
DistMap r2Map() const
--—— Provide useful information --—— ///
bool isTrackSelected(const reco::Track &trk, const reco::PFDisplacedVertex::VertexTrackType vertexTrackType) const
Select tracks tool.
def move(src, dest)
Definition: eostools.py:511
TrackBaseRef originalTrack(const Track &refTrack) const
Definition: Vertex.cc:81
reco::PFDisplacedVertex::VertexType identifyVertex(const reco::PFDisplacedVertex &v) const
Vertex identification tool.
std::ostream & operator<<(std::ostream &out, const PFDisplacedVertexFinder &a)
PFDisplacedVertexHelper helper_