32 primaryVertexCut_(0.0),
52 if(displacedVertexCandidates.
isValid()) {
53 for(
unsigned i=0;
i<displacedVertexCandidates->size();
i++) {
67 if (
debug_)
cout <<
"========= Start Find Displaced Vertices =========" << endl;
83 cout <<
"1) Parsing displacedVertexCandidates into displacedVertexSeeds" << endl;
95 cout <<
"Analyse Vertex Candidate " << i << endl;
102 if (
debug_)
cout <<
"2) Merging Vertex Seeds" << endl;
107 vector<bool> bLockedSeeds;
108 bLockedSeeds.resize(tempDisplacedVertexSeeds.size());
109 mergeSeeds(tempDisplacedVertexSeeds, bLockedSeeds);
111 if (
debug_)
cout <<
"3) Fitting Vertices From Seeds" << endl;
114 for(
unsigned idv = 0; idv < tempDisplacedVertexSeeds.size(); idv++){
116 if (!tempDisplacedVertexSeeds[idv].isEmpty() && !bLockedSeeds[idv]) {
118 bLockedSeeds[idv] =
fitVertexFromSeed(tempDisplacedVertexSeeds[idv], displacedVertex);
119 if (!bLockedSeeds[idv]) tempDisplacedVertices.push_back(displacedVertex);
123 if (
debug_)
cout <<
"4) Rejecting Bad Vertices and label them" << endl;
126 vector<bool> bLocked;
127 bLocked.resize(tempDisplacedVertices.size());
130 if (
debug_)
cout <<
"5) Fill the Displaced Vertices" << endl;
135 for(
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
138 if (
debug_)
cout <<
"========= End Find Displaced Vertices =========" << endl;
150 bool bNeedNewCandidate =
false;
156 for (PFDisplacedVertexCandidate::DistMap::const_iterator imap = r2Map.begin();
157 imap != r2Map.end(); imap++){
159 unsigned ie1 = (*imap).second.first;
160 unsigned ie2 = (*imap).second.second;
162 if (
debug_)
cout <<
"ie1 = " << ie1 <<
" ie2 = " << ie2 <<
" radius = " <<
sqrt((*imap).first) << endl;
165 if (fabs(dcaPoint.
x()) > 1e9)
continue;
167 bNeedNewCandidate =
true;
168 for (idvc_current = tempDisplacedVertexSeeds.begin(); idvc_current != tempDisplacedVertexSeeds.end(); idvc_current++){
169 if ((*idvc_current).isEmpty()) {
170 bNeedNewCandidate =
false;
173 const GlobalPoint vertexPoint = (*idvc_current).seedPoint();
174 double Delta_Long =
getLongDiff(vertexPoint, dcaPoint);
178 bNeedNewCandidate =
false;
181 if (bNeedNewCandidate) {
182 if (
debug_)
cout <<
"create new displaced vertex" << endl;
184 idvc_current = tempDisplacedVertexSeeds.end();
186 bNeedNewCandidate =
false;
191 (*idvc_current).updateSeedPoint(dcaPoint, vertexCandidate.
tref(ie1), vertexCandidate.
tref(ie2));
208 for(
unsigned idv_mother = 0;idv_mother < tempDisplacedVertexSeeds.size(); idv_mother++){
209 if (!bLocked[idv_mother]){
211 for (
unsigned idv_daughter = idv_mother+1;idv_daughter < tempDisplacedVertexSeeds.size(); idv_daughter++){
213 if (!bLocked[idv_daughter]){
214 if (
isCloseTo(tempDisplacedVertexSeeds[idv_mother], tempDisplacedVertexSeeds[idv_daughter])) {
216 tempDisplacedVertexSeeds[idv_mother].mergeWith(tempDisplacedVertexSeeds[idv_daughter]);
217 bLocked[idv_daughter] =
true;
218 if (
debug_)
cout <<
"Seeds " << idv_mother <<
" and " << idv_daughter <<
" merged" << endl;
238 if (
debug_)
cout <<
"== Start vertexing procedure ==" << endl;
243 set < TrackBaseRef, PFDisplacedVertexSeed::Compare > tracksToFit = displacedVertexSeed.
elements();
246 vector<TransientTrack> transTracks;
247 vector<TransientTrack> transTracksRaw;
248 vector<TrackBaseRef> transTracksRef;
249 vector<TrackBaseRef> transTracksRefRaw;
251 transTracks.reserve(tracksToFit.size());
252 transTracksRaw.reserve(tracksToFit.size());
253 transTracksRef.reserve(tracksToFit.size());
254 transTracksRefRaw.reserve(tracksToFit.size());
265 if (tracksToFit.size() < 2) {
266 if (
debug_)
cout <<
"Only one to Fit Track" << endl;
270 double rho =
sqrt(seedPoint.
x()*seedPoint.
x()+seedPoint.
y()*seedPoint.
y());
271 double z = seedPoint.
z();
274 if (
debug_)
cout <<
"Seed Point out of the tracker rho = " << rho <<
" z = "<< z <<
" nTracks = " << tracksToFit.size() << endl;
281 int nNotIterative = 0;
284 for(
IEset ie = tracksToFit.begin(); ie != tracksToFit.end(); ie++){
286 transTracksRaw.push_back( tmpTk );
287 transTracksRefRaw.push_back( *ie );
288 switch((*ie)->algo()) {
312 if (rho > 25 && nStep45 + nNotIterative < 1){
313 if (
debug_)
cout <<
"Seed point at rho > 25 cm but no step 4-5 tracks" << endl;
326 if ( transTracksRaw.size() == 2 ){
328 if (
debug_)
cout <<
"No raw fit done" << endl;
331 cout <<
"Due to probably high pile-up conditions 2 track vertices switched off" << endl;
337 theVertexAdaptiveRaw =
TransientVertex(seedPoint, globalError, transTracksRaw, 1.);
357 if ( transTracksRaw.size() < 1000 && transTracksRaw.size() > 3){
359 if (
debug_)
cout <<
"First test with KFT" << endl;
362 theVertexAdaptiveRaw = theKalmanFitter.
vertex(transTracksRaw, seedPoint);
370 if (
debug_)
cout <<
"We use KFT instead of seed point to set up a point for AVF "
371 <<
" x = " << theVertexAdaptiveRaw.
position().
x()
372 <<
" y = " << theVertexAdaptiveRaw.
position().
y()
373 <<
" z = " << theVertexAdaptiveRaw.
position().
z()
379 Vertex vtx = theVertexAdaptiveRaw;
384 if (rho < primaryVertexCut_ || rho > 100) {
385 if (
debug_)
cout <<
"KFT Vertex geometrically rejected with tracks #rho = " << rho << endl;
391 theVertexAdaptiveRaw = theAdaptiveFitterRaw.
vertex(transTracksRaw, theVertexAdaptiveRaw.
position());
397 theVertexAdaptiveRaw = theAdaptiveFitterRaw.
vertex(transTracksRaw, seedPoint);
410 Vertex vtx = theVertexAdaptiveRaw;
414 if (
debug_)
cout <<
"Vertex " <<
" geometrically rejected with " << transTracksRaw.size() <<
" tracks #rho = " << rho << endl;
429 for (
unsigned i = 0;
i < transTracksRaw.size();
i++) {
431 if (
debug_)
cout <<
"Raw Weight track " <<
i <<
" = " << theVertexAdaptiveRaw.
trackWeight(transTracksRaw[
i]) << endl;
439 if (vertexTrackType != PFDisplacedVertex::T_NOT_FROM_VERTEX){
444 transTracks.push_back(transTracksRaw[i]);
445 transTracksRef.push_back(transTracksRefRaw[i]);
448 cout <<
"Track rejected nChi2 = " << transTracksRaw[
i].track().normalizedChi2()
449 <<
" pt = " << transTracksRaw[
i].track().pt()
450 <<
" dxy (wrt (0,0,0)) = " << transTracksRaw[
i].track().dxy()
451 <<
" nHits = " << transTracksRaw[
i].track().numberOfValidHits()
452 <<
" nOuterHits = " << transTracksRaw[
i].track().hitPattern().numberOfHits(HitPattern::MISSING_OUTER_HITS) << endl;
457 cout <<
"Remove track because too far away from the vertex:" << endl;
468 if (
debug_)
cout <<
"All Tracks " << transTracksRaw.size()
469 <<
" with good weight " << transTracks.size() << endl;
475 if (transTracks.size() < 2)
return true;
476 else if (transTracks.size() == 2){
480 cout <<
"Due to probably high pile-up conditions 2 track vertices switched off" << endl;
485 else if (transTracks.size() > 2 && transTracksRaw.size() > transTracks.size())
487 else if (transTracks.size() > 2 && transTracksRaw.size() == transTracks.size())
491 if (
debug_)
cout <<
"Vertex Fitter " << vtxFitter << endl;
496 theRecoVertex = theKalmanFitter.
vertex(transTracks, seedPoint);
507 theRecoVertex = theAdaptiveFitter.
vertex(transTracks, seedPoint);
510 theRecoVertex = theVertexAdaptiveRaw;
526 Vertex theRecoVtx = theRecoVertex;
528 double chi2 = theRecoVtx.
chi2();
529 double ndf = theRecoVtx.
ndof();
532 if (chi2 > TMath::ChisquareQuantile(0.95, ndf)) {
534 cout <<
"Rejected because of chi2 = " << chi2 <<
" ndf = " << ndf <<
" confid. level: " << TMath::ChisquareQuantile(0.95, ndf) << endl;
550 for(
unsigned i = 0;
i < transTracks.size();
i++) {
569 cout <<
"Vertex Track Type = " << vertexTrackType << endl;
571 cout <<
"nHitBeforeVertex = " << pattern.first.first
572 <<
" nHitAfterVertex = " << pattern.second.first
573 <<
" nMissHitBeforeVertex = " << pattern.first.second
574 <<
" nMissHitAfterVertex = " << pattern.second.second
575 <<
" Weight = " << weight << endl;
580 pattern, vertexTrackType, weight);
589 if (
debug_)
cout <<
"== End vertexing procedure ==" << endl;
603 if (
debug_)
cout <<
" 4.1) Reject vertices " << endl;
605 for(
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++){
612 const float rho = tempDisplacedVertices[idv].position().rho();
613 const float z = tempDisplacedVertices[idv].position().z();
617 <<
" geometrically rejected #rho = " << rho
618 <<
" z = " << z << endl;
625 unsigned nPrimary = tempDisplacedVertices[idv].nPrimaryTracks();
626 unsigned nMerged = tempDisplacedVertices[idv].nMergedTracks();
627 unsigned nSecondary = tempDisplacedVertices[idv].nSecondaryTracks();
629 if (nPrimary + nMerged > 1) {
632 <<
" rejected because two primary or merged tracks" << endl;
637 if (nPrimary + nMerged + nSecondary < 2){
640 <<
" rejected because only one track related to the vertex" << endl;
647 if (
debug_)
cout <<
" 4.2) Check for common vertices" << endl;
652 for(
unsigned idv_mother = 0; idv_mother < tempDisplacedVertices.size(); idv_mother++){
653 for(
unsigned idv_daughter = idv_mother+1;
654 idv_daughter < tempDisplacedVertices.size(); idv_daughter++){
656 if(!bLocked[idv_daughter] && !bLocked[idv_mother]){
658 const unsigned commonTrks =
commonTracks(tempDisplacedVertices[idv_daughter], tempDisplacedVertices[idv_mother]);
660 if (commonTrks > 1) {
662 if (
debug_)
cout <<
"Vertices " << idv_daughter <<
" and " << idv_mother
663 <<
" has many common tracks" << endl;
667 const int mother_size = tempDisplacedVertices[idv_mother].nTracks();
668 const int daughter_size = tempDisplacedVertices[idv_daughter].nTracks();
670 if (mother_size > daughter_size) bLocked[idv_daughter] =
true;
671 else if (mother_size < daughter_size) bLocked[idv_mother] =
true;
676 const float mother_normChi2 = tempDisplacedVertices[idv_mother].normalizedChi2();
677 const float daughter_normChi2 = tempDisplacedVertices[idv_daughter].normalizedChi2();
678 if (mother_normChi2 < daughter_normChi2) bLocked[idv_daughter] =
true;
679 else bLocked[idv_mother] =
true;
687 for(
unsigned idv = 0; idv < tempDisplacedVertices.size(); idv++)
713 if (Delta_Long >
longSize_)
return false;
728 return fabs((vRef.
dot(vToProject)-vRef.
mag2())/vRef.
mag());
737 return (vRef.
dot(vToProject))/vRef.
mag();
748 return fabs(vRef.
cross(vToProject).
mag()/vRef.
mag());
756 unsigned int nHitBeforeVertex = pairTrackHitInfo.first.first;
757 unsigned int nHitAfterVertex = pairTrackHitInfo.second.first;
759 unsigned int nMissHitBeforeVertex = pairTrackHitInfo.first.second;
760 unsigned int nMissHitAfterVertex = pairTrackHitInfo.second.second;
764 if (nHitBeforeVertex <= 1 && nHitAfterVertex >= 3 && nMissHitAfterVertex <= 1)
765 return PFDisplacedVertex::T_FROM_VERTEX;
766 else if (nHitBeforeVertex >= 3 && nHitAfterVertex <= 1 && nMissHitBeforeVertex <= 1)
767 return PFDisplacedVertex::T_TO_VERTEX;
768 else if ((nHitBeforeVertex >= 2 && nHitAfterVertex >= 3)
770 (nHitBeforeVertex >= 3 && nHitAfterVertex >= 2))
771 return PFDisplacedVertex::T_MERGED;
773 return PFDisplacedVertex::T_NOT_FROM_VERTEX;
784 for (
unsigned il1 = 0; il1 < vt1.size(); il1++){
787 for (
unsigned il2 = 0; il2 < vt2.size(); il2++)
798 if(! out)
return out;
799 out << setprecision(3) << setw(5) << endl;
801 out <<
" ====================================== " << endl;
802 out <<
" ====== Displaced Vertex Finder ======= " << endl;
803 out <<
" ====================================== " << endl;
808 <<
" Adaptive Vertex Fitter parameters are :"<< endl
809 <<
" sigmacut = " << a.
sigmacut_ <<
" T_ini = "
812 const std::auto_ptr< reco::PFDisplacedVertexCollection >& displacedVertices_
816 if(!displacedVertices_.get() ) {
817 out<<
"displacedVertex already transfered"<<endl;
821 out<<
"Number of displacedVertices found : "<< displacedVertices_->size()<<endl<<endl;
826 idv != displacedVertices_->end(); idv++){
828 out << i <<
" "; idv->Dump(); out <<
"" << endl;
double getTransvDiff(const GlobalPoint &, const GlobalPoint &) const
std::vector< PFDisplacedVertex > PFDisplacedVertexCollection
collection of PFDisplacedVertex objects
std::vector< PFDisplacedVertexCandidate > PFDisplacedVertexCandidateCollection
collection of PFDisplacedVertexCandidate objects
edm::Ref< Container > Ref
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
TrackBaseRef originalTrack(const Track &refTrack) const
std::auto_ptr< reco::PFDisplacedVertexCollection > displacedVertices_
edm::ESHandle< GlobalTrackingGeometry > globTkGeomHandle_
Tracker geometry for discerning hit positions.
virtual CachingVertex< 5 > vertex(const std::vector< reco::TransientTrack > &tracks) const
float totalChiSquared() const
void Dump(std::ostream &out=std::cout) const
Basic3DVector cross(const Basic3DVector &lh) const
Vector product, or "cross" product, with a vector of same type.
bool rejectAndLabelVertex(reco::PFDisplacedVertex &dv)
std::ostream & operator<<(std::ostream &out, const ALILine &li)
std::map< float, std::pair< int, int > > DistMap
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
const std::set< TrackBaseRef, Compare > & elements() const
std::pair< PFTrackHitInfo, PFTrackHitInfo > PFTrackHitFullInfo
bool fitVertexFromSeed(reco::PFDisplacedVertexSeed &, reco::PFDisplacedVertex &)
Fit one by one the vertex points with associated tracks to get displaced vertices.
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.
std::set< reco::TrackBaseRef >::iterator IEset
-----— Useful Types -----— ///
PFTrackHitFullInfo analyze(edm::ESHandle< TrackerGeometry >, const reco::TrackBaseRef track, const TransientVertex &vert)
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.
edm::ESHandle< TrackerGeometry > tkerGeomHandle_
doc?
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::auto_ptr< reco::PFDisplacedVertexCandidateCollection > displacedVertexCandidates_
-----— Members -----— ///
std::vector< PFDisplacedVertexSeed > PFDisplacedVertexSeedCollection
collection of PFDisplacedVertexSeed objects
reco::PFDisplacedVertex::VertexType identifyVertex(const reco::PFDisplacedVertex &v) const
Vertex identification tool.
GlobalPoint position() const
void selectAndLabelVertices(reco::PFDisplacedVertexCollection &, std::vector< bool > &)
Remove potentially fakes displaced vertices.
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
double getLongProj(const GlobalPoint &, const GlobalVector &) const
DistMap r2Map() const
--—— Provide useful information --—— ///
reco::PFDisplacedVertexCandidateCollection::iterator IDVC
void setInput(const edm::Handle< reco::PFDisplacedVertexCandidateCollection > &)
Set input collections of tracks.
float trackWeight(const reco::TransientTrack &track) const
const std::auto_ptr< reco::PFDisplacedVertexCollection > & displacedVertices() const
void findSeedsFromCandidate(reco::PFDisplacedVertexCandidate &, reco::PFDisplacedVertexSeedCollection &)
--—— Different steps of the finder algorithm --—— ///
const GlobalPoint & seedPoint() const
double transvSize_
--—— Parameters --—— ///
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.
double getLongDiff(const GlobalPoint &, const GlobalPoint &) const
volatile std::atomic< bool > shutdown_flag false
bool isCloseTo(const reco::PFDisplacedVertexSeed &, const reco::PFDisplacedVertexSeed &) const
-----— Tools -----— ///
PFCheckHitPattern hitPattern_
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.