CMS 3D CMS Logo

Classes | Enumerations | Functions | Variables
muon Namespace Reference

Classes

struct  SelectionTypeStringToEnum
 a lightweight "map" for selection type string label and enum value More...
 
struct  SelectorStringToEnum
 

Enumerations

enum  AlgorithmType {
  TMLastStation, TM2DCompatibility, TMOneStation, RPCMu,
  ME0Mu, GEMMu
}
 
enum  SelectionType {
  All = 0, AllGlobalMuons = 1, AllStandAloneMuons = 2, AllTrackerMuons = 3,
  TrackerMuonArbitrated = 4, AllArbitrated = 5, GlobalMuonPromptTight = 6, TMLastStationLoose = 7,
  TMLastStationTight = 8, TM2DCompatibilityLoose = 9, TM2DCompatibilityTight = 10, TMOneStationLoose = 11,
  TMOneStationTight = 12, TMLastStationOptimizedLowPtLoose = 13, TMLastStationOptimizedLowPtTight = 14, GMTkChiCompatibility = 15,
  GMStaChiCompatibility = 16, GMTkKinkTight = 17, TMLastStationAngLoose = 18, TMLastStationAngTight = 19,
  TMOneStationAngLoose = 20, TMOneStationAngTight = 21, TMLastStationOptimizedBarrelLowPtLoose = 22, TMLastStationOptimizedBarrelLowPtTight = 23,
  RPCMuLoose = 24, AllME0Muons = 25, ME0MuonArbitrated = 26, AllGEMMuons = 27,
  GEMMuonArbitrated = 28, TriggerIdLoose = 29
}
 Selector type. More...
 

Functions

float caloCompatibility (const reco::Muon &muon)
 
reco::TrackRef getTevRefitTrack (const reco::TrackRef &combinedTrack, const reco::TrackToTrackMap &map)
 
bool isGoodMuon (const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
 main GoodMuon wrapper call More...
 
bool isGoodMuon (const reco::Muon &muon, AlgorithmType type, double minCompatibility, reco::Muon::ArbitrationType arbitrationType)
 
bool isGoodMuon (const reco::Muon &muon, AlgorithmType type, int minNumberOfMatches, double maxAbsDx, double maxAbsPullX, double maxAbsDy, double maxAbsPullY, double maxChamberDist, double maxChamberDistPull, reco::Muon::ArbitrationType arbitrationType, bool syncMinNMatchesNRequiredStationsInBarrelOnly=true, bool applyAlsoAngularCuts=false)
 
bool isHighPtMuon (const reco::Muon &, const reco::Vertex &)
 
bool isLooseMuon (const reco::Muon &)
 
bool isLooseTriggerMuon (const reco::Muon &)
 
bool isMediumMuon (const reco::Muon &, bool run2016_hip_mitigation=false)
 
bool isSoftMuon (const reco::Muon &, const reco::Vertex &, bool run2016_hip_mitigation=false)
 
bool isTightMuon (const reco::Muon &, const reco::Vertex &)
 
bool isTrackerHighPtMuon (const reco::Muon &, const reco::Vertex &)
 
reco::Muon::Selector makeSelectorBitset (reco::Muon const &muon, reco::Vertex const *vertex=nullptr, bool run2016_hip_mitigation=false)
 
bool overlap (const reco::Muon &muon1, const reco::Muon &muon2, double pullX=1.0, double pullY=1.0, bool checkAdjacentChambers=false)
 
unsigned int RequiredStationMask (const reco::Muon &muon, double maxChamberDist, double maxChamberDistPull, reco::Muon::ArbitrationType arbitrationType)
 
float segmentCompatibility (const reco::Muon &muon, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
 
SelectionType selectionTypeFromString (const std::string &label)
 
reco::Muon::Selector selectorFromString (const std::string &label)
 
int sharedSegments (const reco::Muon &muon1, const reco::Muon &muon2, unsigned int segmentArbitrationMask=reco::MuonSegmentMatch::BestInChamberByDR)
 
reco::Muon::MuonTrackTypePair sigmaSwitch (const reco::TrackRef &combinedTrack, const reco::TrackRef &trackerTrack, const double nSigma=2., const double ptThreshold=200.)
 
reco::Muon::MuonTrackTypePair sigmaSwitch (const reco::Muon &muon, const double nSigma=2., const double ptThreshold=200.)
 
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)
 
reco::Muon::MuonTrackTypePair tevOptimized (const reco::Muon &muon, const double ptThreshold=200., const double tune1=17., const double tune2=40., const double dptcut=0.25)
 
reco::Muon::MuonTrackTypePair TMR (const reco::TrackRef &trackerTrack, const reco::TrackRef &fmsTrack, const double tune=4.)
 
double trackProbability (const reco::TrackRef track)
 

Variables

static const SelectionTypeStringToEnum selectionTypeStringToEnumMap []
 
static const SelectorStringToEnum selectorStringToEnumMap []
 

Enumeration Type Documentation

◆ AlgorithmType

Enumerator
TMLastStation 
TM2DCompatibility 
TMOneStation 
RPCMu 
ME0Mu 
GEMMu 

Definition at line 156 of file MuonSelectors.h.

◆ SelectionType

Selector type.

Enumerator
All 
AllGlobalMuons 
AllStandAloneMuons 
AllTrackerMuons 
TrackerMuonArbitrated 
AllArbitrated 
GlobalMuonPromptTight 
TMLastStationLoose 
TMLastStationTight 
TM2DCompatibilityLoose 
TM2DCompatibilityTight 
TMOneStationLoose 
TMOneStationTight 
TMLastStationOptimizedLowPtLoose 
TMLastStationOptimizedLowPtTight 
GMTkChiCompatibility 
GMStaChiCompatibility 
GMTkKinkTight 
TMLastStationAngLoose 
TMLastStationAngTight 
TMOneStationAngLoose 
TMOneStationAngTight 
TMLastStationOptimizedBarrelLowPtLoose 
TMLastStationOptimizedBarrelLowPtTight 
RPCMuLoose 
AllME0Muons 
ME0MuonArbitrated 
AllGEMMuons 
GEMMuonArbitrated 
TriggerIdLoose 

Definition at line 18 of file MuonSelectors.h.

18  {
19  All = 0, // dummy options - always true
20  AllGlobalMuons = 1, // checks isGlobalMuon flag
21  AllStandAloneMuons = 2, // checks isStandAloneMuon flag
22  AllTrackerMuons = 3, // checks isTrackerMuon flag
23  TrackerMuonArbitrated = 4, // resolve ambiguity of sharing segments
24  AllArbitrated = 5, // all muons with the tracker muon arbitrated
25  GlobalMuonPromptTight = 6, // global muons with tighter fit requirements
26  TMLastStationLoose = 7, // penetration depth loose selector
27  TMLastStationTight = 8, // penetration depth tight selector
28  TM2DCompatibilityLoose = 9, // likelihood based loose selector
29  TM2DCompatibilityTight = 10, // likelihood based tight selector
30  TMOneStationLoose = 11, // require one well matched segment
31  TMOneStationTight = 12, // require one well matched segment
32  TMLastStationOptimizedLowPtLoose = 13, // combination of TMLastStation and TMOneStation
33  TMLastStationOptimizedLowPtTight = 14, // combination of TMLastStation and TMOneStation
34  GMTkChiCompatibility = 15, // require tk stub have good chi2 relative to glb track
35  GMStaChiCompatibility = 16, // require sta stub have good chi2 compatibility relative to glb track
36  GMTkKinkTight = 17, // require a small kink value in the tracker stub
37  TMLastStationAngLoose = 18, // TMLastStationLoose with additional angular cuts
38  TMLastStationAngTight = 19, // TMLastStationTight with additional angular cuts
39  TMOneStationAngLoose = 20, // TMOneStationLoose with additional angular cuts
40  TMOneStationAngTight = 21, // TMOneStationTight with additional angular cuts
41  // The two algorithms that follow are identical to what were known as
42  // TMLastStationOptimizedLowPt* (sans the Barrel) as late as revision
43  // 1.7 of this file. The names were changed because indeed the low pt
44  // optimization applies only to the barrel region, whereas the sel-
45  // ectors above are more efficient at low pt in the endcaps, which is
46  // what we feel is more suggestive of the algorithm name. This will be
47  // less confusing for future generations of CMS members, I hope...
48  // combination of TMLastStation and TMOneStation but with low pT optimization in barrel only
50  // combination of TMLastStation and TMOneStation but with low pT optimization in barrel only
52  RPCMuLoose = 24, // checks isRPCMuon flag (require two well matched hits in different RPC layers)
53  AllME0Muons = 25,
54  ME0MuonArbitrated = 26,
55  AllGEMMuons = 27,
56  GEMMuonArbitrated = 28,
57  TriggerIdLoose = 29
58  };

Function Documentation

◆ caloCompatibility()

float muon::caloCompatibility ( const reco::Muon muon)

Definition at line 58 of file MuonSelectors.cc.

Referenced by CSCEfficiency::filter(), isGoodMuon(), and pat::MuonSelector::muIdSelection_().

58 { return muon.caloCompatibility(); }

◆ getTevRefitTrack()

reco::TrackRef muon::getTevRefitTrack ( const reco::TrackRef combinedTrack,
const reco::TrackToTrackMap map 
)

Definition at line 131 of file MuonCocktails.cc.

References genParticles_cff::map, and edm::helpers::KeyVal< K, V >::val.

Referenced by MuonIdProducer::makeMuon().

131  {
132  reco::TrackToTrackMap::const_iterator it = map.find(combinedTrack);
133  return it == map.end() ? reco::TrackRef() : it->val;
134 }
edm::Ref< TrackCollection > TrackRef
persistent reference to a Track
Definition: TrackFwd.h:20

◆ isGoodMuon() [1/3]

bool muon::isGoodMuon ( const reco::Muon muon,
SelectionType  type,
reco::Muon::ArbitrationType  arbitrationType = reco::Muon::SegmentAndTrackArbitration 
)

main GoodMuon wrapper call

Definition at line 649 of file MuonSelectors.cc.

References funct::abs(), All, AllArbitrated, AllGEMMuons, AllGlobalMuons, AllME0Muons, AllStandAloneMuons, AllTrackerMuons, arbitrationType, GEMMu, GEMMuonArbitrated, GlobalMuonPromptTight, GMStaChiCompatibility, GMTkChiCompatibility, GMTkKinkTight, isLooseTriggerMuon(), ME0Mu, ME0MuonArbitrated, RPCMu, RPCMuLoose, TM2DCompatibility, TM2DCompatibilityLoose, TM2DCompatibilityTight, TMLastStation, TMLastStationAngLoose, TMLastStationAngTight, TMLastStationLoose, TMLastStationOptimizedBarrelLowPtLoose, TMLastStationOptimizedBarrelLowPtTight, TMLastStationOptimizedLowPtLoose, TMLastStationOptimizedLowPtTight, TMLastStationTight, TMOneStation, TMOneStationAngLoose, TMOneStationAngTight, TMOneStationLoose, TMOneStationTight, TrackerMuonArbitrated, and TriggerIdLoose.

Referenced by BPHSoftMuonSelect::accept(), ExampleMuonAnalyzer::analyze(), BPhysicsOniaDQM::analyze(), TrackEfficiencyMonitor::analyze(), HiggsDQM::analyze(), MuonIdVal::analyze(), MuonCosmicCompatibilityFiller::checkMuonID(), PFRecoTauDiscriminationAgainstMuon::discriminate(), ZtoMMEventSelector::filter(), HLTDiMuonGlbTrkFilter::hltFilter(), HLTMuonTrkFilter::hltFilter(), HLTMuonTrkL1TFilter::hltFilter(), HLTMuonL3PreFilter::hltFilter(), ZCounting::isCustomTightMuon(), PFMuonAlgo::isGlobalLooseMuon(), PFMuonAlgo::isGlobalTightMuon(), isLooseTriggerMuon(), isSoftMuon(), isTightMuon(), PFMuonAlgo::isTightMuonPOG(), PFMuonAlgo::isTrackerLooseMuon(), PFMuonAlgo::isTrackerTightMuon(), PFB::match(), JetPlusTrackCorrector::matchMuons(), pat::MuonSelector::muIdSelection_(), MuonSelectorVIDWrapper< selectionType, arbitrationType >::operator()(), MuonBadTrackFilter::printMuonProperties(), PFMuonAlgo::printMuonProperties(), MuonIDFilterProducerForHLT::produce(), MuonRefProducer::produce(), MuonSelectionTypeValueMapProducer::produce(), MuonTrackProducer::produce(), pat::PackedCandidateMuonSelectorProducer::produce(), SoftLepton::produce(), and MuonSelectorVIDWrapper< selectionType, arbitrationType >::value().

649  {
650  switch (type) {
651  case muon::All:
652  return true;
653  break;
655  return muon.isGlobalMuon();
656  break;
658  return muon.isTrackerMuon();
659  break;
661  return muon.isStandAloneMuon();
662  break;
664  return muon.isTrackerMuon() && muon.numberOfMatches(arbitrationType) > 0;
665  break;
666  case muon::AllArbitrated:
667  return !muon.isTrackerMuon() || muon.numberOfMatches(arbitrationType) > 0;
668  break;
670  return muon.isGlobalMuon() && muon.globalTrack()->normalizedChi2() < 10. &&
671  muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0;
672  break;
673  // For "Loose" algorithms we choose maximum y quantity cuts of 1E9 instead of
674  // 9999 as before. We do this because the muon methods return 999999 (note
675  // there are six 9's) when the requested information is not available. For
676  // example, if a muon fails to traverse the z measuring superlayer in a station
677  // in the DT, then all methods involving segmentY in this station return
678  // 999999 to demonstrate that the information is missing. In order to not
679  // penalize muons for missing y information in Loose algorithms where we do
680  // not care at all about y information, we raise these limits. In the
681  // TMLastStation and TMOneStation algorithms we actually use this huge number
682  // to determine whether to consider y information at all.
684  return muon.isTrackerMuon() &&
685  isGoodMuon(muon, TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3, arbitrationType, true, false);
686  break;
688  return muon.isTrackerMuon() &&
689  isGoodMuon(muon, TMLastStation, 2, 3, 3, 3, 3, -3, -3, arbitrationType, true, false);
690  break;
692  return muon.isTrackerMuon() &&
693  isGoodMuon(muon, TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9, arbitrationType, false, false);
694  break;
696  return muon.isTrackerMuon() &&
697  isGoodMuon(muon, TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9, arbitrationType, false, false);
698  break;
700  if (muon.pt() < 8. && std::abs(muon.eta()) < 1.2)
701  return muon.isTrackerMuon() &&
702  isGoodMuon(muon, TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9, arbitrationType, false, false);
703  else
704  return muon.isTrackerMuon() &&
705  isGoodMuon(muon, TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3, arbitrationType, false, false);
706  break;
708  if (muon.pt() < 8. && std::abs(muon.eta()) < 1.2)
709  return muon.isTrackerMuon() &&
710  isGoodMuon(muon, TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9, arbitrationType, false, false);
711  else
712  return muon.isTrackerMuon() &&
713  isGoodMuon(muon, TMLastStation, 2, 3, 3, 3, 3, -3, -3, arbitrationType, false, false);
714  break;
715  //compatibility loose
717  return muon.isTrackerMuon() && isGoodMuon(muon, TM2DCompatibility, 0.7, arbitrationType);
718  break;
719  //compatibility tight
721  return muon.isTrackerMuon() && isGoodMuon(muon, TM2DCompatibility, 1.0, arbitrationType);
722  break;
724  return muon.isGlobalMuon() && muon.isQualityValid() &&
725  std::abs(muon.combinedQuality().trkRelChi2 - muon.innerTrack()->normalizedChi2()) < 2.0;
726  break;
728  return muon.isGlobalMuon() && muon.isQualityValid() &&
729  std::abs(muon.combinedQuality().staRelChi2 - muon.outerTrack()->normalizedChi2()) < 2.0;
730  break;
731  case muon::GMTkKinkTight:
732  return muon.isGlobalMuon() && muon.isQualityValid() && muon.combinedQuality().trkKink < 100.0;
733  break;
735  return muon.isTrackerMuon() &&
736  isGoodMuon(muon, TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3, arbitrationType, false, true);
737  break;
739  return muon.isTrackerMuon() &&
740  isGoodMuon(muon, TMLastStation, 2, 3, 3, 3, 3, -3, -3, arbitrationType, false, true);
741  break;
743  return muon.isTrackerMuon() &&
744  isGoodMuon(muon, TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9, arbitrationType, false, true);
745  break;
747  return muon.isTrackerMuon() &&
748  isGoodMuon(muon, TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9, arbitrationType, false, true);
749  break;
751  if (muon.pt() < 8. && std::abs(muon.eta()) < 1.2)
752  return muon.isTrackerMuon() &&
753  isGoodMuon(muon, TMOneStation, 1, 3, 3, 1E9, 1E9, 1E9, 1E9, arbitrationType, false, false);
754  else
755  return muon.isTrackerMuon() &&
756  isGoodMuon(muon, TMLastStation, 2, 3, 3, 1E9, 1E9, -3, -3, arbitrationType, true, false);
757  break;
759  if (muon.pt() < 8. && std::abs(muon.eta()) < 1.2)
760  return muon.isTrackerMuon() &&
761  isGoodMuon(muon, TMOneStation, 1, 3, 3, 3, 3, 1E9, 1E9, arbitrationType, false, false);
762  else
763  return muon.isTrackerMuon() &&
764  isGoodMuon(muon, TMLastStation, 2, 3, 3, 3, 3, -3, -3, arbitrationType, true, false);
765  break;
766  case muon::RPCMuLoose:
767  return muon.isRPCMuon() && isGoodMuon(muon, RPCMu, 2, 20, 4, 1e9, 1e9, 1e9, 1e9, arbitrationType, false, false);
768  break;
769  case muon::AllME0Muons:
770  return muon.isME0Muon();
771  break;
773  return muon.isME0Muon() &&
774  isGoodMuon(muon, ME0Mu, 1, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, arbitrationType, false, false);
775  break;
776  case muon::AllGEMMuons:
777  return muon.isGEMMuon();
778  break;
780  return muon.isGEMMuon() &&
781  isGoodMuon(muon, GEMMu, 1, 1e9, 1e9, 1e9, 1e9, 1e9, 1e9, arbitrationType, false, false);
782  break;
784  return isLooseTriggerMuon(muon);
785  break;
786  default:
787  return false;
788  }
789 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isGoodMuon(const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
main GoodMuon wrapper call
const reco::Muon::ArbitrationType arbitrationType
bool isLooseTriggerMuon(const reco::Muon &)

◆ isGoodMuon() [2/3]

bool muon::isGoodMuon ( const reco::Muon muon,
AlgorithmType  type,
double  minCompatibility,
reco::Muon::ArbitrationType  arbitrationType 
)

Definition at line 293 of file MuonSelectors.cc.

References arbitrationType, caloCompatibility(), extraflags_cff::segmentCompatibility, and TM2DCompatibility.

296  {
297  if (!muon.isMatchesValid())
298  return false;
299  bool goodMuon = false;
300 
301  switch (type) {
302  case TM2DCompatibility:
303  // Simplistic first cut in the 2D segment- vs calo-compatibility plane. Will have to be refined!
304  if (((0.8 * caloCompatibility(muon)) + (1.2 * segmentCompatibility(muon, arbitrationType))) > minCompatibility)
305  goodMuon = true;
306  else
307  goodMuon = false;
308  return goodMuon;
309  break;
310  default:
311  // LogTrace("MuonIdentification")<<" // Invalid Algorithm Type called!";
312  goodMuon = false;
313  return goodMuon;
314  break;
315  }
316 }
float caloCompatibility(const reco::Muon &muon)
const reco::Muon::ArbitrationType arbitrationType

◆ isGoodMuon() [3/3]

bool muon::isGoodMuon ( const reco::Muon muon,
AlgorithmType  type,
int  minNumberOfMatches,
double  maxAbsDx,
double  maxAbsPullX,
double  maxAbsDy,
double  maxAbsPullY,
double  maxChamberDist,
double  maxChamberDistPull,
reco::Muon::ArbitrationType  arbitrationType,
bool  syncMinNMatchesNRequiredStationsInBarrelOnly = true,
bool  applyAlsoAngularCuts = false 
)

Definition at line 318 of file MuonSelectors.cc.

References funct::abs(), arbitrationType, hgcalTestNeighbor_cfi::detector, fftjetvertexadder_cfi::errX, MuonSubdetId::GEM, GEMMu, HLT_2022v15_cff::maxAbsDx, HLT_2022v15_cff::maxAbsDy, HLT_2022v15_cff::maxAbsPullX, HLT_2022v15_cff::maxAbsPullY, MuonSubdetId::ME0, ME0Mu, HLT_2022v15_cff::minNumberOfMatches, or, RequiredStationMask(), MuonSubdetId::RPC, RPCMu, mathSSE::sqrt(), relativeConstraints::station, TMLastStation, and TMOneStation.

329  {
330  if (!muon.isMatchesValid())
331  return false;
332  bool goodMuon = false;
333 
334  if (type == TMLastStation) {
335  // To satisfy my own paranoia, if the user specifies that the
336  // minimum number of matches is zero, then return true.
337  if (minNumberOfMatches == 0)
338  return true;
339 
340  unsigned int theStationMask = muon.stationMask(arbitrationType);
341  unsigned int theRequiredStationMask =
342  RequiredStationMask(muon, maxChamberDist, maxChamberDistPull, arbitrationType);
343 
344  // Require that there be at least a minimum number of segments
345  int numSegs = 0;
346  int numRequiredStations = 0;
347  for (int it = 0; it < 8; ++it) {
348  if (theStationMask & 1 << it)
349  ++numSegs;
350  if (theRequiredStationMask & 1 << it)
351  ++numRequiredStations;
352  }
353 
354  // Make sure the minimum number of matches is not greater than
355  // the number of required stations but still greater than zero
356  if (syncMinNMatchesNRequiredStationsInBarrelOnly) {
357  // Note that we only do this in the barrel region!
358  if (std::abs(muon.eta()) < 1.2) {
359  if (minNumberOfMatches > numRequiredStations)
360  minNumberOfMatches = numRequiredStations;
361  if (minNumberOfMatches < 1) //SK: this only happens for negative values
362  minNumberOfMatches = 1;
363  }
364  } else {
365  if (minNumberOfMatches > numRequiredStations)
366  minNumberOfMatches = numRequiredStations;
367  if (minNumberOfMatches < 1) //SK: this only happens for negative values
368  minNumberOfMatches = 1;
369  }
370 
371  if (numSegs >= minNumberOfMatches)
372  goodMuon = true;
373 
374  // Require that last required station have segment
375  // If there are zero required stations keep track
376  // of the last station with a segment so that we may
377  // apply the quality cuts below to it instead
378  int lastSegBit = 0;
379  if (theRequiredStationMask) {
380  for (int stationIdx = 7; stationIdx >= 0; --stationIdx)
381  if (theRequiredStationMask & 1 << stationIdx) {
382  if (theStationMask & 1 << stationIdx) {
383  lastSegBit = stationIdx;
384  goodMuon &= 1;
385  break;
386  } else {
387  goodMuon = false;
388  break;
389  }
390  }
391  } else {
392  for (int stationIdx = 7; stationIdx >= 0; --stationIdx)
393  if (theStationMask & 1 << stationIdx) {
394  lastSegBit = stationIdx;
395  break;
396  }
397  }
398 
399  if (!goodMuon)
400  return false;
401 
402  // Impose pull cuts on last segment
403  int station = 0, detector = 0;
404  station = lastSegBit < 4 ? lastSegBit + 1 : lastSegBit - 3;
405  detector = lastSegBit < 4 ? 1 : 2;
406 
407  // Check x information
408  if (std::abs(muon.pullX(station, detector, arbitrationType, true)) > maxAbsPullX &&
410  return false;
411 
412  if (applyAlsoAngularCuts && std::abs(muon.pullDxDz(station, detector, arbitrationType, true)) > maxAbsPullX)
413  return false;
414 
415  // Is this a tight algorithm, i.e. do we bother to check y information?
416  if (maxAbsDy < 999999) { // really if maxAbsDy < 1E9 as currently defined
417 
418  // Check y information
419  if (detector == 2) { // CSC
420  if (std::abs(muon.pullY(station, 2, arbitrationType, true)) > maxAbsPullY &&
422  return false;
423 
424  if (applyAlsoAngularCuts && std::abs(muon.pullDyDz(station, 2, arbitrationType, true)) > maxAbsPullY)
425  return false;
426  } else {
427  //
428  // In DT, if this is a "Tight" algorithm and the last segment is
429  // missing y information (always the case in station 4!!!), impose
430  // respective cuts on the next station in the stationMask that has
431  // a segment with y information. If there are no segments with y
432  // information then there is nothing to penalize. Should we
433  // penalize in Tight for having zero segments with y information?
434  // That is the fundamental question. Of course I am being uber
435  // paranoid; if this is a good muon then there will probably be at
436  // least one segment with y information but not always. Suppose
437  // somehow a muon only creates segments in station 4, then we
438  // definitely do not want to require that there be at least one
439  // segment with y information because we will lose it completely.
440  //
441 
442  for (int stationIdx = station; stationIdx > 0; --stationIdx) {
443  if (!(theStationMask & 1 << (stationIdx - 1))) // don't bother if the station is not in the stationMask
444  continue;
445 
446  if (muon.dY(stationIdx, 1, arbitrationType) > 999998) // no y-information
447  continue;
448 
449  if (std::abs(muon.pullY(stationIdx, 1, arbitrationType, true)) > maxAbsPullY &&
450  std::abs(muon.dY(stationIdx, 1, arbitrationType)) > maxAbsDy) {
451  return false;
452  }
453 
454  if (applyAlsoAngularCuts && std::abs(muon.pullDyDz(stationIdx, 1, arbitrationType, true)) > maxAbsPullY)
455  return false;
456 
457  // If we get this far then great this is a good muon
458  return true;
459  }
460  }
461  }
462 
463  return goodMuon;
464  } // TMLastStation
465 
466  // TMOneStation requires only that there be one "good" segment, regardless
467  // of the required stations. We do not penalize if there are absolutely zero
468  // segments with y information in the Tight algorithm. Maybe I'm being
469  // paranoid but so be it. If it's really a good muon then we will probably
470  // find at least one segment with both x and y information but you never
471  // know, and I don't want to deal with a potential inefficiency in the DT
472  // like we did with the original TMLastStation. Incidentally, not penalizing
473  // for total lack of y information in the Tight algorithm is what is done in
474  // the new TMLastStation
475  //
476  if (type == TMOneStation) {
477  unsigned int theStationMask = muon.stationMask(arbitrationType);
478 
479  // Of course there must be at least one segment
480  if (!theStationMask)
481  return false;
482 
483  int station = 0, detector = 0;
484  // Keep track of whether or not there is a DT segment with y information.
485  // In the end, if it turns out there are absolutely zero DT segments with
486  // y information, require only that there was a segment with good x info.
487  // This of course only applies to the Tight algorithms.
488  bool existsGoodDTSegX = false;
489  bool existsDTSegY = false;
490 
491  // Impose cuts on the segments in the station mask until we find a good one
492  // Might as well start with the lowest bit to speed things up.
493  for (int stationIdx = 0; stationIdx <= 7; ++stationIdx)
494  if (theStationMask & 1 << stationIdx) {
495  station = stationIdx < 4 ? stationIdx + 1 : stationIdx - 3;
496  detector = stationIdx < 4 ? 1 : 2;
497 
498  if ((std::abs(muon.pullX(station, detector, arbitrationType, true)) > maxAbsPullX &&
500  (applyAlsoAngularCuts && std::abs(muon.pullDxDz(station, detector, arbitrationType, true)) > maxAbsPullX))
501  continue;
502  else if (detector == 1)
503  existsGoodDTSegX = true;
504 
505  // Is this a tight algorithm? If yes, use y information
506  if (maxAbsDy < 999999) {
507  if (detector == 2) { // CSC
508  if ((std::abs(muon.pullY(station, 2, arbitrationType, true)) > maxAbsPullY &&
510  (applyAlsoAngularCuts && std::abs(muon.pullDyDz(station, 2, arbitrationType, true)) > maxAbsPullY))
511  continue;
512  } else {
513  if (muon.dY(station, 1, arbitrationType) > 999998) // no y-information
514  continue;
515  else
516  existsDTSegY = true;
517 
518  if ((std::abs(muon.pullY(station, 1, arbitrationType, true)) > maxAbsPullY &&
520  (applyAlsoAngularCuts && std::abs(muon.pullDyDz(station, 1, arbitrationType, true)) > maxAbsPullY)) {
521  continue;
522  }
523  }
524  }
525 
526  // If we get this far then great this is a good muon
527  return true;
528  }
529 
530  // If we get this far then for sure there are no "good" CSC segments. For
531  // DT, check if there were any segments with y information. If there
532  // were none, but there was a segment with good x, then we're happy. If
533  // there WERE segments with y information, then they must have been shit
534  // since we are here so fail it. Of course, if this is a Loose algorithm
535  // then fail immediately since if we had good x we would already have
536  // returned true
537  if (maxAbsDy < 999999) {
538  if (existsDTSegY)
539  return false;
540  else if (existsGoodDTSegX)
541  return true;
542  } else
543  return false;
544  } // TMOneStation
545 
546  if (type == RPCMu) {
547  if (minNumberOfMatches == 0)
548  return true;
549 
550  int nMatch = 0;
551  for (const auto& chamberMatch : muon.matches()) {
552  if (chamberMatch.detector() != MuonSubdetId::RPC)
553  continue;
554 
555  const float trkX = chamberMatch.x;
556  const float errX = chamberMatch.xErr;
557 
558  for (const auto& rpcMatch : chamberMatch.rpcMatches) {
559  const float rpcX = rpcMatch.x;
560  const float dX = std::abs(rpcX - trkX);
561  if (dX < maxAbsDx or dX < maxAbsPullX * errX) {
562  ++nMatch;
563  break;
564  }
565  }
566  }
567 
568  if (nMatch >= minNumberOfMatches)
569  return true;
570  else
571  return false;
572  } // RPCMu
573 
574  if (type == ME0Mu) {
575  if (minNumberOfMatches == 0)
576  return true;
577 
578  int nMatch = 0;
579  for (const auto& chamberMatch : muon.matches()) {
580  if (chamberMatch.detector() != MuonSubdetId::ME0)
581  continue;
582 
583  const float trkX = chamberMatch.x;
584  const float errX2 = chamberMatch.xErr * chamberMatch.xErr;
585  const float trkY = chamberMatch.y;
586  const float errY2 = chamberMatch.yErr * chamberMatch.yErr;
587 
588  for (const auto& segment : chamberMatch.me0Matches) {
589  const float me0X = segment.x;
590  const float me0ErrX2 = segment.xErr * segment.xErr;
591  const float me0Y = segment.y;
592  const float me0ErrY2 = segment.yErr * segment.yErr;
593 
594  const float dX = std::abs(me0X - trkX);
595  const float dY = std::abs(me0Y - trkY);
596  const float invPullX2 = errX2 + me0ErrX2;
597  const float invPullY2 = errY2 + me0ErrY2;
598 
599  if ((dX < maxAbsDx or dX < maxAbsPullX * std::sqrt(invPullX2)) and
600  (dY < maxAbsDy or dY < maxAbsPullY * std::sqrt(invPullY2))) {
601  ++nMatch;
602  break;
603  }
604  }
605  }
606 
607  return (nMatch >= minNumberOfMatches);
608  } // ME0Mu
609 
610  if (type == GEMMu) {
611  if (minNumberOfMatches == 0)
612  return true;
613 
614  int nMatch = 0;
615  for (const auto& chamberMatch : muon.matches()) {
616  if (chamberMatch.detector() != MuonSubdetId::GEM)
617  continue;
618 
619  const float trkX = chamberMatch.x;
620  const float errX2 = chamberMatch.xErr * chamberMatch.xErr;
621  const float trkY = chamberMatch.y;
622  const float errY2 = chamberMatch.yErr * chamberMatch.yErr;
623 
624  for (const auto& segment : chamberMatch.gemMatches) {
625  const float gemX = segment.x;
626  const float gemErrX2 = segment.xErr * segment.xErr;
627  const float gemY = segment.y;
628  const float gemErrY2 = segment.yErr * segment.yErr;
629 
630  const float dX = std::abs(gemX - trkX);
631  const float dY = std::abs(gemY - trkY);
632  const float invPullX2 = errX2 + gemErrX2;
633  const float invPullY2 = errY2 + gemErrY2;
634 
635  if ((dX < maxAbsDx or dX < maxAbsPullX * std::sqrt(invPullX2)) and
636  (dY < maxAbsDy or dY < maxAbsPullY * std::sqrt(invPullY2))) {
637  ++nMatch;
638  break;
639  }
640  }
641  }
642 
643  return (nMatch >= minNumberOfMatches);
644  } // GEMMu
645 
646  return goodMuon;
647 }
static constexpr int GEM
Definition: MuonSubdetId.h:14
T sqrt(T t)
Definition: SSEVec.h:19
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static constexpr int ME0
Definition: MuonSubdetId.h:15
const reco::Muon::ArbitrationType arbitrationType
static constexpr int RPC
Definition: MuonSubdetId.h:13
unsigned int RequiredStationMask(const reco::Muon &muon, double maxChamberDist, double maxChamberDistPull, reco::Muon::ArbitrationType arbitrationType)

◆ isHighPtMuon()

bool muon::isHighPtMuon ( const reco::Muon muon,
const reco::Vertex vtx 
)

Definition at line 933 of file MuonSelectors.cc.

References funct::abs(), hfClusterShapes_cfi::hits, and extraflags_cff::vtx.

Referenced by MuonKinVsEtaAnalyzer::analyze(), makeSelectorBitset(), Muon.Muon::muonID(), MuonPOGStandardCut::operator()(), MuonMiniAOD::PassesCut_A(), HLTDQMMuonSelector::passMuonSel(), and MuonPOGStandardCut::value().

933  {
934  if (!muon.isGlobalMuon())
935  return false;
936 
937  bool muValHits = (muon.globalTrack()->hitPattern().numberOfValidMuonHits() > 0 ||
938  muon.tunePMuonBestTrack()->hitPattern().numberOfValidMuonHits() > 0);
939 
940  bool muMatchedSt = muon.numberOfMatchedStations() > 1;
941  if (!muMatchedSt) {
942  if (muon.isTrackerMuon() && muon.numberOfMatchedStations() == 1) {
943  if (muon.expectedNnumberOfMatchedStations() < 2 || !(muon.stationMask() == 1 || muon.stationMask() == 16) ||
944  muon.numberOfMatchedRPCLayers() > 2)
945  muMatchedSt = true;
946  }
947  }
948 
949  bool muID = muValHits && muMatchedSt;
950 
951  bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
952  muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
953 
954  bool momQuality = muon.tunePMuonBestTrack()->ptError() / muon.tunePMuonBestTrack()->pt() < 0.3;
955 
956  bool ip =
957  std::abs(muon.innerTrack()->dxy(vtx.position())) < 0.2 && std::abs(muon.innerTrack()->dz(vtx.position())) < 0.5;
958 
959  return muID && hits && momQuality && ip;
960 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22

◆ isLooseMuon()

bool muon::isLooseMuon ( const reco::Muon muon)

◆ isLooseTriggerMuon()

bool muon::isLooseTriggerMuon ( const reco::Muon muon)

Definition at line 866 of file MuonSelectors.cc.

References isGoodMuon(), or, and TMOneStationTight.

Referenced by isGoodMuon(), makeSelectorBitset(), and MuonIDFilterProducerForHLT::produce().

866  {
867  // Requirements:
868  // - no depencence on information not availabe in the muon object
869  // - use only robust inputs
870  bool tk_id = muon::isGoodMuon(muon, TMOneStationTight);
871  if (not tk_id)
872  return false;
873  bool layer_requirements = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
874  muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0;
875  bool match_requirements =
876  (muon.expectedNnumberOfMatchedStations() < 2) or (muon.numberOfMatchedStations() > 1) or (muon.pt() < 8);
877  return layer_requirements and match_requirements;
878 }
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool isGoodMuon(const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
main GoodMuon wrapper call

◆ isMediumMuon()

bool muon::isMediumMuon ( const reco::Muon muon,
bool  run2016_hip_mitigation = false 
)

Definition at line 899 of file MuonSelectors.cc.

References isLooseMuon(), and extraflags_cff::segmentCompatibility.

Referenced by DiMuonHistograms::analyze(), EfficiencyAnalyzer::analyze(), MuonKinVsEtaAnalyzer::analyze(), HcalHBHEMuonAnalyzer::analyze(), makeSelectorBitset(), MuonPOGStandardCut::operator()(), MuonMiniAOD::PassesCut_A(), ZCounting::passMuonID(), HLTDQMMuonSelector::passMuonSel(), AlCaHcalHBHEMuonProducer::produce(), BadGlobalMuonTagger::tighterId(), and MuonPOGStandardCut::value().

899  {
900  if (not isLooseMuon(muon))
901  return false;
902  if (run2016_hip_mitigation) {
903  if (muon.innerTrack()->validFraction() < 0.49)
904  return false;
905  } else {
906  if (muon.innerTrack()->validFraction() < 0.8)
907  return false;
908  }
909 
910  bool goodGlb = muon.isGlobalMuon() && muon.globalTrack()->normalizedChi2() < 3. &&
911  muon.combinedQuality().chi2LocalPosition < 12. && muon.combinedQuality().trkKink < 20.;
912 
913  return (segmentCompatibility(muon) > (goodGlb ? 0.303 : 0.451));
914 }
bool isLooseMuon(const reco::Muon &)

◆ isSoftMuon()

bool muon::isSoftMuon ( const reco::Muon muon,
const reco::Vertex vtx,
bool  run2016_hip_mitigation = false 
)

Definition at line 916 of file MuonSelectors.cc.

References funct::abs(), reco::TrackBase::highPurity, isGoodMuon(), hgcalTopologyTester_cfi::layers, TMOneStationTight, and extraflags_cff::vtx.

Referenced by DiMuonHistograms::analyze(), MuonKinVsEtaAnalyzer::analyze(), LeptonSkimming::filter(), makeSelectorBitset(), Muon.Muon::muonID(), MuonPOGStandardCut::operator()(), MuonMiniAOD::PassesCut_A(), HLTDQMMuonSelector::passMuonSel(), and MuonPOGStandardCut::value().

916  {
918 
919  if (!muID)
920  return false;
921 
922  bool layers = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
923  muon.innerTrack()->hitPattern().pixelLayersWithMeasurement() > 0;
924 
925  bool ishighq = muon.innerTrack()->quality(reco::Track::highPurity);
926 
927  bool ip =
928  std::abs(muon.innerTrack()->dxy(vtx.position())) < 0.3 && std::abs(muon.innerTrack()->dz(vtx.position())) < 20.;
929 
930  return layers && ip && (ishighq | run2016_hip_mitigation);
931 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isGoodMuon(const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
main GoodMuon wrapper call

◆ isTightMuon()

bool muon::isTightMuon ( const reco::Muon muon,
const reco::Vertex vtx 
)

Definition at line 880 of file MuonSelectors.cc.

References funct::abs(), GlobalMuonPromptTight, hfClusterShapes_cfi::hits, isGoodMuon(), and extraflags_cff::vtx.

Referenced by METplusTrackMonitor::analyze(), RecoMuonValidator::analyze(), MuonKinVsEtaAnalyzer::analyze(), DiMuonHistograms::analyze(), EfficiencyAnalyzer::analyze(), MuonPFAnalyzer::analyze(), MuonRecoOneHLT::analyze(), HcalHBHEMuonAnalyzer::analyze(), L1TMuonDQMOffline::getTightMuons(), makeSelectorBitset(), Muon.Muon::muonID(), MuonPOGStandardCut::operator()(), MuonMiniAOD::PassesCut_A(), ZCounting::passMuonID(), HLTDQMMuonSelector::passMuonSel(), AlCaHcalHBHEMuonProducer::produce(), and MuonPOGStandardCut::value().

880  {
881  if (!muon.isPFMuon() || !muon.isGlobalMuon())
882  return false;
883 
884  bool muID = isGoodMuon(muon, GlobalMuonPromptTight) && (muon.numberOfMatchedStations() > 1);
885 
886  bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
887  muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
888 
889  bool ip = std::abs(muon.muonBestTrack()->dxy(vtx.position())) < 0.2 &&
890  std::abs(muon.muonBestTrack()->dz(vtx.position())) < 0.5;
891 
892  return muID && hits && ip;
893 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isGoodMuon(const reco::Muon &muon, SelectionType type, reco::Muon::ArbitrationType arbitrationType=reco::Muon::SegmentAndTrackArbitration)
main GoodMuon wrapper call

◆ isTrackerHighPtMuon()

bool muon::isTrackerHighPtMuon ( const reco::Muon muon,
const reco::Vertex vtx 
)

Definition at line 962 of file MuonSelectors.cc.

References funct::abs(), hfClusterShapes_cfi::hits, and extraflags_cff::vtx.

Referenced by makeSelectorBitset().

962  {
963  bool muID = muon.isTrackerMuon() && muon.track().isNonnull() && (muon.numberOfMatchedStations() > 1);
964  if (!muID)
965  return false;
966 
967  bool hits = muon.innerTrack()->hitPattern().trackerLayersWithMeasurement() > 5 &&
968  muon.innerTrack()->hitPattern().numberOfValidPixelHits() > 0;
969 
970  bool momQuality = muon.tunePMuonBestTrack()->ptError() < 0.3 * muon.tunePMuonBestTrack()->pt();
971 
972  bool ip =
973  std::abs(muon.innerTrack()->dxy(vtx.position())) < 0.2 && std::abs(muon.innerTrack()->dz(vtx.position())) < 0.5;
974 
975  return muID && hits && momQuality && ip;
976 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22

◆ makeSelectorBitset()

reco::Muon::Selector muon::makeSelectorBitset ( reco::Muon const &  muon,
reco::Vertex const *  vertex = nullptr,
bool  run2016_hip_mitigation = false 
)

Definition at line 1033 of file MuonSelectors.cc.

References funct::abs(), reco::Muon::CutBasedIdGlobalHighPt, reco::Muon::CutBasedIdLoose, reco::Muon::CutBasedIdMedium, reco::Muon::CutBasedIdMediumPrompt, reco::Muon::CutBasedIdTight, reco::Muon::CutBasedIdTrkHighPt, reco::Muon::InTimeMuon, isHighPtMuon(), isLooseMuon(), isLooseTriggerMuon(), isMediumMuon(), isSoftMuon(), isTightMuon(), isTrackerHighPtMuon(), SiStripPI::max, outOfTimeMuon(), reco::Muon::PFIsoLoose, reco::Muon::PFIsoMedium, reco::Muon::PFIsoTight, reco::Muon::PFIsoVeryLoose, reco::Muon::PFIsoVeryTight, reco::Muon::PFIsoVeryVeryTight, TrackValidation_cff::selectors, reco::Muon::SoftCutBasedId, reco::Muon::TkIsoLoose, reco::Muon::TkIsoTight, muons_cff::tkRelIso, reco::Muon::TriggerIdLoose, and bphysicsOniaDQM_cfi::vertex.

Referenced by MuonProducer::produce(), pat::PATMuonProducer::produce(), and pat::LeptonUpdater< T >::recomputeMuonBasicSelectors().

1035  {
1036  // https://twiki.cern.ch/twiki/bin/viewauth/CMS/SWGuideMuonIdRun2
1037  unsigned int selectors = muon.selectors();
1038  // Compute Id and Isolation variables
1039  double chIso = muon.pfIsolationR04().sumChargedHadronPt;
1040  double nIso = muon.pfIsolationR04().sumNeutralHadronEt;
1041  double phoIso = muon.pfIsolationR04().sumPhotonEt;
1042  double puIso = muon.pfIsolationR04().sumPUPt;
1043  double dbCorrectedIsolation = chIso + std::max(nIso + phoIso - .5 * puIso, 0.);
1044  double dbCorrectedRelIso = dbCorrectedIsolation / muon.pt();
1045  double tkRelIso = muon.isolationR03().sumPt / muon.pt();
1046 
1047  // Base selectors
1048  if (muon::isLooseMuon(muon))
1050  if (vertex) {
1051  if (muon::isTightMuon(muon, *vertex))
1053  if (muon::isSoftMuon(muon, *vertex, run2016_hip_mitigation))
1059  }
1060  if (muon::isMediumMuon(muon, run2016_hip_mitigation)) {
1062  if (vertex and std::abs(muon.muonBestTrack()->dz(vertex->position())) < 0.1 and
1063  std::abs(muon.muonBestTrack()->dxy(vertex->position())) < 0.02)
1065  }
1066 
1067  // PF isolation
1068  if (dbCorrectedRelIso < 0.40)
1070  if (dbCorrectedRelIso < 0.25)
1071  selectors |= (1UL << reco::Muon::PFIsoLoose);
1072  if (dbCorrectedRelIso < 0.20)
1073  selectors |= (1UL << reco::Muon::PFIsoMedium);
1074  if (dbCorrectedRelIso < 0.15)
1075  selectors |= (1UL << reco::Muon::PFIsoTight);
1076  if (dbCorrectedRelIso < 0.10)
1078  if (dbCorrectedRelIso < 0.05)
1080 
1081  // Tracker isolation
1082  if (tkRelIso < 0.10)
1083  selectors |= (1UL << reco::Muon::TkIsoLoose);
1084  if (tkRelIso < 0.05)
1085  selectors |= (1UL << reco::Muon::TkIsoTight);
1086 
1087  // Trigger selectors
1088  if (isLooseTriggerMuon(muon))
1090 
1091  // Timing
1092  if (!outOfTimeMuon(muon))
1093  selectors |= (1UL << reco::Muon::InTimeMuon);
1094 
1095  return static_cast<reco::Muon::Selector>(selectors);
1096 }
bool isMediumMuon(const reco::Muon &, bool run2016_hip_mitigation=false)
bool isLooseMuon(const reco::Muon &)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isSoftMuon(const reco::Muon &, const reco::Vertex &, bool run2016_hip_mitigation=false)
bool isHighPtMuon(const reco::Muon &, const reco::Vertex &)
bool outOfTimeMuon(const reco::Muon &muon)
bool isTrackerHighPtMuon(const reco::Muon &, const reco::Vertex &)
bool isTightMuon(const reco::Muon &, const reco::Vertex &)
bool isLooseTriggerMuon(const reco::Muon &)
Selector
Definition: Muon.h:202

◆ overlap()

bool muon::overlap ( const reco::Muon muon1,
const reco::Muon muon2,
double  pullX = 1.0,
double  pullY = 1.0,
bool  checkAdjacentChambers = false 
)

Definition at line 791 of file MuonSelectors.cc.

References funct::abs(), MuonSubdetId::CSC, globals_cff::id1, globals_cff::id2, reco::Muon::matches(), reco::Muon::numberOfMatches(), reco::LeafCandidate::pt(), reco::Muon::SegmentAndTrackArbitration, and mathSSE::sqrt().

792  {
793  unsigned int nMatches1 = muon1.numberOfMatches(reco::Muon::SegmentAndTrackArbitration);
794  unsigned int nMatches2 = muon2.numberOfMatches(reco::Muon::SegmentAndTrackArbitration);
795  unsigned int betterMuon = (muon1.pt() > muon2.pt() ? 1 : 2);
796  for (std::vector<reco::MuonChamberMatch>::const_iterator chamber1 = muon1.matches().begin();
797  chamber1 != muon1.matches().end();
798  ++chamber1)
799  for (std::vector<reco::MuonChamberMatch>::const_iterator chamber2 = muon2.matches().begin();
800  chamber2 != muon2.matches().end();
801  ++chamber2) {
802  // if ( (chamber1->segmentMatches.empty() || chamber2->segmentMatches.empty()) ) continue;
803 
804  // handle case where both muons have information about the same chamber
805  // here we know how close they are
806  if (chamber1->id == chamber2->id) {
807  // found the same chamber
808  if (std::abs(chamber1->x - chamber2->x) <
809  pullX * sqrt(chamber1->xErr * chamber1->xErr + chamber2->xErr * chamber2->xErr)) {
810  if (betterMuon == 1)
811  nMatches2--;
812  else
813  nMatches1--;
814  if (nMatches1 == 0 || nMatches2 == 0)
815  return true;
816  continue;
817  }
818  if (std::abs(chamber1->y - chamber2->y) <
819  pullY * sqrt(chamber1->yErr * chamber1->yErr + chamber2->yErr * chamber2->yErr)) {
820  if (betterMuon == 1)
821  nMatches2--;
822  else
823  nMatches1--;
824  if (nMatches1 == 0 || nMatches2 == 0)
825  return true;
826  }
827  } else {
828  if (!checkAdjacentChambers)
829  continue;
830  // check if tracks are pointing into overlaping region of the CSC detector
831  if (chamber1->id.subdetId() != MuonSubdetId::CSC || chamber2->id.subdetId() != MuonSubdetId::CSC)
832  continue;
833  CSCDetId id1(chamber1->id);
834  CSCDetId id2(chamber2->id);
835  if (id1.endcap() != id2.endcap())
836  continue;
837  if (id1.station() != id2.station())
838  continue;
839  if (id1.ring() != id2.ring())
840  continue;
841  if (std::abs(id1.chamber() - id2.chamber()) > 1)
842  continue;
843  // FIXME: we don't handle 18->1; 36->1 transitions since
844  // I don't know how to check for sure how many chambers
845  // are there. Probably need to hard code some checks.
846 
847  // Now we have to make sure that both tracks are close to an edge
848  // FIXME: ignored Y coordinate for now
849  if (std::abs(chamber1->edgeX) > chamber1->xErr * pullX)
850  continue;
851  if (std::abs(chamber2->edgeX) > chamber2->xErr * pullX)
852  continue;
853  if (chamber1->x * chamber2->x < 0) { // check if the same edge
854  if (betterMuon == 1)
855  nMatches2--;
856  else
857  nMatches1--;
858  if (nMatches1 == 0 || nMatches2 == 0)
859  return true;
860  }
861  }
862  }
863  return false;
864 }
double pt() const final
transverse momentum
T sqrt(T t)
Definition: SSEVec.h:19
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int numberOfMatches(ArbitrationType type=SegmentAndTrackArbitration) const
get number of chambers with matched segments
std::vector< MuonChamberMatch > & matches()
get muon matching information
Definition: Muon.h:145
static constexpr int CSC
Definition: MuonSubdetId.h:12

◆ RequiredStationMask()

unsigned int muon::RequiredStationMask ( const reco::Muon muon,
double  maxChamberDist,
double  maxChamberDistPull,
reco::Muon::ArbitrationType  arbitrationType 
)

Definition at line 40 of file MuonSelectors.cc.

References arbitrationType.

Referenced by isGoodMuon().

43  {
44  unsigned int theMask = 0;
45 
46  for (int stationIdx = 1; stationIdx < 5; ++stationIdx) {
47  for (int detectorIdx = 1; detectorIdx < 3; ++detectorIdx) {
48  float dist = muon.trackDist(stationIdx, detectorIdx, arbitrationType);
49  if (dist < maxChamberDist &&
50  dist < maxChamberDistPull * muon.trackDistErr(stationIdx, detectorIdx, arbitrationType))
51  theMask += 1 << ((stationIdx - 1) + 4 * (detectorIdx - 1));
52  }
53  }
54  return theMask;
55 }
const reco::Muon::ArbitrationType arbitrationType

◆ segmentCompatibility()

float muon::segmentCompatibility ( const reco::Muon muon,
reco::Muon::ArbitrationType  arbitrationType = reco::Muon::SegmentAndTrackArbitration 
)

Definition at line 61 of file MuonSelectors.cc.

References arbitrationType, f, mps_fire::i, and funct::pow().

Referenced by ExampleMuonAnalyzer::analyze(), HiggsDQM::analyze(), MuonIdVal::analyze(), StudyTriggerHLT::analyze(), HcalHBHEMuonAnalyzer::analyze(), StudyCaloResponse::analyze(), HcalHBHEMuonHighEtaAnalyzer::analyzeMuon(), MuonCosmicCompatibilityFiller::checkMuonSegments(), PFRecoTauDiscriminationAgainstMuon::discriminate(), BadParticleFilter::filter(), isMediumMuonCustom(), pat::MuonSelector::muIdSelection_(), HcalIsoTrkAnalyzer::notaMuon(), AlCaHcalIsotrkProducer::notaMuon(), MuonSegmentCompatibilityCut::operator()(), AlCaHcalHBHEMuonProducer::produce(), and MuonSegmentCompatibilityCut::value().

61  {
62  bool use_weight_regain_at_chamber_boundary = true;
63  bool use_match_dist_penalty = true;
64 
65  int nr_of_stations_crossed = 0;
66  int nr_of_stations_with_segment = 0;
67  std::vector<int> stations_w_track(8);
68  std::vector<int> station_has_segmentmatch(8);
69  std::vector<int> station_was_crossed(8);
70  std::vector<float> stations_w_track_at_boundary(8);
71  std::vector<float> station_weight(8);
72  int position_in_stations = 0;
73  float full_weight = 0.;
74 
75  for (int i = 1; i <= 8; ++i) {
76  // ********************************************************;
77  // *** fill local info for this muon (do some counting) ***;
78  // ************** begin ***********************************;
79  if (i <= 4) { // this is the section for the DTs
80  float thisTrackDist = muon.trackDist(i, 1, arbitrationType);
81  if (thisTrackDist < 999999) { //current "raw" info that a track is close to a chamber
82  ++nr_of_stations_crossed;
83  station_was_crossed[i - 1] = 1;
84  if (thisTrackDist > -10.)
85  stations_w_track_at_boundary[i - 1] = thisTrackDist;
86  else
87  stations_w_track_at_boundary[i - 1] = 0.;
88  }
89  //current "raw" info that a segment is matched to the current track
90  if (muon.segmentX(i, 1, arbitrationType) < 999999) {
91  ++nr_of_stations_with_segment;
92  station_has_segmentmatch[i - 1] = 1;
93  }
94  } else { // this is the section for the CSCs
95  float thisTrackDist = muon.trackDist(i - 4, 2, arbitrationType);
96  if (thisTrackDist < 999999) { //current "raw" info that a track is close to a chamber
97  ++nr_of_stations_crossed;
98  station_was_crossed[i - 1] = 1;
99  if (thisTrackDist > -10.)
100  stations_w_track_at_boundary[i - 1] = thisTrackDist;
101  else
102  stations_w_track_at_boundary[i - 1] = 0.;
103  }
104  //current "raw" info that a segment is matched to the current track
105  if (muon.segmentX(i - 4, 2, arbitrationType) < 999999) {
106  ++nr_of_stations_with_segment;
107  station_has_segmentmatch[i - 1] = 1;
108  }
109  }
110  // rough estimation of chamber border efficiency (should be parametrized better, this is just a quick guess):
111  // TF1 * merf = new TF1("merf","-0.5*(TMath::Erf(x/6.)-1)",-100,100);
112  // use above value to "unpunish" missing segment if close to border, i.e. rather than not adding any weight, add
113  // the one from the function. Only for dist ~> -10 cm, else full punish!.
114 
115  // ********************************************************;
116  // *** fill local info for this muon (do some counting) ***;
117  // ************** end *************************************;
118  }
119 
120  // ********************************************************;
121  // *** calculate weights for each station *****************;
122  // ************** begin ***********************************;
123  // const float slope = 0.5;
124  // const float attenuate_weight_regain = 1.;
125  // if attenuate_weight_regain < 1., additional punishment if track is close to boundary and no segment
126  const float attenuate_weight_regain = 0.5;
127 
128  for (int i = 1; i <= 8; ++i) { // loop over all possible stations
129 
130  // first set all weights if a station has been crossed
131  // later penalize if a station did not have a matching segment
132 
133  //old logic if(station_has_segmentmatch[i-1] > 0 ) { // the track has an associated segment at the current station
134  if (station_was_crossed[i - 1] > 0) { // the track crossed this chamber (or was nearby)
135  // - Apply a weight depending on the "depth" of the muon passage.
136  // - The station_weight is later reduced for stations with badly matched segments.
137  // - Even if there is no segment but the track passes close to a chamber boundary, the
138  // weight is set non zero and can go up to 0.5 of the full weight if the track is quite
139  // far from any station.
140  ++position_in_stations;
141 
142  switch (nr_of_stations_crossed) { // define different weights depending on how many stations were crossed
143  case 1:
144  station_weight[i - 1] = 1.f;
145  break;
146  case 2:
147  if (position_in_stations == 1)
148  station_weight[i - 1] = 0.33f;
149  else
150  station_weight[i - 1] = 0.67f;
151  break;
152  case 3:
153  if (position_in_stations == 1)
154  station_weight[i - 1] = 0.23f;
155  else if (position_in_stations == 2)
156  station_weight[i - 1] = 0.33f;
157  else
158  station_weight[i - 1] = 0.44f;
159  break;
160  case 4:
161  if (position_in_stations == 1)
162  station_weight[i - 1] = 0.10f;
163  else if (position_in_stations == 2)
164  station_weight[i - 1] = 0.20f;
165  else if (position_in_stations == 3)
166  station_weight[i - 1] = 0.30f;
167  else
168  station_weight[i - 1] = 0.40f;
169  break;
170 
171  default:
172  // LogTrace("MuonIdentification")<<" // Message: A muon candidate track has more than 4 stations with matching segments.";
173  // LogTrace("MuonIdentification")<<" // Did not expect this - please let me know: ibloch@fnal.gov";
174  // for all other cases
175  station_weight[i - 1] = 1.f / nr_of_stations_crossed;
176  }
177 
178  if (use_weight_regain_at_chamber_boundary) { // reconstitute some weight if there is no match but the segment is close to a boundary:
179  if (station_has_segmentmatch[i - 1] <= 0 && stations_w_track_at_boundary[i - 1] != 0.) {
180  // if segment is not present but track in inefficient region, do not count as "missing match" but add some reduced weight.
181  // original "match weight" is currently reduced by at least attenuate_weight_regain, variing with an error function down to 0 if the track is
182  // inside the chamber.
183  // remark: the additional scale of 0.5 normalizes Err to run from 0 to 1 in y
184  station_weight[i - 1] = station_weight[i - 1] * attenuate_weight_regain * 0.5f *
185  (std::erf(stations_w_track_at_boundary[i - 1] / 6.f) + 1.f);
186  } else if (station_has_segmentmatch[i - 1] <= 0 &&
187  stations_w_track_at_boundary[i - 1] == 0.f) { // no segment match and track well inside chamber
188  // full penalization
189  station_weight[i - 1] = 0.f;
190  }
191  } else { // always fully penalize tracks with no matching segment, whether the segment is close to the boundary or not.
192  if (station_has_segmentmatch[i - 1] <= 0)
193  station_weight[i - 1] = 0.f;
194  }
195 
196  // if track has matching segment, but the matching is not high quality, penalize
197  if (station_has_segmentmatch[i - 1] > 0) {
198  if (i <= 4) { // we are in the DTs
199  if (muon.dY(i, 1, arbitrationType) < 999999.f &&
200  muon.dX(i, 1, arbitrationType) < 999999.f) { // have both X and Y match
201  const float pullTot2 =
202  std::pow(muon.pullX(i, 1, arbitrationType), 2.) + std::pow(muon.pullY(i, 1, arbitrationType), 2.);
203  if (pullTot2 > 1.f) {
204  const float dxy2 =
205  std::pow(muon.dX(i, 1, arbitrationType), 2.) + std::pow(muon.dY(i, 1, arbitrationType), 2.);
206  // reduce weight
207  if (use_match_dist_penalty) {
208  // only use pull if 3 sigma is not smaller than 3 cm
209  if (dxy2 < 9.f && pullTot2 > 9.f) {
210  if (dxy2 > 1.f)
211  station_weight[i - 1] *= 1.f / std::pow(dxy2, .125);
212  } else {
213  station_weight[i - 1] *= 1.f / std::pow(pullTot2, .125);
214  }
215  }
216  }
217  } else if (muon.dY(i, 1, arbitrationType) >= 999999.f) { // has no match in Y
218  // has a match in X. Pull larger that 1 to avoid increasing the weight (just penalize, don't anti-penalize)
219  if (muon.pullX(i, 1, arbitrationType) > 1.f) {
220  // reduce weight
221  if (use_match_dist_penalty) {
222  // only use pull if 3 sigma is not smaller than 3 cm
223  if (muon.dX(i, 1, arbitrationType) < 3.f && muon.pullX(i, 1, arbitrationType) > 3.f) {
224  if (muon.dX(i, 1, arbitrationType) > 1.f)
225  station_weight[i - 1] *= 1.f / std::pow(muon.dX(i, 1, arbitrationType), .25);
226  } else {
227  station_weight[i - 1] *= 1.f / std::pow(muon.pullX(i, 1, arbitrationType), .25);
228  }
229  }
230  }
231  } else { // has no match in X
232  // has a match in Y. Pull larger that 1 to avoid increasing the weight (just penalize, don't anti-penalize)
233  if (muon.pullY(i, 1, arbitrationType) > 1.f) {
234  // reduce weight
235  if (use_match_dist_penalty) {
236  // only use pull if 3 sigma is not smaller than 3 cm
237  if (muon.dY(i, 1, arbitrationType) < 3. && muon.pullY(i, 1, arbitrationType) > 3.) {
238  if (muon.dY(i, 1, arbitrationType) > 1.f)
239  station_weight[i - 1] *= 1.f / std::pow(muon.dY(i, 1, arbitrationType), .25);
240  } else {
241  station_weight[i - 1] *= 1.f / std::pow(muon.pullY(i, 1, arbitrationType), .25);
242  }
243  }
244  }
245  }
246  } else { // We are in the CSCs
247  const float pullTot2 =
248  std::pow(muon.pullX(i - 4, 2, arbitrationType), 2.) + std::pow(muon.pullY(i - 4, 2, arbitrationType), 2.);
249  if (pullTot2 > 1.f) {
250  // reduce weight
251  if (use_match_dist_penalty) {
252  const float dxy2 =
253  std::pow(muon.dX(i - 4, 2, arbitrationType), 2.) + std::pow(muon.dY(i - 4, 2, arbitrationType), 2.);
254  // only use pull if 3 sigma is not smaller than 3 cm
255  if (dxy2 < 9.f && pullTot2 > 9.f) {
256  if (dxy2 > 1.f)
257  station_weight[i - 1] *= 1.f / std::pow(dxy2, .125);
258  } else {
259  station_weight[i - 1] *= 1.f / std::pow(pullTot2, .125);
260  }
261  }
262  }
263  }
264  }
265 
266  // Thoughts:
267  // - should penalize if the segment has only x OR y info
268  // - should also use the segment direction, as it now works!
269 
270  } else { // track did not pass a chamber in this station - just reset weight
271  station_weight[i - 1] = 0.f;
272  }
273 
274  //increment final weight for muon:
275  full_weight += station_weight[i - 1];
276  }
277 
278  // if we don't expect any matches, we set the compatibility to
279  // 0.5 as the track is as compatible with a muon as it is with
280  // background - we should maybe rather set it to -0.5!
281  if (nr_of_stations_crossed == 0) {
282  // full_weight = attenuate_weight_regain*0.5;
283  full_weight = 0.5f;
284  }
285 
286  // ********************************************************;
287  // *** calculate weights for each station *****************;
288  // ************** end *************************************;
289 
290  return full_weight;
291 }
double f[11][100]
const reco::Muon::ArbitrationType arbitrationType
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ selectionTypeFromString()

SelectionType muon::selectionTypeFromString ( const std::string &  label)

Definition at line 9 of file MuonSelectors.cc.

References Exception, newFWLiteAna::found, mps_fire::i, label, muon::SelectionTypeStringToEnum::label, selectionTypeStringToEnumMap, relativeConstraints::value, and muon::SelectionTypeStringToEnum::value.

Referenced by MuonSelectionTypeValueMapProducer::MuonSelectionTypeValueMapProducer(), MuonTrackProducer::produce(), and pat::PackedCandidateMuonSelectorProducer::produce().

9  {
11  bool found = false;
12  for (int i = 0; selectionTypeStringToEnumMap[i].label && (!found); ++i)
13  if (!strcmp(label.c_str(), selectionTypeStringToEnumMap[i].label)) {
14  found = true;
16  }
17 
18  // in case of unrecognized selection type
19  if (!found)
20  throw cms::Exception("MuonSelectorError") << label << " is not a recognized SelectionType";
21  return value;
22  }
SelectionType
Selector type.
Definition: MuonSelectors.h:18
char const * label
Definition: value.py:1
static const SelectionTypeStringToEnum selectionTypeStringToEnumMap[]
Definition: MuonSelectors.h:66

◆ selectorFromString()

reco::Muon::Selector muon::selectorFromString ( const std::string &  label)

Definition at line 24 of file MuonSelectors.cc.

References Exception, newFWLiteAna::found, mps_fire::i, label, muon::SelectorStringToEnum::label, selectorStringToEnumMap, relativeConstraints::value, and muon::SelectorStringToEnum::value.

24  {
26  bool found = false;
27  for (int i = 0; selectorStringToEnumMap[i].label && (!found); ++i)
28  if (!strcmp(label.c_str(), selectorStringToEnumMap[i].label)) {
29  found = true;
31  }
32 
33  // in case of unrecognized selection type
34  if (!found)
35  throw cms::Exception("MuonSelectorError") << label << " is not a recognized reco::Muon::Selector";
36  return value;
37  }
reco::Muon::Selector value
char const * label
Definition: value.py:1
static const SelectorStringToEnum selectorStringToEnumMap[]
Selector
Definition: Muon.h:202

◆ sharedSegments()

int muon::sharedSegments ( const reco::Muon muon1,
const reco::Muon muon2,
unsigned int  segmentArbitrationMask = reco::MuonSegmentMatch::BestInChamberByDR 
)

Determine the number of shared segments between two muons. Comparison is done using the segment references in the reco::Muon object.

Definition at line 978 of file MuonSelectors.cc.

References reco::Muon::matches(), amptDefaultParameters_cff::mu, and runTheMatrix::ret.

Referenced by heppy::CMGMuonCleanerBySegmentsAlgo::clean(), BadGlobalMuonTagger::filter(), and modules::MuonCleanerBySegmentsT< T >::produce().

978  {
979  int ret = 0;
980 
981  // Will do with a stupid double loop, since creating and filling a map is probably _more_ inefficient for a single lookup.
982  for (std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch = mu.matches().begin();
983  chamberMatch != mu.matches().end();
984  ++chamberMatch) {
985  if (chamberMatch->segmentMatches.empty())
986  continue;
987  for (std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch2 = mu2.matches().begin();
988  chamberMatch2 != mu2.matches().end();
989  ++chamberMatch2) {
990  if (chamberMatch2->segmentMatches.empty())
991  continue;
992  if (chamberMatch2->id() != chamberMatch->id())
993  continue;
994  for (std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch = chamberMatch->segmentMatches.begin();
995  segmentMatch != chamberMatch->segmentMatches.end();
996  ++segmentMatch) {
997  if (!segmentMatch->isMask(segmentArbitrationMask))
998  continue;
999  for (std::vector<reco::MuonSegmentMatch>::const_iterator segmentMatch2 = chamberMatch2->segmentMatches.begin();
1000  segmentMatch2 != chamberMatch2->segmentMatches.end();
1001  ++segmentMatch2) {
1002  if (!segmentMatch2->isMask(segmentArbitrationMask))
1003  continue;
1004  if ((segmentMatch->cscSegmentRef.isNonnull() &&
1005  segmentMatch->cscSegmentRef == segmentMatch2->cscSegmentRef) ||
1006  (segmentMatch->dtSegmentRef.isNonnull() && segmentMatch->dtSegmentRef == segmentMatch2->dtSegmentRef)) {
1007  ++ret;
1008  } // is the same
1009  } // segment of mu2 in chamber
1010  } // segment of mu1 in chamber
1011  } // chamber of mu2
1012  } // chamber of mu1
1013 
1014  return ret;
1015 }
ret
prodAgent to be discontinued

◆ sigmaSwitch() [1/2]

reco::Muon::MuonTrackTypePair muon::sigmaSwitch ( const reco::TrackRef combinedTrack,
const reco::TrackRef trackerTrack,
const double  nSigma = 2.,
const double  ptThreshold = 200. 
)

Definition at line 139 of file MuonCocktails.cc.

References reco::Muon::CombinedTrack, dumpMFGeometry_cfg::delta, reco::Muon::InnerTrack, HLTSiStripMonitoring_cff::nSigma, ewkMuLumiMonitorDQM_cfi::ptThreshold, and remoteMonitoring_LASER_era2018_cfg::threshold.

Referenced by MuonIdProducer::makeMuon(), and sigmaSwitch().

142  {
143  // If either the global or tracker-only fits have pT below threshold
144  // (default 200 GeV), return the tracker-only fit.
145  if (combinedTrack->pt() < ptThreshold || trackerTrack->pt() < ptThreshold)
146  return make_pair(trackerTrack, reco::Muon::InnerTrack);
147 
148  // If both are above the pT threshold, compare the difference in
149  // q/p: if less than two sigma of the tracker-only track, switch to
150  // global. Otherwise, use tracker-only.
151  const double delta = fabs(trackerTrack->qoverp() - combinedTrack->qoverp());
152  const double threshold = nSigma * trackerTrack->qoverpError();
153  return delta > threshold ? make_pair(trackerTrack, reco::Muon::InnerTrack)
154  : make_pair(combinedTrack, reco::Muon::CombinedTrack);
155 }
Definition: Muon.py:1
fixed size matrix

◆ sigmaSwitch() [2/2]

reco::Muon::MuonTrackTypePair muon::sigmaSwitch ( const reco::Muon muon,
const double  nSigma = 2.,
const double  ptThreshold = 200. 
)
inline

Definition at line 57 of file MuonCocktails.h.

References HLTSiStripMonitoring_cff::nSigma, ewkMuLumiMonitorDQM_cfi::ptThreshold, and sigmaSwitch().

59  {
60  return muon::sigmaSwitch(muon.globalTrack(), muon.innerTrack(), nSigma, ptThreshold);
61  }
reco::Muon::MuonTrackTypePair sigmaSwitch(const reco::TrackRef &combinedTrack, const reco::TrackRef &trackerTrack, const double nSigma=2., const double ptThreshold=200.)

◆ tevOptimized() [1/2]

reco::Muon::MuonTrackTypePair muon::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 at line 9 of file MuonCocktails.cc.

References reco::Muon::CombinedTrack, reco::Muon::DYT, first, mps_fire::i, reco::Muon::InnerTrack, reco::Muon::Picky, TtFullHadEvtBuilder_cfi::prob, ewkMuLumiMonitorDQM_cfi::ptThreshold, reco::Muon::TPFMS, trackProbability(), and validateGeometry_cfg::valid.

Referenced by MuonIdProducer::makeMuon(), MuonsFromRefitTracksProducer::produce(), PFMuonAlgo::reconstructMuon(), and tevOptimized().

17  {
18  const unsigned int nAlgo = 5;
19 
20  // Array for convenience below.
21  const reco::Muon::MuonTrackTypePair refit[nAlgo] = {make_pair(trackerTrack, reco::Muon::InnerTrack),
22  make_pair(combinedTrack, reco::Muon::CombinedTrack),
23  make_pair(tpfmsTrack, reco::Muon::TPFMS),
24  make_pair(pickyTrack, reco::Muon::Picky),
25  make_pair(dytTrack, reco::Muon::DYT)};
26 
27  // Calculate the log(tail probabilities). If there's a problem,
28  // signify this with prob == 0. The current problems recognized are:
29  // the track being not available, whether the (re)fit failed or it's
30  // just not in the event, or if the (re)fit ended up with no valid
31  // hits.
32  double prob[nAlgo] = {0., 0., 0., 0., 0.};
33  bool valid[nAlgo] = {false, false, false, false, false};
34 
35  double dptmin = 1.;
36 
37  if (dptcut > 0) {
38  for (unsigned int i = 0; i < nAlgo; ++i)
39  if (refit[i].first.isNonnull())
40  if (refit[i].first->ptError() / refit[i].first->pt() < dptmin)
41  dptmin = refit[i].first->ptError() / refit[i].first->pt();
42 
43  if (dptmin > dptcut)
44  dptcut = dptmin + 0.15;
45  }
46 
47  for (unsigned int i = 0; i < nAlgo; ++i)
48  if (refit[i].first.isNonnull()) {
49  valid[i] = true;
50  if (refit[i].first->numberOfValidHits() &&
51  (refit[i].first->ptError() / refit[i].first->pt() < dptcut || dptcut < 0))
52  prob[i] = muon::trackProbability(refit[i].first);
53  }
54 
55  // Start with picky.
56  int chosen = 3;
57 
58  // If there's a problem with picky, make the default one of the
59  // other tracks. Try TPFMS first, then global, then tracker-only.
60  if (prob[3] == 0.) {
61  // split so that passing dptcut<0 recreates EXACTLY the old tuneP behavior
62  if (dptcut > 0) {
63  if (prob[4] > 0.)
64  chosen = 4;
65  else if (prob[0] > 0.)
66  chosen = 0;
67  else if (prob[2] > 0.)
68  chosen = 2;
69  else if (prob[1] > 0.)
70  chosen = 1;
71  } else {
72  if (prob[2] > 0.)
73  chosen = 2;
74  else if (prob[1] > 0.)
75  chosen = 1;
76  else if (prob[0] > 0.)
77  chosen = 0;
78  }
79  }
80 
81  // Now the algorithm: switch from picky to dyt if the difference is lower than a tuned value. Then
82  // switch from picky to tracker-only if the
83  // difference, log(tail prob(picky)) - log(tail prob(tracker-only))
84  // is greater than a tuned value. Then compare the
85  // so-picked track to TPFMS in the same manner using another tuned
86  // value.
87  if (prob[4] > 0. && prob[3] > 0.) {
88  if (refit[3].first->pt() > 0 && refit[4].first->pt() > 0 &&
89  (refit[4].first->ptError() / refit[4].first->pt() - refit[3].first->ptError() / refit[3].first->pt()) <= 0)
90  chosen = 4; // dyt
91  }
92 
93  if (prob[0] > 0. && prob[chosen] > 0. && (prob[chosen] - prob[0]) > tune1)
94  chosen = 0;
95  if (prob[2] > 0. && (prob[chosen] - prob[2]) > tune2)
96  chosen = 2;
97 
98  // Sanity checks
99  if (chosen == 4 && !valid[4])
100  chosen = 3;
101  if (chosen == 3 && !valid[3])
102  chosen = 2;
103  if (chosen == 2 && !valid[2])
104  chosen = 1;
105  if (chosen == 1 && !valid[1])
106  chosen = 0;
107 
108  // Done. If pT of the chosen track (or pT of the tracker track) is below the threshold value, return the tracker track.
109  if (valid[chosen] && refit[chosen].first->pt() < ptThreshold && prob[0] > 0.)
110  return make_pair(trackerTrack, reco::Muon::InnerTrack);
111  if (trackerTrack->pt() < ptThreshold && prob[0] > 0.)
112  return make_pair(trackerTrack, reco::Muon::InnerTrack);
113 
114  // Return the chosen track (which can be the global track in
115  // very rare cases).
116  return refit[chosen];
117 }
double trackProbability(const reco::TrackRef track)
std::pair< TrackRef, Muon::MuonTrackType > MuonTrackTypePair
Definition: Muon.h:38

◆ tevOptimized() [2/2]

reco::Muon::MuonTrackTypePair muon::tevOptimized ( const reco::Muon muon,
const double  ptThreshold = 200.,
const double  tune1 = 17.,
const double  tune2 = 40.,
const double  dptcut = 0.25 
)
inline

Definition at line 31 of file MuonCocktails.h.

References ewkMuLumiMonitorDQM_cfi::ptThreshold, and tevOptimized().

35  {
36  return tevOptimized(muon.globalTrack(),
37  muon.innerTrack(),
38  muon.tpfmsTrack(),
39  muon.pickyTrack(),
40  muon.dytTrack(),
42  tune1,
43  tune2,
44  dptcut);
45  }
reco::Muon::MuonTrackTypePair tevOptimized(const reco::Muon &muon, const double ptThreshold=200., const double tune1=17., const double tune2=40., const double dptcut=0.25)
Definition: MuonCocktails.h:31

◆ TMR()

reco::Muon::MuonTrackTypePair muon::TMR ( const reco::TrackRef trackerTrack,
const reco::TrackRef fmsTrack,
const double  tune = 4. 
)

Definition at line 160 of file MuonCocktails.cc.

References reco::Muon::InnerTrack, edm::Ref< C, T, F >::isNonnull(), reco::Muon::None, reco::Muon::TPFMS, and trackProbability().

162  {
163  double probTK = 0;
164  double probFMS = 0;
165 
166  if (trackerTrack.isNonnull() && trackerTrack->numberOfValidHits())
167  probTK = muon::trackProbability(trackerTrack);
168  if (fmsTrack.isNonnull() && fmsTrack->numberOfValidHits())
169  probFMS = muon::trackProbability(fmsTrack);
170 
171  bool TKok = probTK > 0;
172  bool FMSok = probFMS > 0;
173 
174  if (TKok && FMSok) {
175  if (probFMS - probTK > tune)
176  return make_pair(trackerTrack, reco::Muon::InnerTrack);
177  else
178  return make_pair(fmsTrack, reco::Muon::TPFMS);
179  } else if (FMSok)
180  return make_pair(fmsTrack, reco::Muon::TPFMS);
181  else if (TKok)
182  return make_pair(trackerTrack, reco::Muon::InnerTrack);
183  else
184  return make_pair(reco::TrackRef(), reco::Muon::None);
185 }
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
double trackProbability(const reco::TrackRef track)

◆ trackProbability()

double muon::trackProbability ( const reco::TrackRef  track)

Definition at line 122 of file MuonCocktails.cc.

References createfilelist::int, dqm-mbProfile::log, and HLT_2022v15_cff::track.

Referenced by HistogramProbabilityEstimator::probability(), tevOptimized(), tevOptimizedTMR(), and TMR().

122  {
123  int nDOF = (int)track->ndof();
124  if (nDOF > 0 && track->chi2() > 0) {
125  return -log(TMath::Prob(track->chi2(), nDOF));
126  } else {
127  return 0.0;
128  }
129 }

Variable Documentation

◆ selectionTypeStringToEnumMap

const SelectionTypeStringToEnum muon::selectionTypeStringToEnumMap[]
static

Definition at line 66 of file MuonSelectors.h.

Referenced by selectionTypeFromString().

◆ selectorStringToEnumMap

const SelectorStringToEnum muon::selectorStringToEnumMap[]
static

Definition at line 107 of file MuonSelectors.h.

Referenced by selectorFromString().