CMS 3D CMS Logo

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