Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:25:31

0001 #include <memory>
0002 
0003 #include "FWCore/Framework/interface/Event.h"
0004 #include "FWCore/Framework/interface/global/EDFilter.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/Utilities/interface/InputTag.h"
0007 
0008 #include "DataFormats/Math/interface/deltaR.h"
0009 #include "DataFormats/Common/interface/View.h"
0010 #include "DataFormats/Common/interface/PtrVector.h"
0011 
0012 #include "DataFormats/MuonReco/interface/Muon.h"
0013 #include "DataFormats/MuonReco/interface/MuonSelectors.h"
0014 #include "DataFormats/VertexReco/interface/Vertex.h"
0015 
0016 class BadGlobalMuonTagger : public edm::global::EDFilter<> {
0017 public:
0018   explicit BadGlobalMuonTagger(const edm::ParameterSet &iConfig);
0019   ~BadGlobalMuonTagger() override {}
0020 
0021   bool filter(edm::StreamID iID, edm::Event &iEvent, const edm::EventSetup &iSetup) const override;
0022 
0023 private:
0024   edm::EDGetTokenT<edm::View<reco::Muon>> muons_;
0025   edm::EDGetTokenT<std::vector<reco::Vertex>> vtx_;
0026   double ptCut_;
0027   bool selectClones_, taggingMode_, verbose_;
0028 
0029   bool outInOnly(const reco::Muon &mu) const {
0030     const reco::Track &tk = *mu.innerTrack();
0031     return tk.algoMask().count() == 1 && tk.isAlgoInMask(reco::Track::muonSeededStepOutIn);
0032   }
0033   bool preselection(const reco::Muon &mu) const { return (!selectClones_ || outInOnly(mu)); }
0034   bool tighterId(const reco::Muon &mu) const { return muon::isMediumMuon(mu) && mu.numberOfMatchedStations() >= 2; }
0035   bool tightGlobal(const reco::Muon &mu) const {
0036     return mu.isGlobalMuon() && (mu.globalTrack()->hitPattern().muonStationsWithValidHits() >= 3 &&
0037                                  mu.globalTrack()->normalizedChi2() <= 20);
0038   }
0039   bool safeId(const reco::Muon &mu) const {
0040     if (mu.muonBestTrack()->ptError() > 0.2 * mu.muonBestTrack()->pt()) {
0041       return false;
0042     }
0043     return mu.numberOfMatchedStations() >= 1 || tightGlobal(mu);
0044   }
0045   bool partnerId(const reco::Muon &mu) const { return mu.pt() >= 10 && mu.numberOfMatchedStations() >= 1; }
0046 };
0047 
0048 BadGlobalMuonTagger::BadGlobalMuonTagger(const edm::ParameterSet &iConfig)
0049     : muons_(consumes<edm::View<reco::Muon>>(iConfig.getParameter<edm::InputTag>("muons"))),
0050       vtx_(consumes<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("vtx"))),
0051       ptCut_(iConfig.getParameter<double>("muonPtCut")),
0052       selectClones_(iConfig.getParameter<bool>("selectClones")),
0053       taggingMode_(iConfig.getParameter<bool>("taggingMode")),
0054       verbose_(iConfig.getUntrackedParameter<bool>("verbose", false)) {
0055   produces<edm::PtrVector<reco::Muon>>("bad");
0056   produces<bool>("notBadEvent");
0057 }
0058 
0059 bool BadGlobalMuonTagger::filter(edm::StreamID iID, edm::Event &iEvent, const edm::EventSetup &iSetup) const {
0060   using namespace edm;
0061 
0062   // read input
0063   Handle<edm::View<reco::Muon>> hmuons;
0064   Handle<std::vector<reco::Vertex>> vtx;
0065   std::vector<int> goodMuon;
0066 
0067   iEvent.getByToken(vtx_, vtx);
0068   assert(!vtx->empty());
0069   const auto &PV = vtx->front().position();
0070 
0071   std::unique_ptr<edm::PtrVector<reco::Muon>> out(new edm::PtrVector<reco::Muon>());
0072   iEvent.getByToken(muons_, hmuons);
0073   const edm::View<reco::Muon> &muons = *hmuons;
0074   for (const reco::Muon &mu : muons) {
0075     if (!mu.isPFMuon() || mu.innerTrack().isNull()) {
0076       goodMuon.push_back(-1);  // bad but we don't care
0077       continue;
0078     }
0079     if (preselection(mu)) {
0080       float dxypv = std::abs(mu.innerTrack()->dxy(PV));
0081       float dzpv = std::abs(mu.innerTrack()->dz(PV));
0082       if (tighterId(mu)) {
0083         bool ipLoose = ((dxypv < 0.5 && dzpv < 2.0) || mu.innerTrack()->hitPattern().pixelLayersWithMeasurement() >= 2);
0084         goodMuon.push_back(ipLoose || (!selectClones_ && tightGlobal(mu)));
0085       } else if (safeId(mu)) {
0086         bool ipTight = (dxypv < 0.2 && dzpv < 0.5);
0087         goodMuon.push_back(ipTight);
0088       } else {
0089         goodMuon.push_back(0);
0090       }
0091     } else {
0092       goodMuon.push_back(3);  // maybe good, maybe bad, but we don't care
0093     }
0094   }
0095 
0096   bool found = false;
0097   for (unsigned int i = 0, n = muons.size(); i < n; ++i) {
0098     if (muons[i].pt() < ptCut_ || goodMuon[i] != 0)
0099       continue;
0100     if (verbose_)
0101       printf("potentially bad muon %d of pt %.1f eta %+.3f phi %+.3f\n",
0102              int(i + 1),
0103              muons[i].pt(),
0104              muons[i].eta(),
0105              muons[i].phi());
0106     bool bad = true;
0107     if (selectClones_) {
0108       bad = false;  // unless proven otherwise
0109       unsigned int n1 = muons[i].numberOfMatches(reco::Muon::SegmentArbitration);
0110       for (unsigned int j = 0; j < n; ++j) {
0111         if (j == i || goodMuon[j] <= 0 || !partnerId(muons[j]))
0112           continue;
0113         unsigned int n2 = muons[j].numberOfMatches(reco::Muon::SegmentArbitration);
0114         if (deltaR2(muons[i], muons[j]) < 0.16 ||
0115             (n1 > 0 && n2 > 0 && muon::sharedSegments(muons[i], muons[j]) >= 0.5 * std::min(n1, n2))) {
0116           if (verbose_)
0117             printf("     tagged as clone of muon %d of pt %.1f eta %+.3f phi %+.3f\n",
0118                    int(j + 1),
0119                    muons[j].pt(),
0120                    muons[j].eta(),
0121                    muons[j].phi());
0122           bad = true;
0123           break;
0124         }
0125       }
0126     }
0127     if (bad) {
0128       found = true;
0129       out->push_back(muons.ptrAt(i));
0130     }
0131   }
0132 
0133   iEvent.put(std::move(out), "bad");
0134   iEvent.put(std::make_unique<bool>(!found), "notBadEvent");
0135   return taggingMode_ || found;
0136 }
0137 
0138 #include "FWCore/Framework/interface/MakerMacros.h"
0139 DEFINE_FWK_MODULE(BadGlobalMuonTagger);