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