Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-05 05:20:09

0001 #include "FWCore/Framework/interface/Event.h"
0002 #include "FWCore/Framework/interface/EventSetup.h"
0003 #include "DataFormats/Common/interface/Handle.h"
0004 #include "DataFormats/MuonReco/interface/Muon.h"
0005 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0006 #include "FWCore/Framework/interface/Frameworkfwd.h"
0007 #include "FWCore/Framework/interface/global/EDFilter.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0011 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0012 
0013 class AlignmentGoodIdMuonSelector : public edm::global::EDFilter<> {
0014 public:
0015   explicit AlignmentGoodIdMuonSelector(const edm::ParameterSet&);
0016   ~AlignmentGoodIdMuonSelector() override = default;
0017 
0018   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0019 
0020 private:
0021   bool filter(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0022 
0023   const edm::EDGetTokenT<reco::MuonCollection> muonToken_;
0024   const double maxEta_;
0025   const double maxChi2_;
0026   const int minMuonHits_;
0027   const int minMatches_;
0028   const bool requireGlobal_;
0029   const bool requireTracker_;
0030   const bool filterEvents_;  // flag to control event filtering behavior
0031 
0032   // Secondary selection parameters (e.g., for Phase 2)
0033   const bool useSecondarySelection_;
0034   const double secondaryEtaLow_;
0035   const double secondaryEtaHigh_;
0036   const int secondaryMinMatches_;
0037   const bool requireTrackerForSecondary_;
0038 };
0039 
0040 void AlignmentGoodIdMuonSelector::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0041   edm::ParameterSetDescription desc;
0042   desc.add<edm::InputTag>("src", edm::InputTag("muons"))->setComment("Input muon collection");
0043   desc.add<double>("maxEta", 2.5)->setComment("|eta| cut");
0044   desc.add<double>("maxChi2", 20.)->setComment("max chi2 of the global tags");
0045   desc.add<int>("minMuonHits", 0.)->setComment("minimum number of valid muon hits");
0046   desc.add<int>("minMatches", 1.)->setComment("minimum number of matches");
0047   desc.add<bool>("requireGlobal", true)->setComment("is global muons");
0048   desc.add<bool>("requireTracker", true)->setComment("is tracker muon");
0049   desc.add<bool>("useSecondarySelection", false)->setComment("secondary selection");
0050   desc.add<double>("secondaryEtaLow", 2.3)->setComment("min eta cut (secondary)");
0051   desc.add<double>("secondaryEtaHigh", 3.0)->setComment("max eta cut (secondary)");
0052   desc.add<int>("secondaryMinMatches", 0.)->setComment("minimum number of matches (secondary)");
0053   desc.add<bool>("secondaryRequireTracker", true)->setComment("is tracker muon (secondary)");
0054   desc.add<bool>("filter", true)->setComment("retain event only if non empty collection");
0055   descriptions.addWithDefaultLabel(desc);
0056 }
0057 
0058 AlignmentGoodIdMuonSelector::AlignmentGoodIdMuonSelector(const edm::ParameterSet& iConfig)
0059     : muonToken_(consumes<reco::MuonCollection>(iConfig.getParameter<edm::InputTag>("src"))),
0060       maxEta_(iConfig.getParameter<double>("maxEta")),
0061       maxChi2_(iConfig.getParameter<double>("maxChi2")),
0062       minMuonHits_(iConfig.getParameter<int>("minMuonHits")),
0063       minMatches_(iConfig.getParameter<int>("minMatches")),
0064       requireGlobal_(iConfig.getParameter<bool>("requireGlobal")),
0065       requireTracker_(iConfig.getParameter<bool>("requireTracker")),
0066       filterEvents_(iConfig.getParameter<bool>("filter")),
0067 
0068       // Secondary selection
0069       useSecondarySelection_(iConfig.getParameter<bool>("useSecondarySelection")),
0070       secondaryEtaLow_(iConfig.getParameter<double>("secondaryEtaLow")),
0071       secondaryEtaHigh_(iConfig.getParameter<double>("secondaryEtaHigh")),
0072       secondaryMinMatches_(iConfig.getParameter<int>("secondaryMinMatches")),
0073       requireTrackerForSecondary_(iConfig.getParameter<bool>("secondaryRequireTracker")) {
0074   produces<reco::MuonCollection>();
0075 }
0076 
0077 bool AlignmentGoodIdMuonSelector::filter(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const {
0078   edm::Handle<reco::MuonCollection> muons;
0079   iEvent.getByToken(muonToken_, muons);
0080 
0081   auto selectedMuons = std::make_unique<reco::MuonCollection>();
0082 
0083   for (const auto& muon : *muons) {
0084     bool passPrimarySelection = true;
0085 
0086     // Check if globalTrack() is valid before using it
0087     if (requireGlobal_) {
0088       if (!muon.isGlobalMuon() || muon.globalTrack().isNull()) {
0089         passPrimarySelection = false;
0090       } else {
0091         // Only access properties if the global track is valid
0092         if (muon.globalTrack()->hitPattern().numberOfValidMuonHits() <= minMuonHits_)
0093           passPrimarySelection = false;
0094         if (muon.globalTrack()->normalizedChi2() >= maxChi2_)
0095           passPrimarySelection = false;
0096       }
0097     }
0098 
0099     if (requireTracker_ && !muon.isTrackerMuon())
0100       passPrimarySelection = false;
0101     if (muon.numberOfMatches() <= minMatches_)
0102       passPrimarySelection = false;
0103     if (std::abs(muon.eta()) >= maxEta_)
0104       passPrimarySelection = false;
0105 
0106     bool passSecondarySelection = false;
0107     if (useSecondarySelection_) {
0108       if (std::abs(muon.eta()) > secondaryEtaLow_ && std::abs(muon.eta()) < secondaryEtaHigh_ &&
0109           muon.numberOfMatches() >= secondaryMinMatches_ && (!requireTrackerForSecondary_ || muon.isTrackerMuon())) {
0110         passSecondarySelection = true;
0111       }
0112     }
0113 
0114     if (passPrimarySelection || passSecondarySelection) {
0115       selectedMuons->push_back(muon);
0116     }
0117   }
0118 
0119   const bool passEvent = !selectedMuons->empty();
0120   iEvent.put(std::move(selectedMuons));
0121 
0122   // Decide if the event should pass based on filterEvents_ flag
0123   return filterEvents_ ? passEvent : true;
0124 }
0125 
0126 #include "FWCore/Framework/interface/MakerMacros.h"
0127 DEFINE_FWK_MODULE(AlignmentGoodIdMuonSelector);