CMS 3D CMS Logo

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