CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HLTMuonTrimuonL3Filter.cc
Go to the documentation of this file.
1 
11 
14 
16 
25 
33 
35 
36 using namespace edm;
37 using namespace std;
38 using namespace reco;
39 using namespace trigger;
40 
41 //
42 // constructors and destructor
43 //
45  beamspotTag_ (iConfig.getParameter< edm::InputTag > ("BeamSpotTag")),
46  candTag_ (iConfig.getParameter< edm::InputTag > ("CandTag")),
47  previousCandTag_ (iConfig.getParameter<InputTag > ("PreviousCandTag")),
48  fast_Accept_ (iConfig.getParameter<bool> ("FastAccept")),
49  max_Eta_ (iConfig.getParameter<double> ("MaxEta")),
50  min_Nhits_ (iConfig.getParameter<int> ("MinNhits")),
51  max_Dr_ (iConfig.getParameter<double> ("MaxDr")),
52  max_Dz_ (iConfig.getParameter<double> ("MaxDz")),
53  chargeOpt_ (iConfig.getParameter<int> ("ChargeOpt")),
54  min_PtTriplet_ (iConfig.getParameter<double> ("MinPtTriplet")),
55  min_PtMax_ (iConfig.getParameter<double> ("MinPtMax")),
56  min_PtMin_ (iConfig.getParameter<double> ("MinPtMin")),
57  min_InvMass_ (iConfig.getParameter<double> ("MinInvMass")),
58  max_InvMass_ (iConfig.getParameter<double> ("MaxInvMass")),
59  min_Acop_ (iConfig.getParameter<double> ("MinAcop")),
60  max_Acop_ (iConfig.getParameter<double> ("MaxAcop")),
61  min_PtBalance_ (iConfig.getParameter<double> ("MinPtBalance")),
62  max_PtBalance_ (iConfig.getParameter<double> ("MaxPtBalance")),
63  nsigma_Pt_ (iConfig.getParameter<double> ("NSigmaPt")),
64  max_DCAMuMu_ (iConfig.getParameter<double>("MaxDCAMuMu")),
65  max_YTriplet_ (iConfig.getParameter<double>("MaxRapidityTriplet"))
66 {
67 
68  LogDebug("HLTMuonTrimuonL3Filter")
69  << " CandTag/MinN/MaxEta/MinNhits/MaxDr/MaxDz/MinPt1/MinPt2/MinInvMass/MaxInvMass/MinAcop/MaxAcop/MinPtBalance/MaxPtBalance/NSigmaPt/MaxDzMuMu/MaxRapidityTriplet : "
70  << candTag_.encode()
71  << " " << fast_Accept_
72  << " " << max_Eta_
73  << " " << min_Nhits_
74  << " " << max_Dr_
75  << " " << max_Dz_
76  << " " << chargeOpt_ << " " << min_PtTriplet_
77  << " " << min_PtMax_ << " " << min_PtMin_
78  << " " << min_InvMass_ << " " << max_InvMass_
79  << " " << min_Acop_ << " " << max_Acop_
80  << " " << min_PtBalance_ << " " << max_PtBalance_
81  << " " << nsigma_Pt_
82  << " " << max_DCAMuMu_
83  << " " << max_YTriplet_;
84 }
85 
87 {
88 }
89 
90 void
93  desc.add<edm::InputTag>("BeamSpotTag",edm::InputTag("hltOfflineBeamSpot"));
94  desc.add<edm::InputTag>("CandTag",edm::InputTag("hltL3MuonCandidates"));
95  desc.add<edm::InputTag>("PreviousCandTag",edm::InputTag(""));
96  desc.add<bool>("FastAccept",false);
97  desc.add<double>("MaxEta",2.5);
98  desc.add<int>("MinNhits",0);
99  desc.add<double>("MaxDr",2.0);
100  desc.add<double>("MaxDz",9999.0);
101  desc.add<int>("ChargeOpt",0);
102  desc.add<double>("MinPtTriplet",0.0);
103  desc.add<double>("MinPtMax",3.0);
104  desc.add<double>("MinPtMin",3.0);
105  desc.add<double>("MinInvMass",2.8);
106  desc.add<double>("MaxInvMass",3.4);
107  desc.add<double>("MinAcop",-1.0);
108  desc.add<double>("MaxAcop",3.15);
109  desc.add<double>("MinPtBalance",-1.0);
110  desc.add<double>("MaxPtBalance",999999.0);
111  desc.add<double>("NSigmaPt",0.0);
112  desc.add<bool>("saveTags",false);
113  desc.add<double>("MaxDCAMuMu",99999.9);
114  desc.add<double>("MaxRapidityTriplet",999999.0);
115  descriptions.add("hltMuonTrimuonL3Filter",desc);
116 }
117 
118 //
119 // member functions
120 //
121 
122 // ------------ method called to produce the data ------------
123 bool
125 {
126 
127  double const MuMass = 0.106;
128  double const MuMass2 = MuMass*MuMass;
129  // All HLT filters must create and fill an HLT filter object,
130  // recording any reconstructed physics objects satisfying (or not)
131  // this HLT filter, and place it in the Event.
132 
133  // get hold of trks
135  if (saveTags()) filterproduct.addCollectionTag(candTag_);
136  iEvent.getByLabel (candTag_,mucands);
137  // sort them by L2Track
138  std::map<reco::TrackRef, std::vector<RecoChargedCandidateRef> > L2toL3s;
139  unsigned int maxI = mucands->size();
140  for (unsigned int i=0;i!=maxI;i++){
141  TrackRef tk = (*mucands)[i].track();
143  TrackRef staTrack = l3seedRef->l2Track();
144  L2toL3s[staTrack].push_back(RecoChargedCandidateRef(mucands,i));
145  }
146 
147  Handle<TriggerFilterObjectWithRefs> previousLevelCands;
148  iEvent.getByLabel (previousCandTag_,previousLevelCands);
150  Handle<BeamSpot> recoBeamSpotHandle;
151  iEvent.getByLabel(beamspotTag_,recoBeamSpotHandle);
152  beamSpot = *recoBeamSpotHandle;
153 
154  // Needed for DCA calculation
155  ESHandle<MagneticField> bFieldHandle;
156  iSetup.get<IdealMagneticFieldRecord>().get(bFieldHandle);
157 
158  // needed to compare to L2
159  vector<RecoChargedCandidateRef> vl2cands;
160  previousLevelCands->getObjects(TriggerMuon,vl2cands);
161 
162  // look at all mucands, check cuts and add to filter object
163  int n = 0;
164  double e1,e2,e3;
166 
167  std::map<reco::TrackRef, std::vector<RecoChargedCandidateRef> > ::iterator L2toL3s_it1 = L2toL3s.begin();
168  std::map<reco::TrackRef, std::vector<RecoChargedCandidateRef> > ::iterator L2toL3s_end = L2toL3s.end();
169  bool atLeastOneTriplet=false;
170  for (; L2toL3s_it1!=L2toL3s_end; ++L2toL3s_it1){
171 
172  if (!triggeredByLevel2(L2toL3s_it1->first,vl2cands)) continue;
173 
174  //loop over the L3Tk reconstructed for this L2.
175  unsigned int iTk1=0;
176  unsigned int maxItk1=L2toL3s_it1->second.size();
177  for (; iTk1!=maxItk1; iTk1++){
178  bool thisL3Index1isDone=false;
179  RecoChargedCandidateRef & cand1=L2toL3s_it1->second[iTk1];
180  TrackRef tk1 = cand1->get<TrackRef>();
181  // eta cut
182  LogDebug("HLTMuonTrimuonL3Filter") << " 1st muon in loop: q*pt= "
183  << tk1->charge()*tk1->pt() << " (" << cand1->charge()*cand1->pt()<< ") " << ", eta= " << tk1->eta() << " (" << cand1->eta() << ") " << ", hits= " << tk1->numberOfValidHits();
184 
185  if (fabs(cand1->eta())>max_Eta_) continue;
186 
187  // cut on number of hits
188  if (tk1->numberOfValidHits()<min_Nhits_) continue;
189 
190  //dr cut
191  // if (fabs(tk1->d0())>max_Dr_) continue;
192  if (fabs( (- (cand1->vx()-beamSpot.x0()) * cand1->py() + (cand1->vy()-beamSpot.y0()) * cand1->px() ) / cand1->pt() ) >max_Dr_) continue;
193 
194  //dz cut
195  if (fabs((cand1->vz()-beamSpot.z0()) - ((cand1->vx()-beamSpot.x0())*cand1->px()+(cand1->vy()-beamSpot.y0())*cand1->py())/cand1->pt() * cand1->pz()/cand1->pt())>max_Dz_) continue;
196 
197  // Pt threshold cut
198  double pt1 = cand1->pt();
199  // double err1 = tk1->error(0);
200  // double abspar1 = fabs(tk1->parameter(0));
201  double ptLx1 = pt1;
202  // Don't convert to 90% efficiency threshold
203  LogDebug("HLTMuonTrimuonL3Filter") << " ... 1st muon in loop, pt1= "
204  << pt1 << ", ptLx1= " << ptLx1;
205  std::map<reco::TrackRef, std::vector<RecoChargedCandidateRef> > ::iterator L2toL3s_it2 = L2toL3s_it1;
206  L2toL3s_it2++;
207  for (; L2toL3s_it2!=L2toL3s_end; ++L2toL3s_it2){
208  if (!triggeredByLevel2(L2toL3s_it2->first,vl2cands)) continue;
209 
210  //loop over the L3Tk reconstructed for this L2.
211  unsigned int iTk2=0;
212  unsigned int maxItk2=L2toL3s_it2->second.size();
213  for (; iTk2!=maxItk2; iTk2++){
214  RecoChargedCandidateRef & cand2=L2toL3s_it2->second[iTk2];
215  TrackRef tk2 = cand2->get<TrackRef>();
216 
217  // eta cut
218  LogDebug("HLTMuonTrimuonL3Filter") << " 2nd muon in loop: q*pt= " << tk2->charge()*tk2->pt() << " (" << cand2->charge()*cand2->pt() << ") " << ", eta= " << tk2->eta() << " (" << cand2->eta() << ") " << ", hits= " << tk2->numberOfValidHits() << ", d0= " << tk2->d0() ;
219  if (fabs(cand2->eta())>max_Eta_) continue;
220 
221  // cut on number of hits
222  if (tk2->numberOfValidHits()<min_Nhits_) continue;
223 
224  //dr cut
225  // if (fabs(tk2->d0())>max_Dr_) continue;
226  if (fabs( (- (cand2->vx()-beamSpot.x0()) * cand2->py() + (cand2->vy()-beamSpot.y0()) * cand2->px() ) / cand2->pt() ) >max_Dr_) continue;
227 
228  //dz cut
229  if (fabs((cand2->vz()-beamSpot.z0()) - ((cand2->vx()-beamSpot.x0())*cand2->px()+(cand2->vy()-beamSpot.y0())*cand2->py())/cand2->pt() * cand2->pz()/cand2->pt())>max_Dz_) continue;
230 
231  // Pt threshold cut
232  double pt2 = cand2->pt();
233  // double err2 = tk2->error(0);
234  // double abspar2 = fabs(tk2->parameter(0));
235  double ptLx2 = pt2;
236  // Don't convert to 90% efficiency threshold
237  LogDebug("HLTMuonTrimuonL3Filter") << " ... 2nd muon in loop, pt2= "
238  << pt2 << ", ptLx2= " << ptLx2;
239 
240  std::map<reco::TrackRef, std::vector<RecoChargedCandidateRef> > ::iterator L2toL3s_it3 = L2toL3s_it2;
241  L2toL3s_it3++;
242  for (; L2toL3s_it3!=L2toL3s_end; ++L2toL3s_it3){
243 
244  if (!triggeredByLevel2(L2toL3s_it3->first,vl2cands)) continue;
245 
246  //loop over the L3Tk reconstructed for this L2.
247  unsigned int iTk3=0;
248  unsigned int maxItk3=L2toL3s_it3->second.size();
249  for (; iTk3!=maxItk3; iTk3++){
250  RecoChargedCandidateRef & cand3=L2toL3s_it3->second[iTk3];
251  TrackRef tk3 = cand3->get<TrackRef>();
252  // eta cut
253  LogDebug("HLTMuonTrimuonL3Filter") << " 3rd muon in loop: q*pt= "
254  << tk3->charge()*tk3->pt() << " (" << cand3->charge()*cand3->pt()<< ") " << ", eta= " << tk3->eta() << " (" << cand3->eta() << ") " << ", hits= " << tk3->numberOfValidHits();
255 
256  if (fabs(cand3->eta())>max_Eta_) continue;
257 
258  // cut on number of hits
259  if (tk3->numberOfValidHits()<min_Nhits_) continue;
260 
261  //dr cut
262  // if (fabs(tk1->d0())>max_Dr_) continue;
263  if (fabs( (- (cand3->vx()-beamSpot.x0()) * cand3->py() + (cand3->vy()-beamSpot.y0()) * cand3->px() ) / cand3->pt() ) >max_Dr_) continue;
264 
265  //dz cut
266  if (fabs((cand3->vz()-beamSpot.z0()) - ((cand3->vx()-beamSpot.x0())*cand3->px()+(cand3->vy()-beamSpot.y0())*cand3->py())/cand3->pt() * cand3->pz()/cand3->pt())>max_Dz_) continue;
267 
268  // Pt threshold cut
269  double pt3 = cand3->pt();
270  // double err3 = tk3->error(0);
271  // double abspar3 = fabs(tk3->parameter(0));
272  double ptLx3 = pt3;
273  // Don't convert to 90% efficiency threshold
274  LogDebug("HLTMuonTrimuonL3Filter") << " ... 3rd muon in loop, pt3= "
275  << pt3 << ", ptLx3= " << ptLx3;
276 
277  if (ptLx1>ptLx2 && ptLx1>ptLx3 && ptLx1<min_PtMax_) continue;
278  else if (ptLx2>ptLx1 && ptLx2>ptLx3 && ptLx2<min_PtMax_) continue;
279  else if (ptLx3<ptLx2 && ptLx3>ptLx1 && ptLx3<min_PtMax_) continue;
280 
281  if (ptLx1<ptLx2 && ptLx1<ptLx3 && ptLx1<min_PtMin_) continue;
282  else if (ptLx2<ptLx1 && ptLx2<ptLx3 && ptLx2<min_PtMin_) continue;
283  else if (ptLx3<ptLx2 && ptLx3<ptLx1 && ptLx3<min_PtMin_) continue;
284 
285  if (chargeOpt_>0) {
286  if (abs (cand1->charge()+cand2->charge()+cand3->charge()) != chargeOpt_) continue;
287  }
288 
289  // Acoplanarity
290  double acop = fabs(cand1->phi()-cand2->phi());
291  if (acop>M_PI) acop = 2*M_PI - acop;
292  acop = M_PI - acop;
293  LogDebug("HLTMuonTrimuonL3Filter") << " ... 1-2 acop= " << acop;
294  if (acop<min_Acop_) continue;
295  if (acop>max_Acop_) continue;
296 
297  acop = fabs(cand1->phi()-cand3->phi());
298  if (acop>M_PI) acop = 2*M_PI - acop;
299  acop = M_PI - acop;
300  LogDebug("HLTMuonTrimuonL3Filter") << " ... 1-3 acop= " << acop;
301  if (acop<min_Acop_) continue;
302  if (acop>max_Acop_) continue;
303 
304  acop = fabs(cand3->phi()-cand2->phi());
305  if (acop>M_PI) acop = 2*M_PI - acop;
306  acop = M_PI - acop;
307  LogDebug("HLTMuonTrimuonL3Filter") << " ... 3-2 acop= " << acop;
308  if (acop<min_Acop_) continue;
309  if (acop>max_Acop_) continue;
310 
311  // Pt balance
312  double ptbalance = fabs(cand1->pt()-cand2->pt());
313  if (ptbalance<min_PtBalance_) continue;
314  if (ptbalance>max_PtBalance_) continue;
315  ptbalance = fabs(cand1->pt()-cand3->pt());
316  if (ptbalance<min_PtBalance_) continue;
317  if (ptbalance>max_PtBalance_) continue;
318  ptbalance = fabs(cand3->pt()-cand2->pt());
319  if (ptbalance<min_PtBalance_) continue;
320  if (ptbalance>max_PtBalance_) continue;
321 
322  // Combined trimuon system
323  e1 = sqrt(cand1->momentum().Mag2()+MuMass2);
324  e2 = sqrt(cand2->momentum().Mag2()+MuMass2);
325  e3 = sqrt(cand3->momentum().Mag2()+MuMass2);
326  p1 = Particle::LorentzVector(cand1->px(),cand1->py(),cand1->pz(),e1);
327  p2 = Particle::LorentzVector(cand2->px(),cand2->py(),cand2->pz(),e2);
328  p3 = Particle::LorentzVector(cand3->px(),cand3->py(),cand3->pz(),e3);
329  p = p1+p2+p3;
330 
331  double pt123 = p.pt();
332  LogDebug("HLTMuonTrimuonL3Filter") << " ... 1-2 pt123= " << pt123;
333  if (pt123<min_PtTriplet_) continue;
334 
335  double invmass = abs(p.mass());
336  // if (invmass>0) invmass = sqrt(invmass); else invmass = 0;
337  LogDebug("HLTMuonTrimuonL3Filter") << " ... 1-2 invmass= " << invmass;
338  if (invmass<min_InvMass_) continue;
339  if (invmass>max_InvMass_) continue;
340 
341  // Delta Z between the two muons
342  //double DeltaZMuMu = fabs(tk2->dz(beamSpot.position())-tk1->dz(beamSpot.position()));
343  //if ( DeltaZMuMu > max_DzMuMu_) continue;
344 
345  // DCA between the three muons
346  TransientTrack mu1TT(*tk1, &(*bFieldHandle));
347  TransientTrack mu2TT(*tk2, &(*bFieldHandle));
348  TransientTrack mu3TT(*tk3, &(*bFieldHandle));
352  if (mu1TS.isValid() && mu2TS.isValid() && mu3TS.isValid()) {
354  cApp.calculate(mu1TS.theState(), mu2TS.theState());
355  if (!cApp.status()
356  || cApp.distance() > max_DCAMuMu_) continue;
357  cApp.calculate(mu1TS.theState(), mu3TS.theState());
358  if (!cApp.status()
359  || cApp.distance() > max_DCAMuMu_) continue;
360  cApp.calculate(mu3TS.theState(), mu2TS.theState());
361  if (!cApp.status()
362  || cApp.distance() > max_DCAMuMu_) continue;
363  }
364 
365  // Max dimuon |rapidity|
366  double rapidity = fabs(p.Rapidity());
367  if ( rapidity > max_YTriplet_) continue;
368 
369  // Add this triplet
370  n++;
371  LogDebug("HLTMuonTrimuonL3Filter") << " Track1 passing filter: pt= " << cand1->pt() << ", eta: " << cand1->eta();
372  LogDebug("HLTMuonTrimuonL3Filter") << " Track2 passing filter: pt= " << cand2->pt() << ", eta: " << cand2->eta();
373  LogDebug("HLTMuonTrimuonL3Filter") << " Track2 passing filter: pt= " << cand3->pt() << ", eta: " << cand3->eta();
374  LogDebug("HLTMuonTrimuonL3Filter") << " Invmass= " << invmass;
375 
376  bool i1done = false;
377  bool i2done = false;
378  bool i3done = false;
379  vector<RecoChargedCandidateRef> vref;
380  filterproduct.getObjects(TriggerMuon,vref);
381  for (unsigned int i=0; i<vref.size(); i++) {
383  TrackRef tktmp = candref->get<TrackRef>();
384  if (tktmp==tk1) {
385  i1done = true;
386  } else if (tktmp==tk2) {
387  i2done = true;
388  } else if (tktmp==tk3) {
389  i3done = true;
390  }
391  if (i1done && i2done && i3done) break;
392  }
393 
394  if (!i1done) {
395  filterproduct.addObject(TriggerMuon,cand1);
396  }
397  if (!i2done) {
398  filterproduct.addObject(TriggerMuon,cand2);
399  }
400  if (!i3done) {
401  filterproduct.addObject(TriggerMuon,cand3);
402  }
403 
404  //break anyway since a L3 track triplet has been found matching the criteria
405  thisL3Index1isDone=true;
406  atLeastOneTriplet=true;
407  break;
408  }//loop on the track of the third L2
409  //break the loop if fast accept.
410  if (atLeastOneTriplet && fast_Accept_) break;
411  }//loop on the third L2
412  }//loop on the track of the second L2
413  //break the loop if fast accept.
414  if (atLeastOneTriplet && fast_Accept_) break;
415  }//loop on the second L2
416 
417 
418  //break the loop if fast accept.
419  if (atLeastOneTriplet && fast_Accept_) break;
420  if (thisL3Index1isDone) break;
421  }//loop on tracks for first L2
422  //break the loop if fast accept.
423  if (atLeastOneTriplet && fast_Accept_) break;
424  }//loop on the first L2
425 
426  // filter decision
427  const bool accept (n >= 1);
428 
429  LogDebug("HLTMuonTrimuonL3Filter") << " >>>>> Result of HLTMuonTrimuonL3Filter is "<< accept << ", number of muon triplets passing thresholds= " << n;
430 
431  return accept;
432 }
433 
434 
435 bool
436 HLTMuonTrimuonL3Filter::triggeredByLevel2(const TrackRef& staTrack,vector<RecoChargedCandidateRef>& vcands)
437 {
438  bool ok=false;
439  for (unsigned int i=0; i<vcands.size(); i++) {
440  if ( vcands[i]->get<TrackRef>() == staTrack ) {
441  ok=true;
442  LogDebug("HLTMuonL3PreFilter") << "The L2 track triggered";
443  break;
444  }
445  }
446  return ok;
447 }
#define LogDebug(id)
double z0() const
z coordinate
Definition: BeamSpot.h:69
int i
Definition: DBlmapReader.cc:9
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
HLTMuonTrimuonL3Filter(const edm::ParameterSet &)
void getObjects(Vids &ids, VRphoton &refs) const
various physics-level getters:
TrajectoryStateClosestToPoint impactPointTSCP() const
const FreeTrajectoryState & theState() const
bool triggeredByLevel2(const reco::TrackRef &track, std::vector< reco::RecoChargedCandidateRef > &vcands)
#define abs(x)
Definition: mlp_lapack.h:159
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:22
std::string encode() const
Definition: InputTag.cc:72
void addObject(int id, const reco::RecoEcalCandidateRef &ref)
setters for L3 collections: (id=physics type, and Ref&lt;C&gt;)
int iEvent
Definition: GenABIO.cc:243
T sqrt(T t)
Definition: SSEVec.h:46
virtual bool hltFilter(edm::Event &, const edm::EventSetup &, trigger::TriggerFilterObjectWithRefs &filterproduct)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
double p2[4]
Definition: TauolaWrapper.h:90
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:356
#define M_PI
Definition: BFit3D.cc:3
virtual bool calculate(const TrajectoryStateOnSurface &sta, const TrajectoryStateOnSurface &stb)
const T & get() const
Definition: EventSetup.h:55
void addCollectionTag(const edm::InputTag &collectionTag)
collectionTags
void add(std::string const &label, ParameterSetDescription const &psetDescription)
bool saveTags() const
Definition: HLTFilter.h:45
double p1[4]
Definition: TauolaWrapper.h:89
double y0() const
y coordinate
Definition: BeamSpot.h:67
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:242
virtual float distance() const
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:25
virtual bool status() const
math::PtEtaPhiELorentzVectorF LorentzVector
double p3[4]
Definition: TauolaWrapper.h:91
double x0() const
x coordinate
Definition: BeamSpot.h:65