File indexing completed on 2024-04-06 12:01:10
0001 #include "CommonTools/RecoAlgos/interface/PrimaryVertexAssignment.h"
0002 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0003 #include "DataFormats/VertexReco/interface/Vertex.h"
0004 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0005 #include "DataFormats/Math/interface/deltaR.h"
0006 #include "TrackingTools/IPTools/interface/IPTools.h"
0007 #include "FWCore/Utilities/interface/isFinite.h"
0008
0009 std::pair<int, PrimaryVertexAssignment::Quality> PrimaryVertexAssignment::chargedHadronVertex(
0010 const reco::VertexCollection& vertices,
0011 const reco::TrackRef& trackRef,
0012 const reco::Track* track,
0013 float time,
0014 float timeReso,
0015 const edm::View<reco::Candidate>& jets,
0016 const TransientTrackBuilder& builder) const {
0017 typedef reco::VertexCollection::const_iterator IV;
0018 typedef reco::Vertex::trackRef_iterator IT;
0019
0020 int iVertex = -1;
0021 size_t index = 0;
0022 float bestweight = 0;
0023 for (auto const& vtx : vertices) {
0024 float w = vtx.trackWeight(trackRef);
0025 if (w > bestweight) {
0026 bestweight = w;
0027 iVertex = index;
0028 }
0029 index++;
0030 }
0031 return chargedHadronVertex(vertices, iVertex, track, time, timeReso, jets, builder);
0032 }
0033
0034 std::pair<int, PrimaryVertexAssignment::Quality> PrimaryVertexAssignment::chargedHadronVertex(
0035 const reco::VertexCollection& vertices,
0036 int iVertex,
0037 const reco::Track* track,
0038 float time,
0039 float timeReso,
0040 const edm::View<reco::Candidate>& jets,
0041 const TransientTrackBuilder& builder) const {
0042 typedef reco::VertexCollection::const_iterator IV;
0043 typedef reco::Vertex::trackRef_iterator IT;
0044
0045 bool useTime = useTiming_;
0046 if (edm::isNotFinite(time) || timeReso < 1e-6) {
0047 useTime = false;
0048 time = 0.;
0049 timeReso = -1.;
0050 }
0051
0052 if (preferHighRanked_) {
0053 for (IV iv = vertices.begin(); iv != vertices.end(); ++iv) {
0054 int ivtx = iv - vertices.begin();
0055 if (useVertexFit_ && (iVertex == ivtx))
0056 return {ivtx, PrimaryVertexAssignment::UsedInFit};
0057
0058 double dz = std::abs(track->dz(iv->position()));
0059 double dt = std::abs(time - iv->t());
0060
0061 bool useTimeVtx = useTime && iv->tError() > 0.;
0062
0063 if ((dz < maxDzForPrimaryAssignment_ or dz / track->dzError() < maxDzSigForPrimaryAssignment_) and
0064 (!useTimeVtx or dt / timeReso < maxDtSigForPrimaryAssignment_)) {
0065 return {ivtx, PrimaryVertexAssignment::PrimaryDz};
0066 }
0067 }
0068 }
0069
0070 double firstVertexDz = std::numeric_limits<double>::max();
0071 if (!vertices.empty())
0072 firstVertexDz = std::abs(track->dz(vertices[0].position()));
0073
0074 if (useVertexFit_ && (iVertex > 0) && (iVertex <= int(fNumOfPUVtxsForCharged_)) &&
0075 firstVertexDz < fDzCutForChargedFromPUVtxs_)
0076 return {0, PrimaryVertexAssignment::PrimaryDz};
0077
0078 if (useVertexFit_ && (iVertex >= 0))
0079 return {iVertex, PrimaryVertexAssignment::UsedInFit};
0080
0081 double distmin = std::numeric_limits<double>::max();
0082 double dzmin = std::numeric_limits<double>::max();
0083 double dtmin = std::numeric_limits<double>::max();
0084 int vtxIdMinSignif = -1;
0085 for (IV iv = vertices.begin(); iv != vertices.end(); ++iv) {
0086 double dz = std::abs(track->dz(iv->position()));
0087 double dt = std::abs(time - iv->t());
0088
0089 double dzsig = dz / track->dzError();
0090 double dist = dzsig * dzsig;
0091
0092 bool useTimeVtx = useTime && iv->tError() > 0.;
0093 if (useTime && !useTimeVtx) {
0094 dt = timeReso;
0095 }
0096
0097 if (useTime) {
0098 double dtsig = dt / timeReso;
0099
0100 dist += dtsig * dtsig;
0101 }
0102 if (dist < distmin) {
0103 distmin = dist;
0104 dzmin = dz;
0105 dtmin = dt;
0106 vtxIdMinSignif = iv - vertices.begin();
0107 }
0108 }
0109
0110
0111 if ((fPtMaxCharged_ > 0) && (vtxIdMinSignif >= 0) && (track->pt() > fPtMaxCharged_)) {
0112 iVertex = 0;
0113 } else {
0114
0115 const float add_cov = vtxIdMinSignif >= 0 ? vertices[vtxIdMinSignif].covariance(2, 2) : 0.f;
0116 const float dzE = sqrt(track->dzError() * track->dzError() + add_cov);
0117 if (!fOnlyUseFirstDz_) {
0118 if (vtxIdMinSignif >= 0 and
0119 (dzmin < maxDzForPrimaryAssignment_ and dzmin / dzE < maxDzSigForPrimaryAssignment_ and
0120 track->dzError() < maxDzErrorForPrimaryAssignment_) and
0121 (!useTime or dtmin / timeReso < maxDtSigForPrimaryAssignment_))
0122 iVertex = vtxIdMinSignif;
0123 } else {
0124
0125 if ((vtxIdMinSignif >= 0) && (std::abs(track->eta()) > fEtaMinUseDz_) &&
0126 ((firstVertexDz < maxDzForPrimaryAssignment_ && firstVertexDz / dzE < maxDzSigForPrimaryAssignment_ &&
0127 track->dzError() < maxDzErrorForPrimaryAssignment_) &&
0128 (!useTime || std::abs(time - vertices[0].t()) / timeReso < maxDtSigForPrimaryAssignment_)))
0129 iVertex = 0;
0130 }
0131 }
0132
0133 if (iVertex >= 0)
0134 return {iVertex, PrimaryVertexAssignment::PrimaryDz};
0135
0136
0137
0138 int jetIdx = -1;
0139 double minDeltaR2 = maxJetDeltaR_ * maxJetDeltaR_;
0140 for (edm::View<reco::Candidate>::const_iterator ij = jets.begin(); ij != jets.end(); ++ij) {
0141 if (ij->pt() < minJetPt_)
0142 continue;
0143
0144 double deltaR2 = reco::deltaR2(*ij, *track);
0145 if (deltaR2 < minDeltaR2 and track->dzError() < maxDzErrorForPrimaryAssignment_) {
0146 minDeltaR2 = deltaR2;
0147 jetIdx = std::distance(jets.begin(), ij);
0148 }
0149 }
0150
0151 if (jetIdx != -1) {
0152 reco::TransientTrack transientTrack = builder.build(*track);
0153 GlobalVector direction(jets.at(jetIdx).px(), jets.at(jetIdx).py(), jets.at(jetIdx).pz());
0154
0155 int vtxIdx = -1;
0156 double minDistanceToJetAxis = maxDistanceToJetAxis_;
0157 for (IV iv = vertices.begin(); iv != vertices.end(); ++iv) {
0158
0159 if (std::abs(track->dz(iv->position())) > maxDzForJetAxisAssigment_ ||
0160 std::abs(track->dxy(iv->position())) > maxDxyForJetAxisAssigment_)
0161 continue;
0162
0163 double distanceToJetAxis = IPTools::jetTrackDistance(transientTrack, direction, *iv).second.value();
0164 if (distanceToJetAxis < minDistanceToJetAxis) {
0165 minDistanceToJetAxis = distanceToJetAxis;
0166 vtxIdx = std::distance(vertices.begin(), iv);
0167 }
0168 }
0169 if (vtxIdx >= 0) {
0170 iVertex = vtxIdx;
0171 }
0172 }
0173 if (iVertex >= 0)
0174 return {iVertex, PrimaryVertexAssignment::BTrack};
0175
0176
0177
0178 if (!vertices.empty() && std::abs(track->dxy(vertices[0].position())) < maxDxyForNotReconstructedPrimary_ &&
0179 std::abs(track->dxy(vertices[0].position()) / track->dxyError()) < maxDxySigForNotReconstructedPrimary_)
0180 return {vtxIdMinSignif, PrimaryVertexAssignment::NotReconstructedPrimary};
0181
0182
0183
0184
0185 if (vtxIdMinSignif >= 0)
0186 return {vtxIdMinSignif, PrimaryVertexAssignment::OtherDz};
0187
0188 return {-1, PrimaryVertexAssignment::Unassigned};
0189 }