29 : displacedVertexCandidates_(
nullptr),
33 primaryVertexCut_(0.0),
43 if (displacedVertexCandidates.
isValid()) {
54 cout <<
"========= Start Find Displaced Vertices =========" << endl;
65 <<
"displacedVertexCandidates are not set or the setInput was called with invalid vertex";
76 cout <<
"1) Parsing displacedVertexCandidates into displacedVertexSeeds" << endl;
86 cout <<
"Analyse Vertex Candidate " << i << endl;
93 cout <<
"2) Merging Vertex Seeds" << endl;
98 vector<bool> bLockedSeeds;
99 bLockedSeeds.resize(tempDisplacedVertexSeeds.size());
100 mergeSeeds(tempDisplacedVertexSeeds, bLockedSeeds);
103 cout <<
"3) Fitting Vertices From Seeds" << endl;
106 for (
unsigned idv = 0; idv < tempDisplacedVertexSeeds.size(); idv++) {
107 if (!tempDisplacedVertexSeeds[idv].isEmpty() && !bLockedSeeds[idv]) {
109 bLockedSeeds[idv] =
fitVertexFromSeed(tempDisplacedVertexSeeds[idv], displacedVertex);
110 if (!bLockedSeeds[idv])
111 tempDisplacedVertices.emplace_back(displacedVertex);
116 cout <<
"4) Rejecting Bad Vertices and label them" << endl;
119 vector<bool> bLocked;
120 bLocked.resize(tempDisplacedVertices.size());
124 cout <<
"5) Fill the Displaced Vertices" << endl;
129 for (
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
134 cout <<
"========= End Find Displaced Vertices =========" << endl;
142 bool bNeedNewCandidate =
false;
148 for (PFDisplacedVertexCandidate::DistMap::const_iterator imap = r2Map.begin(); imap != r2Map.end(); imap++) {
149 unsigned ie1 = (*imap).second.first;
150 unsigned ie2 = (*imap).second.second;
153 cout <<
"ie1 = " << ie1 <<
" ie2 = " << ie2 <<
" radius = " <<
sqrt((*imap).first) << endl;
156 if (fabs(dcaPoint.
x()) > 1e9)
159 bNeedNewCandidate =
true;
160 for (idvc_current = tempDisplacedVertexSeeds.begin(); idvc_current != tempDisplacedVertexSeeds.end();
162 if ((*idvc_current).isEmpty()) {
163 bNeedNewCandidate =
false;
166 const GlobalPoint vertexPoint = (*idvc_current).seedPoint();
172 bNeedNewCandidate =
false;
175 if (bNeedNewCandidate) {
177 cout <<
"create new displaced vertex" << endl;
179 idvc_current = tempDisplacedVertexSeeds.end();
183 (*idvc_current).updateSeedPoint(dcaPoint, vertexCandidate.
tref(ie1), vertexCandidate.
tref(ie2));
188 vector<bool>& bLocked) {
191 for (
unsigned idv_mother = 0; idv_mother < tempDisplacedVertexSeeds.size(); idv_mother++) {
192 if (!bLocked[idv_mother]) {
193 for (
unsigned idv_daughter = idv_mother + 1; idv_daughter < tempDisplacedVertexSeeds.size(); idv_daughter++) {
194 if (!bLocked[idv_daughter]) {
195 if (
isCloseTo(tempDisplacedVertexSeeds[idv_mother], tempDisplacedVertexSeeds[idv_daughter])) {
196 tempDisplacedVertexSeeds[idv_mother].mergeWith(tempDisplacedVertexSeeds[idv_daughter]);
197 bLocked[idv_daughter] =
true;
199 cout <<
"Seeds " << idv_mother <<
" and " << idv_daughter <<
" merged" << endl;
210 cout <<
"== Start vertexing procedure ==" << endl;
214 auto const& tracksToFit = displacedVertexSeed.
elements();
217 vector<TransientTrack> transTracks;
218 vector<TransientTrack> transTracksRaw;
219 vector<TrackBaseRef> transTracksRef;
221 transTracks.reserve(tracksToFit.size());
222 transTracksRaw.reserve(tracksToFit.size());
223 transTracksRef.reserve(tracksToFit.size());
231 if (tracksToFit.size() < 2) {
233 cout <<
"Only one to Fit Track" << endl;
237 double rho =
sqrt(seedPoint.
x() * seedPoint.
x() + seedPoint.
y() * seedPoint.
y());
238 double z = seedPoint.
z();
242 cout <<
"Seed Point out of the tracker rho = " << rho <<
" z = " << z <<
" nTracks = " << tracksToFit.size()
248 displacedVertexSeed.
Dump();
251 int nNotIterative = 0;
254 for (
auto const& ie : tracksToFit) {
256 transTracksRaw.emplace_back(tmpTk);
270 if (rho > 25 && nStep45 + nNotIterative < 1) {
272 cout <<
"Seed point at rho > 25 cm but no step 4-5 tracks" << endl;
282 if (transTracksRaw.size() == 2) {
284 cout <<
"No raw fit done" << endl;
287 cout <<
"Due to probably high pile-up conditions 2 track vertices switched off" << endl;
292 theVertexAdaptiveRaw =
TransientVertex(seedPoint, globalError, transTracksRaw, 1.);
297 cout <<
"Raw fit done." << endl;
305 if (transTracksRaw.size() == 3) {
306 theVertexAdaptiveRaw = theAdaptiveFitterRaw.
vertex(transTracksRaw, seedPoint);
308 }
else if (transTracksRaw.size() < 1000) {
313 cout <<
"First test with KFT" << endl;
316 theVertexAdaptiveRaw = theKalmanFitter.
vertex(transTracksRaw, seedPoint);
320 cout <<
"Prefit failed : valid? " << theVertexAdaptiveRaw.
isValid()
326 cout <<
"We use KFT instead of seed point to set up a point for AVF " 327 <<
" x = " << theVertexAdaptiveRaw.
position().
x() <<
" y = " << theVertexAdaptiveRaw.
position().
y()
328 <<
" z = " << theVertexAdaptiveRaw.
position().
z() << endl;
338 if (rho < primaryVertexCut_ || rho > 100) {
340 cout <<
"KFT Vertex geometrically rejected with tracks #rho = " << rho << endl;
346 theVertexAdaptiveRaw = theAdaptiveFitterRaw.
vertex(transTracksRaw, theVertexAdaptiveRaw.
position());
349 edm::LogWarning(
"TooManyPFDVCandidates") <<
"gave up vertex reco for " << transTracksRaw.size() <<
" tracks";
354 cout <<
"Fit failed : valid? " << theVertexAdaptiveRaw.
isValid()
368 <<
" geometrically rejected with " << transTracksRaw.size() <<
" tracks #rho = " << rho << endl;
377 for (
unsigned i = 0;
i < transTracksRaw.size();
i++) {
379 cout <<
"Raw Weight track " <<
i <<
" = " << theVertexAdaptiveRaw.
trackWeight(transTracksRaw[
i]) << endl;
386 if (vertexTrackType != PFDisplacedVertex::T_NOT_FROM_VERTEX) {
390 transTracks.push_back(transTracksRaw[i]);
391 transTracksRef.push_back(tracksToFit[i]);
394 cout <<
"Track rejected nChi2 = " << transTracksRaw[
i].track().normalizedChi2()
395 <<
" pt = " << transTracksRaw[
i].track().pt()
396 <<
" dxy (wrt (0,0,0)) = " << transTracksRaw[
i].track().dxy()
397 <<
" nHits = " << transTracksRaw[
i].track().numberOfValidHits() <<
" nOuterHits = " 398 << transTracksRaw[
i].track().hitPattern().numberOfLostHits(HitPattern::MISSING_OUTER_HITS) << endl;
402 cout <<
"Remove track because too far away from the vertex:" << endl;
409 cout <<
"All Tracks " << transTracksRaw.size() <<
" with good weight " << transTracks.size() << endl;
414 if (transTracks.size() < 2)
416 else if (transTracks.size() == 2) {
419 cout <<
"Due to probably high pile-up conditions 2 track vertices switched off" << endl;
423 }
else if (transTracks.size() > 2 && transTracksRaw.size() > transTracks.size())
425 else if (transTracks.size() > 2 && transTracksRaw.size() == transTracks.size())
431 cout <<
"Vertex Fitter " << vtxFitter << endl;
435 theRecoVertex = theKalmanFitter.
vertex(transTracks, seedPoint);
444 theRecoVertex = theAdaptiveFitter.
vertex(transTracks, seedPoint);
447 theRecoVertex = theVertexAdaptiveRaw;
463 Vertex theRecoVtx = theRecoVertex;
466 double ndf = theRecoVtx.
ndof();
468 if (chi2 > TMath::ChisquareQuantile(0.95, ndf)) {
470 cout <<
"Rejected because of chi2 = " << chi2 <<
" ndf = " << ndf
471 <<
" confid. level: " << TMath::ChisquareQuantile(0.95, ndf) << endl;
481 displacedVertex = theRecoVtx;
484 for (
unsigned i = 0;
i < transTracks.size();
i++) {
502 cout <<
"Vertex Track Type = " << vertexTrackType << endl;
504 cout <<
"nHitBeforeVertex = " << pattern.first.first <<
" nHitAfterVertex = " << pattern.second.first
505 <<
" nMissHitBeforeVertex = " << pattern.first.second <<
" nMissHitAfterVertex = " << pattern.second.second
506 <<
" Weight = " << weight << endl;
509 displacedVertex.
addElement(transTracksRef[i], refittedTrack, pattern, vertexTrackType, weight);
516 cout <<
"== End vertexing procedure ==" << endl;
522 vector<bool>& bLocked) {
524 cout <<
" 4.1) Reject vertices " << endl;
526 for (
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++) {
531 const float rho = tempDisplacedVertices[idv].position().rho();
532 const float z = tempDisplacedVertices[idv].position().z();
536 cout <<
"Vertex " << idv <<
" geometrically rejected #rho = " << rho <<
" z = " << z << endl;
543 unsigned nPrimary = tempDisplacedVertices[idv].nPrimaryTracks();
544 unsigned nMerged = tempDisplacedVertices[idv].nMergedTracks();
545 unsigned nSecondary = tempDisplacedVertices[idv].nSecondaryTracks();
547 if (nPrimary + nMerged > 1) {
550 cout <<
"Vertex " << idv <<
" rejected because two primary or merged tracks" << endl;
553 if (nPrimary + nMerged + nSecondary < 2) {
556 cout <<
"Vertex " << idv <<
" rejected because only one track related to the vertex" << endl;
561 cout <<
" 4.2) Check for common vertices" << endl;
566 for (
unsigned idv_mother = 0; idv_mother < tempDisplacedVertices.size(); idv_mother++) {
567 for (
unsigned idv_daughter = idv_mother + 1; idv_daughter < tempDisplacedVertices.size(); idv_daughter++) {
568 if (!bLocked[idv_daughter] && !bLocked[idv_mother]) {
569 const unsigned commonTrks =
570 commonTracks(tempDisplacedVertices[idv_daughter], tempDisplacedVertices[idv_mother]);
572 if (commonTrks > 1) {
574 cout <<
"Vertices " << idv_daughter <<
" and " << idv_mother <<
" has many common tracks" << endl;
578 const int mother_size = tempDisplacedVertices[idv_mother].nTracks();
579 const int daughter_size = tempDisplacedVertices[idv_daughter].nTracks();
581 if (mother_size > daughter_size)
582 bLocked[idv_daughter] =
true;
583 else if (mother_size < daughter_size)
584 bLocked[idv_mother] =
true;
588 const float mother_normChi2 = tempDisplacedVertices[idv_mother].normalizedChi2();
589 const float daughter_normChi2 = tempDisplacedVertices[idv_daughter].normalizedChi2();
590 if (mother_normChi2 < daughter_normChi2)
591 bLocked[idv_daughter] =
true;
593 bLocked[idv_mother] =
true;
600 for (
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
632 float vRefMag2 = vRef.
mag2();
633 float oneOverMag = 1.0f /
sqrt(vRefMag2);
635 return std::make_pair(fabs(vRef.cross(vToProject).mag() * oneOverMag),
636 fabs((vRef.dot(vToProject) - vRefMag2) * oneOverMag));
641 unsigned int nHitBeforeVertex = pairTrackHitInfo.first.first;
642 unsigned int nHitAfterVertex = pairTrackHitInfo.second.first;
644 unsigned int nMissHitBeforeVertex = pairTrackHitInfo.first.second;
645 unsigned int nMissHitAfterVertex = pairTrackHitInfo.second.second;
649 if (nHitBeforeVertex <= 1 && nHitAfterVertex >= 3 && nMissHitAfterVertex <= 1)
650 return PFDisplacedVertex::T_FROM_VERTEX;
651 else if (nHitBeforeVertex >= 3 && nHitAfterVertex <= 1 && nMissHitBeforeVertex <= 1)
652 return PFDisplacedVertex::T_TO_VERTEX;
653 else if ((nHitBeforeVertex >= 2 && nHitAfterVertex >= 3) || (nHitBeforeVertex >= 3 && nHitAfterVertex >= 2))
654 return PFDisplacedVertex::T_MERGED;
656 return PFDisplacedVertex::T_NOT_FROM_VERTEX;
665 for (
unsigned il1 = 0; il1 < vt1.size(); il1++) {
668 for (
unsigned il2 = 0; il2 < vt2.size(); il2++)
681 out << setprecision(3) << setw(5) << endl;
683 out <<
" ====================================== " << endl;
684 out <<
" ====== Displaced Vertex Finder ======= " << endl;
685 out <<
" ====================================== " << endl;
690 <<
" Adaptive Vertex Fitter parameters are :" << endl
696 if (!displacedVertices_.get()) {
697 out <<
"displacedVertex already transfered" << endl;
699 out <<
"Number of displacedVertices found : " << displacedVertices_->size() << endl << endl;
std::vector< PFDisplacedVertex > PFDisplacedVertexCollection
collection of PFDisplacedVertex objects
edm::Ref< Container > Ref
const std::unique_ptr< reco::PFDisplacedVertexCollection > & displacedVertices() const
A block of tracks linked together.
void setPrimaryDirection(const math::XYZPoint &pvtx)
reco::PFDisplacedVertexSeedCollection::iterator IDVS
-----— Useful Types -----— ///
TrackBaseRef originalTrack(const Track &refTrack) const
edm::ESHandle< GlobalTrackingGeometry > globTkGeomHandle_
Tracker geometry for discerning hit positions.
const TrackerTopology * tkerTopo_
doc?
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.
bool rejectAndLabelVertex(reco::PFDisplacedVertex &dv)
CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &) const override
const std::vector< Track > & refittedTracks() const
Returns the container of refitted tracks.
void findDisplacedVertices()
-----— Main function which find vertices -----— ///
bool debug_
If true, debug printouts activated.
const Point & position() const
position
std::unique_ptr< reco::PFDisplacedVertexCollection > displacedVertices_
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
~PFDisplacedVertexFinder()
void Dump(std::ostream &out=std::cout) const
cout function
bool switchOff2TrackVertex_
PFDisplacedVertexFinder()
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
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 --—— ///
void selectAndLabelVertices(reco::PFDisplacedVertexCollection &, std::vector< bool > &)
Remove potentially fakes displaced vertices.
const MagneticField * magField_
to be able to extrapolate tracks f
double chi2() const
chi-squares
friend std::ostream & operator<<(std::ostream &, const PFDisplacedVertexFinder &)
CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &tracks) const override
DistMap r2Map() const
--—— Provide useful information --—— ///
void setInput(const edm::Handle< reco::PFDisplacedVertexCandidateCollection > &)
Set input collections of tracks.
float trackWeight(const reco::TransientTrack &track) const
std::pair< float, float > getTransvLongDiff(const GlobalPoint &, const GlobalPoint &) const
const GlobalPoint & seedPoint() const
T const * product() const
const Track & track() const
double sigmacut_
Adaptive Vertex Fitter parameters.
reco::PFDisplacedVertexCollection::iterator IDV
math::XYZPoint primaryVertex() const
Set Vertex direction using the primary vertex.
float transvSize_
--—— Parameters --—— ///
const TrackerGeometry * tkerGeom_
std::map< float, std::pair< int, int > > DistMap
bool isCloseTo(const reco::PFDisplacedVertexSeed &, const reco::PFDisplacedVertexSeed &) const
-----— Tools -----— ///
PFCheckHitPattern hitPattern_
const std::vector< TrackBaseRef > & elements() const
const BasicVectorType & basicVector() const
reco::PFDisplacedVertex::VertexTrackType getVertexTrackType(PFTrackHitFullInfo &) const
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
PFDisplacedVertexHelper helper_