CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PFMuonAlgo.cc
Go to the documentation of this file.
10 #include <iostream>
11 #include <memory>
12 
13 using namespace std;
14 using namespace reco;
15 using namespace boost;
16 
18 
19  : pfCosmicsMuonCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
20  pfCleanedTrackerAndGlobalMuonCandidates_(std::make_unique<reco::PFCandidateCollection>()),
21  pfFakeMuonCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
22  pfPunchThroughMuonCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
23  pfPunchThroughHadronCleanedCandidates_(std::make_unique<reco::PFCandidateCollection>()),
24  pfAddedMuonCandidates_(std::make_unique<reco::PFCandidateCollection>()),
25 
26  maxDPtOPt_(iConfig.getParameter<double>("maxDPtOPt")),
27  trackQuality_(reco::TrackBase::qualityByName(iConfig.getParameter<std::string>("trackQuality"))),
28  errorCompScale_(iConfig.getParameter<double>("ptErrorScale")),
29 
30  postCleaning_(postMuonCleaning), // disable by default (for HLT)
31  eventFractionCleaning_(iConfig.getParameter<double>("eventFractionForCleaning")),
32  minPostCleaningPt_(iConfig.getParameter<double>("minPtForPostCleaning")),
33  eventFactorCosmics_(iConfig.getParameter<double>("eventFactorForCosmics")),
34  metSigForCleaning_(iConfig.getParameter<double>("metSignificanceForCleaning")),
35  metSigForRejection_(iConfig.getParameter<double>("metSignificanceForRejection")),
36  metFactorCleaning_(iConfig.getParameter<double>("metFactorForCleaning")),
37  eventFractionRejection_(iConfig.getParameter<double>("eventFractionForRejection")),
38  metFactorRejection_(iConfig.getParameter<double>("metFactorForRejection")),
39  metFactorHighEta_(iConfig.getParameter<double>("metFactorForHighEta")),
40  ptFactorHighEta_(iConfig.getParameter<double>("ptFactorForHighEta")),
41  metFactorFake_(iConfig.getParameter<double>("metFactorForFakes")),
42  minPunchThroughMomentum_(iConfig.getParameter<double>("minMomentumForPunchThrough")),
43  minPunchThroughEnergy_(iConfig.getParameter<double>("minEnergyForPunchThrough")),
44  punchThroughFactor_(iConfig.getParameter<double>("punchThroughFactor")),
45  punchThroughMETFactor_(iConfig.getParameter<double>("punchThroughMETFactor")),
46  cosmicRejDistance_(iConfig.getParameter<double>("cosmicRejectionDistance")) {}
47 
49  const auto* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
50 
51  assert(eltTrack);
52  reco::MuonRef muonRef = eltTrack->muonRef();
53 
54  return isMuon(muonRef);
55 }
56 
58  const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
59 
60  assert(eltTrack);
61 
62  reco::MuonRef muonRef = eltTrack->muonRef();
63 
64  return isLooseMuon(muonRef);
65 }
66 
68  const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
69 
70  assert(eltTrack);
71  reco::MuonRef muonRef = eltTrack->muonRef();
72 
73  return isGlobalTightMuon(muonRef);
74 }
75 
77  const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
78 
79  assert(eltTrack);
80  reco::MuonRef muonRef = eltTrack->muonRef();
81 
82  return isGlobalLooseMuon(muonRef);
83 }
84 
86  const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
87 
88  assert(eltTrack);
89  reco::MuonRef muonRef = eltTrack->muonRef();
90 
91  return isTrackerTightMuon(muonRef);
92 }
93 
95  const reco::PFBlockElementTrack* eltTrack = dynamic_cast<const reco::PFBlockElementTrack*>(&elt);
96 
97  assert(eltTrack);
98  reco::MuonRef muonRef = eltTrack->muonRef();
99 
100  return isIsolatedMuon(muonRef);
101 }
102 
103 bool PFMuonAlgo::isMuon(const reco::MuonRef& muonRef) {
104  return isGlobalTightMuon(muonRef) || isTrackerTightMuon(muonRef) || isIsolatedMuon(muonRef);
105 }
106 
108  return (isGlobalLooseMuon(muonRef) || isTrackerLooseMuon(muonRef));
109 }
110 
112  if (!muonRef.isNonnull())
113  return false;
114 
115  if (!muonRef->isGlobalMuon())
116  return false;
117  if (!muonRef->isStandAloneMuon())
118  return false;
119 
120  if (muonRef->isTrackerMuon()) {
122 
123  bool isTM2DCompatibilityTight = muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityTight);
124  int nMatches = muonRef->numberOfMatches();
125  bool quality = nMatches > 2 || isTM2DCompatibilityTight;
126 
127  return result && quality;
128 
129  } else {
130  reco::TrackRef standAloneMu = muonRef->standAloneMuon();
131 
132  // No tracker muon -> Request a perfect stand-alone muon, or an even better global muon
133  bool result = false;
134 
135  // Check the quality of the stand-alone muon :
136  // good chi**2 and large number of hits and good pt error
137  if ((standAloneMu->hitPattern().numberOfValidMuonDTHits() < 22 &&
138  standAloneMu->hitPattern().numberOfValidMuonCSCHits() < 15) ||
139  standAloneMu->normalizedChi2() > 10. || standAloneMu->ptError() / standAloneMu->pt() > 0.20) {
140  result = false;
141  } else {
142  reco::TrackRef combinedMu = muonRef->combinedMuon();
143  reco::TrackRef trackerMu = muonRef->track();
144 
145  // If the stand-alone muon is good, check the global muon
146  if (combinedMu->normalizedChi2() > standAloneMu->normalizedChi2()) {
147  // If the combined muon is worse than the stand-alone, it
148  // means that either the corresponding tracker track was not
149  // reconstructed, or that the sta muon comes from a late
150  // pion decay (hence with a momentum smaller than the track)
151  // Take the stand-alone muon only if its momentum is larger
152  // than that of the track
153  result = standAloneMu->pt() > trackerMu->pt();
154  } else {
155  // If the combined muon is better (and good enough), take the
156  // global muon
157  result =
158  combinedMu->ptError() / combinedMu->pt() < std::min(0.20, standAloneMu->ptError() / standAloneMu->pt());
159  }
160  }
161 
162  return result;
163  }
164 
165  return false;
166 }
167 
169  if (!muonRef.isNonnull())
170  return false;
171 
172  if (!muonRef->isTrackerMuon())
173  return false;
174 
175  reco::TrackRef trackerMu = muonRef->track();
176  const reco::Track& track = *trackerMu;
177 
178  unsigned nTrackerHits = track.hitPattern().numberOfValidTrackerHits();
179 
180  if (nTrackerHits <= 12)
181  return false;
182 
183  bool isAllArbitrated = muon::isGoodMuon(*muonRef, muon::AllArbitrated);
184 
185  bool isTM2DCompatibilityTight = muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityTight);
186 
187  if (!isAllArbitrated || !isTM2DCompatibilityTight)
188  return false;
189 
190  if ((trackerMu->ptError() / trackerMu->pt() > 0.10)) {
191  //std::cout<<" PT ERROR > 10 % "<< trackerMu->pt() <<std::endl;
192  return false;
193  }
194  return true;
195 }
196 
198  if (!muonRef.isNonnull())
199  return false;
200  if (!muonRef->isGlobalMuon())
201  return false;
202  if (!muonRef->isStandAloneMuon())
203  return false;
204 
205  reco::TrackRef standAloneMu = muonRef->standAloneMuon();
206  reco::TrackRef combinedMu = muonRef->combinedMuon();
207  reco::TrackRef trackerMu = muonRef->track();
208 
209  unsigned nMuonHits =
210  standAloneMu->hitPattern().numberOfValidMuonDTHits() + 2 * standAloneMu->hitPattern().numberOfValidMuonCSCHits();
211 
212  bool quality = false;
213 
214  if (muonRef->isTrackerMuon()) {
215  bool result = combinedMu->normalizedChi2() < 100.;
216 
217  bool laststation = muon::isGoodMuon(*muonRef, muon::TMLastStationAngTight);
218 
219  int nMatches = muonRef->numberOfMatches();
220 
221  quality = laststation && nMuonHits > 12 && nMatches > 1;
222 
223  return result && quality;
224 
225  } else {
226  // Check the quality of the stand-alone muon :
227  // good chi**2 and large number of hits and good pt error
228  if (nMuonHits <= 15 || standAloneMu->normalizedChi2() > 10. ||
229  standAloneMu->ptError() / standAloneMu->pt() > 0.20) {
230  quality = false;
231  } else {
232  // If the stand-alone muon is good, check the global muon
233  if (combinedMu->normalizedChi2() > standAloneMu->normalizedChi2()) {
234  // If the combined muon is worse than the stand-alone, it
235  // means that either the corresponding tracker track was not
236  // reconstructed, or that the sta muon comes from a late
237  // pion decay (hence with a momentum smaller than the track)
238  // Take the stand-alone muon only if its momentum is larger
239  // than that of the track
240 
241  // Note that here we even take the standAlone if it has a smaller pT, in contrast to GlobalTight
242  if (standAloneMu->pt() > trackerMu->pt() || combinedMu->normalizedChi2() < 5.)
243  quality = true;
244  } else {
245  // If the combined muon is better (and good enough), take the
246  // global muon
247  if (combinedMu->ptError() / combinedMu->pt() < std::min(0.20, standAloneMu->ptError() / standAloneMu->pt()))
248  quality = true;
249  }
250  }
251  }
252 
253  return quality;
254 }
255 
257  if (!muonRef.isNonnull())
258  return false;
259  if (!muonRef->isTrackerMuon())
260  return false;
261 
262  reco::TrackRef trackerMu = muonRef->track();
263 
264  if (trackerMu->ptError() / trackerMu->pt() > 0.20)
265  return false;
266 
267  // this doesn't seem to be necessary on the small samples looked at, but keep it around as insurance
268  if (trackerMu->pt() > 20.)
269  return false;
270 
271  bool isAllArbitrated = muon::isGoodMuon(*muonRef, muon::AllArbitrated);
272  bool isTMLastStationAngTight = muon::isGoodMuon(*muonRef, muon::TMLastStationAngTight);
273 
274  bool quality = isAllArbitrated && isTMLastStationAngTight;
275 
276  return quality;
277 }
278 
280  if (!muonRef.isNonnull())
281  return false;
282  if (!muonRef->isIsolationValid())
283  return false;
284 
285  // Isolated Muons which are missed by standard cuts are nearly always global+tracker
286  if (!muonRef->isGlobalMuon())
287  return false;
288 
289  // If it's not a tracker muon, only take it if there are valid muon hits
290 
291  reco::TrackRef standAloneMu = muonRef->standAloneMuon();
292 
293  if (!muonRef->isTrackerMuon()) {
294  if (standAloneMu->hitPattern().numberOfValidMuonDTHits() == 0 &&
295  standAloneMu->hitPattern().numberOfValidMuonCSCHits() == 0)
296  return false;
297  }
298 
299  // for isolation, take the smallest pt available to reject fakes
300 
301  reco::TrackRef combinedMu = muonRef->combinedMuon();
302  double smallestMuPt = combinedMu->pt();
303 
304  if (standAloneMu->pt() < smallestMuPt)
305  smallestMuPt = standAloneMu->pt();
306 
307  if (muonRef->isTrackerMuon()) {
308  reco::TrackRef trackerMu = muonRef->track();
309  if (trackerMu->pt() < smallestMuPt)
310  smallestMuPt = trackerMu->pt();
311  }
312 
313  double sumPtR03 = muonRef->isolationR03().sumPt;
314 
315  double relIso = sumPtR03 / smallestMuPt;
316 
317  if (relIso < 0.1)
318  return true;
319  else
320  return false;
321 }
322 
325  return false;
326 
327  if (!muonRef->isTrackerMuon())
328  return false;
329 
330  if (muonRef->numberOfMatches() < 2)
331  return false;
332 
333  //const reco::TrackRef& combinedMuon = muonRef->combinedMuon();
334  const reco::TrackRef& combinedMuon = muonRef->globalTrack();
335 
336  if (combinedMuon->hitPattern().numberOfValidTrackerHits() < 11)
337  return false;
338 
339  if (combinedMuon->hitPattern().numberOfValidPixelHits() == 0)
340  return false;
341 
342  if (combinedMuon->hitPattern().numberOfValidMuonHits() == 0)
343  return false;
344 
345  return true;
346 }
347 
348 bool PFMuonAlgo::hasValidTrack(const reco::MuonRef& muonRef, bool loose, double maxDPtOPt) {
349  if (loose)
350  return !muonTracks(muonRef).empty();
351  else
352  return !muonTracks(muonRef, maxDPtOPt).empty();
353 }
354 
356  if (!muonRef.isNonnull())
357  return;
358 
359  bool isGL = muonRef->isGlobalMuon();
360  bool isTR = muonRef->isTrackerMuon();
361  bool isST = muonRef->isStandAloneMuon();
362 
363  std::cout << " GL: " << isGL << " TR: " << isTR << " ST: " << isST << std::endl;
364  std::cout << " nMatches " << muonRef->numberOfMatches() << std::endl;
365 
366  if (muonRef->isGlobalMuon()) {
367  reco::TrackRef combinedMu = muonRef->combinedMuon();
368  std::cout << " GL, pt: " << combinedMu->pt() << " +/- " << combinedMu->ptError() / combinedMu->pt()
369  << " chi**2 GBL : " << combinedMu->normalizedChi2() << std::endl;
370  std::cout << " Total Muon Hits : " << combinedMu->hitPattern().numberOfValidMuonHits() << "/"
371  << combinedMu->hitPattern().numberOfLostMuonHits()
372  << " DT Hits : " << combinedMu->hitPattern().numberOfValidMuonDTHits() << "/"
373  << combinedMu->hitPattern().numberOfLostMuonDTHits()
374  << " CSC Hits : " << combinedMu->hitPattern().numberOfValidMuonCSCHits() << "/"
375  << combinedMu->hitPattern().numberOfLostMuonCSCHits()
376  << " RPC Hits : " << combinedMu->hitPattern().numberOfValidMuonRPCHits() << "/"
377  << combinedMu->hitPattern().numberOfLostMuonRPCHits() << std::endl;
378 
379  std::cout << " # of Valid Tracker Hits " << combinedMu->hitPattern().numberOfValidTrackerHits() << std::endl;
380  std::cout << " # of Valid Pixel Hits " << combinedMu->hitPattern().numberOfValidPixelHits() << std::endl;
381  }
382  if (muonRef->isStandAloneMuon()) {
383  reco::TrackRef standAloneMu = muonRef->standAloneMuon();
384  std::cout << " ST, pt: " << standAloneMu->pt() << " +/- " << standAloneMu->ptError() / standAloneMu->pt()
385  << " eta : " << standAloneMu->eta()
386  << " DT Hits : " << standAloneMu->hitPattern().numberOfValidMuonDTHits() << "/"
387  << standAloneMu->hitPattern().numberOfLostMuonDTHits()
388  << " CSC Hits : " << standAloneMu->hitPattern().numberOfValidMuonCSCHits() << "/"
389  << standAloneMu->hitPattern().numberOfLostMuonCSCHits()
390  << " RPC Hits : " << standAloneMu->hitPattern().numberOfValidMuonRPCHits() << "/"
391  << standAloneMu->hitPattern().numberOfLostMuonRPCHits()
392  << " chi**2 STA : " << standAloneMu->normalizedChi2() << std::endl;
393  }
394 
395  if (muonRef->isTrackerMuon()) {
396  reco::TrackRef trackerMu = muonRef->track();
397  const reco::Track& track = *trackerMu;
398  std::cout << " TR, pt: " << trackerMu->pt() << " +/- " << trackerMu->ptError() / trackerMu->pt()
399  << " chi**2 TR : " << trackerMu->normalizedChi2() << std::endl;
400  std::cout << " nTrackerHits " << track.hitPattern().numberOfValidTrackerHits() << std::endl;
401  std::cout << "TMLastStationAngLoose " << muon::isGoodMuon(*muonRef, muon::TMLastStationAngLoose)
402  << std::endl
403  << "TMLastStationAngTight " << muon::isGoodMuon(*muonRef, muon::TMLastStationAngTight)
404  << std::endl
405  << "TMLastStationLoose " << muon::isGoodMuon(*muonRef, muon::TMLastStationLoose)
406  << std::endl
407  << "TMLastStationTight " << muon::isGoodMuon(*muonRef, muon::TMLastStationTight)
408  << std::endl
409  << "TMOneStationLoose " << muon::isGoodMuon(*muonRef, muon::TMOneStationLoose) << std::endl
410  << "TMOneStationTight " << muon::isGoodMuon(*muonRef, muon::TMOneStationTight) << std::endl
411  << "TMLastStationOptimizedLowPtLoose "
413  << "TMLastStationOptimizedLowPtTight "
415  << "TMLastStationOptimizedBarrelLowPtLoose "
417  << "TMLastStationOptimizedBarrelLowPtTight "
419  << std::endl;
420  }
421 
422  std::cout << "TM2DCompatibilityLoose " << muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityLoose)
423  << std::endl
424  << "TM2DCompatibilityTight " << muon::isGoodMuon(*muonRef, muon::TM2DCompatibilityTight)
425  << std::endl;
426 
427  if (muonRef->isGlobalMuon() && muonRef->isTrackerMuon() && muonRef->isStandAloneMuon()) {
428  reco::TrackRef combinedMu = muonRef->combinedMuon();
429  reco::TrackRef trackerMu = muonRef->track();
430  reco::TrackRef standAloneMu = muonRef->standAloneMuon();
431 
432  double sigmaCombined = combinedMu->ptError() / (combinedMu->pt() * combinedMu->pt());
433  double sigmaTracker = trackerMu->ptError() / (trackerMu->pt() * trackerMu->pt());
434  double sigmaStandAlone = standAloneMu->ptError() / (standAloneMu->pt() * standAloneMu->pt());
435 
436  bool combined = combinedMu->ptError() / combinedMu->pt() < 0.20;
437  bool tracker = trackerMu->ptError() / trackerMu->pt() < 0.20;
438  bool standAlone = standAloneMu->ptError() / standAloneMu->pt() < 0.20;
439 
440  double delta1 = combined && tracker ? fabs(1. / combinedMu->pt() - 1. / trackerMu->pt()) /
441  sqrt(sigmaCombined * sigmaCombined + sigmaTracker * sigmaTracker)
442  : 100.;
443  double delta2 = combined && standAlone ? fabs(1. / combinedMu->pt() - 1. / standAloneMu->pt()) /
444  sqrt(sigmaCombined * sigmaCombined + sigmaStandAlone * sigmaStandAlone)
445  : 100.;
446  double delta3 = standAlone && tracker ? fabs(1. / standAloneMu->pt() - 1. / trackerMu->pt()) /
447  sqrt(sigmaStandAlone * sigmaStandAlone + sigmaTracker * sigmaTracker)
448  : 100.;
449 
450  double delta =
451  standAloneMu->hitPattern().numberOfValidMuonDTHits() + standAloneMu->hitPattern().numberOfValidMuonCSCHits() > 0
452  ? std::min(delta3, std::min(delta1, delta2))
453  : std::max(delta3, std::max(delta1, delta2));
454 
455  std::cout << "delta = " << delta << " delta1 " << delta1 << " delta2 " << delta2 << " delta3 " << delta3
456  << std::endl;
457 
458  double ratio = combinedMu->ptError() / combinedMu->pt() / (trackerMu->ptError() / trackerMu->pt());
459  //if ( ratio > 2. && delta < 3. ) std::cout << "ALARM ! " << ratio << ", " << delta << std::endl;
460  std::cout << " ratio " << ratio << " combined mu pt " << combinedMu->pt() << std::endl;
461  //bool quality3 = ( combinedMu->pt() < 50. || ratio < 2. ) && delta < 3.;
462  }
463 
464  double sumPtR03 = muonRef->isolationR03().sumPt;
465  double emEtR03 = muonRef->isolationR03().emEt;
466  double hadEtR03 = muonRef->isolationR03().hadEt;
467  double relIsoR03 = (sumPtR03 + emEtR03 + hadEtR03) / muonRef->pt();
468  double sumPtR05 = muonRef->isolationR05().sumPt;
469  double emEtR05 = muonRef->isolationR05().emEt;
470  double hadEtR05 = muonRef->isolationR05().hadEt;
471  double relIsoR05 = (sumPtR05 + emEtR05 + hadEtR05) / muonRef->pt();
472  std::cout << " 0.3 Radion Rel Iso: " << relIsoR03 << " sumPt " << sumPtR03 << " emEt " << emEtR03 << " hadEt "
473  << hadEtR03 << std::endl;
474  std::cout << " 0.5 Radion Rel Iso: " << relIsoR05 << " sumPt " << sumPtR05 << " emEt " << emEtR05 << " hadEt "
475  << hadEtR05 << std::endl;
476  return;
477 }
478 
480  auto muon = std::find_if(muons.cbegin(), muons.cend(), [&](const reco::Muon& m) {
481  return (m.track().isNonnull() && m.track() == trackref);
482  });
483  return (muon != muons.cend() ? std::distance(muons.cbegin(), muon) : -1);
484 }
485 
486 std::vector<reco::Muon::MuonTrackTypePair> PFMuonAlgo::muonTracks(const reco::MuonRef& muon,
487  double maxDPtOPt,
488  bool includeSA) {
489  std::vector<reco::Muon::MuonTrackTypePair> out;
490 
491  if (muon->globalTrack().isNonnull() && muon->globalTrack()->pt() > 0)
492  if (muon->globalTrack()->ptError() / muon->globalTrack()->pt() < maxDPtOPt)
493  out.emplace_back(muon->globalTrack(), reco::Muon::CombinedTrack);
494 
495  if (muon->innerTrack().isNonnull() && muon->innerTrack()->pt() > 0)
496  if (muon->innerTrack()->ptError() / muon->innerTrack()->pt() < maxDPtOPt) //Here Loose!@
497  out.emplace_back(muon->innerTrack(), reco::Muon::InnerTrack);
498 
499  bool pickyExists = false;
500  double pickyDpt = 99999.;
501  if (muon->pickyTrack().isNonnull() && muon->pickyTrack()->pt() > 0) {
502  pickyDpt = muon->pickyTrack()->ptError() / muon->pickyTrack()->pt();
503  if (pickyDpt < maxDPtOPt)
504  out.emplace_back(muon->pickyTrack(), reco::Muon::Picky);
505  pickyExists = true;
506  }
507 
508  bool dytExists = false;
509  double dytDpt = 99999.;
510  if (muon->dytTrack().isNonnull() && muon->dytTrack()->pt() > 0) {
511  dytDpt = muon->dytTrack()->ptError() / muon->dytTrack()->pt();
512  if (dytDpt < maxDPtOPt)
513  out.emplace_back(muon->dytTrack(), reco::Muon::DYT);
514  dytExists = true;
515  }
516 
517  //Magic: TPFMS is not a really good track especially under misalignment
518  //IT is kind of crap because if mu system is displaced it can make a change
519  //So allow TPFMS if there is no picky or the error of tpfms is better than picky
520  //AND if there is no DYT or the error of tpfms is better than DYT
521  if (muon->tpfmsTrack().isNonnull() && muon->tpfmsTrack()->pt() > 0) {
522  double tpfmsDpt = muon->tpfmsTrack()->ptError() / muon->tpfmsTrack()->pt();
523  if (((pickyExists && tpfmsDpt < pickyDpt) || (!pickyExists)) &&
524  ((dytExists && tpfmsDpt < dytDpt) || (!dytExists)) && tpfmsDpt < maxDPtOPt)
525  out.emplace_back(muon->tpfmsTrack(), reco::Muon::TPFMS);
526  }
527 
528  if (includeSA && muon->outerTrack().isNonnull())
529  if (muon->outerTrack()->ptError() / muon->outerTrack()->pt() < maxDPtOPt)
530  out.emplace_back(muon->outerTrack(), reco::Muon::OuterTrack);
531 
532  return out;
533 }
534 
536 
537 bool PFMuonAlgo::reconstructMuon(reco::PFCandidate& candidate, const reco::MuonRef& muon, bool allowLoose) {
538  using namespace std;
539  using namespace reco;
540 
541  if (!muon.isNonnull())
542  return false;
543 
544  bool isMu = false;
545 
546  if (allowLoose)
547  isMu = isMuon(muon) || isLooseMuon(muon);
548  else
549  isMu = isMuon(muon);
550 
551  if (!isMu)
552  return false;
553 
554  //get the valid tracks(without standalone except we allow loose muons)
555  //MIKE: Here we need to be careful. If we have a muon inside a dense
556  //jet environment often the track is badly measured. In this case
557  //we should not apply Dpt/Pt<1
558 
559  std::vector<reco::Muon::MuonTrackTypePair> validTracks = muonTracks(muon, maxDPtOPt_);
560  if (!allowLoose)
561  validTracks = muonTracks(muon, maxDPtOPt_);
562  else
563  validTracks = muonTracks(muon);
564 
565  if (validTracks.empty())
566  return false;
567 
568  //check what is the track used.Rerun TuneP
569  reco::Muon::MuonTrackTypePair bestTrackPair = muon::tevOptimized(*muon);
570 
571  TrackRef bestTrack = bestTrackPair.first;
572  MuonTrackType trackType = bestTrackPair.second;
573 
574  MuonTrackTypePair trackPairWithSmallestError = getTrackWithSmallestError(validTracks);
575  TrackRef trackWithSmallestError = trackPairWithSmallestError.first;
576 
577  if (trackType == reco::Muon::InnerTrack &&
578  (!bestTrack->quality(trackQuality_) ||
579  bestTrack->ptError() / bestTrack->pt() >
580  errorCompScale_ * trackWithSmallestError->ptError() / trackWithSmallestError->pt())) {
581  bestTrack = trackWithSmallestError;
582  trackType = trackPairWithSmallestError.second;
583  } else if (trackType != reco::Muon::InnerTrack &&
584  bestTrack->ptError() / bestTrack->pt() >
585  errorCompScale_ * trackWithSmallestError->ptError() / trackWithSmallestError->pt()) {
586  bestTrack = trackWithSmallestError;
587  trackType = trackPairWithSmallestError.second;
588  }
589 
590  changeTrack(candidate, std::make_pair(bestTrack, trackType));
591  candidate.setMuonRef(muon);
592 
593  return true;
594 }
595 
597  using namespace reco;
598  reco::TrackRef bestTrack = track.first;
599  MuonTrackType trackType = track.second;
600  //OK Now redefine the canddiate with that track
601  double px = bestTrack->px();
602  double py = bestTrack->py();
603  double pz = bestTrack->pz();
604  double energy = sqrt(bestTrack->p() * bestTrack->p() + 0.1057 * 0.1057);
605 
606  candidate.setCharge(bestTrack->charge() > 0 ? 1 : -1);
607  candidate.setP4(math::XYZTLorentzVector(px, py, pz, energy));
609  // candidate.setTrackRef( bestTrack );
610  candidate.setMuonTrackType(trackType);
611  candidate.setVertex(bestTrack->vertex());
612 }
613 
615  const std::vector<reco::Muon::MuonTrackTypePair>& tracks) {
617  return *std::min_element(tracks.begin(), tracks.end(), sorter);
618 }
619 
621  //SUM ET
622  sumetPU_ = 0.0;
623  METX_ = 0.;
624  METY_ = 0.;
625  sumet_ = 0.0;
626  for (reco::PFCandidateCollection::const_iterator i = pfc->begin(); i != pfc->end(); ++i) {
627  sumet_ += i->pt();
628  METX_ += i->px();
629  METY_ += i->py();
630  }
631 }
632 
634  using namespace std;
635  using namespace reco;
636  if (!postCleaning_)
637  return;
638 
639  //Initialize vectors
640 
643  else
644  pfCosmicsMuonCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
645 
648  else
649  pfCleanedTrackerAndGlobalMuonCandidates_ = std::make_unique<reco::PFCandidateCollection>();
650 
653  else
654  pfFakeMuonCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
655 
658  else
659  pfPunchThroughMuonCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
660 
663  else
664  pfPunchThroughHadronCleanedCandidates_ = std::make_unique<reco::PFCandidateCollection>();
665 
667 
668  maskedIndices_.clear();
669 
670  //Estimate MET and SumET
671 
673 
674  std::vector<int> muons;
675  std::vector<int> cosmics;
676  //get the muons
677  for (unsigned int i = 0; i < cands->size(); ++i) {
678  const reco::PFCandidate& cand = (*cands)[i];
679  if (cand.particleId() == reco::PFCandidate::mu)
680  muons.push_back(i);
681  }
682  //Then sort the muon indicess by decsending pt
683 
684  IndexPtComparator comparator(cands);
685  std::sort(muons.begin(), muons.end(), comparator);
686 
687  //first kill cosmics
688  double METXCosmics = 0;
689  double METYCosmics = 0;
690  double SUMETCosmics = 0.0;
691 
692  for (unsigned int i = 0; i < muons.size(); ++i) {
693  const PFCandidate& pfc = cands->at(muons[i]);
694  double origin = 0.0;
695  if (!vertices_->empty() && vertices_->at(0).isValid() && !vertices_->at(0).isFake())
696  origin = pfc.muonRef()->muonBestTrack()->dxy(vertices_->at(0).position());
697 
698  if (origin > cosmicRejDistance_) {
699  cosmics.push_back(muons[i]);
700  METXCosmics += pfc.px();
701  METYCosmics += pfc.py();
702  SUMETCosmics += pfc.pt();
703  }
704  }
705  double MET2Cosmics = METXCosmics * METXCosmics + METYCosmics * METYCosmics;
706 
707  if (SUMETCosmics > (sumet_ - sumetPU_) / eventFactorCosmics_ && MET2Cosmics < METX_ * METX_ + METY_ * METY_)
708  for (unsigned int i = 0; i < cosmics.size(); ++i) {
709  maskedIndices_.push_back(cosmics[i]);
710  pfCosmicsMuonCleanedCandidates_->push_back(cands->at(cosmics[i]));
711  }
712 
713  //Loop on the muons candidates and clean
714  for (unsigned int i = 0; i < muons.size(); ++i) {
715  if (cleanMismeasured(cands->at(muons[i]), muons[i]))
716  continue;
717  cleanPunchThroughAndFakes(cands->at(muons[i]), cands, muons[i]);
718  }
719 
720  //OK Now do the hard job ->remove the candidates that were cleaned
722 }
723 
725  if (!postCleaning_)
726  return;
727 
728  if (pfAddedMuonCandidates_.get())
729  pfAddedMuonCandidates_->clear();
730  else
731  pfAddedMuonCandidates_ = std::make_unique<reco::PFCandidateCollection>();
732 
733  // do not recover muons if they are in the veto list
734  typedef std::pair<edm::ProductID, unsigned> TrackProdIDKey;
735  std::vector<TrackProdIDKey> vetoed;
736  if (vetoes_) {
737  for (const auto& veto : *vetoes_) {
738  if (veto.trackRef().isNull())
739  continue;
740  vetoed.emplace_back(veto.trackRef().id(), veto.trackRef().key());
741  }
742  std::sort(vetoed.begin(), vetoed.end());
743  }
744 
745  for (unsigned imu = 0; imu < muons->size(); ++imu) {
746  reco::MuonRef muonRef(muons, imu);
747  bool used = false;
748  bool hadron = false;
749  for (unsigned i = 0; i < cands->size(); i++) {
750  const PFCandidate& pfc = cands->at(i);
751  if (!pfc.trackRef().isNonnull())
752  continue;
753  if (pfc.trackRef().isNonnull() && pfc.trackRef() == muonRef->track())
754  hadron = true;
755  if (!pfc.muonRef().isNonnull())
756  continue;
757 
758  if (pfc.muonRef()->innerTrack() == muonRef->innerTrack())
759  used = true;
760  else {
761  // Check if the stand-alone muon is not a spurious copy of an existing muon
762  // (Protection needed for HLT)
763  if (pfc.muonRef()->isStandAloneMuon() && muonRef->isStandAloneMuon()) {
764  double dEta = pfc.muonRef()->standAloneMuon()->eta() - muonRef->standAloneMuon()->eta();
765  double dPhi = pfc.muonRef()->standAloneMuon()->phi() - muonRef->standAloneMuon()->phi();
766  double dR = sqrt(dEta * dEta + dPhi * dPhi);
767  if (dR < 0.005) {
768  used = true;
769  }
770  }
771  }
772 
773  if (used)
774  break;
775  }
776 
777  if (!vetoed.empty()) {
778  TrackProdIDKey trk = std::make_pair(muonRef->track().id(), muonRef->track().key());
779  auto lower = std::lower_bound(vetoed.begin(), vetoed.end(), trk);
780  bool inVetoList = (lower != vetoed.end() && *lower == trk);
781  if (inVetoList)
782  used = true;
783  }
784 
785  if (used || hadron || (!muonRef.isNonnull()))
786  continue;
787 
788  TrackMETComparator comparator(METX_, METY_);
789  //Low pt dont need to be cleaned
790 
791  std::vector<reco::Muon::MuonTrackTypePair> tracks = muonTracks(muonRef, maxDPtOPt_, true);
792  //If there is at least 1 track choice try to change the track
793  if (!tracks.empty()) {
794  //Find tracks that change dramatically MET or Pt
795  std::vector<reco::Muon::MuonTrackTypePair> tracksThatChangeMET = tracksPointingAtMET(tracks);
796  //From those tracks get the one with smallest MET
797  if (!tracksThatChangeMET.empty()) {
798  reco::Muon::MuonTrackTypePair bestTrackType =
799  *std::min_element(tracksThatChangeMET.begin(), tracksThatChangeMET.end(), comparator);
800 
801  //Make sure it is not cosmic
802  if ((vertices_->empty()) || bestTrackType.first->dz(vertices_->at(0).position()) < cosmicRejDistance_) {
803  //make a pfcandidate
804  int charge = bestTrackType.first->charge() > 0 ? 1 : -1;
805  math::XYZTLorentzVector momentum(bestTrackType.first->px(),
806  bestTrackType.first->py(),
807  bestTrackType.first->pz(),
808  sqrt(bestTrackType.first->p() * bestTrackType.first->p() + 0.1057 * 0.1057));
809 
810  cands->push_back(PFCandidate(charge, momentum, reco::PFCandidate::mu));
811 
812  changeTrack(cands->back(), bestTrackType);
813 
814  if (muonRef->track().isNonnull())
815  cands->back().setTrackRef(muonRef->track());
816 
817  cands->back().setMuonRef(muonRef);
818 
819  pfAddedMuonCandidates_->push_back(cands->back());
820  }
821  }
822  }
823  }
824 }
825 
826 std::pair<double, double> PFMuonAlgo::getMinMaxMET2(const reco::PFCandidate& pfc) {
827  std::vector<reco::Muon::MuonTrackTypePair> tracks = muonTracks((pfc.muonRef()), maxDPtOPt_, true);
828 
829  double METXNO = METX_ - pfc.px();
830  double METYNO = METY_ - pfc.py();
831  std::vector<double> met2;
832  for (unsigned int i = 0; i < tracks.size(); ++i) {
833  met2.push_back(pow(METXNO + tracks.at(i).first->px(), 2) + pow(METYNO + tracks.at(i).first->py(), 2));
834  }
835 
836  //PROTECT for cases of only one track. If there is only one track it will crash .
837  //Has never happened but could likely happen!
838 
839  if (tracks.size() > 1)
840  return std::make_pair(*std::min_element(met2.begin(), met2.end()), *std::max_element(met2.begin(), met2.end()));
841  else
842  return std::make_pair(0, 0);
843 }
844 
846  using namespace std;
847  using namespace reco;
848  bool cleaned = false;
849 
850  //First define the MET without this guy
851  double METNOX = METX_ - pfc.px();
852  double METNOY = METY_ - pfc.py();
853  double SUMETNO = sumet_ - pfc.pt();
854 
855  TrackMETComparator comparator(METNOX, METNOY);
856  //Low pt dont need to be cleaned
857  if (pfc.pt() < minPostCleaningPt_)
858  return false;
859  std::vector<reco::Muon::MuonTrackTypePair> tracks = muonTracks(pfc.muonRef(), maxDPtOPt_, false);
860 
861  //If there is more than 1 track choice try to change the track
862  if (tracks.size() > 1) {
863  //Find tracks that change dramatically MET or Pt
864  std::vector<reco::Muon::MuonTrackTypePair> tracksThatChangeMET = tracksWithBetterMET(tracks, pfc);
865  //From those tracks get the one with smallest MET
866  if (!tracksThatChangeMET.empty()) {
867  reco::Muon::MuonTrackTypePair bestTrackType =
868  *std::min_element(tracksThatChangeMET.begin(), tracksThatChangeMET.end(), comparator);
869  changeTrack(pfc, bestTrackType);
870 
872  //update eventquantities
873  METX_ = METNOX + pfc.px();
874  METY_ = METNOY + pfc.py();
875  sumet_ = SUMETNO + pfc.pt();
876  }
877  }
878 
879  //Now attempt to kill it
880  if (!(pfc.muonRef()->isGlobalMuon() && pfc.muonRef()->isTrackerMuon())) {
881  //define MET significance and SUM ET
882  double MET2 = METX_ * METX_ + METY_ * METY_;
883  double newMET2 = METNOX * METNOX + METNOY * METNOY;
884  double METSig = sqrt(MET2) / sqrt(sumet_ - sumetPU_);
885  if (METSig > metSigForRejection_)
886  if ((newMET2 < MET2 / metFactorRejection_) &&
887  ((SUMETNO - sumetPU_) / (sumet_ - sumetPU_) < eventFractionRejection_)) {
888  pfFakeMuonCleanedCandidates_->push_back(pfc);
889  maskedIndices_.push_back(i);
890  METX_ = METNOX;
891  METY_ = METNOY;
892  sumet_ = SUMETNO;
893  cleaned = true;
894  }
895  }
896  return cleaned;
897 }
898 
899 std::vector<reco::Muon::MuonTrackTypePair> PFMuonAlgo::tracksWithBetterMET(
900  const std::vector<reco::Muon::MuonTrackTypePair>& tracks, const reco::PFCandidate& pfc) {
901  std::vector<reco::Muon::MuonTrackTypePair> outputTracks;
902 
903  double METNOX = METX_ - pfc.px();
904  double METNOY = METY_ - pfc.py();
905  double SUMETNO = sumet_ - pfc.pt();
906  double MET2 = METX_ * METX_ + METY_ * METY_;
907  double newMET2 = 0.0;
908  double newSUMET = 0.0;
909  double METSIG = sqrt(MET2) / sqrt(sumet_ - sumetPU_);
910 
911  if (METSIG > metSigForCleaning_)
912  for (unsigned int i = 0; i < tracks.size(); ++i) {
913  //calculate new SUM ET and MET2
914  newSUMET = SUMETNO + tracks.at(i).first->pt() - sumetPU_;
915  newMET2 = pow(METNOX + tracks.at(i).first->px(), 2) + pow(METNOY + tracks.at(i).first->py(), 2);
916 
917  if (newSUMET / (sumet_ - sumetPU_) > eventFractionCleaning_ && newMET2 < MET2 / metFactorCleaning_)
918  outputTracks.push_back(tracks.at(i));
919  }
920 
921  return outputTracks;
922 }
923 
924 std::vector<reco::Muon::MuonTrackTypePair> PFMuonAlgo::tracksPointingAtMET(
925  const std::vector<reco::Muon::MuonTrackTypePair>& tracks) {
926  std::vector<reco::Muon::MuonTrackTypePair> outputTracks;
927 
928  double newMET2 = 0.0;
929 
930  for (unsigned int i = 0; i < tracks.size(); ++i) {
931  //calculate new SUM ET and MET2
932  newMET2 = pow(METX_ + tracks.at(i).first->px(), 2) + pow(METY_ + tracks.at(i).first->py(), 2);
933 
934  if (newMET2 < (METX_ * METX_ + METY_ * METY_) / metFactorCleaning_)
935  outputTracks.push_back(tracks.at(i));
936  }
937 
938  return outputTracks;
939 }
940 
942 
945  unsigned int imu) {
946  using namespace reco;
947 
948  bool cleaned = false;
949 
950  if (pfc.pt() < minPostCleaningPt_)
951  return false;
952 
953  double METXNO = METX_ - pfc.pt();
954  double METYNO = METY_ - pfc.pt();
955  double MET2NO = METXNO * METXNO + METYNO * METYNO;
956  double MET2 = METX_ * METX_ + METY_ * METY_;
957  bool fake1 = false;
958 
959  std::pair<double, double> met2 = getMinMaxMET2(pfc);
960 
961  //Check for Fakes at high pseudorapidity
962  if (pfc.muonRef()->standAloneMuon().isNonnull())
963  fake1 = fabs(pfc.eta()) > 2.15 && met2.first < met2.second / 2 && MET2NO < MET2 / metFactorHighEta_ &&
964  pfc.muonRef()->standAloneMuon()->pt() < pfc.pt() / ptFactorHighEta_;
965 
966  double factor = std::max(2., 2000. / (sumet_ - pfc.pt() - sumetPU_));
967  bool fake2 =
968  (pfc.pt() / (sumet_ - sumetPU_) < 0.25 && MET2NO < MET2 / metFactorFake_ && met2.first < met2.second / factor);
969 
970  bool punchthrough = pfc.p() > minPunchThroughMomentum_ && pfc.rawHcalEnergy() > minPunchThroughEnergy_ &&
971  pfc.rawEcalEnergy() + pfc.rawHcalEnergy() > pfc.p() / punchThroughFactor_ &&
972  !isIsolatedMuon(pfc.muonRef()) && MET2NO < MET2 / punchThroughMETFactor_;
973 
974  if (fake1 || fake2 || punchthrough) {
975  // Find the block of the muon
976  const PFCandidate::ElementsInBlocks& eleInBlocks = pfc.elementsInBlocks();
977  if (!eleInBlocks.empty()) {
978  PFBlockRef blockRefMuon = eleInBlocks[0].first;
979  unsigned indexMuon = eleInBlocks[0].second;
980  if (eleInBlocks.size() > 1)
981  indexMuon = eleInBlocks[1].second;
982 
983  // Check if the muon gave rise to a neutral hadron
984  double iHad = 1E9;
985  bool hadron = false;
986  for (unsigned i = imu + 1; i < cands->size(); ++i) {
987  const PFCandidate& pfcn = cands->at(i);
989  if (ele.empty()) {
990  continue;
991  }
992  PFBlockRef blockRefHadron = ele[0].first;
993  unsigned indexHadron = ele[0].second;
994  // We are out of the block -> exit the loop
995  if (blockRefHadron.key() != blockRefMuon.key())
996  break;
997  // Check that this particle is a neutral hadron
998  if (indexHadron == indexMuon && pfcn.particleId() == reco::PFCandidate::h0) {
999  iHad = i;
1000  hadron = true;
1001  }
1002  if (hadron)
1003  break;
1004  }
1005 
1006  if (hadron) {
1007  double rescaleFactor = cands->at(iHad).p() / cands->at(imu).p();
1008  METX_ -= cands->at(imu).px() + cands->at(iHad).px();
1009  METY_ -= cands->at(imu).py() + cands->at(iHad).py();
1010  sumet_ -= cands->at(imu).pt();
1011  cands->at(imu).rescaleMomentum(rescaleFactor);
1012  maskedIndices_.push_back(iHad);
1013  pfPunchThroughHadronCleanedCandidates_->push_back(cands->at(iHad));
1014  cands->at(imu).setParticleType(reco::PFCandidate::h);
1015  pfPunchThroughMuonCleanedCandidates_->push_back(cands->at(imu));
1016  METX_ += cands->at(imu).px();
1017  METY_ += cands->at(imu).py();
1018  sumet_ += cands->at(imu).pt();
1019 
1020  } else if (fake1 || fake2) {
1021  METX_ -= cands->at(imu).px();
1022  METY_ -= cands->at(imu).py();
1023  sumet_ -= cands->at(imu).pt();
1024  maskedIndices_.push_back(imu);
1025  pfFakeMuonCleanedCandidates_->push_back(cands->at(imu));
1026  cleaned = true;
1027  }
1028  }
1029  }
1030  return cleaned;
1031 }
1032 
1034  size_t N = indices.size();
1035  size_t collSize = obj->size();
1036 
1037  for (size_t i = 0; i < N; ++i)
1038  obj->at(indices.at(i)) = obj->at(collSize - i - 1);
1039 
1040  obj->resize(collSize - indices.size());
1041 }
1042 
1044  // Muon ID and post cleaning parameters
1045  iDesc.add<double>("maxDPtOPt", 1.0);
1046  iDesc.add<std::string>("trackQuality", "highPurity");
1047  iDesc.add<double>("ptErrorScale", 8.0);
1048 
1049  iDesc.add<double>("eventFractionForCleaning", 0.5);
1050  iDesc.add<double>("minPtForPostCleaning", 20.0);
1051  iDesc.add<double>("eventFactorForCosmics", 10.0);
1052  iDesc.add<double>("metSignificanceForCleaning", 3.0);
1053  iDesc.add<double>("metSignificanceForRejection", 4.0);
1054  iDesc.add<double>("metFactorForCleaning", 4.0);
1055  iDesc.add<double>("eventFractionForRejection", 0.8);
1056  iDesc.add<double>("metFactorForRejection", 4.0);
1057  iDesc.add<double>("metFactorForHighEta", 25.0);
1058  iDesc.add<double>("ptFactorForHighEta", 2.0);
1059  iDesc.add<double>("metFactorForFakes", 4.0);
1060  iDesc.add<double>("minMomentumForPunchThrough", 100.0);
1061  iDesc.add<double>("minEnergyForPunchThrough", 100.0);
1062  iDesc.add<double>("punchThroughFactor", 3.0);
1063  iDesc.add<double>("punchThroughMETFactor", 4.0);
1064  iDesc.add<double>("cosmicRejectionDistance", 1.0);
1065 }
Abstract base class for a PFBlock element (track, cluster...)
static bool isIsolatedMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:94
static int muAssocToTrack(const reco::TrackRef &trackref, const reco::MuonCollection &muons)
Definition: PFMuonAlgo.cc:479
bool cleanMismeasured(reco::PFCandidate &, unsigned int)
Definition: PFMuonAlgo.cc:845
static bool isTightMuonPOG(const reco::MuonRef &muonRef)
Definition: PFMuonAlgo.cc:323
double sumet_
Definition: PFMuonAlgo.h:151
void removeDeadCandidates(reco::PFCandidateCollection *, const std::vector< unsigned int > &)
Definition: PFMuonAlgo.cc:1033
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
std::unique_ptr< reco::PFCandidateCollection > pfPunchThroughMuonCleanedCandidates_
the collection of punch-through cleaned muon candidates
Definition: PFMuonAlgo.h:112
double rawEcalEnergy() const
return corrected Ecal energy
Definition: PFCandidate.h:224
void addMissingMuons(edm::Handle< reco::MuonCollection >, reco::PFCandidateCollection *cands)
Definition: PFMuonAlgo.cc:724
double pt() const final
transverse momentum
Quality qualityByName(std::string const &name)
static bool isMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:48
const double minPunchThroughEnergy_
Definition: PFMuonAlgo.h:145
static bool isTrackerLooseMuon(const reco::PFBlockElement &elt)
const double metFactorRejection_
Definition: PFMuonAlgo.h:140
const bool postCleaning_
Definition: PFMuonAlgo.h:132
std::unique_ptr< reco::PFCandidateCollection > pfFakeMuonCleanedCandidates_
the collection of fake cleaned muon candidates
Definition: PFMuonAlgo.h:110
static bool isGlobalLooseMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:76
const double minPunchThroughMomentum_
Definition: PFMuonAlgo.h:144
bool cleanPunchThroughAndFakes(reco::PFCandidate &, reco::PFCandidateCollection *, unsigned int)
Definition: PFMuonAlgo.cc:943
void setInputsForCleaning(reco::VertexCollection const &)
Definition: PFMuonAlgo.cc:941
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
reco::Muon::MuonTrackTypePair MuonTrackTypePair
Definition: PFMuonAlgo.h:14
auto const & tracks
cannot be loose
const double punchThroughFactor_
Definition: PFMuonAlgo.h:146
string quality
std::unique_ptr< reco::PFCandidateCollection > pfCleanedTrackerAndGlobalMuonCandidates_
the collection of tracker/global cleaned muon candidates
Definition: PFMuonAlgo.h:108
const double maxDPtOPt_
Definition: PFMuonAlgo.h:127
key_type key() const
Accessor for product key.
Definition: Ref.h:250
const double metFactorCleaning_
Definition: PFMuonAlgo.h:138
static void printMuonProperties(const reco::MuonRef &muonRef)
Definition: PFMuonAlgo.cc:355
std::vector< MuonTrackTypePair > tracksPointingAtMET(const std::vector< MuonTrackTypePair > &)
Definition: PFMuonAlgo.cc:924
assert(be >=bs)
static bool isGlobalTightMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:67
ProductID id() const
Accessor for product ID.
Definition: Ref.h:244
std::vector< Muon > MuonCollection
collection of Muon objects
Definition: MuonFwd.h:9
void setVertex(const Point &vertex) override
set vertex
tuple result
Definition: mps_fire.py:311
std::vector< ElementInBlock > ElementsInBlocks
Definition: PFCandidate.h:404
reco::TrackRef trackRef() const
Definition: PFCandidate.cc:430
MuonTrackTypePair getTrackWithSmallestError(const std::vector< MuonTrackTypePair > &)
Definition: PFMuonAlgo.cc:614
U second(std::pair< T, U > const &p)
void setCharge(Charge q) final
set electric charge
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
tuple normalizedChi2
double px() const final
x coordinate of momentum vector
double p() const final
magnitude of momentum vector
reco::Muon::MuonTrackTypePair tevOptimized(const reco::TrackRef &combinedTrack, const reco::TrackRef &trackerTrack, const reco::TrackRef &tpfmsTrack, const reco::TrackRef &pickyTrack, const reco::TrackRef &dytTrack, const double ptThreshold=200., const double tune1=17., const double tune2=40., const double dptcut=0.25)
Definition: MuonCocktails.cc:9
const double metFactorHighEta_
Definition: PFMuonAlgo.h:141
const double cosmicRejDistance_
Definition: PFMuonAlgo.h:148
void setMuonTrackType(const reco::Muon::MuonTrackType &type)
set the Best Muon Track Ref
Definition: PFCandidate.h:381
void setParticleType(ParticleType type)
set Particle Type
Definition: PFCandidate.cc:278
T sqrt(T t)
Definition: SSEVec.h:19
const double minPostCleaningPt_
Definition: PFMuonAlgo.h:134
tuple cosmics
Individual module setups ###.
const reco::MuonRef & muonRef() const override
void estimateEventQuantities(const reco::PFCandidateCollection *)
Definition: PFMuonAlgo.cc:620
const double ptFactorHighEta_
Definition: PFMuonAlgo.h:142
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void changeTrack(reco::PFCandidate &, const MuonTrackTypePair &)
Definition: PFMuonAlgo.cc:596
double py() const final
y coordinate of momentum vector
const double eventFractionCleaning_
Definition: PFMuonAlgo.h:133
tuple postMuonCleaning
bool isGoodMuon(const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
main GoodMuon wrapper call
reco::MuonRef muonRef() const
Definition: PFCandidate.cc:443
std::unique_ptr< reco::PFCandidateCollection > pfAddedMuonCandidates_
the collection of added muon candidates
Definition: PFMuonAlgo.h:116
const double metFactorFake_
Definition: PFMuonAlgo.h:143
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
PFMuonAlgo(edm::ParameterSet const &, bool postMuonCleaning)
constructor
Definition: PFMuonAlgo.cc:17
static void fillPSetDescription(edm::ParameterSetDescription &iDesc)
Definition: PFMuonAlgo.cc:1043
#define N
Definition: blowfish.cc:9
const HitPattern & hitPattern() const
Access the hit pattern, indicating in which Tracker layers the track has hits.
Definition: TrackBase.h:504
static bool isLooseMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:57
double METX_
Definition: PFMuonAlgo.h:152
const reco::PFCandidateCollection * vetoes_
Definition: PFMuonAlgo.h:120
static std::vector< reco::Muon::MuonTrackTypePair > muonTracks(const reco::MuonRef &muon, double maxDPtOPt=1e+9, bool includeSA=false)
Definition: PFMuonAlgo.cc:486
const double eventFactorCosmics_
Definition: PFMuonAlgo.h:135
std::pair< double, double > getMinMaxMET2(const reco::PFCandidate &)
Definition: PFMuonAlgo.cc:826
int numberOfValidTrackerHits() const
Definition: HitPattern.h:819
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:41
void setMuonRef(const reco::MuonRef &ref)
set muon reference
Definition: PFCandidate.cc:432
tuple muons
Definition: patZpeak.py:41
__host__ __device__ constexpr RandomIt lower_bound(RandomIt first, RandomIt last, const T &value, Compare comp={})
double sumetPU_
Definition: PFMuonAlgo.h:150
std::vector< unsigned int > maskedIndices_
Definition: PFMuonAlgo.h:118
constexpr auto loose
static bool hasValidTrack(const reco::MuonRef &muonRef, bool loose, double maxDPtOPt)
Definition: PFMuonAlgo.cc:348
tuple cout
Definition: gather_cfg.py:144
const reco::VertexCollection * vertices_
Definition: PFMuonAlgo.h:123
MuonTrackType
map for Global Muon refitters
Definition: Muon.h:36
const double punchThroughMETFactor_
Definition: PFMuonAlgo.h:147
virtual ParticleType particleId() const
Definition: PFCandidate.h:392
list indices
Definition: dqmdumpme.py:50
std::pair< TrackRef, Muon::MuonTrackType > MuonTrackTypePair
Definition: Muon.h:38
std::unique_ptr< reco::PFCandidateCollection > pfCosmicsMuonCleanedCandidates_
the collection of cosmics cleaned muon candidates
Definition: PFMuonAlgo.h:106
std::vector< MuonTrackTypePair > tracksWithBetterMET(const std::vector< MuonTrackTypePair > &, const reco::PFCandidate &)
Definition: PFMuonAlgo.cc:899
void postClean(reco::PFCandidateCollection *)
Definition: PFMuonAlgo.cc:633
const ElementsInBlocks & elementsInBlocks() const
Definition: PFCandidate.cc:658
const double eventFractionRejection_
Definition: PFMuonAlgo.h:139
void setP4(const LorentzVector &p4) final
set 4-momentum
const double errorCompScale_
Definition: PFMuonAlgo.h:130
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
const double metSigForCleaning_
Definition: PFMuonAlgo.h:136
static bool isTrackerTightMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:85
double rawHcalEnergy() const
return raw Hcal energy
Definition: PFCandidate.h:236
const reco::TrackBase::TrackQuality trackQuality_
Definition: PFMuonAlgo.h:129
const double metSigForRejection_
Definition: PFMuonAlgo.h:137
std::unique_ptr< reco::PFCandidateCollection > pfPunchThroughHadronCleanedCandidates_
the collection of punch-through cleaned neutral hadron candidates
Definition: PFMuonAlgo.h:114
bool reconstructMuon(reco::PFCandidate &, const reco::MuonRef &, bool allowLoose=false)
Definition: PFMuonAlgo.cc:537
double eta() const final
momentum pseudorapidity
double METY_
Definition: PFMuonAlgo.h:153