Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simple filter for L3 muons #22714

Merged
merged 1 commit into from
Mar 23, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
198 changes: 198 additions & 0 deletions HLTrigger/Muon/plugins/HLTMuonL3SimplePreFilter.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/** \class HLTMuonL3SimplePreFilter
*
* See header file for documentation
*
*
*/

#include "HLTMuonL3SimplePreFilter.h"

#include "DataFormats/Common/interface/Handle.h"
#include "DataFormats/Common/interface/RefToBase.h"
#include "DataFormats/TrackReco/interface/Track.h"
#include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
#include "DataFormats/HLTReco/interface/TriggerRefsCollections.h"
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"

#include "FWCore/MessageLogger/interface/MessageLogger.h"

#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include <iostream>

//
// constructors and destructor
//
using namespace std;
using namespace edm;
using namespace trigger;
using namespace reco;

HLTMuonL3SimplePreFilter::HLTMuonL3SimplePreFilter(const edm::ParameterSet& iConfig) : HLTFilter(iConfig),
candTag_ (iConfig.getParameter< edm::InputTag > ("CandTag") ),
previousCandTag_ (iConfig.getParameter< edm::InputTag > ("PreviousCandTag")),
beamspotTag_ (iConfig.getParameter< edm::InputTag > ("BeamSpotTag")),
min_N_ (iConfig.getParameter<int> ("MinN")),
max_Eta_ (iConfig.getParameter<double> ("MaxEta")),
min_Nhits_ (iConfig.getParameter<int> ("MinNhits")),
max_Dz_ (iConfig.getParameter<double> ("MaxDz")),
min_DxySig_ (iConfig.getParameter<double> ("MinDxySig")),
min_Pt_ (iConfig.getParameter<double> ("MinPt")),
nsigma_Pt_ (iConfig.getParameter<double> ("NSigmaPt")),
max_NormalizedChi2_ (iConfig.getParameter<double> ("MaxNormalizedChi2")),
max_DXYBeamSpot_ (iConfig.getParameter<double> ("MaxDXYBeamSpot")),
min_DXYBeamSpot_ (iConfig.getParameter<double> ("MinDXYBeamSpot")),
min_NmuonHits_ (iConfig.getParameter<int> ("MinNmuonHits")),
max_PtDifference_ (iConfig.getParameter<double> ("MaxPtDifference")),
min_TrackPt_ (iConfig.getParameter<double> ("MinTrackPt")),
matchPreviousCand_( iConfig.getParameter<bool>("MatchToPreviousCand") )
{
candToken_ = consumes<reco::RecoChargedCandidateCollection>(candTag_);
previousCandToken_ = consumes<trigger::TriggerFilterObjectWithRefs>(previousCandTag_);
beamspotToken_ = consumes<reco::BeamSpot>(beamspotTag_);

}


HLTMuonL3SimplePreFilter::~HLTMuonL3SimplePreFilter() = default;

//
// member functions
//
void
HLTMuonL3SimplePreFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
makeHLTFilterDescription(desc);
desc.add<edm::InputTag>("BeamSpotTag",edm::InputTag("hltOfflineBeamSpot"));
desc.add<edm::InputTag>("CandTag",edm::InputTag("hltL3MuonCandidates"));
desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag(""));
desc.add<int>("MinN",1);
desc.add<double>("MaxEta",2.5);
desc.add<int>("MinNhits",0);
desc.add<double>("MaxDz",9999.0);
desc.add<double>("MinDxySig",-1.0);
desc.add<double>("MinPt",3.0);
desc.add<double>("NSigmaPt",0.0);
desc.add<double>("MaxNormalizedChi2",9999.0);
desc.add<double>("MaxDXYBeamSpot",9999.0);
desc.add<double>("MinDXYBeamSpot",-1.0);
desc.add<int>("MinNmuonHits",0);
desc.add<double>("MaxPtDifference",9999.0);
desc.add<double>("MinTrackPt",0.0);
desc.add<bool>("MatchToPreviousCand", true);
descriptions.add("hltMuonL3SimplePreFilter", desc);
}

// ------------ method called to produce the data ------------
bool
HLTMuonL3SimplePreFilter::hltFilter(edm::Event& iEvent, const edm::EventSetup& iSetup, trigger::TriggerFilterObjectWithRefs & filterproduct) const
{

// All HLT filters must create and fill an HLT filter object,
// recording any reconstructed physics objects satisfying (or not)
// this HLT filter, and place it in the Event.

if (saveTags()) filterproduct.addCollectionTag(candTag_);

// get hold of trks
Handle<RecoChargedCandidateCollection> mucands;
iEvent.getByToken (candToken_,mucands);
Handle<TriggerFilterObjectWithRefs> previousLevelCands;
iEvent.getByToken (previousCandToken_,previousLevelCands);
vector<RecoChargedCandidateRef> vcands;
if (previousLevelCands.isValid()) {
previousLevelCands->getObjects(TriggerMuon,vcands);
}

Handle<BeamSpot> recoBeamSpotHandle;
iEvent.getByToken(beamspotToken_,recoBeamSpotHandle);

// Number of objects passing the L3 Trigger:
int n = 0;
for (unsigned int iMu=0; iMu<mucands->size(); iMu++) {

RecoChargedCandidateRef cand(mucands,iMu);
LogDebug("HLTMuonL3SimplePreFilter") << "cand isNonnull " << cand.isNonnull();

//did this candidate triggered at previous stage.
if (matchPreviousCand_ && !triggerdByPreviousLevel(cand,vcands)) continue;

if (std::abs(cand->eta())>max_Eta_) continue;

TrackRef tk = cand->track();
LogDebug("HLTMuonL3SimplePreFilter") << " Muon in loop, q*pt= " << tk->charge()*tk->pt() <<" (" << cand->charge()*cand->pt() << ") "
<< ", eta= " << tk->eta() << " (" << cand->eta() << ") " << ", hits= " << tk->numberOfValidHits()
<< ", d0= " << tk->d0() << ", dz= " << tk->dz();

// cut on number of hits
if (tk->numberOfValidHits()<min_Nhits_) continue;

//normalizedChi2 cut
if (tk->normalizedChi2() > max_NormalizedChi2_ ) continue;


if (recoBeamSpotHandle.isValid()){
const BeamSpot& beamSpot = *recoBeamSpotHandle;

//dz cut
if (std::abs((cand->vz()-beamSpot.z0()) - ((cand->vx()-beamSpot.x0())*cand->px()+(cand->vy()-beamSpot.y0())*cand->py())/cand->pt() * cand->pz()/cand->pt())>max_Dz_) continue;

// dxy significance cut (safeguard against bizarre values)
if (min_DxySig_ > 0 && (tk->dxyError() <= 0 || std::abs(tk->dxy(beamSpot.position())/tk->dxyError()) < min_DxySig_)) continue;

//dxy beamspot cut
float absDxy = std::abs(tk->dxy(beamSpot.position()));
if (absDxy > max_DXYBeamSpot_ || absDxy < min_DXYBeamSpot_ ) continue;
}

//min muon hits cut
const reco::HitPattern& trackHits = tk->hitPattern();
if (trackHits.numberOfValidMuonHits() < min_NmuonHits_ ) continue;

//pt difference cut
double candPt = cand->pt();
double trackPt = tk->pt();

if (std::abs(candPt - trackPt) > max_PtDifference_ ) continue;

//track pt cut
if (trackPt < min_TrackPt_ ) continue;

// Pt threshold cut
double pt = cand->pt();
double err0 = tk->error(0);
double abspar0 = std::abs(tk->parameter(0));
double ptLx = pt;
// convert 50% efficiency threshold to 90% efficiency threshold
if (abspar0>0) ptLx += nsigma_Pt_*err0/abspar0*pt;
LogTrace("HLTMuonL3SimplePreFilter") << " ...Muon in loop, trackkRef pt= "
<< tk->pt() << ", ptLx= " << ptLx
<< " cand pT " << cand->pt();
if (ptLx<min_Pt_) continue;

n++;
filterproduct.addObject(TriggerMuon,cand);
}//for iMu

// filter decision
const bool accept (n >= min_N_);

LogDebug("HLTMuonL3SimplePreFilter") << " >>>>> Result of HLTMuonL3PreFilter is " << accept << ", number of muons passing thresholds= " << n;

return accept;
}


bool HLTMuonL3SimplePreFilter::triggerdByPreviousLevel(const reco::RecoChargedCandidateRef & candref, const std::vector<reco::RecoChargedCandidateRef>& vcands){
unsigned int i=0;
unsigned int i_max=vcands.size();
for (;i!=i_max;++i){
if (candref == vcands[i]) return true;
}

return false;
}

// declare this class as a framework plugin
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(HLTMuonL3SimplePreFilter);
54 changes: 54 additions & 0 deletions HLTrigger/Muon/plugins/HLTMuonL3SimplePreFilter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#ifndef HLTMuonL3SimplePreFilter_h
#define HLTMuonL3SimplePreFilter_h

/** \class HLTMuonL3SimplePreFilter
*
*
* This class is an HLTFilter (-> EDFilter) implementing
* the a simple filtering for HLT muons
*
* Original author: S. Folgueras <santiago.folgueras@cern.ch>
*
*/

#include "HLTrigger/HLTcore/interface/HLTFilter.h"
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h"
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "DataFormats/BeamSpot/interface/BeamSpot.h"

class HLTMuonL3SimplePreFilter : public HLTFilter {

public:
explicit HLTMuonL3SimplePreFilter(const edm::ParameterSet&);
~HLTMuonL3SimplePreFilter() override;
static void fillDescriptions(edm::ConfigurationDescriptions & descriptions);
bool hltFilter(edm::Event&, const edm::EventSetup&, trigger::TriggerFilterObjectWithRefs & filterproduct) const override;

private:
static bool triggerdByPreviousLevel(const reco::RecoChargedCandidateRef &, const std::vector<reco::RecoChargedCandidateRef> &);

edm::InputTag candTag_ ; // input tag identifying muon container
edm::EDGetTokenT<reco::RecoChargedCandidateCollection> candToken_; // token identifying muon container
edm::InputTag previousCandTag_ ; // input tag identifying product contains muons passing the previous level
edm::EDGetTokenT<trigger::TriggerFilterObjectWithRefs> previousCandToken_; // token identifying product contains muons passing the previous level
edm::InputTag beamspotTag_ ;
edm::EDGetTokenT<reco::BeamSpot> beamspotToken_ ;

const int min_N_; // minimum number of muons to fire the trigger
const double max_Eta_; // Eta cut
const int min_Nhits_; // threshold on number of hits on muon
const double max_Dz_; // dz cut
const double min_DxySig_; // dxy significance cut
const double min_Pt_; // pt threshold in GeV
const double nsigma_Pt_; // pt uncertainty margin (in number of sigmas)
const double max_NormalizedChi2_; // cutoff in normalized chi2
const double max_DXYBeamSpot_; // cutoff in dxy from the beamspot
const double min_DXYBeamSpot_; // minimum cut on dxy from the beamspot
const int min_NmuonHits_; // cutoff in minumum number of chi2 hits
const double max_PtDifference_; // cutoff in maximum different between global track and tracker track
const double min_TrackPt_; // cutoff in tracker track pt
bool matchPreviousCand_;
};
#endif //HLTMuonL3SimplePreFilter_h