File indexing completed on 2023-03-17 11:20:10
0001 from builtins import range
0002 import ROOT
0003 ROOT.gInterpreter.ProcessLine("#include <DataFormats/MuonReco/interface/MuonSelectors.h>")
0004
0005 from PhysicsTools.HeppyCore.utils.deltar import deltaR
0006
0007
0008 class BadGlobalMuonTagger:
0009 def __init__(self,selectClones,muonPtCut):
0010 self.selectClones_ = selectClones
0011 self.ptCut_ = muonPtCut
0012
0013 def outInOnly(self,mu):
0014 tk = mu.innerTrack().get();
0015 return tk.algoMask().count() == 1 and tk.isAlgoInMask(tk.muonSeededStepOutIn);
0016 def preselection(self, mu):
0017 return (not(self.selectClones_) or self.outInOnly(mu));
0018 def tighterId(self, mu):
0019 return mu.isMediumMuon() and mu.numberOfMatchedStations() >= 2;
0020 def tightGlobal(self, mu):
0021 return mu.isGlobalMuon() and (mu.globalTrack().hitPattern().muonStationsWithValidHits() >= 3 and mu.globalTrack().normalizedChi2() <= 20);
0022 def safeId(self, mu):
0023 if (mu.muonBestTrack().ptError() > 0.2 * mu.muonBestTrack().pt()): return False;
0024 return mu.numberOfMatchedStations() >= 1 or self.tightGlobal(mu);
0025 def partnerId(self, mu):
0026 return mu.pt() >= 10 and mu.numberOfMatchedStations() >= 1;
0027
0028 def badMuons(self, allmuons, allvertices):
0029 """Returns the list of bad muons in an event"""
0030
0031 muons = list(m for m in allmuons)
0032 goodMuon = []
0033
0034 if len(allvertices) < 1: raise RuntimeError
0035 PV = allvertices[0].position()
0036
0037 out = []
0038 for mu in muons:
0039 if (not(mu.isPFMuon()) or mu.innerTrack().isNull()):
0040 goodMuon.append(-1);
0041 continue;
0042 if (self.preselection(mu)):
0043 dxypv = abs(mu.innerTrack().dxy(PV));
0044 dzpv = abs(mu.innerTrack().dz(PV));
0045 if (self.tighterId(mu)):
0046 ipLoose = ((dxypv < 0.5 and dzpv < 2.0) or mu.innerTrack().hitPattern().pixelLayersWithMeasurement() >= 2);
0047 goodMuon.append(ipLoose or (not(self.selectClones_) and self.tightGlobal(mu)));
0048 elif (self.safeId(mu)):
0049 ipTight = (dxypv < 0.2 and dzpv < 0.5);
0050 goodMuon.append(ipTight);
0051 else:
0052 goodMuon.append(0);
0053 else:
0054 goodMuon.append(3);
0055
0056 n = len(muons)
0057 for i in range(n):
0058 if (muons[i].pt() < self.ptCut_ or goodMuon[i] != 0): continue;
0059 bad = True;
0060 if (self.selectClones_):
0061 bad = False;
0062 n1 = muons[i].numberOfMatches(ROOT.reco.Muon.SegmentArbitration);
0063 for j in range(n):
0064 if (j == i or goodMuon[j] <= 0 or not(self.partnerId(muons[j]))): continue
0065 n2 = muons[j].numberOfMatches(ROOT.reco.Muon.SegmentArbitration);
0066 if (deltaR(muons[i],muons[j]) < 0.4 or (n1 > 0 and n2 > 0 and ROOT.muon.sharedSegments(muons[i],muons[j]) >= 0.5*min(n1,n2))):
0067 bad = True;
0068 break;
0069 if (bad):
0070 out.append(muons[i]);
0071 return out
0072