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] && isCloseTo(tempDisplacedVertexSeeds[idv_mother], tempDisplacedVertexSeeds[idv_daughter])) {
00214
00215 tempDisplacedVertexSeeds[idv_mother].mergeWith(tempDisplacedVertexSeeds[idv_daughter]);
00216 bLocked[idv_daughter] = true;
00217 if (debug_) cout << "Seeds " << idv_mother << " and " << idv_daughter << " merged" << endl;
00218
00219 }
00220 }
00221 }
00222 }
00223
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233 bool
00234 PFDisplacedVertexFinder::fitVertexFromSeed(PFDisplacedVertexSeed& displacedVertexSeed, PFDisplacedVertex& displacedVertex) {
00235
00236
00237 if (debug_) cout << "== Start vertexing procedure ==" << endl;
00238
00239
00240
00241
00242 set < TrackBaseRef, PFDisplacedVertexSeed::Compare > tracksToFit = displacedVertexSeed.elements();
00243 GlobalPoint seedPoint = displacedVertexSeed.seedPoint();
00244
00245 vector<TransientTrack> transTracks;
00246 vector<TransientTrack> transTracksRaw;
00247 vector<TrackBaseRef> transTracksRef;
00248 vector<TrackBaseRef> transTracksRefRaw;
00249
00250 transTracks.reserve(tracksToFit.size());
00251 transTracksRaw.reserve(tracksToFit.size());
00252 transTracksRef.reserve(tracksToFit.size());
00253 transTracksRefRaw.reserve(tracksToFit.size());
00254
00255
00256
00257 TransientVertex theVertexAdaptiveRaw;
00258 TransientVertex theRecoVertex;
00259
00260
00261
00262
00263
00264 if (tracksToFit.size() < 2) {
00265 if (debug_) cout << "Only one to Fit Track" << endl;
00266 return true;
00267 }
00268
00269 double rho = sqrt(seedPoint.x()*seedPoint.x()+seedPoint.y()*seedPoint.y());
00270 double z = seedPoint.z();
00271
00272 if (rho > tobCut_ || fabs(z) > tecCut_) {
00273 if (debug_) cout << "Seed Point out of the tracker rho = " << rho << " z = "<< z << " nTracks = " << tracksToFit.size() << endl;
00274 return true;
00275 }
00276
00277 if (debug_) displacedVertexSeed.Dump();
00278
00279 int nStep45 = 0;
00280 int nNotIterative = 0;
00281
00282
00283 for(IEset ie = tracksToFit.begin(); ie != tracksToFit.end(); ie++){
00284 TransientTrack tmpTk( *((*ie).get()), magField_, globTkGeomHandle_);
00285 transTracksRaw.push_back( tmpTk );
00286 transTracksRefRaw.push_back( *ie );
00287 if ( (*ie)->algo()-4 > 3 ) nStep45++;
00288 if ( (*ie)->algo()-4 < 0 ||(*ie)->algo()-4 > 5 ) nNotIterative++;
00289 }
00290
00291 if (rho > 25 && nStep45 + nNotIterative < 1){
00292 if (debug_) cout << "Seed point at rho > 25 cm but no step 4-5 tracks" << endl;
00293 return true;
00294 }
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 if ( transTracksRaw.size() == 2 ){
00306
00307 if (debug_) cout << "No raw fit done" << endl;
00308
00309 GlobalError globalError;
00310
00311 theVertexAdaptiveRaw = TransientVertex(seedPoint, globalError, transTracksRaw, 1.);
00312
00313
00314
00315 } else {
00316
00317
00318
00319 if (debug_) cout << "Raw fit done." << endl;
00320
00321 AdaptiveVertexFitter theAdaptiveFitterRaw(GeometricAnnealing(sigmacut_, t_ini_, ratio_),
00322 DefaultLinearizationPointFinder(),
00323 KalmanVertexUpdator<5>(),
00324 KalmanVertexTrackCompatibilityEstimator<5>(),
00325 KalmanVertexSmoother() );
00326
00329
00330
00331 if ( transTracksRaw.size() < 10 ){
00332
00333 if (debug_) cout << "First test with KFT" << endl;
00334
00335 KalmanVertexFitter theKalmanFitter(true);
00336 theVertexAdaptiveRaw = theKalmanFitter.vertex(transTracksRaw, seedPoint);
00337
00338 if( !theVertexAdaptiveRaw.isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0. ) {
00339 if(debug_) cout << "Prefit failed : valid? " << theVertexAdaptiveRaw.isValid()
00340 << " totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
00341 return true;
00342 }
00343
00344 if (debug_) cout << "We use KFT instead of seed point to set up a point for AVF "
00345 << " x = " << theVertexAdaptiveRaw.position().x()
00346 << " y = " << theVertexAdaptiveRaw.position().y()
00347 << " z = " << theVertexAdaptiveRaw.position().z()
00348 << endl;
00349
00350
00351
00352
00353 Vertex vtx = theVertexAdaptiveRaw;
00354 rho = vtx.position().rho();
00355
00356 if (rho < primaryVertexCut_) {
00357 if (debug_) cout << "KFT Vertex geometrically rejected with tracks #rho = " << rho << endl;
00358 return true;
00359 }
00360
00361
00362 theVertexAdaptiveRaw = theAdaptiveFitterRaw.vertex(transTracksRaw, theVertexAdaptiveRaw.position());
00363
00364
00365 } else {
00366
00367
00368 theVertexAdaptiveRaw = theAdaptiveFitterRaw.vertex(transTracksRaw, seedPoint);
00369
00370 }
00371
00372 if( !theVertexAdaptiveRaw.isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0. ) {
00373 if(debug_) cout << "Fit failed : valid? " << theVertexAdaptiveRaw.isValid()
00374 << " totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
00375 return true;
00376 }
00377
00378
00379
00380
00381 Vertex vtx = theVertexAdaptiveRaw;
00382 rho = vtx.position().rho();
00383
00384 if (rho < primaryVertexCut_) {
00385 if (debug_) cout << "Vertex " << " geometrically rejected with " << transTracksRaw.size() << " tracks #rho = " << rho << endl;
00386 return true;
00387 }
00388
00389
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 for (unsigned i = 0; i < transTracksRaw.size(); i++) {
00401
00402 if (debug_) cout << "Raw Weight track " << i << " = " << theVertexAdaptiveRaw.trackWeight(transTracksRaw[i]) << endl;
00403
00404 if (theVertexAdaptiveRaw.trackWeight(transTracksRaw[i]) > minAdaptWeight_){
00405
00406 PFTrackHitFullInfo pattern = hitPattern_.analyze(tkerGeomHandle_, transTracksRefRaw[i], theVertexAdaptiveRaw);
00407
00408 PFDisplacedVertex::VertexTrackType vertexTrackType = getVertexTrackType(pattern);
00409
00410 if (vertexTrackType != PFDisplacedVertex::T_NOT_FROM_VERTEX){
00411
00412 bool bGoodTrack = helper_.isTrackSelected(transTracksRaw[i].track(), vertexTrackType);
00413
00414 if (bGoodTrack){
00415 transTracks.push_back(transTracksRaw[i]);
00416 transTracksRef.push_back(transTracksRefRaw[i]);
00417 } else {
00418 if (debug_)
00419 cout << "Track rejected nChi2 = " << transTracksRaw[i].track().normalizedChi2()
00420 << " pt = " << transTracksRaw[i].track().pt()
00421 << " dxy (wrt (0,0,0)) = " << transTracksRaw[i].track().dxy()
00422 << " nHits = " << transTracksRaw[i].track().numberOfValidHits()
00423 << " nOuterHits = " << transTracksRaw[i].track().trackerExpectedHitsOuter().numberOfHits() << endl;
00424 }
00425 } else {
00426
00427 if (debug_){
00428 cout << "Remove track because too far away from the vertex:" << endl;
00429 }
00430
00431 }
00432
00433 }
00434
00435 }
00436
00437
00438
00439 if (debug_) cout << "All Tracks " << transTracksRaw.size()
00440 << " with good weight " << transTracks.size() << endl;
00441
00442
00443
00444 FitterType vtxFitter = F_NOTDEFINED;
00445
00446 if (transTracks.size() < 2) return true;
00447 else if (transTracks.size() == 2)
00448 vtxFitter = F_KALMAN;
00449 else if (transTracks.size() > 2 && transTracksRaw.size() > transTracks.size())
00450 vtxFitter = F_ADAPTIVE;
00451 else if (transTracks.size() > 2 && transTracksRaw.size() == transTracks.size())
00452 vtxFitter = F_DONOTREFIT;
00453 else return true;
00454
00455 if (debug_) cout << "Vertex Fitter " << vtxFitter << endl;
00456
00457 if(vtxFitter == F_KALMAN){
00458
00459 KalmanVertexFitter theKalmanFitter(true);
00460 theRecoVertex = theKalmanFitter.vertex(transTracks, seedPoint);
00461
00462 } else if(vtxFitter == F_ADAPTIVE){
00463
00464 AdaptiveVertexFitter theAdaptiveFitter(
00465 GeometricAnnealing(sigmacut_, t_ini_, ratio_),
00466 DefaultLinearizationPointFinder(),
00467 KalmanVertexUpdator<5>(),
00468 KalmanVertexTrackCompatibilityEstimator<5>(),
00469 KalmanVertexSmoother() );
00470
00471 theRecoVertex = theAdaptiveFitter.vertex(transTracks, seedPoint);
00472
00473 } else if (vtxFitter == F_DONOTREFIT) {
00474 theRecoVertex = theVertexAdaptiveRaw;
00475 } else {
00476 return true;
00477 }
00478
00479
00480
00481
00482 if( !theRecoVertex.isValid() || theRecoVertex.totalChiSquared() < 0. ) {
00483 if (debug_) cout << "Refit failed : valid? " << theRecoVertex.isValid()
00484 << " totalChi2 = " << theRecoVertex.totalChiSquared() << endl;
00485 return true;
00486 }
00487
00488
00489
00490 Vertex theRecoVtx = theRecoVertex;
00491
00492 double chi2 = theRecoVtx.chi2();
00493 double ndf = theRecoVtx.ndof();
00494
00495
00496 if (chi2 > TMath::ChisquareQuantile(0.95, ndf)) {
00497 if (debug_)
00498 cout << "Rejected because of chi2 = " << chi2 << " ndf = " << ndf << " confid. level: " << TMath::ChisquareQuantile(0.95, ndf) << endl;
00499 return true;
00500 }
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 displacedVertex = (PFDisplacedVertex) theRecoVtx;
00512 displacedVertex.removeTracks();
00513
00514 for(unsigned i = 0; i < transTracks.size();i++) {
00515
00516 PFTrackHitFullInfo pattern = hitPattern_.analyze(tkerGeomHandle_, transTracksRef[i], theRecoVertex);
00517
00518 PFDisplacedVertex::VertexTrackType vertexTrackType = getVertexTrackType(pattern);
00519
00520 Track refittedTrack;
00521 float weight = theRecoVertex.trackWeight(transTracks[i]);
00522
00523
00524 if (weight < minAdaptWeight_) continue;
00525
00526 try{
00527 refittedTrack = theRecoVertex.refittedTrack(transTracks[i]).track();
00528 }catch( cms::Exception& exception ){
00529 continue;
00530 }
00531
00532 if (debug_){
00533 cout << "Vertex Track Type = " << vertexTrackType << endl;
00534
00535 cout << "nHitBeforeVertex = " << pattern.first.first
00536 << " nHitAfterVertex = " << pattern.second.first
00537 << " nMissHitBeforeVertex = " << pattern.first.second
00538 << " nMissHitAfterVertex = " << pattern.second.second
00539 << " Weight = " << weight << endl;
00540 }
00541
00542 displacedVertex.addElement(transTracksRef[i],
00543 refittedTrack,
00544 pattern, vertexTrackType, weight);
00545
00546 }
00547
00548 displacedVertex.setPrimaryDirection(helper_.primaryVertex());
00549 displacedVertex.calcKinematics();
00550
00551
00552
00553 if (debug_) cout << "== End vertexing procedure ==" << endl;
00554
00555 return false;
00556
00557 }
00558
00559
00560
00561
00562
00563
00564 void
00565 PFDisplacedVertexFinder::selectAndLabelVertices(PFDisplacedVertexCollection& tempDisplacedVertices, vector <bool>& bLocked){
00566
00567 if (debug_) cout << " 4.1) Reject vertices " << endl;
00568
00569 for(unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++){
00570
00571
00572
00573
00574
00575
00576 const float rho = tempDisplacedVertices[idv].position().rho();
00577 const float z = tempDisplacedVertices[idv].position().z();
00578
00579 if (rho > tobCut_ || rho < primaryVertexCut_ || fabs(z) > tecCut_) {
00580 if (debug_) cout << "Vertex " << idv
00581 << " geometrically rejected #rho = " << rho
00582 << " z = " << z << endl;
00583
00584 bLocked[idv] = true;
00585
00586 continue;
00587 }
00588
00589 unsigned nPrimary = tempDisplacedVertices[idv].nPrimaryTracks();
00590 unsigned nMerged = tempDisplacedVertices[idv].nMergedTracks();
00591 unsigned nSecondary = tempDisplacedVertices[idv].nSecondaryTracks();
00592
00593 if (nPrimary + nMerged > 1) {
00594 bLocked[idv] = true;
00595 if (debug_) cout << "Vertex " << idv
00596 << " rejected because two primary or merged tracks" << endl;
00597
00598
00599 }
00600
00601 if (nPrimary + nMerged + nSecondary < 2){
00602 bLocked[idv] = true;
00603 if (debug_) cout << "Vertex " << idv
00604 << " rejected because only one track related to the vertex" << endl;
00605 }
00606
00607
00608 }
00609
00610
00611 if (debug_) cout << " 4.2) Check for common vertices" << endl;
00612
00613
00614
00615
00616 for(unsigned idv_mother = 0; idv_mother < tempDisplacedVertices.size(); idv_mother++){
00617 for(unsigned idv_daughter = idv_mother+1;
00618 idv_daughter < tempDisplacedVertices.size(); idv_daughter++){
00619
00620 if(!bLocked[idv_daughter] && !bLocked[idv_mother]){
00621
00622 const unsigned commonTrks = commonTracks(tempDisplacedVertices[idv_daughter], tempDisplacedVertices[idv_mother]);
00623
00624 if (commonTrks > 1) {
00625
00626 if (debug_) cout << "Vertices " << idv_daughter << " and " << idv_mother
00627 << " has many common tracks" << endl;
00628
00629
00630
00631 const int mother_size = tempDisplacedVertices[idv_mother].nTracks();
00632 const int daughter_size = tempDisplacedVertices[idv_daughter].nTracks();
00633
00634 if (mother_size > daughter_size) bLocked[idv_daughter] = true;
00635 else if (mother_size < daughter_size) bLocked[idv_mother] = true;
00636 else {
00637
00638
00639
00640 const float mother_normChi2 = tempDisplacedVertices[idv_mother].normalizedChi2();
00641 const float daughter_normChi2 = tempDisplacedVertices[idv_daughter].normalizedChi2();
00642 if (mother_normChi2 < daughter_normChi2) bLocked[idv_daughter] = true;
00643 else bLocked[idv_mother] = true;
00644 }
00645
00646 }
00647 }
00648 }
00649 }
00650
00651 for(unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
00652 if ( !bLocked[idv] ) bLocked[idv] = rejectAndLabelVertex(tempDisplacedVertices[idv]);
00653
00654
00655 }
00656
00657 bool
00658 PFDisplacedVertexFinder::rejectAndLabelVertex(PFDisplacedVertex& dv){
00659
00660 PFDisplacedVertex::VertexType vertexType = helper_.identifyVertex(dv);
00661 dv.setVertexType(vertexType);
00662
00663 return dv.isFake();
00664
00665 }
00666
00667
00669
00670 bool
00671 PFDisplacedVertexFinder::isCloseTo(const PFDisplacedVertexSeed& dv1, const PFDisplacedVertexSeed& dv2) const {
00672
00673 bool isCloseTo = false;
00674
00675 const GlobalPoint vP1 = dv1.seedPoint();
00676 const GlobalPoint vP2 = dv2.seedPoint();
00677
00678 double Delta_Long = getLongDiff(vP1, vP2);
00679 double Delta_Transv = getTransvDiff(vP1, vP2);
00680 if (Delta_Long < longSize_ && Delta_Transv < transvSize_) isCloseTo = true;
00681
00682 return isCloseTo;
00683
00684 }
00685
00686
00687 double
00688 PFDisplacedVertexFinder::getLongDiff(const GlobalPoint& Ref, const GlobalPoint& ToProject) const {
00689
00690 Basic3DVector<double>vRef(Ref);
00691 Basic3DVector<double>vToProject(ToProject);
00692 return fabs((vRef.dot(vToProject)-vRef.mag2())/vRef.mag());
00693
00694 }
00695
00696 double
00697 PFDisplacedVertexFinder::getLongProj(const GlobalPoint& Ref, const GlobalVector& ToProject) const {
00698
00699 Basic3DVector<double>vRef(Ref);
00700 Basic3DVector<double>vToProject(ToProject);
00701 return (vRef.dot(vToProject))/vRef.mag();
00702
00703
00704 }
00705
00706
00707 double
00708 PFDisplacedVertexFinder::getTransvDiff(const GlobalPoint& Ref, const GlobalPoint& ToProject) const {
00709
00710 Basic3DVector<double>vRef(Ref);
00711 Basic3DVector<double>vToProject(ToProject);
00712 return fabs(vRef.cross(vToProject).mag()/vRef.mag());
00713
00714 }
00715
00716
00717 reco::PFDisplacedVertex::VertexTrackType
00718 PFDisplacedVertexFinder::getVertexTrackType(PFTrackHitFullInfo& pairTrackHitInfo) const {
00719
00720 unsigned int nHitBeforeVertex = pairTrackHitInfo.first.first;
00721 unsigned int nHitAfterVertex = pairTrackHitInfo.second.first;
00722
00723 unsigned int nMissHitBeforeVertex = pairTrackHitInfo.first.second;
00724 unsigned int nMissHitAfterVertex = pairTrackHitInfo.second.second;
00725
00726
00727
00728 if (nHitBeforeVertex <= 1 && nHitAfterVertex >= 3 && nMissHitAfterVertex <= 1)
00729 return PFDisplacedVertex::T_FROM_VERTEX;
00730 else if (nHitBeforeVertex >= 3 && nHitAfterVertex <= 1 && nMissHitBeforeVertex <= 1)
00731 return PFDisplacedVertex::T_TO_VERTEX;
00732 else if ((nHitBeforeVertex >= 2 && nHitAfterVertex >= 3)
00733 ||
00734 (nHitBeforeVertex >= 3 && nHitAfterVertex >= 2))
00735 return PFDisplacedVertex::T_MERGED;
00736 else
00737 return PFDisplacedVertex::T_NOT_FROM_VERTEX;
00738 }
00739
00740
00741 unsigned PFDisplacedVertexFinder::commonTracks(const PFDisplacedVertex& v1, const PFDisplacedVertex& v2) const {
00742
00743 vector<Track> vt1 = v1.refittedTracks();
00744 vector<Track> vt2 = v2.refittedTracks();
00745
00746 unsigned commonTracks = 0;
00747
00748 for ( unsigned il1 = 0; il1 < vt1.size(); il1++){
00749 unsigned il1_idx = v1.originalTrack(vt1[il1]).key();
00750
00751 for ( unsigned il2 = 0; il2 < vt2.size(); il2++)
00752 if (il1_idx == v2.originalTrack(vt2[il2]).key()) {commonTracks++; break;}
00753
00754 }
00755
00756 return commonTracks;
00757
00758 }
00759
00760 std::ostream& operator<<(std::ostream& out, const PFDisplacedVertexFinder& a) {
00761
00762 if(! out) return out;
00763 out << setprecision(3) << setw(5) << endl;
00764 out << "" << endl;
00765 out << " ====================================== " << endl;
00766 out << " ====== Displaced Vertex Finder ======= " << endl;
00767 out << " ====================================== " << endl;
00768 out << " " << endl;
00769
00770 a.helper_.Dump();
00771 out << "" << endl
00772 << " Adaptive Vertex Fitter parameters are :"<< endl
00773 << " sigmacut = " << a.sigmacut_ << " T_ini = "
00774 << a.t_ini_ << " ratio = " << a.ratio_ << endl << endl;
00775
00776 const std::auto_ptr< reco::PFDisplacedVertexCollection >& displacedVertices_
00777 = a.displacedVertices();
00778
00779
00780 if(!displacedVertices_.get() ) {
00781 out<<"displacedVertex already transfered"<<endl;
00782 }
00783 else{
00784
00785 out<<"Number of displacedVertices found : "<< displacedVertices_->size()<<endl<<endl;
00786
00787 int i = -1;
00788
00789 for(PFDisplacedVertexFinder::IDV idv = displacedVertices_->begin();
00790 idv != displacedVertices_->end(); idv++){
00791 i++;
00792 out << i << " "; idv->Dump(); out << "" << endl;
00793 }
00794 }
00795
00796 return out;
00797 }