Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:46

0001 // system include files
0002 #include <memory>
0003 
0004 // user include files
0005 #include "FWCore/Framework/interface/Frameworkfwd.h"
0006 #include "FWCore/Framework/interface/global/EDProducer.h"
0007 
0008 #include "FWCore/Framework/interface/Event.h"
0009 
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0013 
0014 #include "DataFormats/PatCandidates/interface/Muon.h"
0015 #include "DataFormats/VertexReco/interface/Vertex.h"
0016 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0017 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0018 
0019 class MuonIDTableProducer : public edm::global::EDProducer<> {
0020 public:
0021   explicit MuonIDTableProducer(const edm::ParameterSet& iConfig)
0022       : name_(iConfig.getParameter<std::string>("name")),
0023         src_(consumes<std::vector<pat::Muon>>(iConfig.getParameter<edm::InputTag>("muons"))),
0024         srcVtx_(consumes<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("vertices"))) {
0025     produces<nanoaod::FlatTable>();
0026   }
0027 
0028   ~MuonIDTableProducer() override{};
0029 
0030   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0031     edm::ParameterSetDescription desc;
0032     desc.add<edm::InputTag>("muons")->setComment("input muon collection");
0033     desc.add<edm::InputTag>("vertices", edm::InputTag("offlineSlimmedPrimaryVertices"))
0034         ->setComment("input vertex collection, for dxy/dz");
0035     desc.add<std::string>("name")->setComment("name of the muon nanoaod::FlatTable we are extending with IDs");
0036     descriptions.add("muonIDTable", desc);
0037   }
0038 
0039 private:
0040   void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override;
0041 
0042   std::string name_;
0043   edm::EDGetTokenT<std::vector<pat::Muon>> src_;
0044   edm::EDGetTokenT<std::vector<reco::Vertex>> srcVtx_;
0045 
0046   static bool isMediumMuonHIP(const pat::Muon& muon);
0047   static bool isSoftMuonHIP(const pat::Muon& muon, const reco::Vertex& vtx);
0048   static bool isTrackerHighPt(const pat::Muon& mu, const reco::Vertex& primaryVertex);
0049 };
0050 
0051 // ------------ method called to produce the data  ------------
0052 void MuonIDTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0053   edm::Handle<std::vector<pat::Muon>> muons;
0054   iEvent.getByToken(src_, muons);
0055   edm::Handle<std::vector<reco::Vertex>> vertices;
0056   iEvent.getByToken(srcVtx_, vertices);
0057 
0058   unsigned int ncand = muons->size();
0059 
0060   const reco::Vertex& pv = vertices->front();  // consistent with IP information in slimmedLeptons.
0061 
0062   bool isRun2016BCDEF = (272007 <= iEvent.run() && iEvent.run() <= 278808);
0063   std::vector<uint8_t> tight(ncand, 0), highPt(ncand, 0), soft(ncand, 0), medium(ncand, 0);
0064   for (unsigned int i = 0; i < ncand; ++i) {
0065     const pat::Muon& mu = (*muons)[i];
0066     tight[i] = muon::isTightMuon(mu, pv);
0067     highPt[i] = muon::isHighPtMuon(mu, pv) ? 2 : isTrackerHighPt(mu, pv);
0068     soft[i] = isRun2016BCDEF ? isSoftMuonHIP(mu, pv) : muon::isSoftMuon(mu, pv);
0069     medium[i] = isRun2016BCDEF ? isMediumMuonHIP(mu) : muon::isMediumMuon(mu);
0070   }
0071 
0072   auto tab = std::make_unique<nanoaod::FlatTable>(ncand, name_, false, true);
0073   tab->addColumn<bool>("tightId", tight, "POG Tight muon ID");
0074   tab->addColumn<uint8_t>(
0075       "highPtId",
0076       highPt,
0077       "POG highPt muon ID (1 = tracker high pT, 2 = global high pT, which includes tracker high pT)");
0078   tab->addColumn<bool>(
0079       "softId",
0080       soft,
0081       "POG Soft muon ID (using the relaxed cuts in the data Run 2016 B-F periods, and standard cuts elsewhere)");
0082   tab->addColumn<bool>(
0083       "mediumId",
0084       medium,
0085       "POG Medium muon ID (using the relaxed cuts in the data Run 2016 B-F periods, and standard cuts elsewhere)");
0086 
0087   iEvent.put(std::move(tab));
0088 }
0089 
0090 bool MuonIDTableProducer::isMediumMuonHIP(const pat::Muon& mu) {
0091   bool goodGlob = mu.isGlobalMuon() && mu.globalTrack()->normalizedChi2() < 3 &&
0092                   mu.combinedQuality().chi2LocalPosition < 12 && mu.combinedQuality().trkKink < 20;
0093   bool isMedium = muon::isLooseMuon(mu) && mu.innerTrack()->validFraction() > 0.49 &&
0094                   muon::segmentCompatibility(mu) > (goodGlob ? 0.303 : 0.451);
0095   return isMedium;
0096 }
0097 
0098 bool MuonIDTableProducer::isSoftMuonHIP(const pat::Muon& mu, const reco::Vertex& vtx) {
0099   return muon::isGoodMuon(mu, muon::TMOneStationTight) &&
0100          mu.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
0101          mu.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0 &&
0102          std::abs(mu.innerTrack()->dxy(vtx.position())) < 0.3 && std::abs(mu.innerTrack()->dz(vtx.position())) < 20.;
0103 }
0104 
0105 bool MuonIDTableProducer::isTrackerHighPt(const pat::Muon& mu, const reco::Vertex& primaryVertex) {
0106   return (mu.numberOfMatchedStations() > 1 && (mu.muonBestTrack()->ptError() / mu.muonBestTrack()->pt()) < 0.3 &&
0107           std::abs(mu.muonBestTrack()->dxy(primaryVertex.position())) < 0.2 &&
0108           std::abs(mu.muonBestTrack()->dz(primaryVertex.position())) < 0.5 &&
0109           mu.innerTrack()->hitPattern().numberOfValidPixelHits() > 0 &&
0110           mu.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5);
0111 }
0112 
0113 #include "FWCore/Framework/interface/MakerMacros.h"
0114 //define this as a plug-in
0115 DEFINE_FWK_MODULE(MuonIDTableProducer);