00001 #include "RecoParticleFlow/PFTracking/interface/PFDisplacedVertexFinder.h"
00002
00003 #include "FWCore/Utilities/interface/Exception.h"
00004
00005 #include "DataFormats/TrackReco/interface/Track.h"
00006 #include "DataFormats/VertexReco/interface/Vertex.h"
00007
00008 #include "RecoVertex/VertexPrimitives/interface/TransientVertex.h"
00009 #include "RecoVertex/AdaptiveVertexFit/interface/AdaptiveVertexFitter.h"
00010 #include "RecoVertex/KalmanVertexFit/interface/KalmanVertexSmoother.h"
00011
00012 #include "PhysicsTools/RecoAlgos/plugins/KalmanVertexFitter.h"
00013
00014 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00015 #include "Geometry/CommonDetUnit/interface/TrackingGeometry.h"
00016
00017 #include "MagneticField/Engine/interface/MagneticField.h"
00018
00019 #include "TMath.h"
00020
00021 using namespace std;
00022 using namespace reco;
00023
00024
00025
00026
00027 PFDisplacedVertexFinder::PFDisplacedVertexFinder() :
00028 displacedVertexCandidates_( new PFDisplacedVertexCandidateCollection ),
00029 displacedVertices_( new PFDisplacedVertexCollection ),
00030 transvSize_(0.0),
00031 longSize_(0.0),
00032 primaryVertexCut_(0.0),
00033 tobCut_(0.0),
00034 tecCut_(0.0),
00035 minAdaptWeight_(2.0),
00036 debug_(false) {}
00037
00038
00039 PFDisplacedVertexFinder::~PFDisplacedVertexFinder() {}
00040
00041 void
00042 PFDisplacedVertexFinder::setInput(
00043 const edm::Handle<reco::PFDisplacedVertexCandidateCollection>& displacedVertexCandidates) {
00044
00045 if( displacedVertexCandidates_.get() ) {
00046 displacedVertexCandidates_->clear();
00047 }
00048 else
00049 displacedVertexCandidates_.reset( new PFDisplacedVertexCandidateCollection );
00050
00051
00052 if(displacedVertexCandidates.isValid()) {
00053 for(unsigned i=0;i<displacedVertexCandidates->size(); i++) {
00054 PFDisplacedVertexCandidateRef dvcref( displacedVertexCandidates, i);
00055 displacedVertexCandidates_->push_back( (*dvcref));
00056 }
00057 }
00058
00059 }
00060
00061
00062
00063
00064 void
00065 PFDisplacedVertexFinder::findDisplacedVertices() {
00066
00067 if (debug_) cout << "========= Start Find Displaced Vertices =========" << endl;
00068
00069
00070
00071 if( displacedVertices_.get() ) displacedVertices_->clear();
00072 else
00073 displacedVertices_.reset( new PFDisplacedVertexCollection );
00074
00075
00076
00077 PFDisplacedVertexSeedCollection tempDisplacedVertexSeeds;
00078 tempDisplacedVertexSeeds.reserve(4*displacedVertexCandidates_->size());
00079 PFDisplacedVertexCollection tempDisplacedVertices;
00080 tempDisplacedVertices.reserve(4*displacedVertexCandidates_->size());
00081
00082 if (debug_)
00083 cout << "1) Parsing displacedVertexCandidates into displacedVertexSeeds" << endl;
00084
00085
00086
00087
00088 int i = -1;
00089
00090 for(IDVC idvc = displacedVertexCandidates_->begin();
00091 idvc != displacedVertexCandidates_->end(); idvc++) {
00092
00093 i++;
00094 if (debug_) {
00095 cout << "Analyse Vertex Candidate " << i << endl;
00096 }
00097
00098 findSeedsFromCandidate(*idvc, tempDisplacedVertexSeeds);
00099
00100 }
00101
00102 if (debug_) cout << "2) Merging Vertex Seeds" << endl;
00103
00104
00105
00106
00107 vector<bool> bLockedSeeds;
00108 bLockedSeeds.resize(tempDisplacedVertexSeeds.size());
00109 mergeSeeds(tempDisplacedVertexSeeds, bLockedSeeds);
00110
00111 if (debug_) cout << "3) Fitting Vertices From Seeds" << endl;
00112
00113
00114 for(unsigned idv = 0; idv < tempDisplacedVertexSeeds.size(); idv++){
00115
00116 if (!tempDisplacedVertexSeeds[idv].isEmpty() && !bLockedSeeds[idv]) {
00117 PFDisplacedVertex displacedVertex;
00118 bLockedSeeds[idv] = fitVertexFromSeed(tempDisplacedVertexSeeds[idv], displacedVertex);
00119 if (!bLockedSeeds[idv]) tempDisplacedVertices.push_back(displacedVertex);
00120 }
00121 }
00122
00123 if (debug_) cout << "4) Rejecting Bad Vertices and label them" << endl;
00124
00125
00126 vector<bool> bLocked;
00127 bLocked.resize(tempDisplacedVertices.size());
00128 selectAndLabelVertices(tempDisplacedVertices, bLocked);
00129
00130 if (debug_) cout << "5) Fill the Displaced Vertices" << endl;
00131
00132
00133 displacedVertices_->reserve(tempDisplacedVertices.size());
00134
00135 for(unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
00136 if (!bLocked[idv]) displacedVertices_->push_back(tempDisplacedVertices[idv]);
00137
00138 if (debug_) cout << "========= End Find Displaced Vertices =========" << endl;
00139
00140
00141 }
00142
00143
00144
00145
00146 void
00147 PFDisplacedVertexFinder::findSeedsFromCandidate(PFDisplacedVertexCandidate& vertexCandidate, PFDisplacedVertexSeedCollection& tempDisplacedVertexSeeds){
00148
00149 const PFDisplacedVertexCandidate::DistMap r2Map = vertexCandidate.r2Map();
00150 bool bNeedNewCandidate = false;
00151
00152 tempDisplacedVertexSeeds.push_back( PFDisplacedVertexSeed() );
00153
00154 IDVS idvc_current;
00155
00156 for (PFDisplacedVertexCandidate::DistMap::const_iterator imap = r2Map.begin();
00157 imap != r2Map.end(); imap++){
00158
00159 unsigned ie1 = (*imap).second.first;
00160 unsigned ie2 = (*imap).second.second;
00161
00162 if (debug_) cout << "ie1 = " << ie1 << " ie2 = " << ie2 << " radius = " << sqrt((*imap).first) << endl;
00163
00164 GlobalPoint dcaPoint = vertexCandidate.dcaPoint(ie1, ie2);
00165 if (fabs(dcaPoint.x()) > 1e9) continue;
00166
00167 bNeedNewCandidate = true;
00168 for (idvc_current = tempDisplacedVertexSeeds.begin(); idvc_current != tempDisplacedVertexSeeds.end(); idvc_current++){
00169 if ((*idvc_current).isEmpty()) {
00170 bNeedNewCandidate = false;
00171 break;
00172 }
00173 const GlobalPoint vertexPoint = (*idvc_current).seedPoint();
00174 double Delta_Long = getLongDiff(vertexPoint, dcaPoint);
00175 double Delta_Transv = getTransvDiff(vertexPoint, dcaPoint);
00176 if (Delta_Long > longSize_) continue;
00177 if (Delta_Transv > transvSize_) continue;
00178 bNeedNewCandidate = false;
00179 break;
00180 }
00181 if (bNeedNewCandidate) {
00182 if (debug_) cout << "create new displaced vertex" << endl;
00183 tempDisplacedVertexSeeds.push_back( PFDisplacedVertexSeed() );
00184 idvc_current = tempDisplacedVertexSeeds.end();
00185 idvc_current--;
00186 bNeedNewCandidate = false;
00187 }
00188
00189
00190
00191 (*idvc_current).updateSeedPoint(dcaPoint, vertexCandidate.tref(ie1), vertexCandidate.tref(ie2));
00192
00193
00194
00195 }
00196
00197
00198 }
00199
00200
00201
00202
00203 void
00204 PFDisplacedVertexFinder::mergeSeeds(PFDisplacedVertexSeedCollection& tempDisplacedVertexSeeds, vector<bool>& bLocked){
00205
00206
00207
00208 for(unsigned idv_mother = 0;idv_mother < tempDisplacedVertexSeeds.size(); idv_mother++){
00209 if (!bLocked[idv_mother]){
00210
00211 for (unsigned idv_daughter = idv_mother+1;idv_daughter < tempDisplacedVertexSeeds.size(); idv_daughter++){
00212
00213 if (!bLocked[idv_daughter]){
00214 if (isCloseTo(tempDisplacedVertexSeeds[idv_mother], tempDisplacedVertexSeeds[idv_daughter])) {
00215
00216 tempDisplacedVertexSeeds[idv_mother].mergeWith(tempDisplacedVertexSeeds[idv_daughter]);
00217 bLocked[idv_daughter] = true;
00218 if (debug_) cout << "Seeds " << idv_mother << " and " << idv_daughter << " merged" << endl;
00219 }
00220 }
00221 }
00222 }
00223 }
00224
00225 }
00226
00227
00228
00229
00230
00231
00232
00233
00234 bool
00235 PFDisplacedVertexFinder::fitVertexFromSeed(PFDisplacedVertexSeed& displacedVertexSeed, PFDisplacedVertex& displacedVertex) {
00236
00237
00238 if (debug_) cout << "== Start vertexing procedure ==" << endl;
00239
00240
00241
00242
00243 set < TrackBaseRef, PFDisplacedVertexSeed::Compare > tracksToFit = displacedVertexSeed.elements();
00244 GlobalPoint seedPoint = displacedVertexSeed.seedPoint();
00245
00246 vector<TransientTrack> transTracks;
00247 vector<TransientTrack> transTracksRaw;
00248 vector<TrackBaseRef> transTracksRef;
00249 vector<TrackBaseRef> transTracksRefRaw;
00250
00251 transTracks.reserve(tracksToFit.size());
00252 transTracksRaw.reserve(tracksToFit.size());
00253 transTracksRef.reserve(tracksToFit.size());
00254 transTracksRefRaw.reserve(tracksToFit.size());
00255
00256
00257
00258 TransientVertex theVertexAdaptiveRaw;
00259 TransientVertex theRecoVertex;
00260
00261
00262
00263
00264
00265 if (tracksToFit.size() < 2) {
00266 if (debug_) cout << "Only one to Fit Track" << endl;
00267 return true;
00268 }
00269
00270 double rho = sqrt(seedPoint.x()*seedPoint.x()+seedPoint.y()*seedPoint.y());
00271 double z = seedPoint.z();
00272
00273 if (rho > tobCut_ || fabs(z) > tecCut_) {
00274 if (debug_) cout << "Seed Point out of the tracker rho = " << rho << " z = "<< z << " nTracks = " << tracksToFit.size() << endl;
00275 return true;
00276 }
00277
00278 if (debug_) displacedVertexSeed.Dump();
00279
00280 int nStep45 = 0;
00281 int nNotIterative = 0;
00282
00283
00284 for(IEset ie = tracksToFit.begin(); ie != tracksToFit.end(); ie++){
00285 TransientTrack tmpTk( *((*ie).get()), magField_, globTkGeomHandle_);
00286 transTracksRaw.push_back( tmpTk );
00287 transTracksRefRaw.push_back( *ie );
00288 if ( (*ie)->algo()-4 > 3 ) nStep45++;
00289 if ( (*ie)->algo()-4 < 0 ||(*ie)->algo()-4 > 5 ) nNotIterative++;
00290 }
00291
00292 if (rho > 25 && nStep45 + nNotIterative < 1){
00293 if (debug_) cout << "Seed point at rho > 25 cm but no step 4-5 tracks" << endl;
00294 return true;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 if ( transTracksRaw.size() == 2 ){
00307
00308 if (debug_) cout << "No raw fit done" << endl;
00309 if (switchOff2TrackVertex_) {
00310 if (debug_)
00311 cout << "Due to probably high pile-up conditions 2 track vertices switched off" << endl;
00312 return true;
00313
00314 }
00315 GlobalError globalError;
00316
00317 theVertexAdaptiveRaw = TransientVertex(seedPoint, globalError, transTracksRaw, 1.);
00318
00319
00320
00321 } else {
00322
00323
00324
00325 if (debug_) cout << "Raw fit done." << endl;
00326
00327 AdaptiveVertexFitter theAdaptiveFitterRaw(GeometricAnnealing(sigmacut_, t_ini_, ratio_),
00328 DefaultLinearizationPointFinder(),
00329 KalmanVertexUpdator<5>(),
00330 KalmanVertexTrackCompatibilityEstimator<5>(),
00331 KalmanVertexSmoother() );
00332
00335
00336
00337 if ( transTracksRaw.size() < 1000 && transTracksRaw.size() > 3){
00338
00339 if (debug_) cout << "First test with KFT" << endl;
00340
00341 KalmanVertexFitter theKalmanFitter(true);
00342 theVertexAdaptiveRaw = theKalmanFitter.vertex(transTracksRaw, seedPoint);
00343
00344 if( !theVertexAdaptiveRaw.isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0. ) {
00345 if(debug_) cout << "Prefit failed : valid? " << theVertexAdaptiveRaw.isValid()
00346 << " totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
00347 return true;
00348 }
00349
00350 if (debug_) cout << "We use KFT instead of seed point to set up a point for AVF "
00351 << " x = " << theVertexAdaptiveRaw.position().x()
00352 << " y = " << theVertexAdaptiveRaw.position().y()
00353 << " z = " << theVertexAdaptiveRaw.position().z()
00354 << endl;
00355
00356
00357
00358
00359 Vertex vtx = theVertexAdaptiveRaw;
00360 rho = vtx.position().rho();
00361
00362
00363
00364 if (rho < primaryVertexCut_ || rho > 100) {
00365 if (debug_) cout << "KFT Vertex geometrically rejected with tracks #rho = " << rho << endl;
00366 return true;
00367 }
00368
00369
00370
00371 theVertexAdaptiveRaw = theAdaptiveFitterRaw.vertex(transTracksRaw, theVertexAdaptiveRaw.position());
00372
00373
00374 } else {
00375
00376
00377 theVertexAdaptiveRaw = theAdaptiveFitterRaw.vertex(transTracksRaw, seedPoint);
00378
00379 }
00380
00381 if( !theVertexAdaptiveRaw.isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0. ) {
00382 if(debug_) cout << "Fit failed : valid? " << theVertexAdaptiveRaw.isValid()
00383 << " totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
00384 return true;
00385 }
00386
00387
00388
00389
00390 Vertex vtx = theVertexAdaptiveRaw;
00391 rho = vtx.position().rho();
00392
00393 if (rho < primaryVertexCut_) {
00394 if (debug_) cout << "Vertex " << " geometrically rejected with " << transTracksRaw.size() << " tracks #rho = " << rho << endl;
00395 return true;
00396 }
00397
00398
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 for (unsigned i = 0; i < transTracksRaw.size(); i++) {
00410
00411 if (debug_) cout << "Raw Weight track " << i << " = " << theVertexAdaptiveRaw.trackWeight(transTracksRaw[i]) << endl;
00412
00413 if (theVertexAdaptiveRaw.trackWeight(transTracksRaw[i]) > minAdaptWeight_){
00414
00415 PFTrackHitFullInfo pattern = hitPattern_.analyze(tkerGeomHandle_, transTracksRefRaw[i], theVertexAdaptiveRaw);
00416
00417 PFDisplacedVertex::VertexTrackType vertexTrackType = getVertexTrackType(pattern);
00418
00419 if (vertexTrackType != PFDisplacedVertex::T_NOT_FROM_VERTEX){
00420
00421 bool bGoodTrack = helper_.isTrackSelected(transTracksRaw[i].track(), vertexTrackType);
00422
00423 if (bGoodTrack){
00424 transTracks.push_back(transTracksRaw[i]);
00425 transTracksRef.push_back(transTracksRefRaw[i]);
00426 } else {
00427 if (debug_)
00428 cout << "Track rejected nChi2 = " << transTracksRaw[i].track().normalizedChi2()
00429 << " pt = " << transTracksRaw[i].track().pt()
00430 << " dxy (wrt (0,0,0)) = " << transTracksRaw[i].track().dxy()
00431 << " nHits = " << transTracksRaw[i].track().numberOfValidHits()
00432 << " nOuterHits = " << transTracksRaw[i].track().trackerExpectedHitsOuter().numberOfHits() << endl;
00433 }
00434 } else {
00435
00436 if (debug_){
00437 cout << "Remove track because too far away from the vertex:" << endl;
00438 }
00439
00440 }
00441
00442 }
00443
00444 }
00445
00446
00447
00448 if (debug_) cout << "All Tracks " << transTracksRaw.size()
00449 << " with good weight " << transTracks.size() << endl;
00450
00451
00452
00453 FitterType vtxFitter = F_NOTDEFINED;
00454
00455 if (transTracks.size() < 2) return true;
00456 else if (transTracks.size() == 2){
00457
00458 if (switchOff2TrackVertex_) {
00459 if (debug_)
00460 cout << "Due to probably high pile-up conditions 2 track vertices switched off" << endl;
00461 return true;
00462 }
00463 vtxFitter = F_KALMAN;
00464 }
00465 else if (transTracks.size() > 2 && transTracksRaw.size() > transTracks.size())
00466 vtxFitter = F_ADAPTIVE;
00467 else if (transTracks.size() > 2 && transTracksRaw.size() == transTracks.size())
00468 vtxFitter = F_DONOTREFIT;
00469 else return true;
00470
00471 if (debug_) cout << "Vertex Fitter " << vtxFitter << endl;
00472
00473 if(vtxFitter == F_KALMAN){
00474
00475 KalmanVertexFitter theKalmanFitter(true);
00476 theRecoVertex = theKalmanFitter.vertex(transTracks, seedPoint);
00477
00478 } else if(vtxFitter == F_ADAPTIVE){
00479
00480 AdaptiveVertexFitter theAdaptiveFitter(
00481 GeometricAnnealing(sigmacut_, t_ini_, ratio_),
00482 DefaultLinearizationPointFinder(),
00483 KalmanVertexUpdator<5>(),
00484 KalmanVertexTrackCompatibilityEstimator<5>(),
00485 KalmanVertexSmoother() );
00486
00487 theRecoVertex = theAdaptiveFitter.vertex(transTracks, seedPoint);
00488
00489 } else if (vtxFitter == F_DONOTREFIT) {
00490 theRecoVertex = theVertexAdaptiveRaw;
00491 } else {
00492 return true;
00493 }
00494
00495
00496
00497
00498 if( !theRecoVertex.isValid() || theRecoVertex.totalChiSquared() < 0. ) {
00499 if (debug_) cout << "Refit failed : valid? " << theRecoVertex.isValid()
00500 << " totalChi2 = " << theRecoVertex.totalChiSquared() << endl;
00501 return true;
00502 }
00503
00504
00505
00506 Vertex theRecoVtx = theRecoVertex;
00507
00508 double chi2 = theRecoVtx.chi2();
00509 double ndf = theRecoVtx.ndof();
00510
00511
00512 if (chi2 > TMath::ChisquareQuantile(0.95, ndf)) {
00513 if (debug_)
00514 cout << "Rejected because of chi2 = " << chi2 << " ndf = " << ndf << " confid. level: " << TMath::ChisquareQuantile(0.95, ndf) << endl;
00515 return true;
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 displacedVertex = (PFDisplacedVertex) theRecoVtx;
00528 displacedVertex.removeTracks();
00529
00530 for(unsigned i = 0; i < transTracks.size();i++) {
00531
00532 PFTrackHitFullInfo pattern = hitPattern_.analyze(tkerGeomHandle_, transTracksRef[i], theRecoVertex);
00533
00534 PFDisplacedVertex::VertexTrackType vertexTrackType = getVertexTrackType(pattern);
00535
00536 Track refittedTrack;
00537 float weight = theRecoVertex.trackWeight(transTracks[i]);
00538
00539
00540 if (weight < minAdaptWeight_) continue;
00541
00542 try{
00543 refittedTrack = theRecoVertex.refittedTrack(transTracks[i]).track();
00544 }catch( cms::Exception& exception ){
00545 continue;
00546 }
00547
00548 if (debug_){
00549 cout << "Vertex Track Type = " << vertexTrackType << endl;
00550
00551 cout << "nHitBeforeVertex = " << pattern.first.first
00552 << " nHitAfterVertex = " << pattern.second.first
00553 << " nMissHitBeforeVertex = " << pattern.first.second
00554 << " nMissHitAfterVertex = " << pattern.second.second
00555 << " Weight = " << weight << endl;
00556 }
00557
00558 displacedVertex.addElement(transTracksRef[i],
00559 refittedTrack,
00560 pattern, vertexTrackType, weight);
00561
00562 }
00563
00564 displacedVertex.setPrimaryDirection(helper_.primaryVertex());
00565 displacedVertex.calcKinematics();
00566
00567
00568
00569 if (debug_) cout << "== End vertexing procedure ==" << endl;
00570
00571 return false;
00572
00573 }
00574
00575
00576
00577
00578
00579
00580 void
00581 PFDisplacedVertexFinder::selectAndLabelVertices(PFDisplacedVertexCollection& tempDisplacedVertices, vector <bool>& bLocked){
00582
00583 if (debug_) cout << " 4.1) Reject vertices " << endl;
00584
00585 for(unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++){
00586
00587
00588
00589
00590
00591
00592 const float rho = tempDisplacedVertices[idv].position().rho();
00593 const float z = tempDisplacedVertices[idv].position().z();
00594
00595 if (rho > tobCut_ || rho < primaryVertexCut_ || fabs(z) > tecCut_) {
00596 if (debug_) cout << "Vertex " << idv
00597 << " geometrically rejected #rho = " << rho
00598 << " z = " << z << endl;
00599
00600 bLocked[idv] = true;
00601
00602 continue;
00603 }
00604
00605 unsigned nPrimary = tempDisplacedVertices[idv].nPrimaryTracks();
00606 unsigned nMerged = tempDisplacedVertices[idv].nMergedTracks();
00607 unsigned nSecondary = tempDisplacedVertices[idv].nSecondaryTracks();
00608
00609 if (nPrimary + nMerged > 1) {
00610 bLocked[idv] = true;
00611 if (debug_) cout << "Vertex " << idv
00612 << " rejected because two primary or merged tracks" << endl;
00613
00614
00615 }
00616
00617 if (nPrimary + nMerged + nSecondary < 2){
00618 bLocked[idv] = true;
00619 if (debug_) cout << "Vertex " << idv
00620 << " rejected because only one track related to the vertex" << endl;
00621 }
00622
00623
00624 }
00625
00626
00627 if (debug_) cout << " 4.2) Check for common vertices" << endl;
00628
00629
00630
00631
00632 for(unsigned idv_mother = 0; idv_mother < tempDisplacedVertices.size(); idv_mother++){
00633 for(unsigned idv_daughter = idv_mother+1;
00634 idv_daughter < tempDisplacedVertices.size(); idv_daughter++){
00635
00636 if(!bLocked[idv_daughter] && !bLocked[idv_mother]){
00637
00638 const unsigned commonTrks = commonTracks(tempDisplacedVertices[idv_daughter], tempDisplacedVertices[idv_mother]);
00639
00640 if (commonTrks > 1) {
00641
00642 if (debug_) cout << "Vertices " << idv_daughter << " and " << idv_mother
00643 << " has many common tracks" << endl;
00644
00645
00646
00647 const int mother_size = tempDisplacedVertices[idv_mother].nTracks();
00648 const int daughter_size = tempDisplacedVertices[idv_daughter].nTracks();
00649
00650 if (mother_size > daughter_size) bLocked[idv_daughter] = true;
00651 else if (mother_size < daughter_size) bLocked[idv_mother] = true;
00652 else {
00653
00654
00655
00656 const float mother_normChi2 = tempDisplacedVertices[idv_mother].normalizedChi2();
00657 const float daughter_normChi2 = tempDisplacedVertices[idv_daughter].normalizedChi2();
00658 if (mother_normChi2 < daughter_normChi2) bLocked[idv_daughter] = true;
00659 else bLocked[idv_mother] = true;
00660 }
00661
00662 }
00663 }
00664 }
00665 }
00666
00667 for(unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
00668 if ( !bLocked[idv] ) bLocked[idv] = rejectAndLabelVertex(tempDisplacedVertices[idv]);
00669
00670
00671 }
00672
00673 bool
00674 PFDisplacedVertexFinder::rejectAndLabelVertex(PFDisplacedVertex& dv){
00675
00676 PFDisplacedVertex::VertexType vertexType = helper_.identifyVertex(dv);
00677 dv.setVertexType(vertexType);
00678
00679 return dv.isFake();
00680
00681 }
00682
00683
00685
00686 bool
00687 PFDisplacedVertexFinder::isCloseTo(const PFDisplacedVertexSeed& dv1, const PFDisplacedVertexSeed& dv2) const {
00688
00689 const GlobalPoint vP1 = dv1.seedPoint();
00690 const GlobalPoint vP2 = dv2.seedPoint();
00691
00692 double Delta_Long = getLongDiff(vP1, vP2);
00693 if (Delta_Long > longSize_) return false;
00694 double Delta_Transv = getTransvDiff(vP1, vP2);
00695 if (Delta_Transv > transvSize_) return false;
00696
00697
00698 return true;
00699
00700 }
00701
00702
00703 double
00704 PFDisplacedVertexFinder::getLongDiff(const GlobalPoint& Ref, const GlobalPoint& ToProject) const {
00705
00706 Basic3DVector<double>vRef(Ref);
00707 Basic3DVector<double>vToProject(ToProject);
00708 return fabs((vRef.dot(vToProject)-vRef.mag2())/vRef.mag());
00709
00710 }
00711
00712 double
00713 PFDisplacedVertexFinder::getLongProj(const GlobalPoint& Ref, const GlobalVector& ToProject) const {
00714
00715 Basic3DVector<double>vRef(Ref);
00716 Basic3DVector<double>vToProject(ToProject);
00717 return (vRef.dot(vToProject))/vRef.mag();
00718
00719
00720 }
00721
00722
00723 double
00724 PFDisplacedVertexFinder::getTransvDiff(const GlobalPoint& Ref, const GlobalPoint& ToProject) const {
00725
00726 Basic3DVector<double>vRef(Ref);
00727 Basic3DVector<double>vToProject(ToProject);
00728 return fabs(vRef.cross(vToProject).mag()/vRef.mag());
00729
00730 }
00731
00732
00733 reco::PFDisplacedVertex::VertexTrackType
00734 PFDisplacedVertexFinder::getVertexTrackType(PFTrackHitFullInfo& pairTrackHitInfo) const {
00735
00736 unsigned int nHitBeforeVertex = pairTrackHitInfo.first.first;
00737 unsigned int nHitAfterVertex = pairTrackHitInfo.second.first;
00738
00739 unsigned int nMissHitBeforeVertex = pairTrackHitInfo.first.second;
00740 unsigned int nMissHitAfterVertex = pairTrackHitInfo.second.second;
00741
00742
00743
00744 if (nHitBeforeVertex <= 1 && nHitAfterVertex >= 3 && nMissHitAfterVertex <= 1)
00745 return PFDisplacedVertex::T_FROM_VERTEX;
00746 else if (nHitBeforeVertex >= 3 && nHitAfterVertex <= 1 && nMissHitBeforeVertex <= 1)
00747 return PFDisplacedVertex::T_TO_VERTEX;
00748 else if ((nHitBeforeVertex >= 2 && nHitAfterVertex >= 3)
00749 ||
00750 (nHitBeforeVertex >= 3 && nHitAfterVertex >= 2))
00751 return PFDisplacedVertex::T_MERGED;
00752 else
00753 return PFDisplacedVertex::T_NOT_FROM_VERTEX;
00754 }
00755
00756
00757 unsigned PFDisplacedVertexFinder::commonTracks(const PFDisplacedVertex& v1, const PFDisplacedVertex& v2) const {
00758
00759 vector<Track> vt1 = v1.refittedTracks();
00760 vector<Track> vt2 = v2.refittedTracks();
00761
00762 unsigned commonTracks = 0;
00763
00764 for ( unsigned il1 = 0; il1 < vt1.size(); il1++){
00765 unsigned il1_idx = v1.originalTrack(vt1[il1]).key();
00766
00767 for ( unsigned il2 = 0; il2 < vt2.size(); il2++)
00768 if (il1_idx == v2.originalTrack(vt2[il2]).key()) {commonTracks++; break;}
00769
00770 }
00771
00772 return commonTracks;
00773
00774 }
00775
00776 std::ostream& operator<<(std::ostream& out, const PFDisplacedVertexFinder& a) {
00777
00778 if(! out) return out;
00779 out << setprecision(3) << setw(5) << endl;
00780 out << "" << endl;
00781 out << " ====================================== " << endl;
00782 out << " ====== Displaced Vertex Finder ======= " << endl;
00783 out << " ====================================== " << endl;
00784 out << " " << endl;
00785
00786 a.helper_.Dump();
00787 out << "" << endl
00788 << " Adaptive Vertex Fitter parameters are :"<< endl
00789 << " sigmacut = " << a.sigmacut_ << " T_ini = "
00790 << a.t_ini_ << " ratio = " << a.ratio_ << endl << endl;
00791
00792 const std::auto_ptr< reco::PFDisplacedVertexCollection >& displacedVertices_
00793 = a.displacedVertices();
00794
00795
00796 if(!displacedVertices_.get() ) {
00797 out<<"displacedVertex already transfered"<<endl;
00798 }
00799 else{
00800
00801 out<<"Number of displacedVertices found : "<< displacedVertices_->size()<<endl<<endl;
00802
00803 int i = -1;
00804
00805 for(PFDisplacedVertexFinder::IDV idv = displacedVertices_->begin();
00806 idv != displacedVertices_->end(); idv++){
00807 i++;
00808 out << i << " "; idv->Dump(); out << "" << endl;
00809 }
00810 }
00811
00812 return out;
00813 }