diff --git a/DataFormats/TrackReco/interface/TrackBase.h b/DataFormats/TrackReco/interface/TrackBase.h index 77617eaad0737..665af0800ab1e 100644 --- a/DataFormats/TrackReco/interface/TrackBase.h +++ b/DataFormats/TrackReco/interface/TrackBase.h @@ -327,7 +327,13 @@ class TrackBase /// error on beta double betaError() const; - + + /// error on dxy with respect to a user-given reference point + uncertainty (i.e. reco::Vertex position) + double dxyError(Point const &vtx, math::Error<3>::type const &vertexCov) const; + + /// error on dxy with respect to a user-given beamspot + double dxyError(const BeamSpot &theBeamSpot) const; + /// fill SMatrix CovarianceMatrix &fill(CovarianceMatrix &v) const; @@ -885,6 +891,12 @@ inline double TrackBase::betaError() const return std::sqrt(covbetabeta_); } +// error on dxy with respect to a given beamspot +inline double TrackBase::dxyError(const BeamSpot &theBeamSpot) const +{ + return dxyError(theBeamSpot.position(vz()), theBeamSpot.rotatedCovariance3D()); +} + // number of valid hits found inline unsigned short TrackBase::numberOfValidHits() const { diff --git a/DataFormats/TrackReco/src/TrackBase.cc b/DataFormats/TrackReco/src/TrackBase.cc index bb23e8a341b3f..07874206e8ad6 100644 --- a/DataFormats/TrackReco/src/TrackBase.cc +++ b/DataFormats/TrackReco/src/TrackBase.cc @@ -154,3 +154,16 @@ TrackBase::TrackAlgorithm TrackBase::algoByName(const std::string &name) // cast return TrackAlgorithm(index); } + +double TrackBase::dxyError(Point const &vtx, math::Error<3>::type const &vertexCov) const { + // Gradient of TrackBase::dxy(const Point &myBeamSpot) with respect to track parameters. Using unrolled expressions to avoid calling for higher dimension matrices + // ( 0, 0, x_vert * cos(phi) + y_vert * sin(phi), 1, 0 ) + // Gradient with respect to point parameters + // ( sin(phi), -cos(phi)) + // Propagate covariance assuming cross-terms of the covariance between track and vertex parameters are 0 + return std::sqrt((vtx.x() * px() + vtx.y() * py()) * (vtx.x() * px() + vtx.y() * py()) / (pt() * pt()) * + covariance(i_phi, i_phi) + + 2 * (vtx.x() * px() + vtx.y() * py()) / pt() * covariance(i_phi, i_dxy) + covariance(i_dxy, i_dxy) + + py() * py() / (pt() * pt()) * vertexCov(0, 0) - 2 * py() * px() / (pt() * pt()) * vertexCov(0, 1) + + px() * px() / (pt() * pt()) * vertexCov(1, 1)); +} diff --git a/PhysicsTools/PatAlgos/plugins/PATMuonProducer.cc b/PhysicsTools/PatAlgos/plugins/PATMuonProducer.cc index 0a625371ba8d8..475337b9f6a49 100644 --- a/PhysicsTools/PatAlgos/plugins/PATMuonProducer.cc +++ b/PhysicsTools/PatAlgos/plugins/PATMuonProducer.cc @@ -114,6 +114,8 @@ PATMuonProducer::PATMuonProducer(const edm::ParameterSet& iConfig, PATMuonHeavyO muonTimeExtraToken_ = consumes>(iConfig.getParameter("sourceMuonTimeExtra")); } + // Switch to get the dB from the track instead of using IPTools + getdBFromTrack_ = iConfig.getParameter("getdBFromTrack"); // Monte Carlo matching addGenMatch_ = iConfig.getParameter("addGenMatch"); if (addGenMatch_) { @@ -982,6 +984,9 @@ void PATMuonProducer::fillDescriptions(edm::ConfigurationDescriptions& descripti iDesc.add("sourceInverseBeta", edm::InputTag("muons", "combined")) ->setComment("source of inverse beta values"); + // switch to get the IP from the best track instead of running IPTools + iDesc.add("getdBFromTrack", false)->setComment("switch IP2D computation to use the best track one"); + // MC matching configurables iDesc.add("addGenMatch", true)->setComment("add MC matching"); iDesc.add("embedGenMatch", false)->setComment("embed MC matched MC information"); @@ -1094,14 +1099,25 @@ void PATMuonProducer::embedHighLevel(pat::Muon& aMuon, bool primaryVertexIsValid, reco::BeamSpot& beamspot, bool beamspotIsValid) { + // Generic variable to store measurements + std::pair result; + double d0_corr; + double d0_err; + // Correct to PV // PV2D - std::pair result = + if (getdBFromTrack_){ + aMuon.setDB(track->dxy(primaryVertex.position()), + track->dxyError(primaryVertex.position(), primaryVertex.covariance()), + pat::Muon::PV2D); + } else{ + result = IPTools::signedTransverseImpactParameter(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex); - double d0_corr = result.second.value(); - double d0_err = primaryVertexIsValid ? result.second.error() : -1.0; - aMuon.setDB(d0_corr, d0_err, pat::Muon::PV2D); + d0_corr = result.second.value(); + d0_err = primaryVertexIsValid ? result.second.error() : -1.0; + aMuon.setDB( d0_corr, d0_err, pat::Muon::PV2D); + } // PV3D result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex); @@ -1110,14 +1126,18 @@ void PATMuonProducer::embedHighLevel(pat::Muon& aMuon, aMuon.setDB(d0_corr, d0_err, pat::Muon::PV3D); // Correct to beam spot - // make a fake vertex out of beam spot - reco::Vertex vBeamspot(beamspot.position(), beamspot.rotatedCovariance3D()); // BS2D - result = IPTools::signedTransverseImpactParameter(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot); - d0_corr = result.second.value(); - d0_err = beamspotIsValid ? result.second.error() : -1.0; - aMuon.setDB(d0_corr, d0_err, pat::Muon::BS2D); + // make a fake vertex out of beam spot + reco::Vertex vBeamspot(beamspot.position(), beamspot.rotatedCovariance3D()); + if (getdBFromTrack_){ + aMuon.setDB(track->dxy(beamspot), track->dxyError(beamspot), pat::Muon::BS2D); + } else{ + result = IPTools::signedTransverseImpactParameter(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot); + d0_corr = result.second.value(); + d0_err = beamspotIsValid ? result.second.error() : -1.0; + aMuon.setDB( d0_corr, d0_err, pat::Muon::BS2D); + } // BS3D result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot); diff --git a/PhysicsTools/PatAlgos/plugins/PATMuonProducer.h b/PhysicsTools/PatAlgos/plugins/PATMuonProducer.h index 5f7b4ae236b34..265548af8da13 100644 --- a/PhysicsTools/PatAlgos/plugins/PATMuonProducer.h +++ b/PhysicsTools/PatAlgos/plugins/PATMuonProducer.h @@ -175,6 +175,8 @@ namespace pat { bool embedDytMuon_; /// add combined inverse beta measurement into the muon bool addInverseBeta_; + /// switch on reading the dB information from the track + bool getdBFromTrack_; /// input tag for reading inverse beta edm::EDGetTokenT> muonTimeExtraToken_; /// add generator match information diff --git a/PhysicsTools/PatAlgos/python/producersLayer1/muonProducer_cfi.py b/PhysicsTools/PatAlgos/python/producersLayer1/muonProducer_cfi.py index 554f1f24cf7ca..03e5539efa1fc 100644 --- a/PhysicsTools/PatAlgos/python/producersLayer1/muonProducer_cfi.py +++ b/PhysicsTools/PatAlgos/python/producersLayer1/muonProducer_cfi.py @@ -74,6 +74,10 @@ # Read and store combined inverse beta addInverseBeta = cms.bool(True), sourceMuonTimeExtra = cms.InputTag("muons","combined"), #Use combined info, not only csc or dt + + # Get 2D-IP from the best track instead of using IPTools + getdBFromTrack = cms.bool(False), + # mc matching addGenMatch = cms.bool(True), embedGenMatch = cms.bool(True), diff --git a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py index f755cfa684d70..5dcd650d031b4 100644 --- a/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py +++ b/PhysicsTools/PatAlgos/python/slimming/miniAOD_tools.py @@ -30,6 +30,7 @@ def miniAOD_customizeCommon(process): process.patMuons.computeSoftMuonMVA = True process.patMuons.addTriggerMatching = True + from Configuration.Eras.Modifier_run2_miniAOD_devel_cff import run2_miniAOD_devel from Configuration.Eras.Modifier_run2_muon_2016_cff import run2_muon_2016 from Configuration.Eras.Modifier_run2_muon_2017_cff import run2_muon_2017 from Configuration.Eras.Modifier_run2_muon_2018_cff import run2_muon_2018 @@ -37,7 +38,7 @@ def miniAOD_customizeCommon(process): run2_muon_2017.toModify( process.patMuons, effectiveAreaVec = [0.0566, 0.0562, 0.0363, 0.0119, 0.0064]) run2_muon_2018.toModify( process.patMuons, effectiveAreaVec = [0.0566, 0.0562, 0.0363, 0.0119, 0.0064]) run2_muon_2016.toModify( process.patMuons, mvaTrainingFile = "RecoMuon/MuonIdentification/data/mu_2016_BDTG.weights.xml") - + run2_miniAOD_devel.toModify( process.patMuons, getdBFromTrack = True) process.patMuons.computePuppiCombinedIso = True # # disable embedding of electron and photon associated objects already stored by the ReducedEGProducer @@ -373,7 +374,6 @@ def miniAOD_customizeCommon(process): process.deepTau2017v2p1.taus = _noUpdatedTauName deepTauIDTaskNew_ = cms.Task(process.deepTau2017v2p1,process.slimmedTaus) - from Configuration.Eras.Modifier_run2_miniAOD_devel_cff import run2_miniAOD_devel from Configuration.Eras.Modifier_run2_tau_ul_2016_cff import run2_tau_ul_2016 from Configuration.Eras.Modifier_run2_tau_ul_2018_cff import run2_tau_ul_2018 for era in [run2_miniAOD_devel,run2_tau_ul_2016,run2_tau_ul_2018]: