CMS 3D CMS Logo

HLTMuonDimuonL2FromL1TFilter.cc
Go to the documentation of this file.
1 
11 
14 
16 
23 // #include "DataFormats/L1Trigger/interface/L1MuonParticleFwd.h"
24 // #include "DataFormats/L1Trigger/interface/L1MuonParticle.h"
25 
28 
30 
31 using namespace edm;
32 using namespace std;
33 using namespace reco;
34 using namespace trigger;
35 // using namespace l1extra;
36 //
37 // constructors and destructor
38 //
40  beamspotTag_ (iConfig.getParameter< edm::InputTag > ("BeamSpotTag")),
41  beamspotToken_ (consumes<reco::BeamSpot>(beamspotTag_)),
42  candTag_ (iConfig.getParameter< edm::InputTag > ("CandTag")),
43  candToken_ (consumes<reco::RecoChargedCandidateCollection>(candTag_)),
44  previousCandTag_ (iConfig.getParameter<InputTag > ("PreviousCandTag")),
45  previousCandToken_ (consumes<trigger::TriggerFilterObjectWithRefs>(previousCandTag_)),
46  seedMapTag_( iConfig.getParameter<InputTag >("SeedMapTag") ),
47  seedMapToken_(consumes<SeedMap>(seedMapTag_)),
48  fast_Accept_ (iConfig.getParameter<bool> ("FastAccept")),
49  max_Eta_ (iConfig.getParameter<double> ("MaxEta")),
50  min_Nhits_ (iConfig.getParameter<int> ("MinNhits")),
51  min_Nstations_(iConfig.getParameter<int> ("MinNstations")),
52  min_Nchambers_(iConfig.getParameter<int> ("MinNchambers")),
53  max_Dr_ (iConfig.getParameter<double> ("MaxDr")),
54  max_Dz_ (iConfig.getParameter<double> ("MaxDz")),
55  chargeOpt_ (iConfig.getParameter<int> ("ChargeOpt")),
56  min_PtPair_ (iConfig.getParameter<double> ("MinPtPair")),
57  min_PtMax_ (iConfig.getParameter<double> ("MinPtMax")),
58  min_PtMin_ (iConfig.getParameter<double> ("MinPtMin")),
59  min_InvMass_ (iConfig.getParameter<double> ("MinInvMass")),
60  max_InvMass_ (iConfig.getParameter<double> ("MaxInvMass")),
61  min_Acop_ (iConfig.getParameter<double> ("MinAcop")),
62  max_Acop_ (iConfig.getParameter<double> ("MaxAcop")),
63  min_Angle_ (iConfig.getParameter<double> ("MinAngle")),
64  max_Angle_ (iConfig.getParameter<double> ("MaxAngle")),
65  min_PtBalance_ (iConfig.getParameter<double> ("MinPtBalance")),
66  max_PtBalance_ (iConfig.getParameter<double> ("MaxPtBalance")),
67  nsigma_Pt_ (iConfig.getParameter<double> ("NSigmaPt"))
68 {
69 
70  LogDebug("HLTMuonDimuonL2FromL1TFilter")
71  << " CandTag/MinN/MaxEta/MinNhits/MinNstations/MinNchambers/MaxDr/MaxDz/MinPt1/MinPt2/MinInvMass/MaxInvMass/MinAcop/MaxAcop/MinAngle/MaxAngle/MinPtBalance/MaxPtBalance/NSigmaPt : "
72  << candTag_.encode()
73  << " " << fast_Accept_
74  << " " << max_Eta_
75  << " " << min_Nhits_
76  << " " << min_Nstations_
77  << " " << min_Nchambers_
78  << " " << max_Dr_
79  << " " << max_Dz_
80  << " " << chargeOpt_ << " " << min_PtPair_
81  << " " << min_PtMax_ << " " << min_PtMin_
82  << " " << min_InvMass_ << " " << max_InvMass_
83  << " " << min_Acop_ << " " << max_Acop_
84  << " " << min_Angle_ << " " << max_Angle_
85  << " " << min_PtBalance_ << " " << max_PtBalance_
86  << " " << nsigma_Pt_;
87 }
88 
90 
91 
92 //
93 // member functions
94 //
95 
96 void
100  desc.add<edm::InputTag>("BeamSpotTag",edm::InputTag("hltOfflineBeamSpot"));
101  desc.add<edm::InputTag>("CandTag",edm::InputTag("hltL2MuonCandidates"));
102  desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag(""));
103  desc.add<edm::InputTag>("SeedMapTag",edm::InputTag("hltL2Muons"));
104  desc.add<bool>("FastAccept",false);
105  desc.add<double>("MaxEta",2.5);
106  desc.add<int>("MinNhits",0);
107  desc.add<int>("MinNstations",0);
108  desc.add<int>("MinNchambers",2);
109  desc.add<double>("MaxDr",100.0);
110  desc.add<double>("MaxDz",9999.0);
111  desc.add<int>("ChargeOpt",0);
112  desc.add<double>("MinPtPair",0.0);
113  desc.add<double>("MinPtMax",3.0);
114  desc.add<double>("MinPtMin",3.0);
115  desc.add<double>("MinInvMass",1.6);
116  desc.add<double>("MaxInvMass",5.6);
117  desc.add<double>("MinAcop",-1.0);
118  desc.add<double>("MaxAcop",3.15);
119  desc.add<double>("MinAngle",-999.0);
120  desc.add<double>("MaxAngle",2.5);
121  desc.add<double>("MinPtBalance",-1.0);
122  desc.add<double>("MaxPtBalance",999999.0);
123  desc.add<double>("NSigmaPt",0.0);
124  descriptions.add("hltMuonDimuonL2FromL1TFilter", desc);
125 }
126 
127 // ------------ method called to produce the data ------------
128 bool
130 {
131 
132  double const MuMass = 0.106;
133  double const MuMass2 = MuMass*MuMass;
134  // All HLT filters must create and fill an HLT filter object,
135  // recording any reconstructed physics objects satisfying (or not)
136  // this HLT filter, and place it in the Event.
137 
138  // Ref to Candidate object to be recorded in filter object
141 
142  // get hold of trks
144  iEvent.getByToken(candToken_,mucands);
145  if (saveTags()) filterproduct.addCollectionTag(candTag_);
146 
148  Handle<BeamSpot> recoBeamSpotHandle;
149  iEvent.getByToken(beamspotToken_,recoBeamSpotHandle);
150  beamSpot = *recoBeamSpotHandle;
151 
152  // get the L2 to L1 map object for this event
154 
155  // look at all mucands, check cuts and add to filter object
156  int n = 0;
157  double e1,e2;
159 
160  RecoChargedCandidateCollection::const_iterator cand1;
161  RecoChargedCandidateCollection::const_iterator cand2;
162  for (cand1=mucands->begin(); cand1!=mucands->end(); cand1++) {
163  TrackRef tk1 = cand1->get<TrackRef>();
164  // eta cut
165  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " 1st muon in loop: q*pt= "
166  << tk1->charge()*tk1->pt() << ", eta= " << tk1->eta() << ", hits= " << tk1->numberOfValidHits();
167  // find the L1 Particle corresponding to the L2 Track
168  if (!mapL2ToL1.isTriggeredByL1(tk1)) continue;
169 
170  if (fabs(tk1->eta())>max_Eta_) continue;
171 
172  // cut on number of hits
173  if (tk1->numberOfValidHits()<min_Nhits_) continue;
174 
175  // number of stations
176  if (tk1->hitPattern().muonStationsWithAnyHits() < min_Nstations_) continue;
177 
178  // number of chambers
179  if(tk1->hitPattern().dtStationsWithAnyHits() +
180  tk1->hitPattern().cscStationsWithAnyHits() < min_Nchambers_) continue;
181 
182  //dr cut
183  //if (fabs(tk1->d0())>max_Dr_) continue;
184  if (fabs(tk1->dxy(beamSpot.position()))>max_Dr_) continue;
185 
186  //dz cut
187  if (fabs(tk1->dz())>max_Dz_) continue;
188 
189  // Pt threshold cut
190  double pt1 = tk1->pt();
191  double err1 = tk1->error(0);
192  double abspar1 = fabs(tk1->parameter(0));
193  double ptLx1 = pt1;
194  // convert 50% efficiency threshold to 90% efficiency threshold
195  if (abspar1>0) ptLx1 += nsigma_Pt_*err1/abspar1*pt1;
196  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1st muon in loop, pt1= "
197  << pt1 << ", ptLx1= " << ptLx1;
198 
199  cand2 = cand1; cand2++;
200  for (; cand2!=mucands->end(); cand2++) {
201  TrackRef tk2 = cand2->get<TrackRef>();
202 
203  // eta cut
204  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " 2nd muon in loop: q*pt= " << tk2->charge()*tk2->pt() << ", eta= " << tk2->eta() << ", hits= " << tk2->numberOfValidHits() << ", d0= " << tk2->d0();
205  if (!mapL2ToL1.isTriggeredByL1(tk2)) continue;
206 
207  if (fabs(tk2->eta())>max_Eta_) continue;
208 
209  // cut on number of hits
210  if (tk2->numberOfValidHits()<min_Nhits_) continue;
211 
212  // number of stations
213  if (tk2->hitPattern().muonStationsWithAnyHits() < min_Nstations_) continue;
214 
215  // number of chambers
216  if(tk2->hitPattern().dtStationsWithAnyHits() +
217  tk2->hitPattern().cscStationsWithAnyHits() < min_Nchambers_) continue;
218 
219  //dr cut
220  //if (fabs(tk2->d0())>max_Dr_) continue;
221  if (fabs(tk2->dxy(beamSpot.position()))>max_Dr_) continue;
222 
223  //dz cut
224  if (fabs(tk2->dz())>max_Dz_) continue;
225 
226  // Pt threshold cut
227  double pt2 = tk2->pt();
228  double err2 = tk2->error(0);
229  double abspar2 = fabs(tk2->parameter(0));
230  double ptLx2 = pt2;
231  // convert 50% efficiency threshold to 90% efficiency threshold
232  if (abspar2>0) ptLx2 += nsigma_Pt_*err2/abspar2*pt2;
233  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 2nd muon in loop, pt2= "
234  << pt2 << ", ptLx2= " << ptLx2;
235 
236  if (ptLx1>ptLx2) {
237  if (ptLx1<min_PtMax_) continue;
238  if (ptLx2<min_PtMin_) continue;
239  } else {
240  if (ptLx2<min_PtMax_) continue;
241  if (ptLx1<min_PtMin_) continue;
242  }
243 
244  if (chargeOpt_<0) {
245  if (tk1->charge()*tk2->charge()>0) continue;
246  } else if (chargeOpt_>0) {
247  if (tk1->charge()*tk2->charge()<0) continue;
248  }
249 
250  // Acoplanarity
251  double acop = fabs(tk1->phi()-tk2->phi());
252  if (acop>M_PI) acop = 2*M_PI - acop;
253  acop = M_PI - acop;
254  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 acop= " << acop;
255  if (acop<min_Acop_) continue;
256  if (acop>max_Acop_) continue;
257 
258  // 3D angle
259  double angle = acos((tk1->px()*tk2->px() + tk1->py()*tk2->py() + tk1->pz()*tk2->pz())/(tk1->p()*tk2->p()));
260  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 angle= " << angle;
261  if (angle < min_Angle_) continue;
262  if (angle > max_Angle_) continue;
263 
264  // Pt balance
265  double ptbalance = fabs(tk1->pt()-tk2->pt());
266  if (ptbalance<min_PtBalance_) continue;
267  if (ptbalance>max_PtBalance_) continue;
268 
269  // Combined dimuon system
270  e1 = sqrt(tk1->momentum().Mag2()+MuMass2);
271  e2 = sqrt(tk2->momentum().Mag2()+MuMass2);
272  p1 = Particle::LorentzVector(tk1->px(),tk1->py(),tk1->pz(),e1);
273  p2 = Particle::LorentzVector(tk2->px(),tk2->py(),tk2->pz(),e2);
274  p = p1+p2;
275 
276  double pt12 = p.pt();
277  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 pt12= " << pt12;
278  if (pt12<min_PtPair_) continue;
279 
280  double invmass = abs(p.mass());
281  // if (invmass>0) invmass = sqrt(invmass); else invmass = 0;
282  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " ... 1-2 invmass= " << invmass;
283  if (invmass<min_InvMass_) continue;
284  if (invmass>max_InvMass_) continue;
285 
286  // Add this pair
287  n++;
288  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " Track1 passing filter: pt= " << tk1->pt() << ", eta: " << tk1->eta();
289  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " Track2 passing filter: pt= " << tk2->pt() << ", eta: " << tk2->eta();
290  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " Invmass= " << invmass;
291 
292  bool i1done = false;
293  bool i2done = false;
294  vector<RecoChargedCandidateRef> vref;
295  filterproduct.getObjects(TriggerMuon,vref);
296  for (auto & i : vref) {
298  TrackRef tktmp = candref->get<TrackRef>();
299  if (tktmp==tk1) {
300  i1done = true;
301  } else if (tktmp==tk2) {
302  i2done = true;
303  }
304  if (i1done && i2done) break;
305  }
306 
307  if (!i1done) {
308  ref1=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (mucands,distance(mucands->begin(), cand1)));
309  filterproduct.addObject(TriggerMuon,ref1);
310  }
311  if (!i2done) {
312  ref2=RecoChargedCandidateRef( Ref<RecoChargedCandidateCollection> (mucands,distance(mucands->begin(),cand2 )));
313  filterproduct.addObject(TriggerMuon,ref2);
314  }
315 
316  if (fast_Accept_) break;
317  }
318 
319  }
320 
321  // filter decision
322  const bool accept (n >= 1);
323 
324  LogDebug("HLTMuonDimuonL2FromL1TFilter") << " >>>>> Result of HLTMuonDimuonL2FromL1TFilter is "<< accept << ", number of muon pairs passing thresholds= " << n;
325 
326  return accept;
327 }
328 
329 
330 // declare this class as a framework plugin
#define LogDebug(id)
void getObjects(Vids &ids, VRphoton &refs) const
various physics-level getters:
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
bool isTriggeredByL1(reco::TrackRef &l2muon)
checks if a L2 muon was seeded by a fired L1
edm::Ref< RecoChargedCandidateCollection > RecoChargedCandidateRef
reference to an object in a collection of RecoChargedCandidate objects
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
bool accept(const edm::Event &event, const edm::TriggerResults &triggerTable, const std::string &triggerPath)
Definition: TopDQMHelpers.h:30
edm::EDGetTokenT< reco::RecoChargedCandidateCollection > candToken_
std::string encode() const
Definition: InputTag.cc:159
void addObject(int id, const reco::RecoEcalCandidateRef &ref)
setters for L3 collections: (id=physics type, and Ref<C>)
bool hltFilter(edm::Event &, const edm::EventSetup &, trigger::TriggerFilterObjectWithRefs &filterproduct) const override
~HLTMuonDimuonL2FromL1TFilter() override
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
T sqrt(T t)
Definition: SSEVec.h:18
edm::EDGetTokenT< trigger::TriggerFilterObjectWithRefs > previousCandToken_
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)
double p2[4]
Definition: TauolaWrapper.h:90
HLTMuonDimuonL2FromL1TFilter(const edm::ParameterSet &)
#define M_PI
std::vector< RecoChargedCandidate > RecoChargedCandidateCollection
collectin of RecoChargedCandidate objects
static void makeHLTFilterDescription(edm::ParameterSetDescription &desc)
Definition: HLTFilter.cc:29
void addCollectionTag(const edm::InputTag &collectionTag)
collectionTags
void add(std::string const &label, ParameterSetDescription const &psetDescription)
fixed size matrix
bool saveTags() const
Definition: HLTFilter.h:45
HLT enums.
double p1[4]
Definition: TauolaWrapper.h:89
const Point & position() const
position
Definition: BeamSpot.h:62
edm::EDGetTokenT< SeedMap > seedMapToken_
edm::EDGetTokenT< reco::BeamSpot > beamspotToken_
math::PtEtaPhiELorentzVectorF LorentzVector
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11