From 74b1eb07c4f5346f46e060eb20382bd07616b432 Mon Sep 17 00:00:00 2001 From: Sam Harper Date: Mon, 1 Mar 2021 16:57:06 +0100 Subject: [PATCH 1/2] adding duplicate removal and implimenting L1 quality cuts --- .../HLTfilters/plugins/L1TTkMuonFilter.cc | 48 ++++++++++++++++--- .../HLTfilters/plugins/L1TTkMuonFilter.h | 2 + 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc index 28441229cc793..14b94387dffca 100644 --- a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc +++ b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc @@ -17,6 +17,7 @@ #include "DataFormats/Common/interface/Ref.h" #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h" #include "DataFormats/HLTReco/interface/TriggerTypeDefs.h" +#include "DataFormats/Math/interface/deltaR.h" #include "FWCore/Framework/interface/EventSetup.h" #include "FWCore/Framework/interface/EventSetupRecord.h" @@ -26,6 +27,31 @@ // constructors and destructor // +namespace { + bool passMuQual(const l1t::TkMuon& muon) { + if (muon.muonDetector() == 3) { + int quality = muon.quality(); + if (quality == 11 || quality == 13 || quality == 14 || quality == 15) { + return true; + } else { + return false; + } + } else { + return true; + } + } + bool isDupMuon(const l1t::TkMuonRef& muon, const std::vector& existing) { + for (const auto& exist : existing) { + //it is our understanding that there is an exact eta phi match + //and we should not be concerned with numerical precision + if (reco::deltaR2(*muon, *exist) <= 0) { + return true; + } + } + return false; + } +} // namespace + L1TTkMuonFilter::L1TTkMuonFilter(const edm::ParameterSet& iConfig) : HLTFilter(iConfig), l1TkMuonTag_(iConfig.getParameter("inputTag")), @@ -34,6 +60,8 @@ L1TTkMuonFilter::L1TTkMuonFilter(const edm::ParameterSet& iConfig) min_N_ = iConfig.getParameter("MinN"); min_Eta_ = iConfig.getParameter("MinEta"); max_Eta_ = iConfig.getParameter("MaxEta"); + applyQuality_ = iConfig.getParameter("applyQuality"); + doDupRemoval_ = iConfig.getParameter("doDupRemoval"); scalings_ = iConfig.getParameter("Scalings"); barrelScalings_ = scalings_.getParameter >("barrel"); overlapScalings_ = scalings_.getParameter >("overlap"); @@ -54,6 +82,8 @@ void L1TTkMuonFilter::fillDescriptions(edm::ConfigurationDescriptions& descripti desc.add("MaxEta", 5.0); desc.add("MinN", 1); desc.add("inputTag", edm::InputTag("L1TkMuons")); + desc.add("applyQuality", true); + desc.add("doDupRemoval", true); edm::ParameterSetDescription descScalings; descScalings.add >("barrel", {0.0, 1.0, 0.0}); @@ -88,22 +118,28 @@ bool L1TTkMuonFilter::hltFilter(edm::Event& iEvent, Handle tkMuons; iEvent.getByToken(tkMuonToken_, tkMuons); - // trkMuon - int ntrkmuon(0); + //it looks rather slow to get the added muons back out of the filterproduct + //so we just make a vector of passing and then add them all at the end + std::vector passingMuons; auto atrkmuons(tkMuons->begin()); auto otrkmuons(tkMuons->end()); TkMuonCollection::const_iterator itkMuon; for (itkMuon = atrkmuons; itkMuon != otrkmuons; itkMuon++) { double offlinePt = this->TkMuonOfflineEt(itkMuon->pt(), itkMuon->eta()); - if (offlinePt >= min_Pt_ && itkMuon->eta() <= max_Eta_ && itkMuon->eta() >= min_Eta_) { - ntrkmuon++; + bool passesQual = !applyQuality_ || passMuQual(*itkMuon); + if (passesQual && offlinePt >= min_Pt_ && itkMuon->eta() <= max_Eta_ && itkMuon->eta() >= min_Eta_) { l1t::TkMuonRef ref(l1t::TkMuonRef(tkMuons, distance(atrkmuons, itkMuon))); - filterproduct.addObject(trigger::TriggerObjectType::TriggerL1TkMu, ref); + if (!doDupRemoval_ || !isDupMuon(ref, passingMuons)) { + passingMuons.push_back(ref); + } } } + for (const auto& muon : passingMuons) { + filterproduct.addObject(trigger::TriggerObjectType::TriggerL1TkMu, muon); + } // return with final filter decision - const bool accept(ntrkmuon >= min_N_); + const bool accept(static_cast(passingMuons.size()) >= min_N_); return accept; } diff --git a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h index 9f3d977c8b690..c022de769f917 100644 --- a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h +++ b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h @@ -39,6 +39,8 @@ class L1TTkMuonFilter : public HLTFilter { int min_N_; // min number of candidates above pT cut double min_Eta_; // min eta cut double max_Eta_; // max eta cut + bool applyQuality_; // apply quaility cuts + bool doDupRemoval_; // do dup removal edm::ParameterSet scalings_; // all scalings. An indirection level allows extra flexibility std::vector barrelScalings_; // barrel scalings std::vector overlapScalings_; // overlap scalings From 8b384cf7638f7d2e8d13c3af5c4ec239e691013d Mon Sep 17 00:00:00 2001 From: Sam Harper Date: Tue, 2 Mar 2021 13:50:55 +0100 Subject: [PATCH 2/2] code review comments --- .../HLTfilters/plugins/L1TTkMuonFilter.cc | 75 +++++++++++++------ .../HLTfilters/plugins/L1TTkMuonFilter.h | 15 +++- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc index 14b94387dffca..339bedecfadc4 100644 --- a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc +++ b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc @@ -28,18 +28,6 @@ // namespace { - bool passMuQual(const l1t::TkMuon& muon) { - if (muon.muonDetector() == 3) { - int quality = muon.quality(); - if (quality == 11 || quality == 13 || quality == 14 || quality == 15) { - return true; - } else { - return false; - } - } else { - return true; - } - } bool isDupMuon(const l1t::TkMuonRef& muon, const std::vector& existing) { for (const auto& exist : existing) { //it is our understanding that there is an exact eta phi match @@ -55,17 +43,18 @@ namespace { L1TTkMuonFilter::L1TTkMuonFilter(const edm::ParameterSet& iConfig) : HLTFilter(iConfig), l1TkMuonTag_(iConfig.getParameter("inputTag")), - tkMuonToken_(consumes(l1TkMuonTag_)) { + tkMuonToken_(consumes(l1TkMuonTag_)), + qualityCut_(iConfig.getParameter("qualities")) { min_Pt_ = iConfig.getParameter("MinPt"); min_N_ = iConfig.getParameter("MinN"); min_Eta_ = iConfig.getParameter("MinEta"); max_Eta_ = iConfig.getParameter("MaxEta"); applyQuality_ = iConfig.getParameter("applyQuality"); - doDupRemoval_ = iConfig.getParameter("doDupRemoval"); + applyDuplicateRemoval_ = iConfig.getParameter("applyDuplicateRemoval"); scalings_ = iConfig.getParameter("Scalings"); - barrelScalings_ = scalings_.getParameter >("barrel"); - overlapScalings_ = scalings_.getParameter >("overlap"); - endcapScalings_ = scalings_.getParameter >("endcap"); + barrelScalings_ = scalings_.getParameter>("barrel"); + overlapScalings_ = scalings_.getParameter>("overlap"); + endcapScalings_ = scalings_.getParameter>("endcap"); } L1TTkMuonFilter::~L1TTkMuonFilter() = default; @@ -83,12 +72,13 @@ void L1TTkMuonFilter::fillDescriptions(edm::ConfigurationDescriptions& descripti desc.add("MinN", 1); desc.add("inputTag", edm::InputTag("L1TkMuons")); desc.add("applyQuality", true); - desc.add("doDupRemoval", true); + desc.add("applyDuplicateRemoval", true); + desc.add("qualities", MuonQualityCut::makePSetDescription()); edm::ParameterSetDescription descScalings; - descScalings.add >("barrel", {0.0, 1.0, 0.0}); - descScalings.add >("overlap", {0.0, 1.0, 0.0}); - descScalings.add >("endcap", {0.0, 1.0, 0.0}); + descScalings.add>("barrel", {0.0, 1.0, 0.0}); + descScalings.add>("overlap", {0.0, 1.0, 0.0}); + descScalings.add>("endcap", {0.0, 1.0, 0.0}); desc.add("Scalings", descScalings); descriptions.add("L1TTkMuonFilter", desc); @@ -126,10 +116,10 @@ bool L1TTkMuonFilter::hltFilter(edm::Event& iEvent, TkMuonCollection::const_iterator itkMuon; for (itkMuon = atrkmuons; itkMuon != otrkmuons; itkMuon++) { double offlinePt = this->TkMuonOfflineEt(itkMuon->pt(), itkMuon->eta()); - bool passesQual = !applyQuality_ || passMuQual(*itkMuon); + bool passesQual = !applyQuality_ || qualityCut_(*itkMuon); if (passesQual && offlinePt >= min_Pt_ && itkMuon->eta() <= max_Eta_ && itkMuon->eta() >= min_Eta_) { l1t::TkMuonRef ref(l1t::TkMuonRef(tkMuons, distance(atrkmuons, itkMuon))); - if (!doDupRemoval_ || !isDupMuon(ref, passingMuons)) { + if (!applyDuplicateRemoval_ || !isDupMuon(ref, passingMuons)) { passingMuons.push_back(ref); } } @@ -143,6 +133,45 @@ bool L1TTkMuonFilter::hltFilter(edm::Event& iEvent, return accept; } +L1TTkMuonFilter::MuonQualityCut::MuonQualityCut(const edm::ParameterSet& iConfig) { + auto detQualities = iConfig.getParameter>("values"); + for (const auto& detQuality : detQualities) { + auto dets = detQuality.getParameter>("detectors"); + auto qualities = detQuality.getParameter>("qualities"); + std::sort(qualities.begin(), qualities.end()); + for (const auto& det : dets) { + allowedQualities_.insert({det, std::move(qualities)}); + } + } +} + +bool L1TTkMuonFilter::MuonQualityCut::operator()(const l1t::TkMuon& muon) const { + const auto& qualities = allowedQualities_.find(muon.muonDetector()); + if (qualities != allowedQualities_.end()) { + return std::binary_search(qualities->second.begin(), qualities->second.end(), muon.quality()); + } else { + return true; //if qualities for that detector is not specified, we return true + } +} + +void L1TTkMuonFilter::MuonQualityCut::fillPSetDescription(edm::ParameterSetDescription& desc) { + edm::ParameterSetDescription detQualDesc; + detQualDesc.add>("detectors", {3}); + detQualDesc.add>("qualities", {11, 13, 14, 15}); + std::vector detQualDefaults; + edm::ParameterSet detQualDefault; + detQualDefault.addParameter>("detectors", {3}); + detQualDefault.addParameter>("qualities", {11, 13, 14, 15}); + detQualDefaults.push_back(detQualDefault); + desc.addVPSet("values", detQualDesc, detQualDefaults); +} + +edm::ParameterSetDescription L1TTkMuonFilter::MuonQualityCut::makePSetDescription() { + edm::ParameterSetDescription desc; + fillPSetDescription(desc); + return desc; +} + double L1TTkMuonFilter::TkMuonOfflineEt(double Et, double Eta) const { if (std::abs(Eta) < 0.9) return (barrelScalings_.at(0) + Et * barrelScalings_.at(1) + Et * Et * barrelScalings_.at(2)); diff --git a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h index c022de769f917..f011045b7e836 100644 --- a/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h +++ b/HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h @@ -31,6 +31,17 @@ class L1TTkMuonFilter : public HLTFilter { trigger::TriggerFilterObjectWithRefs& filterproduct) const override; private: + class MuonQualityCut { + public: + MuonQualityCut(const edm::ParameterSet&); + bool operator()(const l1t::TkMuon&) const; + static void fillPSetDescription(edm::ParameterSetDescription& desc); + static edm::ParameterSetDescription makePSetDescription(); + + private: + std::unordered_map> allowedQualities_; + }; + edm::InputTag l1TkMuonTag_; //input tag for L1 Tk Muon product typedef std::vector TkMuonCollection; edm::EDGetTokenT tkMuonToken_; // token identifying product containing L1 TkMuons @@ -40,12 +51,14 @@ class L1TTkMuonFilter : public HLTFilter { double min_Eta_; // min eta cut double max_Eta_; // max eta cut bool applyQuality_; // apply quaility cuts - bool doDupRemoval_; // do dup removal + bool applyDuplicateRemoval_; // apply duplicate removal edm::ParameterSet scalings_; // all scalings. An indirection level allows extra flexibility std::vector barrelScalings_; // barrel scalings std::vector overlapScalings_; // overlap scalings std::vector endcapScalings_; // endcap scalings + MuonQualityCut qualityCut_; + double TkMuonOfflineEt(double Et, double Eta) const; };