Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 78 additions & 13 deletions HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -26,18 +27,34 @@
// constructors and destructor
//

namespace {
bool isDupMuon(const l1t::TkMuonRef& muon, const std::vector<l1t::TkMuonRef>& 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) {
Copy link
Contributor

@fwyzard fwyzard Mar 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the duplicate muons always from the same subsystem (barrel/overlap/forward) ?
or are the coordinates exactly the same also for muons from different subsystems ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont know. I do know the cut listed on the twiki is deltaR>0

return true;
}
}
return false;
}
} // namespace

L1TTkMuonFilter::L1TTkMuonFilter(const edm::ParameterSet& iConfig)
: HLTFilter(iConfig),
l1TkMuonTag_(iConfig.getParameter<edm::InputTag>("inputTag")),
tkMuonToken_(consumes<TkMuonCollection>(l1TkMuonTag_)) {
tkMuonToken_(consumes<TkMuonCollection>(l1TkMuonTag_)),
qualityCut_(iConfig.getParameter<edm::ParameterSet>("qualities")) {
min_Pt_ = iConfig.getParameter<double>("MinPt");
min_N_ = iConfig.getParameter<int>("MinN");
min_Eta_ = iConfig.getParameter<double>("MinEta");
max_Eta_ = iConfig.getParameter<double>("MaxEta");
applyQuality_ = iConfig.getParameter<bool>("applyQuality");
applyDuplicateRemoval_ = iConfig.getParameter<bool>("applyDuplicateRemoval");
scalings_ = iConfig.getParameter<edm::ParameterSet>("Scalings");
barrelScalings_ = scalings_.getParameter<std::vector<double> >("barrel");
overlapScalings_ = scalings_.getParameter<std::vector<double> >("overlap");
endcapScalings_ = scalings_.getParameter<std::vector<double> >("endcap");
barrelScalings_ = scalings_.getParameter<std::vector<double>>("barrel");
overlapScalings_ = scalings_.getParameter<std::vector<double>>("overlap");
endcapScalings_ = scalings_.getParameter<std::vector<double>>("endcap");
}

L1TTkMuonFilter::~L1TTkMuonFilter() = default;
Expand All @@ -54,11 +71,14 @@ void L1TTkMuonFilter::fillDescriptions(edm::ConfigurationDescriptions& descripti
desc.add<double>("MaxEta", 5.0);
desc.add<int>("MinN", 1);
desc.add<edm::InputTag>("inputTag", edm::InputTag("L1TkMuons"));
desc.add<bool>("applyQuality", true);
desc.add<bool>("applyDuplicateRemoval", true);
desc.add<edm::ParameterSetDescription>("qualities", MuonQualityCut::makePSetDescription());

edm::ParameterSetDescription descScalings;
descScalings.add<std::vector<double> >("barrel", {0.0, 1.0, 0.0});
descScalings.add<std::vector<double> >("overlap", {0.0, 1.0, 0.0});
descScalings.add<std::vector<double> >("endcap", {0.0, 1.0, 0.0});
descScalings.add<std::vector<double>>("barrel", {0.0, 1.0, 0.0});
descScalings.add<std::vector<double>>("overlap", {0.0, 1.0, 0.0});
descScalings.add<std::vector<double>>("endcap", {0.0, 1.0, 0.0});
desc.add<edm::ParameterSetDescription>("Scalings", descScalings);

descriptions.add("L1TTkMuonFilter", desc);
Expand Down Expand Up @@ -88,25 +108,70 @@ bool L1TTkMuonFilter::hltFilter(edm::Event& iEvent,
Handle<l1t::TkMuonCollection> 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<l1t::TkMuonRef> 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_ || qualityCut_(*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 (!applyDuplicateRemoval_ || !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<int>(passingMuons.size()) >= min_N_);
return accept;
}

L1TTkMuonFilter::MuonQualityCut::MuonQualityCut(const edm::ParameterSet& iConfig) {
auto detQualities = iConfig.getParameter<std::vector<edm::ParameterSet>>("values");
for (const auto& detQuality : detQualities) {
auto dets = detQuality.getParameter<std::vector<int>>("detectors");
auto qualities = detQuality.getParameter<std::vector<int>>("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<std::vector<int>>("detectors", {3});
detQualDesc.add<std::vector<int>>("qualities", {11, 13, 14, 15});
std::vector<edm::ParameterSet> detQualDefaults;
edm::ParameterSet detQualDefault;
detQualDefault.addParameter<std::vector<int>>("detectors", {3});
detQualDefault.addParameter<std::vector<int>>("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));
Expand Down
15 changes: 15 additions & 0 deletions HLTrigger/HLTfilters/plugins/L1TTkMuonFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<int, std::vector<int>> allowedQualities_;
};

edm::InputTag l1TkMuonTag_; //input tag for L1 Tk Muon product
typedef std::vector<l1t::TkMuon> TkMuonCollection;
edm::EDGetTokenT<TkMuonCollection> tkMuonToken_; // token identifying product containing L1 TkMuons
Expand All @@ -39,11 +50,15 @@ 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 applyDuplicateRemoval_; // apply duplicate removal
edm::ParameterSet scalings_; // all scalings. An indirection level allows extra flexibility
std::vector<double> barrelScalings_; // barrel scalings
std::vector<double> overlapScalings_; // overlap scalings
std::vector<double> endcapScalings_; // endcap scalings

MuonQualityCut qualityCut_;

double TkMuonOfflineEt(double Et, double Eta) const;
};

Expand Down