File indexing completed on 2023-10-25 09:53:11
0001 #include "HLTDiMuonGlbTrkFilter.h"
0002 #include "DataFormats/Common/interface/Handle.h"
0003 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
0004 #include "DataFormats/HLTReco/interface/TriggerRefsCollections.h"
0005 #include "DataFormats/TrackReco/interface/Track.h"
0006 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
0007 #include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
0008 #include "DataFormats/MuonReco/interface/MuonFwd.h"
0009 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0010 #include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h"
0011 #include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeedCollection.h"
0012 #include "DataFormats/Math/interface/deltaR.h"
0013 #include "TrackingTools/PatternTools/interface/ClosestApproachInRPhi.h"
0014 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0018 #include "FWCore/Utilities/interface/InputTag.h"
0019 #include "FWCore/Utilities/interface/EDMException.h"
0020 #include "FWCore/Framework/interface/ESHandle.h"
0021
0022 HLTDiMuonGlbTrkFilter::HLTDiMuonGlbTrkFilter(const edm::ParameterSet& iConfig)
0023 : HLTFilter(iConfig), idealMagneticFieldRecordToken_(esConsumes()) {
0024 m_muonsTag = iConfig.getParameter<edm::InputTag>("inputMuonCollection");
0025 m_muonsToken = consumes<reco::MuonCollection>(m_muonsTag);
0026 m_candsTag = iConfig.getParameter<edm::InputTag>("inputCandCollection");
0027 m_candsToken = consumes<reco::RecoChargedCandidateCollection>(m_candsTag);
0028 m_minTrkHits = iConfig.getParameter<int>("minTrkHits");
0029 m_minMuonHits = iConfig.getParameter<int>("minMuonHits");
0030 m_maxNormalizedChi2 = iConfig.getParameter<double>("maxNormalizedChi2");
0031 m_minDR = iConfig.getParameter<double>("minDR");
0032 m_allowedTypeMask = iConfig.getParameter<unsigned int>("allowedTypeMask");
0033 m_requiredTypeMask = iConfig.getParameter<unsigned int>("requiredTypeMask");
0034 m_trkMuonId = muon::SelectionType(iConfig.getParameter<unsigned int>("trkMuonId"));
0035 m_minPtMuon1 = iConfig.getParameter<double>("minPtMuon1");
0036 m_minPtMuon2 = iConfig.getParameter<double>("minPtMuon2");
0037 m_maxEtaMuon = iConfig.getParameter<double>("maxEtaMuon");
0038 m_maxYDimuon = iConfig.getParameter<double>("maxYDimuon");
0039 m_minMass = iConfig.getParameter<double>("minMass");
0040 m_maxMass = iConfig.getParameter<double>("maxMass");
0041 m_chargeOpt = iConfig.getParameter<int>("ChargeOpt");
0042 m_maxDCAMuMu = iConfig.getParameter<double>("maxDCAMuMu");
0043 m_maxdEtaMuMu = iConfig.getParameter<double>("maxdEtaMuMu");
0044 }
0045
0046 void HLTDiMuonGlbTrkFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0047 edm::ParameterSetDescription desc;
0048 makeHLTFilterDescription(desc);
0049 desc.add<edm::InputTag>("inputMuonCollection", edm::InputTag(""));
0050 desc.add<edm::InputTag>("inputCandCollection", edm::InputTag(""));
0051 desc.add<int>("minTrkHits", -1);
0052 desc.add<int>("minMuonHits", -1);
0053 desc.add<double>("maxNormalizedChi2", 1e99);
0054 desc.add<double>("minDR", 0.1);
0055 desc.add<unsigned int>("allowedTypeMask", 255);
0056 desc.add<unsigned int>("requiredTypeMask", 0);
0057 desc.add<unsigned int>("trkMuonId", 0);
0058 desc.add<double>("minPtMuon1", 17);
0059 desc.add<double>("minPtMuon2", 8);
0060 desc.add<double>("maxEtaMuon", 1e99);
0061 desc.add<double>("maxYDimuon", 1e99);
0062 desc.add<double>("minMass", 1);
0063 desc.add<double>("maxMass", 1e99);
0064 desc.add<int>("ChargeOpt", 0);
0065 desc.add<double>("maxDCAMuMu", 1e99);
0066 desc.add<double>("maxdEtaMuMu", 1e99);
0067 descriptions.add("hltDiMuonGlbTrkFilter", desc);
0068 }
0069
0070 bool HLTDiMuonGlbTrkFilter::hltFilter(edm::Event& iEvent,
0071 const edm::EventSetup& iSetup,
0072 trigger::TriggerFilterObjectWithRefs& filterproduct) const {
0073 edm::Handle<reco::MuonCollection> muons;
0074 iEvent.getByToken(m_muonsToken, muons);
0075 edm::Handle<reco::RecoChargedCandidateCollection> cands;
0076 iEvent.getByToken(m_candsToken, cands);
0077 if (saveTags())
0078 filterproduct.addCollectionTag(m_candsTag);
0079 if (cands->size() != muons->size())
0080 throw edm::Exception(edm::errors::Configuration)
0081 << "Both input collection must be aligned and represent same physical muon objects";
0082 std::vector<unsigned int> filteredMuons;
0083 for (unsigned int i = 0; i < muons->size(); ++i) {
0084 const reco::Muon& muon(muons->at(i));
0085 if ((muon.type() & m_allowedTypeMask) == 0)
0086 continue;
0087 if ((muon.type() & m_requiredTypeMask) != m_requiredTypeMask)
0088 continue;
0089 if (!muon.innerTrack().isNull()) {
0090 if (muon.innerTrack()->numberOfValidHits() < m_minTrkHits)
0091 continue;
0092 }
0093 if (!muon.globalTrack().isNull()) {
0094 if (muon.globalTrack()->normalizedChi2() > m_maxNormalizedChi2)
0095 continue;
0096 if (muon.globalTrack()->hitPattern().numberOfValidMuonHits() < m_minMuonHits)
0097 continue;
0098 }
0099 if (muon.isTrackerMuon() && !muon::isGoodMuon(muon, m_trkMuonId))
0100 continue;
0101 if (muon.pt() < std::min(m_minPtMuon1, m_minPtMuon2))
0102 continue;
0103 if (std::abs(muon.eta()) > m_maxEtaMuon)
0104 continue;
0105 filteredMuons.push_back(i);
0106 }
0107
0108 unsigned int npassed(0);
0109 std::set<unsigned int> mus;
0110 if (filteredMuons.size() > 1) {
0111
0112 edm::ESHandle<MagneticField> bFieldHandle;
0113 if (m_maxDCAMuMu < 100.)
0114 bFieldHandle = iSetup.getHandle(idealMagneticFieldRecordToken_);
0115 for (unsigned int i = 0; i < filteredMuons.size() - 1; ++i)
0116 for (unsigned int j = i + 1; j < filteredMuons.size(); ++j) {
0117 const reco::Muon& mu1(muons->at(filteredMuons.at(i)));
0118 const reco::Muon& mu2(muons->at(filteredMuons.at(j)));
0119 if (std::max(mu1.pt(), mu2.pt()) > std::max(m_minPtMuon1, m_minPtMuon2) &&
0120 std::abs(mu2.eta() - mu1.eta()) < m_maxdEtaMuMu && deltaR(mu1, mu2) > m_minDR &&
0121 (mu1.p4() + mu2.p4()).mass() > m_minMass && (mu1.p4() + mu2.p4()).mass() < m_maxMass &&
0122 std::abs((mu1.p4() + mu2.p4()).Rapidity()) < m_maxYDimuon) {
0123 if (m_chargeOpt < 0) {
0124 if (mu1.charge() * mu2.charge() > 0)
0125 continue;
0126 } else if (m_chargeOpt > 0) {
0127 if (mu1.charge() * mu2.charge() < 0)
0128 continue;
0129 }
0130 if (m_maxDCAMuMu < 100.) {
0131 reco::TrackRef tk1 = mu1.get<reco::TrackRef>();
0132 reco::TrackRef tk2 = mu2.get<reco::TrackRef>();
0133 reco::TransientTrack mu1TT(*tk1, &(*bFieldHandle));
0134 reco::TransientTrack mu2TT(*tk2, &(*bFieldHandle));
0135 TrajectoryStateClosestToPoint mu1TS = mu1TT.impactPointTSCP();
0136 TrajectoryStateClosestToPoint mu2TS = mu2TT.impactPointTSCP();
0137 if (mu1TS.isValid() && mu2TS.isValid()) {
0138 ClosestApproachInRPhi cApp;
0139 cApp.calculate(mu1TS.theState(), mu2TS.theState());
0140 if (!cApp.status() || cApp.distance() > m_maxDCAMuMu)
0141 continue;
0142 }
0143 }
0144 mus.insert(filteredMuons.at(i));
0145 mus.insert(filteredMuons.at(j));
0146 npassed++;
0147 }
0148 }
0149 }
0150
0151 for (unsigned int mu : mus)
0152 filterproduct.addObject(trigger::TriggerMuon, reco::RecoChargedCandidateRef(cands, mu));
0153
0154 return npassed > 0;
0155 }
0156
0157
0158 #include "FWCore/Framework/interface/MakerMacros.h"
0159 DEFINE_FWK_MODULE(HLTDiMuonGlbTrkFilter);