Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:26:45

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) # make it a python list
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); # bad but we don't care
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); # maybe good, maybe bad, but we don't care
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; # unless proven otherwise
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