Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-09-21 02:12:42

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       //for mini-isolation calculation
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     // configurables
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   // must do the specialization within the namespace otherwise gcc complains
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 }  // namespace pat
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 &params = 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     //Fixing the sign of impact parameters
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);