File indexing completed on 2024-04-06 12:23:47
0001 #include "FWCore/Framework/interface/global/EDProducer.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0006 #include "FWCore/Utilities/interface/InputTag.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #include "PhysicsTools/PatUtils/interface/MiniIsolation.h"
0009 #include "DataFormats/Common/interface/View.h"
0010
0011 #include "DataFormats/PatCandidates/interface/Muon.h"
0012 #include "DataFormats/PatCandidates/interface/Electron.h"
0013 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0014 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0015
0016 #include <type_traits>
0017
0018 namespace pat {
0019
0020 template <typename T>
0021 class LeptonUpdater : public edm::global::EDProducer<> {
0022 public:
0023 explicit LeptonUpdater(const edm::ParameterSet &iConfig)
0024 : src_(consumes<std::vector<T>>(iConfig.getParameter<edm::InputTag>("src"))),
0025 vertices_(consumes<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("vertices"))),
0026 beamLineToken_(consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamspot"))),
0027 computeMiniIso_(iConfig.getParameter<bool>("computeMiniIso")),
0028 fixDxySign_(iConfig.getParameter<bool>("fixDxySign")) {
0029
0030 if (computeMiniIso_) {
0031 readMiniIsoParams(iConfig);
0032 pcToken_ = consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfCandsForMiniIso"));
0033 }
0034 recomputeMuonBasicSelectors_ = false;
0035 if (typeid(T) == typeid(pat::Muon))
0036 recomputeMuonBasicSelectors_ = iConfig.getParameter<bool>("recomputeMuonBasicSelectors");
0037 produces<std::vector<T>>();
0038 }
0039
0040 ~LeptonUpdater() override {}
0041
0042 void produce(edm::StreamID, edm::Event &, edm::EventSetup const &) const override;
0043
0044 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0045 edm::ParameterSetDescription desc;
0046 desc.add<edm::InputTag>("src")->setComment("Lepton collection");
0047 desc.add<edm::InputTag>("vertices")->setComment("Vertex collection");
0048 desc.add<edm::InputTag>("beamspot", edm::InputTag("offlineBeamSpot"))->setComment("Beam spot");
0049 desc.add<bool>("computeMiniIso", false)->setComment("Recompute miniIsolation");
0050 desc.add<bool>("fixDxySign", false)->setComment("Fix the IP sign");
0051 desc.addOptional<edm::InputTag>("pfCandsForMiniIso", edm::InputTag("packedPFCandidates"))
0052 ->setComment("PackedCandidate collection used for miniIso");
0053 if (typeid(T) == typeid(pat::Muon)) {
0054 desc.add<bool>("recomputeMuonBasicSelectors", false)
0055 ->setComment("Recompute basic cut-based muon selector flags");
0056 desc.addOptional<std::vector<double>>("miniIsoParams")
0057 ->setComment("Parameters used for miniIso (as in PATMuonProducer)");
0058 descriptions.add("muonsUpdated", desc);
0059 } else if (typeid(T) == typeid(pat::Electron)) {
0060 desc.addOptional<std::vector<double>>("miniIsoParamsB")
0061 ->setComment("Parameters used for miniIso in the barrel (as in PATElectronProducer)");
0062 desc.addOptional<std::vector<double>>("miniIsoParamsE")
0063 ->setComment("Parameters used for miniIso in the endcap (as in PATElectronProducer)");
0064 descriptions.add("electronsUpdated", desc);
0065 }
0066 }
0067
0068 void setDZ(T &lep, const reco::Vertex &pv) const {}
0069
0070 void readMiniIsoParams(const edm::ParameterSet &iConfig) {
0071 miniIsoParams_[0] = iConfig.getParameter<std::vector<double>>("miniIsoParams");
0072 if (miniIsoParams_[0].size() != 9)
0073 throw cms::Exception("ParameterError", "miniIsoParams must have exactly 9 elements.\n");
0074 }
0075 const std::vector<double> &miniIsoParams(const T &lep) const { return miniIsoParams_[0]; }
0076
0077 void recomputeMuonBasicSelectors(T &, const reco::Vertex &, const bool) const;
0078
0079 private:
0080
0081 edm::EDGetTokenT<std::vector<T>> src_;
0082 edm::EDGetTokenT<std::vector<reco::Vertex>> vertices_;
0083 edm::EDGetTokenT<reco::BeamSpot> beamLineToken_;
0084 bool computeMiniIso_;
0085 bool fixDxySign_;
0086 bool recomputeMuonBasicSelectors_;
0087 std::vector<double> miniIsoParams_[2];
0088 edm::EDGetTokenT<pat::PackedCandidateCollection> pcToken_;
0089 };
0090
0091
0092
0093 template <>
0094 void LeptonUpdater<pat::Electron>::setDZ(pat::Electron &anElectron, const reco::Vertex &pv) const {
0095 auto track = anElectron.gsfTrack();
0096 anElectron.setDB(track->dz(pv.position()), std::hypot(track->dzError(), pv.zError()), pat::Electron::PVDZ);
0097 }
0098
0099 template <>
0100 void LeptonUpdater<pat::Muon>::setDZ(pat::Muon &aMuon, const reco::Vertex &pv) const {
0101 auto track = aMuon.muonBestTrack();
0102 aMuon.setDB(track->dz(pv.position()), std::hypot(track->dzError(), pv.zError()), pat::Muon::PVDZ);
0103 }
0104
0105 template <>
0106 void LeptonUpdater<pat::Electron>::readMiniIsoParams(const edm::ParameterSet &iConfig) {
0107 miniIsoParams_[0] = iConfig.getParameter<std::vector<double>>("miniIsoParamsB");
0108 miniIsoParams_[1] = iConfig.getParameter<std::vector<double>>("miniIsoParamsE");
0109 if (miniIsoParams_[0].size() != 9)
0110 throw cms::Exception("ParameterError", "miniIsoParamsB must have exactly 9 elements.\n");
0111 if (miniIsoParams_[1].size() != 9)
0112 throw cms::Exception("ParameterError", "miniIsoParamsE must have exactly 9 elements.\n");
0113 }
0114 template <>
0115 const std::vector<double> &LeptonUpdater<pat::Electron>::miniIsoParams(const pat::Electron &lep) const {
0116 return miniIsoParams_[lep.isEE()];
0117 }
0118
0119 template <typename T>
0120 void LeptonUpdater<T>::recomputeMuonBasicSelectors(T &lep,
0121 const reco::Vertex &pv,
0122 const bool do_hip_mitigation_2016) const {}
0123
0124 template <>
0125 void LeptonUpdater<pat::Muon>::recomputeMuonBasicSelectors(pat::Muon &lep,
0126 const reco::Vertex &pv,
0127 const bool do_hip_mitigation_2016) const {
0128 lep.setSelectors(muon::makeSelectorBitset(lep, &pv, do_hip_mitigation_2016));
0129 }
0130
0131 }
0132
0133 template <typename T>
0134 void pat::LeptonUpdater<T>::produce(edm::StreamID, edm::Event &iEvent, edm::EventSetup const &) const {
0135 edm::Handle<std::vector<T>> src;
0136 iEvent.getByToken(src_, src);
0137
0138 edm::Handle<std::vector<reco::Vertex>> vertices;
0139 iEvent.getByToken(vertices_, vertices);
0140 const reco::Vertex &pv = vertices->front();
0141
0142 edm::Handle<pat::PackedCandidateCollection> pc;
0143 if (computeMiniIso_)
0144 iEvent.getByToken(pcToken_, pc);
0145
0146 edm::Handle<reco::BeamSpot> beamSpotHandle;
0147 iEvent.getByToken(beamLineToken_, beamSpotHandle);
0148 reco::BeamSpot beamSpot;
0149 bool beamSpotIsValid = false;
0150 if (beamSpotHandle.isValid()) {
0151 beamSpot = *beamSpotHandle;
0152 beamSpotIsValid = true;
0153 } else {
0154 edm::LogError("DataNotAvailable") << "No beam spot available \n";
0155 }
0156
0157 std::unique_ptr<std::vector<T>> out(new std::vector<T>(*src));
0158
0159 const bool do_hip_mitigation_2016 =
0160 recomputeMuonBasicSelectors_ && (272728 <= iEvent.run() && iEvent.run() <= 278808);
0161
0162 for (unsigned int i = 0, n = src->size(); i < n; ++i) {
0163 T &lep = (*out)[i];
0164 setDZ(lep, pv);
0165 if (computeMiniIso_) {
0166 const auto ¶ms = miniIsoParams(lep);
0167 pat::PFIsolation miniiso = pat::getMiniPFIsolation(pc.product(),
0168 lep.polarP4(),
0169 params[0],
0170 params[1],
0171 params[2],
0172 params[3],
0173 params[4],
0174 params[5],
0175 params[6],
0176 params[7],
0177 params[8]);
0178 lep.setMiniPFIsolation(miniiso);
0179 }
0180 if (recomputeMuonBasicSelectors_)
0181 recomputeMuonBasicSelectors(lep, pv, do_hip_mitigation_2016);
0182
0183 if (fixDxySign_) {
0184 float signPV = 1.;
0185 float signBS = 1.;
0186 if (beamSpotIsValid) {
0187 if constexpr (std::is_same_v<T, pat::Electron>)
0188 signBS = copysign(1., lep.gsfTrack()->dxy(beamSpot));
0189 else
0190 signBS = copysign(1., lep.bestTrack()->dxy(beamSpot));
0191 }
0192 if constexpr (std::is_same_v<T, pat::Electron>)
0193 signPV = copysign(1., lep.gsfTrack()->dxy(pv.position()));
0194 else
0195 signPV = copysign(1., lep.bestTrack()->dxy(pv.position()));
0196 lep.setDB(abs(lep.dB(T::PV2D)) * signPV, lep.edB(T::PV2D), T::PV2D);
0197 lep.setDB(abs(lep.dB(T::BS2D)) * signBS, lep.edB(T::BS2D), T::BS2D);
0198 }
0199 }
0200
0201 iEvent.put(std::move(out));
0202 }
0203
0204 typedef pat::LeptonUpdater<pat::Electron> PATElectronUpdater;
0205 typedef pat::LeptonUpdater<pat::Muon> PATMuonUpdater;
0206
0207 #include "FWCore/Framework/interface/MakerMacros.h"
0208 DEFINE_FWK_MODULE(PATElectronUpdater);
0209 DEFINE_FWK_MODULE(PATMuonUpdater);