CMS 3D CMS Logo

HLTMuonL1Filter.cc
Go to the documentation of this file.
1 
9 #include "HLTMuonL1Filter.h"
10 
14 
16 
19 
21 #include "TMath.h"
22 
26 
27 #include <vector>
28 
29 //
30 // constructors and destructor
31 //
33  candTag_( iConfig.getParameter<edm::InputTag>("CandTag") ),
34  candToken_( consumes<l1extra::L1MuonParticleCollection>(candTag_)),
35  previousCandTag_( iConfig.getParameter<edm::InputTag>("PreviousCandTag") ),
36  previousCandToken_( consumes<trigger::TriggerFilterObjectWithRefs>(previousCandTag_)),
37  maxEta_( iConfig.getParameter<double>("MaxEta") ),
38  minPt_( iConfig.getParameter<double>("MinPt") ),
39  minN_( iConfig.getParameter<int>("MinN") ),
40  excludeSingleSegmentCSC_( iConfig.getParameter<bool>("ExcludeSingleSegmentCSC") ),
41  csctfTag_( iConfig.getParameter<edm::InputTag>("CSCTFtag") ),
42  csctfToken_(excludeSingleSegmentCSC_ ? consumes<L1CSCTrackCollection>(csctfTag_) : edm::EDGetTokenT<L1CSCTrackCollection>{})
43 {
44  using namespace std;
45 
46  //set the quality bit mask
47  qualityBitMask_ = 0;
48  vector<int> selectQualities = iConfig.getParameter<vector<int> >("SelectQualities");
49  for(int selectQualitie : selectQualities){
50  if(selectQualitie > 7){
51  throw edm::Exception(edm::errors::Configuration) << "QualityBits must be smaller than 8!";
52  }
53  qualityBitMask_ |= 1<<selectQualitie;
54  }
55 
56  // dump parameters for debugging
57  if(edm::isDebugEnabled()){
58  ostringstream ss;
59  ss<<"Constructed with parameters:"<<endl;
60  ss<<" CandTag = "<<candTag_.encode()<<endl;
61  ss<<" PreviousCandTag = "<<previousCandTag_.encode()<<endl;
62  ss<<" MaxEta = "<<maxEta_<<endl;
63  ss<<" MinPt = "<<minPt_<<endl;
64  ss<<" SelectQualities =";
65  for(size_t i=0; i<8; i++){
66  if((qualityBitMask_>>i) % 2) ss<<" "<<i;
67  }
68  ss<<endl;
69  ss<<" MinN = "<<minN_<<endl;
70  ss<<" ExcludeSingleSegmentCSC = "<<excludeSingleSegmentCSC_<<endl;
71  ss<<" CSCTFtag = "<<csctfTag_.encode()<<endl;
72  ss<<" saveTags= "<<saveTags();
73  LogDebug("HLTMuonL1Filter")<<ss.str();
74  }
75 }
76 
78 
79 void
83  desc.add<edm::InputTag>("CandTag",edm::InputTag("hltL1extraParticles"));
84  // desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag("hltL1sL1DoubleMuOpen"));
85  desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag(""));
86  desc.add<double>("MaxEta",2.5);
87  desc.add<double>("MinPt",0.0);
88  desc.add<int>("MinN",1);
89  desc.add<bool>("ExcludeSingleSegmentCSC",false);
90  // desc.add<edm::InputTag>("CSCTFtag",edm::InputTag("unused"));
91  desc.add<edm::InputTag>("CSCTFtag",edm::InputTag("csctfDigis"));
92  {
93  std::vector<int> temp1;
94  temp1.reserve(0);
95  desc.add<std::vector<int> >("SelectQualities",temp1);
96  }
97  descriptions.add("hltMuonL1Filter",desc);
98 }
99 
100 //
101 // member functions
102 //
103 
104 // ------------ method called to produce the data ------------
106  using namespace std;
107  using namespace edm;
108  using namespace trigger;
109  using namespace l1extra;
110 
111  // All HLT filters must create and fill an HLT filter object,
112  // recording any reconstructed physics objects satisfying (or not)
113  // this HLT filter, and place it in the Event.
114 
115  // get hold of all muons
117  iEvent.getByToken(candToken_, allMuons);
118 
120  const L1CSCTrackCollection * csctfTracks = nullptr;
121  const L1MuTriggerScales * l1MuTriggerScales = nullptr;
122 
123  // get hold of CSCTF raw tracks
125  edm::Handle<L1CSCTrackCollection> csctfTracksHandle;
126  iEvent.getByToken(csctfToken_, csctfTracksHandle);
127  csctfTracks = csctfTracksHandle.product();
128 
129  // read scales for every event (fast, no need to cache this)
131  iSetup.get<L1MuTriggerScalesRcd>().get(scales);
132  l1MuTriggerScales = scales.product();
133  }
134 
135  // get hold of muons that fired the previous level
136  Handle<TriggerFilterObjectWithRefs> previousLevelCands;
137  iEvent.getByToken(previousCandToken_, previousLevelCands);
138  vector<L1MuonParticleRef> prevMuons;
139  previousLevelCands->getObjects(TriggerL1Mu, prevMuons);
140 
141  // look at all muon candidates, check cuts and add to filter object
142  int n = 0;
143  for(size_t i = 0; i < allMuons->size(); i++){
144  L1MuonParticleRef muon(allMuons, i);
145 
146  //check if triggered by the previous level
147  if(find(prevMuons.begin(), prevMuons.end(), muon) == prevMuons.end()) continue;
148 
149  //check maxEta cut
150  if(fabs(muon->eta()) > maxEta_) continue;
151 
152  //check pT cut
153  if(muon->pt() < minPt_) continue;
154 
155  //check quality cut
156  if(qualityBitMask_){
157  int quality = muon->gmtMuonCand().empty() ? 0 : (1 << muon->gmtMuonCand().quality());
158  if((quality & qualityBitMask_) == 0) continue;
159  }
160 
161  // reject single-segment CSC objects if necessary
162  if (excludeSingleSegmentCSC_ and isSingleSegmentCSC(muon, * csctfTracks, * l1MuTriggerScales)) continue;
163 
164  //we have a good candidate
165  n++;
166  filterproduct.addObject(TriggerL1Mu,muon);
167  }
168 
169  if (saveTags()) filterproduct.addCollectionTag(candTag_);
170 
171  // filter decision
172  const bool accept(n >= minN_);
173 
174  // dump event for debugging
175  if(edm::isDebugEnabled()){
176  ostringstream ss;
177  ss.precision(2);
178  ss<<"L1mu#"<<'\t'<<"q*pt"<<'\t'<<'\t'<<"eta"<<'\t'<<"phi"<<'\t'<<"quality"<<'\t'<<"isPrev"<<'\t'<<"isFired"<<'\t'<<"isSingleCSC"<<endl;
179  ss<<"--------------------------------------------------------------------------"<<endl;
180 
181  vector<L1MuonParticleRef> firedMuons;
182  filterproduct.getObjects(TriggerL1Mu, firedMuons);
183  for(size_t i=0; i<allMuons->size(); i++){
184  L1MuonParticleRef mu(allMuons, i);
185  int quality = mu->gmtMuonCand().empty() ? 0 : mu->gmtMuonCand().quality();
186  bool isPrev = find(prevMuons.begin(), prevMuons.end(), mu) != prevMuons.end();
187  bool isFired = find(firedMuons.begin(), firedMuons.end(), mu) != firedMuons.end();
188  bool isSingleCSC = excludeSingleSegmentCSC_ and isSingleSegmentCSC(mu, * csctfTracks, * l1MuTriggerScales);
189  ss<<i<<'\t'<<scientific<<mu->charge()*mu->pt()<<'\t'<<fixed<<mu->eta()<<'\t'<<mu->phi()<<'\t'<<quality<<'\t'<<isPrev<<'\t'<<isFired<<'\t'<<isSingleCSC<<endl;
190  }
191  ss<<"--------------------------------------------------------------------------"<<endl;
192  LogDebug("HLTMuonL1Filter")<<ss.str()<<"Decision of filter is "<<accept<<", number of muons passing = "<<filterproduct.l1muonSize();
193  }
194 
195  return accept;
196 }
197 
198 bool HLTMuonL1Filter::isSingleSegmentCSC(l1extra::L1MuonParticleRef const & muon, L1CSCTrackCollection const & csctfTracks, L1MuTriggerScales const & l1MuTriggerScales) const {
199  // is the muon matching a csctf track?
200  //bool matched = false; // unused
201  // which csctf track mode?
202  // -999: no matching
203  // 1: bad phi road. Not good extrapolation, but still triggering
204  // 11: singles
205  // 15: halo
206  // 2->10 and 12->14: coincidence trigger with good extrapolation
207  int csctfMode = -999;
208 
209  // loop over the CSCTF tracks
210  for(auto trk = csctfTracks.begin(); trk < csctfTracks.end(); trk++){
211 
212  int trEndcap = (trk->first.endcap()==2 ? trk->first.endcap()-3 : trk->first.endcap());
213  int trSector = 6*(trk->first.endcap()-1)+trk->first.sector();
214 
215  //... in radians
216  // Type 2 is CSC
217  float trEtaScale = l1MuTriggerScales.getRegionalEtaScale(2)->getCenter(trk->first.eta_packed());
218  float trPhiScale = l1MuTriggerScales.getPhiScale()->getLowEdge(trk->first.localPhi());
219 
220  double trEta = trEtaScale * trEndcap;
221  // there is no L1ExtraParticle below -2.375
222  if(trEta<-2.4) trEta=-2.375;
223 
224  // CSCTF has 6 sectors
225  // sector 1 starts at 15 degrees
226  // trPhiScale is defined inside a sector
227  float trPhi02PI = fmod(trPhiScale +
228  ((trSector-1)*TMath::Pi()/3) +
229  (TMath::Pi()/12) , 2*TMath::Pi());
230 
231  // L1 information are given from [-Pi,Pi]
232  double trPhi = ( trPhi02PI<TMath::Pi()? trPhi02PI : trPhi02PI - 2*TMath::Pi() );
233  /*
234  std::cout << "\ntrEndcap=" << trEndcap << std::endl;
235  std::cout << "trSector=" << trSector << std::endl;
236  std::cout << "trk->first.eta_packed()=" << trk->first.eta_packed() << std::endl;
237  std::cout << "trk->first.localPhi()=" << trk->first.localPhi() << std::endl;
238  std::cout << "trEtaScale=" << trEtaScale << std::endl;
239  std::cout << "trPhiScale=" << trPhiScale << std::endl;
240  std::cout << "trEta=" << trEta << std::endl;
241  std::cout << "trPhi=" << trPhi << std::endl;
242  */
243  if ( fabs (trEta-muon->eta()) < 0.03 &&
244  fabs (trPhi-muon->phi()) < 0.001 ) {
245 
246  //matched = true;
247  ptadd thePtAddress(trk->first.ptLUTAddress());
248  csctfMode = thePtAddress.track_mode;
249  //std::cout << "is matched -> trMode=" << csctfMode << std::endl;
250  }
251  }
252 
253  /*
254  std::cout << " ===================================== " << std::endl;
255  std::cout << " is matched? " << matched << std::endl;
256  std::cout << " is singles? " << (csctfMode==11 ? 1 :0) << std::endl;
257  std::cout << " ===================================== " << std::endl;
258  */
259 
260  // singles are mode 11 "CSCTF tracks"
261  return csctfMode==11;
262 }
263 
264 // declare this class as a framework plugin
#define LogDebug(id)
const double Pi
bool isDebugEnabled()
double minPt_
pT threshold
void getObjects(Vids &ids, VRphoton &refs) const
various physics-level getters:
int minN_
required number of passing candidates to pass the filter
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
bool hltFilter(edm::Event &, const edm::EventSetup &, trigger::TriggerFilterObjectWithRefs &filterproduct) const override
edm::InputTag previousCandTag_
input tag identifying the product containing refs to muons passing the previous level ...
virtual float getCenter(unsigned packed) const =0
get the center of bin represented by packed
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:30
std::vector< L1CSCTrack > L1CSCTrackCollection
std::string encode() const
Definition: InputTag.cc:159
HLTMuonL1Filter(const edm::ParameterSet &)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void addObject(int id, const reco::RecoEcalCandidateRef &ref)
setters for L3 collections: (id=physics type, and Ref<C>)
double maxEta_
max Eta cut
edm::EDGetTokenT< L1CSCTrackCollection > csctfToken_
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool excludeSingleSegmentCSC_
should we exclude single-segment CSC trigger objects from our counting?
const L1MuScale * getPhiScale() const
get the phi scale
edm::InputTag candTag_
input tag identifying the product containing muons
const int mu
Definition: Constants.h:22
ParameterDescriptionBase * add(U const &iLabel, T const &value)
edm::EDGetTokenT< l1extra::L1MuonParticleCollection > candToken_
static void makeHLTFilterDescription(edm::ParameterSetDescription &desc)
Definition: HLTFilter.cc:29
T const * product() const
Definition: Handle.h:74
class pt_address ptadd
void addCollectionTag(const edm::InputTag &collectionTag)
collectionTags
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const L1MuScale * getRegionalEtaScale(int isys) const
get the regioanl muon trigger eta scale, isys = 0(DT), 1(bRPC), 2(CSC), 3(fwdRPC) ...
bool saveTags() const
Definition: HLTFilter.h:45
HLT enums.
bool isSingleSegmentCSC(const l1extra::L1MuonParticleRef &muon, L1CSCTrackCollection const &csctfTracks, L1MuTriggerScales const &scales) const
checks if the passed L1MuExtraParticle is a single segment CSC
T get() const
Definition: EventSetup.h:71
virtual float getLowEdge(unsigned packed) const =0
get the low edge of bin represented by packed
~HLTMuonL1Filter() override
T const * product() const
Definition: ESHandle.h:86
edm::InputTag csctfTag_
input tag identifying the product containing CSCTF tracks
edm::EDGetTokenT< trigger::TriggerFilterObjectWithRefs > previousCandToken_