31 : displacedVertexCandidates_(nullptr),
35 primaryVertexCut_(0.0),
45 if (displacedVertexCandidates.
isValid()) {
56 cout <<
"========= Start Find Displaced Vertices =========" << endl;
67 <<
"displacedVertexCandidates are not set or the setInput was called with invalid vertex";
78 cout <<
"1) Parsing displacedVertexCandidates into displacedVertexSeeds" << endl;
88 cout <<
"Analyse Vertex Candidate " <<
i << endl;
95 cout <<
"2) Merging Vertex Seeds" << endl;
100 vector<bool> bLockedSeeds;
101 bLockedSeeds.resize(tempDisplacedVertexSeeds.size());
102 mergeSeeds(tempDisplacedVertexSeeds, bLockedSeeds);
105 cout <<
"3) Fitting Vertices From Seeds" << endl;
108 for (
unsigned idv = 0; idv < tempDisplacedVertexSeeds.size(); idv++) {
109 if (!tempDisplacedVertexSeeds[idv].isEmpty() && !bLockedSeeds[idv]) {
111 bLockedSeeds[idv] =
fitVertexFromSeed(tempDisplacedVertexSeeds[idv], displacedVertex);
112 if (!bLockedSeeds[idv])
113 tempDisplacedVertices.emplace_back(displacedVertex);
118 cout <<
"4) Rejecting Bad Vertices and label them" << endl;
121 vector<bool> bLocked;
122 bLocked.resize(tempDisplacedVertices.size());
126 cout <<
"5) Fill the Displaced Vertices" << endl;
131 for (
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
136 cout <<
"========= End Find Displaced Vertices =========" << endl;
144 bool bNeedNewCandidate =
false;
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;
155 cout <<
"ie1 = " << ie1 <<
" ie2 = " << ie2 <<
" radius = " <<
sqrt((*imap).first) << endl;
158 if (fabs(dcaPoint.
x()) > 1e9)
161 bNeedNewCandidate =
true;
162 for (idvc_current = tempDisplacedVertexSeeds.begin(); idvc_current != tempDisplacedVertexSeeds.end();
164 if ((*idvc_current).isEmpty()) {
165 bNeedNewCandidate =
false;
168 const GlobalPoint vertexPoint = (*idvc_current).seedPoint();
174 bNeedNewCandidate =
false;
177 if (bNeedNewCandidate) {
179 cout <<
"create new displaced vertex" << endl;
181 idvc_current = tempDisplacedVertexSeeds.end();
185 (*idvc_current).updateSeedPoint(dcaPoint, vertexCandidate.
tref(ie1), vertexCandidate.
tref(ie2));
190 vector<bool>& bLocked) {
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;
201 cout <<
"Seeds " << idv_mother <<
" and " << idv_daughter <<
" merged" << endl;
212 cout <<
"== Start vertexing procedure ==" << endl;
216 auto const& tracksToFit = displacedVertexSeed.
elements();
219 vector<TransientTrack> transTracks;
220 vector<TransientTrack> transTracksRaw;
221 vector<TrackBaseRef> transTracksRef;
223 transTracks.reserve(tracksToFit.size());
224 transTracksRaw.reserve(tracksToFit.size());
225 transTracksRef.reserve(tracksToFit.size());
233 if (tracksToFit.size() < 2) {
235 cout <<
"Only one to Fit Track" << endl;
239 double rho =
sqrt(seedPoint.
x() * seedPoint.
x() + seedPoint.
y() * seedPoint.
y());
240 double z = seedPoint.
z();
244 cout <<
"Seed Point out of the tracker rho = " <<
rho <<
" z = " <<
z <<
" nTracks = " << tracksToFit.size()
250 displacedVertexSeed.
Dump();
253 int nNotIterative = 0;
256 for (
auto const& ie : tracksToFit) {
258 transTracksRaw.emplace_back(tmpTk);
272 if (
rho > 25 && nStep45 + nNotIterative < 1) {
274 cout <<
"Seed point at rho > 25 cm but no step 4-5 tracks" << endl;
284 if (transTracksRaw.size() == 2) {
286 cout <<
"No raw fit done" << endl;
289 cout <<
"Due to probably high pile-up conditions 2 track vertices switched off" << endl;
294 theVertexAdaptiveRaw =
TransientVertex(seedPoint, globalError, transTracksRaw, 1.);
299 cout <<
"Raw fit done." << endl;
307 if (transTracksRaw.size() == 3) {
308 theVertexAdaptiveRaw = theAdaptiveFitterRaw.
vertex(transTracksRaw, seedPoint);
310 }
else if (transTracksRaw.size() < 1000) {
315 cout <<
"First test with KFT" << endl;
318 theVertexAdaptiveRaw = theKalmanFitter.
vertex(transTracksRaw, seedPoint);
320 if (!theVertexAdaptiveRaw.
isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0.) {
322 cout <<
"Prefit failed : valid? " << theVertexAdaptiveRaw.
isValid()
323 <<
" totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
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;
336 rho =
vtx.position().rho();
340 if (rho < primaryVertexCut_ || rho > 100) {
342 cout <<
"KFT Vertex geometrically rejected with tracks #rho = " <<
rho << endl;
348 theVertexAdaptiveRaw = theAdaptiveFitterRaw.
vertex(transTracksRaw, theVertexAdaptiveRaw.
position());
351 edm::LogWarning(
"TooManyPFDVCandidates") <<
"gave up vertex reco for " << transTracksRaw.size() <<
" tracks";
354 if (!theVertexAdaptiveRaw.
isValid() || theVertexAdaptiveRaw.totalChiSquared() < 0.) {
356 cout <<
"Fit failed : valid? " << theVertexAdaptiveRaw.
isValid()
357 <<
" totalChi2 = " << theVertexAdaptiveRaw.totalChiSquared() << endl;
365 rho =
vtx.position().rho();
370 <<
" geometrically rejected with " << transTracksRaw.size() <<
" tracks #rho = " <<
rho << endl;
379 for (
unsigned i = 0;
i < transTracksRaw.size();
i++) {
381 cout <<
"Raw Weight track " <<
i <<
" = " << theVertexAdaptiveRaw.
trackWeight(transTracksRaw[
i]) << endl;
388 if (vertexTrackType != PFDisplacedVertex::T_NOT_FROM_VERTEX) {
392 transTracks.push_back(transTracksRaw[
i]);
393 transTracksRef.push_back(tracksToFit[
i]);
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;
404 cout <<
"Remove track because too far away from the vertex:" << endl;
411 cout <<
"All Tracks " << transTracksRaw.size() <<
" with good weight " << transTracks.size() << endl;
416 if (transTracks.size() < 2)
418 else if (transTracks.size() == 2) {
421 cout <<
"Due to probably high pile-up conditions 2 track vertices switched off" << endl;
425 }
else if (transTracks.size() > 2 && transTracksRaw.size() > transTracks.size())
427 else if (transTracks.size() > 2 && transTracksRaw.size() == transTracks.size())
433 cout <<
"Vertex Fitter " << vtxFitter << endl;
437 theRecoVertex = theKalmanFitter.
vertex(transTracks, seedPoint);
446 theRecoVertex = theAdaptiveFitter.
vertex(transTracks, seedPoint);
449 theRecoVertex = theVertexAdaptiveRaw;
456 if (!theRecoVertex.
isValid() || theRecoVertex.totalChiSquared() < 0.) {
458 cout <<
"Refit failed : valid? " << theRecoVertex.
isValid() <<
" totalChi2 = " << theRecoVertex.totalChiSquared()
465 Vertex theRecoVtx = theRecoVertex;
468 double ndf = theRecoVtx.
ndof();
470 if (
chi2 > TMath::ChisquareQuantile(0.95, ndf)) {
472 cout <<
"Rejected because of chi2 = " <<
chi2 <<
" ndf = " << ndf
473 <<
" confid. level: " << TMath::ChisquareQuantile(0.95, ndf) << endl;
483 displacedVertex = theRecoVtx;
486 for (
unsigned i = 0;
i < transTracks.size();
i++) {
504 cout <<
"Vertex Track Type = " << vertexTrackType << endl;
506 cout <<
"nHitBeforeVertex = " <<
pattern.first.first <<
" nHitAfterVertex = " <<
pattern.second.first
507 <<
" nMissHitBeforeVertex = " <<
pattern.first.second <<
" nMissHitAfterVertex = " <<
pattern.second.second
508 <<
" Weight = " <<
weight << endl;
518 cout <<
"== End vertexing procedure ==" << endl;
524 vector<bool>& bLocked) {
526 cout <<
" 4.1) Reject vertices " << endl;
528 for (
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++) {
533 const float rho = tempDisplacedVertices[idv].position().rho();
534 const float z = tempDisplacedVertices[idv].position().z();
538 cout <<
"Vertex " << idv <<
" geometrically rejected #rho = " <<
rho <<
" z = " <<
z << endl;
545 unsigned nPrimary = tempDisplacedVertices[idv].nPrimaryTracks();
546 unsigned nMerged = tempDisplacedVertices[idv].nMergedTracks();
547 unsigned nSecondary = tempDisplacedVertices[idv].nSecondaryTracks();
549 if (nPrimary + nMerged > 1) {
552 cout <<
"Vertex " << idv <<
" rejected because two primary or merged tracks" << endl;
555 if (nPrimary + nMerged + nSecondary < 2) {
558 cout <<
"Vertex " << idv <<
" rejected because only one track related to the vertex" << endl;
563 cout <<
" 4.2) Check for common vertices" << endl;
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]);
574 if (commonTrks > 1) {
576 cout <<
"Vertices " << idv_daughter <<
" and " << idv_mother <<
" has many common tracks" << endl;
580 const int mother_size = tempDisplacedVertices[idv_mother].nTracks();
581 const int daughter_size = tempDisplacedVertices[idv_daughter].nTracks();
583 if (mother_size > daughter_size)
584 bLocked[idv_daughter] =
true;
585 else if (mother_size < daughter_size)
586 bLocked[idv_mother] =
true;
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;
595 bLocked[idv_mother] =
true;
602 for (
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
632 const auto& vRef =
Ref.basicVector();
634 float vRefMag2 = vRef.
mag2();
635 float oneOverMag = 1.0f /
sqrt(vRefMag2);
637 return std::make_pair(fabs(vRef.cross(vToProject).mag() * oneOverMag),
638 fabs((vRef.dot(vToProject) - vRefMag2) * oneOverMag));
643 unsigned int nHitBeforeVertex = pairTrackHitInfo.first.first;
644 unsigned int nHitAfterVertex = pairTrackHitInfo.second.first;
646 unsigned int nMissHitBeforeVertex = pairTrackHitInfo.first.second;
647 unsigned int nMissHitAfterVertex = pairTrackHitInfo.second.second;
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;
658 return PFDisplacedVertex::T_NOT_FROM_VERTEX;
667 for (
unsigned il1 = 0; il1 < vt1.size(); il1++) {
670 for (
unsigned il2 = 0; il2 < vt2.size(); il2++)
683 out << setprecision(3) << setw(5) << endl;
685 out <<
" ====================================== " << endl;
686 out <<
" ====== Displaced Vertex Finder ======= " << endl;
687 out <<
" ====================================== " << endl;
692 <<
" Adaptive Vertex Fitter parameters are :" << endl
693 <<
" sigmacut = " <<
a.sigmacut_ <<
" T_ini = " <<
a.t_ini_ <<
" ratio = " <<
a.ratio_ << endl
696 const std::unique_ptr<reco::PFDisplacedVertexCollection>& displacedVertices_ =
std::move(
a.displacedVertices());
698 if (!displacedVertices_.get()) {
699 out <<
"displacedVertex already transfered" << endl;
701 out <<
"Number of displacedVertices found : " << displacedVertices_->size() << endl << endl;