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
update L3 filter, for 2017 online muon reconstruction #19465
Merged
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
f900940
modify L3 filter to deal with the full iterL3 reconstruction
sarafiorendi 411f95d
modify L3 filter to deal with the full iterL3 reconstruction
sarafiorendi 3f74f56
avoid creating inputTag, just checking empty label
sarafiorendi ef4cedf
fix indentation, range based loop, add protection for pt 0
sarafiorendi File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,10 +16,9 @@ | |
|
||
#include "FWCore/MessageLogger/interface/MessageLogger.h" | ||
#include "DataFormats/TrackReco/interface/Track.h" | ||
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidate.h" | ||
#include "DataFormats/RecoCandidate/interface/RecoChargedCandidateFwd.h" | ||
#include "DataFormats/MuonReco/interface/MuonTrackLinks.h" | ||
#include "DataFormats/BeamSpot/interface/BeamSpot.h" | ||
#include "DataFormats/MuonReco/interface/Muon.h" | ||
|
||
#include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeed.h" | ||
#include "DataFormats/MuonSeed/interface/L3MuonTrajectorySeedCollection.h" | ||
#include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h" | ||
|
@@ -41,6 +40,10 @@ HLTMuonL3PreFilter::HLTMuonL3PreFilter(const ParameterSet& iConfig) : HLTFilter( | |
candToken_ (consumes<reco::RecoChargedCandidateCollection>(candTag_)), | ||
previousCandTag_ (iConfig.getParameter<InputTag > ("PreviousCandTag")), | ||
previousCandToken_ (consumes<trigger::TriggerFilterObjectWithRefs>(previousCandTag_)), | ||
l1CandTag_ (iConfig.getParameter<InputTag > ("L1CandTag")), | ||
l1CandToken_ (consumes<trigger::TriggerFilterObjectWithRefs>(l1CandTag_)), | ||
recoMuTag_ (iConfig.getParameter<InputTag > ("inputMuonCollection")), | ||
recoMuToken_ (consumes<reco::MuonCollection>(recoMuTag_)), | ||
min_N_ (iConfig.getParameter<int> ("MinN")), | ||
max_Eta_ (iConfig.getParameter<double> ("MaxEta")), | ||
min_Nhits_ (iConfig.getParameter<int> ("MinNhits")), | ||
|
@@ -56,6 +59,14 @@ HLTMuonL3PreFilter::HLTMuonL3PreFilter(const ParameterSet& iConfig) : HLTFilter( | |
min_NmuonHits_ (iConfig.getParameter<int> ("MinNmuonHits")), | ||
max_PtDifference_ (iConfig.getParameter<double> ("MaxPtDifference")), | ||
min_TrackPt_ (iConfig.getParameter<double> ("MinTrackPt")), | ||
min_MuonStations_L3fromL1_ (iConfig.getParameter<int>("minMuonStations")), | ||
allowedTypeMask_L3fromL1_ (iConfig.getParameter<unsigned int>("allowedTypeMask")), | ||
requiredTypeMask_L3fromL1_ (iConfig.getParameter<unsigned int>("requiredTypeMask")), | ||
maxNormalizedChi2_L3fromL1_(iConfig.getParameter<double>("MaxNormalizedChi2_L3FromL1")), | ||
trkMuonId_ ( muon::SelectionType(iConfig.getParameter<unsigned int>("trkMuonId"))), | ||
L1MatchingdR_ (iConfig.getParameter<double> ("L1MatchingdR")), | ||
matchPreviousCand_( iConfig.getParameter<bool>("MatchToPreviousCand") ), | ||
|
||
devDebug_ (false), | ||
theL3LinksLabel (iConfig.getParameter<InputTag>("InputLinks")), | ||
linkToken_ (consumes<reco::MuonTrackLinksCollection>(theL3LinksLabel)) | ||
|
@@ -84,6 +95,8 @@ HLTMuonL3PreFilter::fillDescriptions(edm::ConfigurationDescriptions& description | |
desc.add<edm::InputTag>("CandTag",edm::InputTag("hltL3MuonCandidates")); | ||
// desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag("hltDiMuonL2PreFiltered0")); | ||
desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag("")); | ||
desc.add<edm::InputTag>("L1CandTag",edm::InputTag("")); | ||
desc.add<edm::InputTag>("inputMuonCollection",edm::InputTag("")); | ||
desc.add<int>("MinN",1); | ||
desc.add<double>("MaxEta",2.5); | ||
desc.add<int>("MinNhits",0); | ||
|
@@ -99,6 +112,15 @@ HLTMuonL3PreFilter::fillDescriptions(edm::ConfigurationDescriptions& description | |
desc.add<int>("MinNmuonHits",0); | ||
desc.add<double>("MaxPtDifference",9999.0); | ||
desc.add<double>("MinTrackPt",0.0); | ||
desc.add<int>("minMuonStations",-1); | ||
desc.add<int>("minTrkHits",-1); | ||
desc.add<int>("minMuonHits",-1); | ||
desc.add<unsigned int>("allowedTypeMask",255); | ||
desc.add<unsigned int>("requiredTypeMask",0); | ||
desc.add<double>("MaxNormalizedChi2_L3FromL1",0.0); | ||
desc.add<unsigned int>("trkMuonId",0); | ||
desc.add<double>("L1MatchingdR",0.3); | ||
desc.add<bool>("MatchToPreviousCand", true); | ||
desc.add<edm::InputTag>("InputLinks",edm::InputTag("")); | ||
descriptions.add("hltMuonL3PreFilter",desc); | ||
} | ||
|
@@ -134,9 +156,11 @@ bool HLTMuonL3PreFilter::hltFilter(Event& iEvent, const EventSetup& iSetup, trig | |
// Number of objects passing the L3 Trigger: | ||
int n = 0; | ||
|
||
// sort them by L2Track | ||
// sort them by L2Track | ||
std::map<reco::TrackRef, std::vector<RecoChargedCandidateRef> > L2toL3s; | ||
|
||
// map the L3 cands matched to a L1 to their position in the recoMuon collection | ||
std::map<unsigned int, RecoChargedCandidateRef > MuonToL3s; | ||
|
||
// Test to see if we can use L3MuonTrajectorySeeds: | ||
if (mucands->empty()) return false; | ||
auto const &tk = (*mucands)[0].track(); | ||
|
@@ -168,101 +192,102 @@ bool HLTMuonL3PreFilter::hltFilter(Event& iEvent, const EventSetup& iSetup, trig | |
// Read Links collection: | ||
edm::Handle<reco::MuonTrackLinksCollection> links; | ||
iEvent.getByToken(linkToken_, links); | ||
|
||
|
||
edm::Handle<trigger::TriggerFilterObjectWithRefs> level1Cands; | ||
std::vector<l1t::MuonRef> vl1cands; | ||
std::vector<l1t::MuonRef>::iterator vl1cands_begin; | ||
std::vector<l1t::MuonRef>::iterator vl1cands_end; | ||
|
||
bool check_l1match = true; | ||
|
||
// Loop over RecoChargedCandidates: | ||
for(unsigned int i(0); i < mucands->size(); ++i){ | ||
RecoChargedCandidateRef cand(mucands,i); | ||
TrackRef tk = cand->track(); | ||
check_l1match = true; | ||
int nlink = 0; | ||
for(auto const & link : *links){ | ||
TrackRef tk = cand->track(); | ||
nlink++; | ||
|
||
// Using the same method that was used to create the links between L3 and L2 | ||
// ToDo: there should be a better way than dR,dPt matching | ||
const reco::Track& globalTrack = *link.globalTrack(); | ||
float dR2 = deltaR2(tk->eta(),tk->phi(),globalTrack.eta(),globalTrack.phi()); | ||
float dPt = std::abs(tk->pt() - globalTrack.pt())/tk->pt(); | ||
if (dR2 < 0.02*0.02 and dPt < 0.001) { | ||
const reco::Track& trackerTrack = *link.trackerTrack(); | ||
|
||
float dR2 = deltaR2(tk->eta(),tk->phi(),trackerTrack.eta(),trackerTrack.phi()); | ||
float dPt = std::abs(tk->pt() - trackerTrack.pt())/tk->pt(); | ||
|
||
if (matchPreviousCand_ && dR2 < 0.02*0.02 and dPt < 0.001) { | ||
const TrackRef staTrack = link.standAloneTrack(); | ||
L2toL3s[staTrack].push_back(RecoChargedCandidateRef(cand)); | ||
check_l1match = false; | ||
} | ||
} //MTL loop | ||
|
||
|
||
if ( !( l1CandTag_ == edm::InputTag("")) && check_l1match && matchPreviousCand_){ | ||
iEvent.getByToken(l1CandToken_,level1Cands); | ||
level1Cands->getObjects(trigger::TriggerL1Mu,vl1cands); | ||
const unsigned int nL1Muons(vl1cands.size()); | ||
for (unsigned int il1=0; il1!=nL1Muons; ++il1) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hi @sarafiorendi - please fix the code indentation here. |
||
if (deltaR(cand->eta(), cand->phi(), vl1cands[il1]->eta(), vl1cands[il1]->phi()) < L1MatchingdR_) { | ||
MuonToL3s[i] = RecoChargedCandidateRef(cand); | ||
} | ||
} | ||
} | ||
} //RCC loop | ||
} //end of using normal TrajectorySeeds | ||
|
||
// look at all mucands, check cuts and add to filter object | ||
auto L2toL3s_it = L2toL3s.begin(); | ||
auto L2toL3s_end = L2toL3s.end(); | ||
LogDebug("HLTMuonL3PreFilter")<<"looking at: "<<L2toL3s.size()<<" L2->L3s from: "<<mucands->size(); | ||
for (; L2toL3s_it!=L2toL3s_end; ++L2toL3s_it){ | ||
|
||
if (!triggeredByLevel2(L2toL3s_it->first,vl2cands)) continue; | ||
|
||
//loop over the L3Tk reconstructed for this L2. | ||
unsigned int iTk=0; | ||
unsigned int maxItk=L2toL3s_it->second.size(); | ||
for (; iTk!=maxItk; iTk++){ | ||
|
||
RecoChargedCandidateRef & cand=L2toL3s_it->second[iTk]; | ||
TrackRef tk = cand->track(); | ||
|
||
LogDebug("HLTMuonL3PreFilter") << " 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(); | ||
|
||
// eta cut | ||
if (std::abs(cand->eta())>max_Eta_) continue; | ||
|
||
// cut on number of hits | ||
if (tk->numberOfValidHits()<min_Nhits_) continue; | ||
|
||
//max dr cut | ||
auto dr = std::abs( (- (cand->vx()-beamSpot.x0()) * cand->py() + (cand->vy()-beamSpot.y0()) * cand->px() ) / cand->pt() ); | ||
if (dr >max_Dr_) continue; | ||
|
||
//min dr cut | ||
if (dr <min_Dr_) continue; | ||
|
||
//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; | ||
|
||
//normalizedChi2 cut | ||
if (tk->normalizedChi2() > max_NormalizedChi2_ ) 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; | ||
// look at all mucands, check cuts and add to filter object | ||
auto L2toL3s_it = L2toL3s.begin(); | ||
auto L2toL3s_end = L2toL3s.end(); | ||
LogDebug("HLTMuonL3PreFilter")<<"looking at: "<<L2toL3s.size()<<" L2->L3s from: "<<mucands->size(); | ||
for (; L2toL3s_it!=L2toL3s_end; ++L2toL3s_it){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better rewritten as a range based loop (for const auto & L2toL3: L2toL3s)... |
||
|
||
// 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("HLTMuonL3PreFilter") << " ...Muon in loop, trackkRef pt= " | ||
<< tk->pt() << ", ptLx= " << ptLx | ||
<< " cand pT " << cand->pt(); | ||
if (ptLx<min_Pt_) continue; | ||
if (matchPreviousCand_ && !( triggeredByLevel2(L2toL3s_it->first,vl2cands))) continue; | ||
|
||
filterproduct.addObject(TriggerMuon,cand); | ||
n++; | ||
break; // and go on with the next L2 association | ||
} | ||
}////loop over L2s from L3 grouping | ||
//loop over the L3Tk reconstructed for this L2. | ||
unsigned int iTk=0; | ||
unsigned int maxItk=L2toL3s_it->second.size(); | ||
for (; iTk!=maxItk; iTk++){ | ||
|
||
RecoChargedCandidateRef & cand=L2toL3s_it->second[iTk]; | ||
if (! applySelection(cand, beamSpot)) continue; | ||
|
||
filterproduct.addObject(TriggerMuon,cand); | ||
n++; | ||
break; // and go on with the next L2 association | ||
} | ||
}////loop over L2s from L3 grouping | ||
|
||
// now loop on L3 from L1 | ||
edm::Handle<reco::MuonCollection> recomuons; | ||
iEvent.getByToken(recoMuToken_,recomuons); | ||
|
||
auto MuonToL3s_it = MuonToL3s.begin(); | ||
auto MuonToL3s_end = MuonToL3s.end(); | ||
for (; MuonToL3s_it!=MuonToL3s_end; ++MuonToL3s_it){ | ||
|
||
const reco::Muon& muon(recomuons->at(MuonToL3s_it->first)); | ||
|
||
// applys specific cuts for TkMu | ||
if ( (muon.type() & allowedTypeMask_L3fromL1_ ) == 0 ) continue; | ||
if ( (muon.type() & requiredTypeMask_L3fromL1_) != requiredTypeMask_L3fromL1_ ) continue; | ||
if ( muon.numberOfMatchedStations() < min_MuonStations_L3fromL1_ ) continue; | ||
if ( !muon.globalTrack().isNull() ){ | ||
if (muon.globalTrack()->normalizedChi2() > maxNormalizedChi2_L3fromL1_) continue; | ||
} | ||
if ( muon.isTrackerMuon() && !muon::isGoodMuon(muon,trkMuonId_) ) continue; | ||
|
||
RecoChargedCandidateRef & cand=MuonToL3s_it->second; | ||
// apply common selection | ||
if (! applySelection(cand, beamSpot)) continue; | ||
filterproduct.addObject(TriggerMuon,cand); | ||
n++; | ||
|
||
break; // and go on with the next L3 from L1 | ||
|
||
} | ||
|
||
vector<RecoChargedCandidateRef> vref; | ||
filterproduct.getObjects(TriggerMuon,vref); | ||
for (auto & i : vref) { | ||
|
@@ -295,3 +320,63 @@ HLTMuonL3PreFilter::triggeredByLevel2(const TrackRef& staTrack,vector<RecoCharge | |
return ok; | ||
} | ||
|
||
bool | ||
HLTMuonL3PreFilter::applySelection(const RecoChargedCandidateRef& cand, const BeamSpot& beamSpot) const | ||
{ | ||
// eta cut | ||
if (std::abs(cand->eta())>max_Eta_) return false; | ||
|
||
TrackRef tk = cand->track(); | ||
LogDebug("HLTMuonL3PreFilter") << " 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_) return false; | ||
|
||
//max dr cut | ||
auto dr = std::abs( (- (cand->vx()-beamSpot.x0()) * cand->py() + (cand->vy()-beamSpot.y0()) * cand->px() ) / cand->pt() ); | ||
if (dr >max_Dr_) return false; | ||
|
||
//min dr cut | ||
if (dr <min_Dr_) return false; | ||
|
||
//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_) return false; | ||
|
||
// dxy significance cut (safeguard against bizarre values) | ||
if (min_DxySig_ > 0 && (tk->dxyError() <= 0 || std::abs(tk->dxy(beamSpot.position())/tk->dxyError()) < min_DxySig_)) return false; | ||
|
||
//normalizedChi2 cut | ||
if (tk->normalizedChi2() > max_NormalizedChi2_ ) return false; | ||
|
||
//dxy beamspot cut | ||
float absDxy = std::abs(tk->dxy(beamSpot.position())); | ||
if (absDxy > max_DXYBeamSpot_ || absDxy < min_DXYBeamSpot_ ) return false; | ||
|
||
//min muon hits cut | ||
const reco::HitPattern& trackHits = tk->hitPattern(); | ||
if (trackHits.numberOfValidMuonHits() < min_NmuonHits_ ) return false; | ||
|
||
//pt difference cut | ||
double candPt = cand->pt(); | ||
double trackPt = tk->pt(); | ||
|
||
if (std::abs(candPt - trackPt) > max_PtDifference_ ) return false; | ||
|
||
//track pt cut | ||
if (trackPt < min_TrackPt_ ) return false; | ||
|
||
// 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("HLTMuonL3PreFilter") << " ...Muon in loop, trackkRef pt= " | ||
<< tk->pt() << ", ptLx= " << ptLx | ||
<< " cand pT " << cand->pt(); | ||
if (ptLx<min_Pt_) return false; | ||
|
||
return true; | ||
|
||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you use
instead, to avoid creating
InputTag
s every time ?