CMS 3D CMS Logo

HLTMuonL3PreFilter.cc
Go to the documentation of this file.
1 
9 #include "HLTMuonL3PreFilter.h"
10 
13 
16 
21 
25 
27 
28 //
29 // constructors and destructor
30 //
31 using namespace std;
32 using namespace edm;
33 using namespace reco;
34 using namespace trigger;
35 
37  beamspotTag_ (iConfig.getParameter< edm::InputTag > ("BeamSpotTag")),
38  beamspotToken_ (consumes<reco::BeamSpot>(beamspotTag_)),
39  candTag_ (iConfig.getParameter<InputTag > ("CandTag")),
40  candToken_ (consumes<reco::RecoChargedCandidateCollection>(candTag_)),
41  previousCandTag_ (iConfig.getParameter<InputTag > ("PreviousCandTag")),
42  previousCandToken_ (consumes<trigger::TriggerFilterObjectWithRefs>(previousCandTag_)),
43  l1CandTag_ (iConfig.getParameter<InputTag > ("L1CandTag")),
44  l1CandToken_ (consumes<trigger::TriggerFilterObjectWithRefs>(l1CandTag_)),
45  recoMuTag_ (iConfig.getParameter<InputTag > ("inputMuonCollection")),
46  recoMuToken_ (consumes<reco::MuonCollection>(recoMuTag_)),
47  min_N_ (iConfig.getParameter<int> ("MinN")),
48  max_Eta_ (iConfig.getParameter<double> ("MaxEta")),
49  min_Nhits_ (iConfig.getParameter<int> ("MinNhits")),
50  max_Dr_ (iConfig.getParameter<double> ("MaxDr")),
51  min_Dr_ (iConfig.getParameter<double> ("MinDr")),
52  max_Dz_ (iConfig.getParameter<double> ("MaxDz")),
53  min_DxySig_(iConfig.getParameter<double> ("MinDxySig")),
54  min_Pt_ (iConfig.getParameter<double> ("MinPt")),
55  nsigma_Pt_ (iConfig.getParameter<double> ("NSigmaPt")),
56  max_NormalizedChi2_ (iConfig.getParameter<double> ("MaxNormalizedChi2")),
57  max_DXYBeamSpot_ (iConfig.getParameter<double> ("MaxDXYBeamSpot")),
58  min_DXYBeamSpot_ (iConfig.getParameter<double> ("MinDXYBeamSpot")),
59  min_NmuonHits_ (iConfig.getParameter<int> ("MinNmuonHits")),
60  max_PtDifference_ (iConfig.getParameter<double> ("MaxPtDifference")),
61  min_TrackPt_ (iConfig.getParameter<double> ("MinTrackPt")),
62  min_MuonStations_L3fromL1_ (iConfig.getParameter<int>("minMuonStations")),
63  allowedTypeMask_L3fromL1_ (iConfig.getParameter<unsigned int>("allowedTypeMask")),
64  requiredTypeMask_L3fromL1_ (iConfig.getParameter<unsigned int>("requiredTypeMask")),
65  maxNormalizedChi2_L3fromL1_(iConfig.getParameter<double>("MaxNormalizedChi2_L3FromL1")),
66  trkMuonId_ ( muon::SelectionType(iConfig.getParameter<unsigned int>("trkMuonId"))),
67  L1MatchingdR_ (iConfig.getParameter<double> ("L1MatchingdR")),
68  matchPreviousCand_( iConfig.getParameter<bool>("MatchToPreviousCand") ),
69 
70  devDebug_ (false),
71  theL3LinksLabel (iConfig.getParameter<InputTag>("InputLinks")),
72  linkToken_ (consumes<reco::MuonTrackLinksCollection>(theL3LinksLabel))
73 {
74  LogDebug("HLTMuonL3PreFilter")
75  << " CandTag/MinN/MaxEta/MinNhits/MaxDr/MinDr/MaxDz/MinDxySig/MinPt/NSigmaPt : "
76  << candTag_.encode()
77  << " " << min_N_
78  << " " << max_Eta_
79  << " " << min_Nhits_
80  << " " << max_Dr_
81  << " " << min_Dr_
82  << " " << max_Dz_
83  << " " << min_DxySig_
84  << " " << min_Pt_
85  << " " << nsigma_Pt_;
86 }
87 
89 
90 void
94  desc.add<edm::InputTag>("BeamSpotTag",edm::InputTag("hltOfflineBeamSpot"));
95  desc.add<edm::InputTag>("CandTag",edm::InputTag("hltL3MuonCandidates"));
96  // desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag("hltDiMuonL2PreFiltered0"));
97  desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag(""));
98  desc.add<edm::InputTag>("L1CandTag",edm::InputTag(""));
99  desc.add<edm::InputTag>("inputMuonCollection",edm::InputTag(""));
100  desc.add<int>("MinN",1);
101  desc.add<double>("MaxEta",2.5);
102  desc.add<int>("MinNhits",0);
103  desc.add<double>("MaxDr",2.0);
104  desc.add<double>("MinDr",-1.0);
105  desc.add<double>("MaxDz",9999.0);
106  desc.add<double>("MinDxySig",-1.0);
107  desc.add<double>("MinPt",3.0);
108  desc.add<double>("NSigmaPt",0.0);
109  desc.add<double>("MaxNormalizedChi2",9999.0);
110  desc.add<double>("MaxDXYBeamSpot",9999.0);
111  desc.add<double>("MinDXYBeamSpot",-1.0);
112  desc.add<int>("MinNmuonHits",0);
113  desc.add<double>("MaxPtDifference",9999.0);
114  desc.add<double>("MinTrackPt",0.0);
115  desc.add<int>("minMuonStations",-1);
116  desc.add<int>("minTrkHits",-1);
117  desc.add<int>("minMuonHits",-1);
118  desc.add<unsigned int>("allowedTypeMask",255);
119  desc.add<unsigned int>("requiredTypeMask",0);
120  desc.add<double>("MaxNormalizedChi2_L3FromL1",9999.);
121  desc.add<unsigned int>("trkMuonId",0);
122  desc.add<double>("L1MatchingdR",0.3);
123  desc.add<bool>("MatchToPreviousCand", true);
124  desc.add<edm::InputTag>("InputLinks",edm::InputTag(""));
125  descriptions.add("hltMuonL3PreFilter",desc);
126 }
127 
128 //
129 // member functions
130 //
131 
132 // ------------ method called to produce the data ------------
134 
135  // All HLT filters must create and fill an HLT filter object,
136  // recording any reconstructed physics objects satisfying (or not)
137  // this HLT filter, and place it in the Event.
138 
139  if (saveTags()) filterproduct.addCollectionTag(candTag_);
140 
141  // Read RecoChargedCandidates from L3MuonCandidateProducer:
143  iEvent.getByToken(candToken_,mucands);
144 
145  // Read L2 triggered objects:
146  Handle<TriggerFilterObjectWithRefs> previousLevelCands;
147  iEvent.getByToken(previousCandToken_,previousLevelCands);
148  vector<RecoChargedCandidateRef> vl2cands;
149  previousLevelCands->getObjects(TriggerMuon,vl2cands);
150 
151  // Read BeamSpot information:
152  Handle<BeamSpot> recoBeamSpotHandle;
153  iEvent.getByToken(beamspotToken_,recoBeamSpotHandle);
154  const BeamSpot& beamSpot = *recoBeamSpotHandle;
155 
156  // Number of objects passing the L3 Trigger:
157  int n = 0;
158 
159  // sort them by L2Track
160  std::map<reco::TrackRef, std::vector<RecoChargedCandidateRef> > L2toL3s;
161  // map the L3 cands matched to a L1 to their position in the recoMuon collection
162  std::map<unsigned int, RecoChargedCandidateRef > MuonToL3s;
163 
164  // Test to see if we can use L3MuonTrajectorySeeds:
165  if (mucands->empty()) return false;
166  auto const &tk = (*mucands)[0].track();
167  bool useL3MTS=false;
168 
169  if (tk->seedRef().isNonnull()){
170  auto a = dynamic_cast<const L3MuonTrajectorySeed*>(tk->seedRef().get());
171  useL3MTS = a != nullptr;
172  }
173 
174  // If we can use L3MuonTrajectory seeds run the older code:
175  if (useL3MTS){
176  LogDebug("HLTMuonL3PreFilter") << "HLTMuonL3PreFilter::hltFilter is in mode: useL3MTS";
177 
178  unsigned int maxI = mucands->size();
179  for (unsigned int i=0;i!=maxI;++i){
180  const TrackRef &tk = (*mucands)[i].track();
182  TrackRef staTrack = l3seedRef->l2Track();
183  LogDebug("HLTMuonL3PreFilter") <<"L2 from: "<<iEvent.getProvenance(staTrack.id()).moduleLabel() <<" index: "<<staTrack.key();
184  L2toL3s[staTrack].push_back(RecoChargedCandidateRef(mucands,i));
185  }
186  } //end of useL3MTS
187 
188  // Using normal TrajectorySeeds:
189  else{
190  LogDebug("HLTMuonL3PreFilter") << "HLTMuonL3PreFilter::hltFilter is in mode: not useL3MTS";
191 
192  // Read Links collection:
194  iEvent.getByToken(linkToken_, links);
195 
197  std::vector<l1t::MuonRef> vl1cands;
198 
199  bool check_l1match = true;
200 
201  // Loop over RecoChargedCandidates:
202  for(unsigned int i(0); i < mucands->size(); ++i){
203  RecoChargedCandidateRef cand(mucands,i);
204  TrackRef tk = cand->track();
205 
206  if (!matchPreviousCand_){
207  MuonToL3s[i] = RecoChargedCandidateRef(cand);
208  }
209  else{
210 
211  check_l1match = true;
212  int nlink = 0;
213  for(auto const & link : *links){
214  nlink++;
215 
216  // Using the same method that was used to create the links between L3 and L2
217  // ToDo: there should be a better way than dR,dPt matching
218  const reco::Track& trackerTrack = *link.trackerTrack();
219 
220  float dR2 = deltaR2(tk->eta(),tk->phi(),trackerTrack.eta(),trackerTrack.phi());
221  float dPt = std::abs(tk->pt() - trackerTrack.pt());
222  if (tk->pt() != 0) dPt = dPt/tk->pt();
223 
224  if (dR2 < 0.02*0.02 and dPt < 0.001) {
225  const TrackRef staTrack = link.standAloneTrack();
226  L2toL3s[staTrack].push_back(RecoChargedCandidateRef(cand));
227  check_l1match = false;
228  }
229  } //MTL loop
230 
231 
232  if ( !l1CandTag_.label().empty() && check_l1match ){
233  iEvent.getByToken(l1CandToken_,level1Cands);
234  level1Cands->getObjects(trigger::TriggerL1Mu,vl1cands);
235  const unsigned int nL1Muons(vl1cands.size());
236  for (unsigned int il1=0; il1!=nL1Muons; ++il1) {
237  if (deltaR(cand->eta(), cand->phi(), vl1cands[il1]->eta(), vl1cands[il1]->phi()) < L1MatchingdR_) {
238  MuonToL3s[i] = RecoChargedCandidateRef(cand);
239  }
240  }
241  }
242  }
243  } //RCC loop
244  } //end of using normal TrajectorySeeds
245 
246  // look at all mucands, check cuts and add to filter object
247  LogDebug("HLTMuonL3PreFilter")<<"looking at: "<<L2toL3s.size()<<" L2->L3s from: "<<mucands->size();
248  for ( const auto& L2toL3s_it : L2toL3s ) {
249 
250  if (!triggeredByLevel2(L2toL3s_it.first,vl2cands)) continue;
251 
252  //loop over the L3Tk reconstructed for this L2.
253  unsigned int iTk=0;
254  unsigned int maxItk=L2toL3s_it.second.size();
255  for (; iTk!=maxItk; iTk++){
256 
257  const RecoChargedCandidateRef & cand=L2toL3s_it.second[iTk];
258  if (! applySelection(cand, beamSpot)) continue;
259 
260  filterproduct.addObject(TriggerMuon,cand);
261  n++;
262  break; // and go on with the next L2 association
263  }
264  }
265 
266  // now loop on L3 from L1
268  iEvent.getByToken(recoMuToken_,recomuons);
269 
270  for ( const auto& MuonToL3s_it : MuonToL3s ) {
271 
272  const reco::Muon& muon(recomuons->at(MuonToL3s_it.first));
273 
274  // applys specific cuts for TkMu
275  if ( (muon.type() & allowedTypeMask_L3fromL1_ ) == 0 ) continue;
276  if ( (muon.type() & requiredTypeMask_L3fromL1_) != requiredTypeMask_L3fromL1_ ) continue;
277  if ( muon.numberOfMatchedStations() < min_MuonStations_L3fromL1_ ) continue;
278  if ( !muon.globalTrack().isNull() ){
279  if (muon.globalTrack()->normalizedChi2() > maxNormalizedChi2_L3fromL1_) continue;
280  }
281  if ( muon.isTrackerMuon() && !muon::isGoodMuon(muon,trkMuonId_) ) continue;
282 
283  const RecoChargedCandidateRef & cand=MuonToL3s_it.second;
284  // apply common selection
285  if (! applySelection(cand, beamSpot)) continue;
286  filterproduct.addObject(TriggerMuon,cand);
287  n++;
288 
289  break; // and go on with the next L3 from L1
290 
291  }
292 
293  vector<RecoChargedCandidateRef> vref;
294  filterproduct.getObjects(TriggerMuon,vref);
295  for (auto & i : vref) {
297  TrackRef tk = candref->get<TrackRef>();
298  LogDebug("HLTMuonL3PreFilter")
299  << " Track passing filter: trackRef pt= " << tk->pt() << " (" << candref->pt() << ") " << ", eta: " << tk->eta() << " (" << candref->eta() << ") ";
300  }
301 
302  // filter decision
303  const bool accept (n >= min_N_);
304 
305  LogDebug("HLTMuonL3PreFilter") << " >>>>> Result of HLTMuonL3PreFilter is " << accept << ", number of muons passing thresholds= " << n;
306 
307  return accept;
308 
309 }
310 
311 bool
312 HLTMuonL3PreFilter::triggeredByLevel2(const TrackRef& staTrack,vector<RecoChargedCandidateRef>& vcands) const
313 {
314  bool ok=false;
315  for (auto & vcand : vcands) {
316  if ( vcand->get<TrackRef>() == staTrack ) {
317  ok=true;
318  LogDebug("HLTMuonL3PreFilter") << "The L2 track triggered";
319  break;
320  }
321  }
322  return ok;
323 }
324 
325 bool
327 {
328  // eta cut
329  if (std::abs(cand->eta())>max_Eta_) return false;
330 
331  TrackRef tk = cand->track();
332  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();
333 
334  // cut on number of hits
335  if (tk->numberOfValidHits()<min_Nhits_) return false;
336 
337  //max dr cut
338  auto dr = std::abs( (- (cand->vx()-beamSpot.x0()) * cand->py() + (cand->vy()-beamSpot.y0()) * cand->px() ) / cand->pt() );
339  if (dr >max_Dr_) return false;
340 
341  //min dr cut
342  if (dr <min_Dr_) return false;
343 
344  //dz cut
345  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;
346 
347  // dxy significance cut (safeguard against bizarre values)
348  if (min_DxySig_ > 0 && (tk->dxyError() <= 0 || std::abs(tk->dxy(beamSpot.position())/tk->dxyError()) < min_DxySig_)) return false;
349 
350  //normalizedChi2 cut
351  if (tk->normalizedChi2() > max_NormalizedChi2_ ) return false;
352 
353  //dxy beamspot cut
354  float absDxy = std::abs(tk->dxy(beamSpot.position()));
355  if (absDxy > max_DXYBeamSpot_ || absDxy < min_DXYBeamSpot_ ) return false;
356 
357  //min muon hits cut
358  const reco::HitPattern& trackHits = tk->hitPattern();
359  if (trackHits.numberOfValidMuonHits() < min_NmuonHits_ ) return false;
360 
361  //pt difference cut
362  double candPt = cand->pt();
363  double trackPt = tk->pt();
364 
365  if (std::abs(candPt - trackPt) > max_PtDifference_ ) return false;
366 
367  //track pt cut
368  if (trackPt < min_TrackPt_ ) return false;
369 
370  // Pt threshold cut
371  double pt = cand->pt();
372  double err0 = tk->error(0);
373  double abspar0 = std::abs(tk->parameter(0));
374  double ptLx = pt;
375  // convert 50% efficiency threshold to 90% efficiency threshold
376  if (abspar0>0) ptLx += nsigma_Pt_*err0/abspar0*pt;
377  LogTrace("HLTMuonL3PreFilter") << " ...Muon in loop, trackkRef pt= "
378  << tk->pt() << ", ptLx= " << ptLx
379  << " cand pT " << cand->pt();
380  if (ptLx<min_Pt_) return false;
381 
382  return true;
383 
384 }
385 
386 // declare this class as a framework plugin
#define LogDebug(id)
const edm::InputTag l1CandTag_
double z0() const
z coordinate
Definition: BeamSpot.h:68
const edm::InputTag candTag_
void getObjects(Vids &ids, VRphoton &refs) const
various physics-level getters:
const edm::EDGetTokenT< trigger::TriggerFilterObjectWithRefs > previousCandToken_
const double min_DXYBeamSpot_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
enum start value shifted to 81 so as to avoid clashes with PDG codes
const int min_MuonStations_L3fromL1_
edm::Ref< RecoChargedCandidateCollection > RecoChargedCandidateRef
reference to an object in a collection of RecoChargedCandidate objects
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:684
const edm::EDGetTokenT< reco::BeamSpot > beamspotToken_
key_type key() const
Accessor for product key.
Definition: Ref.h:263
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:30
std::string encode() const
Definition: InputTag.cc:159
bool applySelection(const reco::RecoChargedCandidateRef &, const reco::BeamSpot &) const
ProductID id() const
Accessor for product ID.
Definition: Ref.h:257
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
std::vector< MuonTrackLinks > MuonTrackLinksCollection
collection of MuonTrackLinks
Definition: MuonFwd.h:22
SelectionType
Selector type.
Definition: MuonSelectors.h:17
const edm::EDGetTokenT< reco::MuonTrackLinksCollection > linkToken_
void addObject(int id, const reco::RecoEcalCandidateRef &ref)
setters for L3 collections: (id=physics type, and Ref<C>)
HLTMuonL3PreFilter(const edm::ParameterSet &)
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:690
const unsigned int allowedTypeMask_L3fromL1_
const unsigned int requiredTypeMask_L3fromL1_
double pt() const
track transverse momentum
Definition: TrackBase.h:660
const double min_DxySig_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:243
ParameterDescriptionBase * add(U const &iLabel, T const &value)
const std::string * moduleLabel() const
Definition: HLTFilter.cc:66
#define LogTrace(id)
const double min_TrackPt_
const double L1MatchingdR_
bool isGoodMuon(const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
main GoodMuon wrapper call
const double max_PtDifference_
const edm::EDGetTokenT< reco::MuonCollection > recoMuToken_
std::vector< RecoChargedCandidate > RecoChargedCandidateCollection
collectin of RecoChargedCandidate objects
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
static void makeHLTFilterDescription(edm::ParameterSetDescription &desc)
Definition: HLTFilter.cc:29
const bool matchPreviousCand_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
bool triggeredByLevel2(const reco::TrackRef &track, std::vector< reco::RecoChargedCandidateRef > &vcands) const
void addCollectionTag(const edm::InputTag &collectionTag)
collectionTags
const edm::EDGetTokenT< trigger::TriggerFilterObjectWithRefs > l1CandToken_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const double max_DXYBeamSpot_
std::string const & label() const
Definition: InputTag.h:36
const edm::EDGetTokenT< reco::RecoChargedCandidateCollection > candToken_
fixed size matrix
bool saveTags() const
Definition: HLTFilter.h:45
HLT enums.
double a
Definition: hdecay.h:121
double y0() const
y coordinate
Definition: BeamSpot.h:66
const double max_NormalizedChi2_
const Point & position() const
position
Definition: BeamSpot.h:62
muon::SelectionType trkMuonId_
int numberOfValidMuonHits() const
Definition: HitPattern.h:906
Provenance getProvenance(BranchID const &theID) const
Definition: Event.cc:105
bool hltFilter(edm::Event &, const edm::EventSetup &, trigger::TriggerFilterObjectWithRefs &filterproduct) const override
~HLTMuonL3PreFilter() override
double x0() const
x coordinate
Definition: BeamSpot.h:64