Skip to content

Commit

Permalink
Merge pull request cms-sw#74 from cbernet/heppy_7_4_5
Browse files Browse the repository at this point in the history
Heppy 745 from colin side
  • Loading branch information
arizzi committed Jun 23, 2015
2 parents 37fcb8e + 569d01b commit 584ffeb
Show file tree
Hide file tree
Showing 37 changed files with 1,973 additions and 366 deletions.
16 changes: 9 additions & 7 deletions PhysicsTools/Heppy/python/analyzers/core/AutoHandle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@ class AutoHandle( Handle, object ):

handles = {}

def __init__(self, label, type, mayFail=False, fallbackLabel=None):
def __init__(self, label, type, mayFail=False, fallbackLabel=None, lazy=True):
'''Note: label can be a tuple : (module_label, collection_label, process)'''
self.label = label
self.fallbackLabel = fallbackLabel
self.type = type
self.mayFail = mayFail
self.lazy = lazy
Handle.__init__(self, self.type)
def product(self):
if not self.isLoaded :
self.ReallyLoad(self.event)
self.isLoaded=True
return super(AutoHandle,self).product()
if not self.isLoaded :
self.ReallyLoad(self.event)
self.isLoaded=True
return super(AutoHandle,self).product()

def Load(self, event): #is actually a reset state
self.event=event
self.isLoaded=False
self.event=event
self.isLoaded=False
if self.lazy==False: self.ReallyLoad(self.event)

def ReallyLoad(self, event):
'''Load self from a given event.
Expand Down
15 changes: 15 additions & 0 deletions PhysicsTools/Heppy/python/analyzers/gen/GeneratorAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ class GeneratorAnalyzer( Analyzer ):
event.genwzquarks and event.genbquarks, might have overlaps
event.genbquarksFromTop and event.genbquarksFromH are all contained in event.genbquarks
In addition to genParticles, if makeLHEweights is set to True, the list WeightsInfo objects of the LHE branch
is stored in event.LHE_weights
"""

def __init__(self, cfg_ana, cfg_comp, looperName ):
Expand All @@ -54,10 +57,13 @@ def __init__(self, cfg_ana, cfg_comp, looperName ):
self.makeAllGenParticles = cfg_ana.makeAllGenParticles
self.makeSplittedGenLists = cfg_ana.makeSplittedGenLists
self.allGenTaus = cfg_ana.allGenTaus if self.makeSplittedGenLists else False
self.makeLHEweights = cfg_ana.makeLHEweights

def declareHandles(self):
super(GeneratorAnalyzer, self).declareHandles()
self.mchandles['genParticles'] = AutoHandle( 'prunedGenParticles', 'std::vector<reco::GenParticle>' )
if self.makeLHEweights:
self.mchandles['LHEweights'] = AutoHandle( 'source', 'LHEEventProduct', mayFail = True, lazy = False )

def beginLoop(self,setup):
super(GeneratorAnalyzer,self).beginLoop(setup)
Expand Down Expand Up @@ -239,6 +245,13 @@ def makeMCInfo(self, event):
if id <= 5 and any([abs(m.pdgId()) in {23,24} for m in realGenMothers(p)]):
event.genwzquarks.append(p)

#Add LHE weight info
event.LHE_weights = []
if self.makeLHEweights:
if self.mchandles['LHEweights'].isValid():
for w in self.mchandles['LHEweights'].product().weights():
event.LHE_weights.append(w)

def process(self, event):
self.readCollections( event.input )

Expand All @@ -263,6 +276,8 @@ def process(self, event):
# Make also the splitted lists
makeSplittedGenLists = True,
allGenTaus = False,
# Save LHE weights in LHEEventProduct
makeLHEweights = True,
# Print out debug information
verbose = False,
)
Expand Down
12 changes: 10 additions & 2 deletions PhysicsTools/Heppy/python/analyzers/objects/LeptonAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ def makeAllElectrons(self, event):
ele.tightIdResult = ele.electronID("POG_MVA_ID_Trig_full5x5")
elif self.cfg_ana.ele_tightId=="Cuts_2012" :
ele.tightIdResult = -1 + 1*ele.electronID("POG_Cuts_ID_2012_Veto_full5x5") + 1*ele.electronID("POG_Cuts_ID_2012_Loose_full5x5") + 1*ele.electronID("POG_Cuts_ID_2012_Medium_full5x5") + 1*ele.electronID("POG_Cuts_ID_2012_Tight_full5x5")
elif self.cfg_ana.ele_tightId=="Cuts_PHYS14_25ns_v1_ConvVetoDxyDz" :
ele.tightIdResult = -1 + 1*ele.electronID("POG_Cuts_ID_PHYS14_25ns_v1_ConvVetoDxyDz_Veto_full5x5") + 1*ele.electronID("POG_Cuts_ID_PHYS14_25ns_v1_ConvVetoDxyDz_Loose_full5x5") + 1*ele.electronID("POG_Cuts_ID_PHYS14_25ns_v1_ConvVetoDxyDz_Medium_full5x5") + 1*ele.electronID("POG_Cuts_ID_PHYS14_25ns_v1_ConvVetoDxyDz_Tight_full5x5")

else :
try:
ele.tightIdResult = ele.electronID(self.cfg_ana.ele_tightId)
Expand All @@ -349,7 +352,10 @@ def attachMiniIsolation(self, mu):
# -- version with increasing cone at low pT, gives slightly better performance for tight cuts and low pt leptons
# mu.miniIsoR = 10.0/min(max(mu.pt(), 50),200) if mu.pt() > 20 else 4.0/min(max(mu.pt(),10),20)
what = "mu" if (abs(mu.pdgId()) == 13) else ("eleB" if mu.isEB() else "eleE")
mu.miniAbsIsoCharged = self.IsolationComputer.chargedAbsIso(mu.physObj, mu.miniIsoR, {"mu":0.0001,"eleB":0,"eleE":0.015}[what], 0.0);
if what == "mu":
mu.miniAbsIsoCharged = self.IsolationComputer.chargedAbsIso(mu.physObj, mu.miniIsoR, {"mu":0.0001,"eleB":0,"eleE":0.015}[what], 0.0);
else:
mu.miniAbsIsoCharged = self.IsolationComputer.chargedAbsIso(mu.physObj, mu.miniIsoR, {"mu":0.0001,"eleB":0,"eleE":0.015}[what], 0.0,self.IsolationComputer.selfVetoNone);
if self.miniIsolationPUCorr == "weights":
if what == "mu":
mu.miniAbsIsoNeutral = self.IsolationComputer.neutralAbsIsoWeighted(mu.physObj, mu.miniIsoR, 0.01, 0.5);
Expand All @@ -373,7 +379,7 @@ def attachMiniIsolation(self, mu):
if what == "mu":
mu.miniAbsIsoPU = self.IsolationComputer.puAbsIso(mu.physObj, mu.miniIsoR, 0.01, 0.5);
else:
mu.miniAbsIsoPU = self.IsolationComputer.puAbsIso(mu.physObj, mu.miniIsoR, 0.015 if what == "eleE" else 0.0, 0.0);
mu.miniAbsIsoPU = self.IsolationComputer.puAbsIso(mu.physObj, mu.miniIsoR, 0.015 if what == "eleE" else 0.0, 0.0,self.IsolationComputer.selfVetoNone);
mu.miniAbsIsoNeutral = max(0.0, mu.miniAbsIsoNeutral - 0.5*mu.miniAbsIsoPU)
elif self.miniIsolationPUCorr != 'raw':
raise RuntimeError, "Unsupported miniIsolationCorr name '" + str(self.cfg_ana.miniIsolationCorr) + "'! For now only 'rhoArea', 'deltaBeta', 'raw', 'weights' are supported (and 'weights' is not tested)."
Expand Down Expand Up @@ -473,6 +479,7 @@ def process(self, event):
loose_muon_dxy = 0.05,
loose_muon_dz = 0.2,
loose_muon_relIso = 0.4,
# loose_muon_isoCut = lambda muon :muon.miniRelIso < 0.2
# inclusive very loose electron selection
inclusive_electron_id = "",
inclusive_electron_pt = 5,
Expand All @@ -487,6 +494,7 @@ def process(self, event):
loose_electron_dxy = 0.05,
loose_electron_dz = 0.2,
loose_electron_relIso = 0.4,
# loose_electron_isoCut = lambda electron : electron.miniRelIso < 0.1
loose_electron_lostHits = 1.0,
# muon isolation correction method (can be "rhoArea" or "deltaBeta")
mu_isoCorr = "rhoArea" ,
Expand Down
20 changes: 13 additions & 7 deletions PhysicsTools/Heppy/python/analyzers/objects/autophobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
NTupleVariable("pdgId", lambda x : x.pdgId(), int),
])

weightsInfoType = NTupleObjectType("WeightsInfo", variables = [
NTupleVariable("id", lambda x : x.id, int),
NTupleVariable("wgt", lambda x : x.wgt),
])

##------------------------------------------
## LEPTON
##------------------------------------------
Expand All @@ -53,13 +58,15 @@
# Isolations with the two radia
NTupleVariable("relIso03", lambda x : x.relIso03, help="PF Rel Iso, R=0.3, pile-up corrected"),
NTupleVariable("relIso04", lambda x : x.relIso04, help="PF Rel Iso, R=0.4, pile-up corrected"),
NTupleVariable("miniRelIso", lambda x : x.miniRelIso if hasattr(x,'miniRelIso') else -999, help="PF Rel miniRel, pile-up corrected"),
# Charge flip rejection criteria
NTupleVariable("tightCharge", lambda lepton : ( lepton.isGsfCtfScPixChargeConsistent() + lepton.isGsfScPixChargeConsistent() ) if abs(lepton.pdgId()) == 11 else 2*(lepton.innerTrack().ptError()/lepton.innerTrack().pt() < 0.2), int, help="Tight charge criteria: for electrons, 2 if isGsfCtfScPixChargeConsistent, 1 if only isGsfScPixChargeConsistent, 0 otherwise; for muons, 2 if ptError/pt < 0.20, 0 otherwise "),
# MC-match info
NTupleVariable("mcMatchId", lambda x : x.mcMatchId, int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
NTupleVariable("mcMatchId", lambda x : getattr(x, 'mcMatchId', -99), int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
NTupleVariable("mcMatchAny", lambda x : x.mcMatchAny, int, mcOnly=True, help="Match to any final state leptons: 0 if unmatched, 1 if light flavour (including prompt), 4 if charm, 5 if bottom"),
NTupleVariable("mcMatchTau", lambda x : x.mcMatchTau, int, mcOnly=True, help="True if the leptons comes from a tau"),
NTupleVariable("mcPt", lambda x : x.mcLep.pt() if getattr(x,"mcLep",None) else 0., mcOnly=True, help="p_{T} of associated gen lepton"),
NTupleVariable("mediumMuonId", lambda x : x.muonID("POG_ID_Medium") if abs(x.pdgId())==13 else 1, int, help="Muon POG Medium id"),
])

### EXTENDED VERSION WITH INDIVIUAL DISCRIMINATING VARIABLES
Expand All @@ -70,7 +77,6 @@
# Extra muon ID working points
NTupleVariable("softMuonId", lambda x : x.muonID("POG_ID_Soft") if abs(x.pdgId())==13 else 1, int, help="Muon POG Soft id"),
NTupleVariable("pfMuonId", lambda x : x.muonID("POG_ID_Loose") if abs(x.pdgId())==13 else 1, int, help="Muon POG Loose id"),
NTupleVariable("mediumMuonId", lambda x : x.muonID("POG_ID_Medium") if abs(x.pdgId())==13 else 1, int, help="Muon POG Medium id"),
# Extra electron ID working points
NTupleVariable("eleCutId2012_full5x5", lambda x : (1*x.electronID("POG_Cuts_ID_2012_full5x5_Veto") + 1*x.electronID("POG_Cuts_ID_2012_full5x5_Loose") + 1*x.electronID("POG_Cuts_ID_2012_full5x5_Medium") + 1*x.electronID("POG_Cuts_ID_2012_full5x5_Tight")) if abs(x.pdgId()) == 11 else -1, int, help="Electron cut-based id (POG 2012, full5x5 shapes): 0=none, 1=veto, 2=loose, 3=medium, 4=tight"),
# Extra tracker-related variables
Expand Down Expand Up @@ -117,7 +123,7 @@
NTupleVariable("idAntiE", lambda x : x.idAntiE, int, help="1,2,3,4,5 if the tau passes the v loose, loose, medium, tight, v tight WP of the againstElectron<X>MVA5 discriminator"),
NTupleVariable("isoCI3hit", lambda x : x.tauID("byCombinedIsolationDeltaBetaCorrRaw3Hits"), help="byCombinedIsolationDeltaBetaCorrRaw3Hits raw output discriminator"),
# MC-match info
NTupleVariable("mcMatchId", lambda x : x.mcMatchId, int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
NTupleVariable("mcMatchId", lambda x : getattr(x, 'mcMatchId', -99), int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
])

##------------------------------------------
Expand All @@ -128,7 +134,7 @@
NTupleVariable("charge", lambda x : x.charge(), int),
NTupleVariable("dz", lambda x : x.dz() , help="d_{z} of lead track with respect to PV, in cm (with sign)"),
NTupleVariable("absIso", lambda x : x.absIso, float, mcOnly=False, help="abs charged iso with condition for isolation such that Min(0.2*pt, 8 GeV)"),
NTupleVariable("mcMatchId", lambda x : x.mcMatchId, int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
NTupleVariable("mcMatchId", lambda x : getattr(x, 'mcMatchId', -99), int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
])


Expand All @@ -148,7 +154,7 @@
NTupleVariable("chHadIso04", lambda x : x.chargedHadronIso(), float, help="chargedHadronIsolation for photons (PAT method, deltaR = 0.4)"),
NTupleVariable("neuHadIso", lambda x : x.recoNeutralHadronIso(), float, help="neutralHadronIsolation for photons"),
NTupleVariable("phIso", lambda x : x.recoPhotonIso(), float, help="gammaIsolation for photons"),
NTupleVariable("mcMatchId", lambda x : x.mcMatchId, int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
NTupleVariable("mcMatchId", lambda x : getattr(x, 'mcMatchId', -99), int, mcOnly=True, help="Match to source from hard scatter (pdgId of heaviest particle in chain, 25 for H, 6 for t, 23/24 for W/Z), zero if non-prompt or fake"),
NTupleVariable("mcPt", lambda x : x.mcGamma.pt() if getattr(x,"mcGamma",None) else 0., mcOnly=True, help="p_{T} of associated gen photon"),
])

Expand All @@ -159,8 +165,8 @@
jetType = NTupleObjectType("jet", baseObjectTypes = [ fourVectorType ], variables = [
NTupleVariable("id", lambda x : x.jetID("POG_PFID") , int, mcOnly=False,help="POG Loose jet ID"),
NTupleVariable("puId", lambda x : getattr(x, 'puJetIdPassed', -99), int, mcOnly=False, help="puId (full MVA, loose WP, 5.3.X training on AK5PFchs: the only thing that is available now)"),
NTupleVariable("btagCSV", lambda x : x.btag('combinedInclusiveSecondaryVertexV2BJetTags'), help="CSV-IVF v2 discriminator"),
NTupleVariable("btagCMVA", lambda x : x.btag('combinedMVABJetTags'), help="CMVA discriminator"),
NTupleVariable("btagCSV", lambda x : x.btag('pfCombinedInclusiveSecondaryVertexV2BJetTags'), help="CSV-IVF v2 discriminator"),
NTupleVariable("btagCMVA", lambda x : x.btag('pfCombinedMVABJetTags'), help="CMVA discriminator"),
NTupleVariable("rawPt", lambda x : x.pt() * x.rawFactor(), help="p_{T} before JEC"),
NTupleVariable("mcPt", lambda x : x.mcJet.pt() if getattr(x,"mcJet",None) else 0., mcOnly=True, help="p_{T} of associated gen jet"),
NTupleVariable("mcFlavour", lambda x : x.partonFlavour(), int, mcOnly=True, help="parton flavour (physics definition, i.e. including b's from shower)"),
Expand Down
24 changes: 22 additions & 2 deletions PhysicsTools/Heppy/python/physicsobjects/Electron.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ def electronID( self, id, vertex=None, rho=None ):
elif id == "POG_MVA_ID_Trig": return self.mvaIDTight()
elif id == "POG_MVA_ID_NonTrig_full5x5": return self.mvaIDLoose(full5x5=True)
elif id == "POG_MVA_ID_Trig_full5x5": return self.mvaIDTight(full5x5=True)
elif id == "POG_MVA_ID_Run2_NonTrig_VLoose": return self.mvaIDRun2("NonTrigPhys14","VLoose")
elif id == "POG_MVA_ID_Run2_NonTrig_Loose": return self.mvaIDRun2("NonTrigPhys14","Loose")
elif id == "POG_MVA_ID_Run2_NonTrig_Tight": return self.mvaIDRun2("NonTrigPhys14","Tight")
elif id.startswith("POG_Cuts_ID_"):
Expand All @@ -42,7 +43,7 @@ def cutBasedId(self, wp, showerShapes="auto"):
showerShapes = "full5x5"
wp = wp.replace("_full5x5","")
elif showerShapes == "auto":
if "POG_CSA14_25ns_v1" in wp or "POG_CSA14_50ns_v1" in wp or "POG_PHYS14_25ns_v1" in wp:
if "POG_CSA14_25ns_v1" in wp or "POG_CSA14_50ns_v1" in wp or "POG_PHYS14_25ns_v1" in wp or "POG_PHYS14_25ns_v1_ConvVeto" in wp or "POG_PHYS14_25ns_v1_ConvVetoDxyDz" in wp:
showerShapes = "full5x5"
vars = {
'dEtaIn' : abs(self.physObj.deltaEtaSuperClusterTrackAtVtx()),
Expand All @@ -53,6 +54,8 @@ def cutBasedId(self, wp, showerShapes="auto"):
'1/E-1/p' : abs(1.0/self.physObj.ecalEnergy() - self.physObj.eSuperClusterOverP()/self.physObj.ecalEnergy()) if self.physObj.ecalEnergy()>0. else 9e9,
'conversionVeto' : self.physObj.passConversionVeto(),
'missingHits' : self.physObj.gsfTrack().hitPattern().numberOfHits(ROOT.reco.HitPattern.MISSING_INNER_HITS), # http://cmslxr.fnal.gov/source/DataFormats/TrackReco/interface/HitPattern.h?v=CMSSW_7_2_3#0153
'dxy' : abs(self.dxy()),
'dz' : abs(self.dz()),
}
WP = {
## ------- https://twiki.cern.ch/twiki/bin/viewauth/CMS/EgammaCutBasedIdentification?rev=31
Expand Down Expand Up @@ -97,11 +100,24 @@ def cutBasedId(self, wp, showerShapes="auto"):

WP.update(WP_conversion_veto)

WP_conversion_veto_DxyDz = {
# missing Hits incremented by 1 because we return False if >=, note the '='
## ------- https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedElectronIdentificationRun2#Working_points_for_PHYS14_sample
'POG_PHYS14_25ns_v1_ConvVetoDxyDz_Veto' : WP['POG_PHYS14_25ns_v1_ConvVeto_Veto' ]+[('dxy',[0.060279, 0.273097]), ('dz',[0.800538, 0.885860])],
'POG_PHYS14_25ns_v1_ConvVetoDxyDz_Loose' : WP['POG_PHYS14_25ns_v1_ConvVeto_Loose' ]+[('dxy',[0.022664, 0.097358]), ('dz',[0.173670, 0.198444])],
'POG_PHYS14_25ns_v1_ConvVetoDxyDz_Medium' : WP['POG_PHYS14_25ns_v1_ConvVeto_Medium']+[('dxy',[0.011811, 0.051682]), ('dz',[0.070775, 0.180720])],
'POG_PHYS14_25ns_v1_ConvVetoDxyDz_Tight' : WP['POG_PHYS14_25ns_v1_ConvVeto_Tight' ]+[('dxy',[0.009924, 0.027261]), ('dz',[0.015310, 0.147154])],
}

WP.update(WP_conversion_veto_DxyDz)


if wp not in WP:
raise RuntimeError, "Working point '%s' not yet implemented in Electron.py" % wp
for (cut_name,(cut_eb,cut_ee)) in WP[wp]:
if cut_name == 'conversionVeto':
return vars[cut_name] == (cut_eb if self.physObj.isEB() else cut_ee)
if (cut_eb if self.physObj.isEB() else cut_ee) and not vars[cut_name]:
return False
elif vars[cut_name] >= (cut_eb if self.physObj.isEB() else cut_ee):
return False
return True
Expand Down Expand Up @@ -177,6 +193,10 @@ def mvaIDRun2(self, name, wp):
if (eta < 0.8) : return self.mvaRun2(name) > +0.35;
elif (eta < 1.479): return self.mvaRun2(name) > +0.20;
else : return self.mvaRun2(name) > -0.52;
elif wp=="VLoose":
if (eta < 0.8) : return self.mvaRun2(name) > -0.11;
elif (eta < 1.479): return self.mvaRun2(name) > -0.35;
else : return self.mvaRun2(name) > -0.55;
elif wp=="Tight":
if (eta < 0.8) : return self.mvaRun2(name) > 0.73;
elif (eta < 1.479): return self.mvaRun2(name) > 0.57;
Expand Down
Loading

0 comments on commit 584ffeb

Please sign in to comment.