Skip to content

Commit

Permalink
Merge pull request cms-sw#74 from vhbb/vhbbToHeppy80X
Browse files Browse the repository at this point in the history
Vhbb to central heppy 80X
  • Loading branch information
cbernet committed Jun 8, 2016
2 parents ee4dfb7 + 21794e7 commit 730c7d5
Show file tree
Hide file tree
Showing 14 changed files with 319 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,14 @@ def getPythonWrapper(self):

for cname, coll in self.collections.items():
classes += coll.get_py_wrapper_class(isMC)
anclass += " event.{0} = {0}.make_array(event)\n".format(coll.name)
anclass += " event.{0} = {0}.make_array(event.input)\n".format(coll.name)

for cname, coll in self.globalObjects.items():
classes += coll.get_py_wrapper_class(isMC)
anclass += " event.{0} = {0}.make_obj(event.input)\n".format(coll.name)

for v in self.globalVariables:
anclass += " event.{0} = getattr(event.input, \"{0}\", None)\n".format(v.name)

return classes + "\n" + anclass

15 changes: 10 additions & 5 deletions PhysicsTools/Heppy/python/analyzers/core/JSONAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,20 @@ class JSONAnalyzer( Analyzer ):
- if the json file was not set for this component
- False if the component is MC or embed (for H->tau tau),
and if the run/lumi pair is not in the JSON file.
If the option "passAll" is specified and set to True, all events will be selected and a flag event.json is set with the value of the filter
'''

def __init__(self, cfg_ana, cfg_comp, looperName):
super(JSONAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)
if not cfg_comp.isMC:
if self.cfg_comp.json is None:
if self.cfg_comp.json is None and hasattr(self.cfg_ana,"json") == False :
raise ValueError('component {cname} is not MC, and contains no JSON file. Either remove the JSONAnalyzer for your path or set the "json" attribute of this component'.format(cname=cfg_comp.name))
self.lumiList = LumiList(os.path.expandvars(self.cfg_comp.json))
#use json from this analyzer if given, otherwise use the component json
self.lumiList = LumiList(os.path.expandvars(getattr(self.cfg_ana,"json",self.cfg_comp.json)))
else:
self.lumiList = None

self.passAll = getattr(self.cfg_ana,'passAll',False)
self.useLumiBlocks = self.cfg_ana.useLumiBlocks if (hasattr(self.cfg_ana,'useLumiBlocks')) else False

self.rltInfo = RLTInfo()
Expand Down Expand Up @@ -75,13 +78,15 @@ def process(self, event):
return True

self.count.inc('All Events')
if self.lumiList.contains(run,lumi):
sel = self.lumiList.contains(run,lumi)
setattr(event,"json"+getattr(self.cfg_ana,"suffix",""), sel)
if sel :
self.count.inc('Passed Events')
if not self.useLumiBlocks:
self.rltInfo.add('dummy', run, lumi)
return True
else:
return False
return self.passAll


def write(self, setup):
Expand Down
15 changes: 15 additions & 0 deletions PhysicsTools/Heppy/python/analyzers/core/PileUpAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,19 @@ def __init__(self, cfg_ana, cfg_comp, looperName):
self.datafile = TFile( self.cfg_comp.puFileData )
self.datahist = self.datafile.Get('pileup')
self.datahist.Scale( 1 / self.datahist.Integral() )

#PU uncertainties variations
self.datahistPlus=None
self.datahistMinus=None
if hasattr(self.cfg_comp,"puFileDataPlus") :
self.datafilePlus = TFile( self.cfg_comp.puFileDataPlus )
self.datahistPlus = self.datafilePlus.Get('pileup')
self.datahistPlus.Scale( 1. / self.datahistPlus.Integral() )
if hasattr(self.cfg_comp,"puFileDataMinus") :
self.datafileMinus = TFile( self.cfg_comp.puFileDataMinus )
self.datahistMinus = self.datafileMinus.Get('pileup')
self.datahistMinus.Scale( 1. / self.datahistMinus.Integral() )

# import pdb; pdb.set_trace()
if self.mchist.GetNbinsX() != self.datahist.GetNbinsX():
raise ValueError('data and mc histograms must have the same number of bins')
Expand Down Expand Up @@ -147,6 +160,8 @@ def process(self, event):
#Protect 0 division!!!!
if mc !=0.0:
event.puWeight = data/mc
event.puWeightPlus = self.datahistPlus.GetBinContent(bin)/mc if self.datahistPlus is not None else 1.
event.puWeightMinus = self.datahistMinus.GetBinContent(bin)/mc if self.datahistMinus is not None else 1.
else:
event.puWeight = 1

Expand Down
112 changes: 112 additions & 0 deletions PhysicsTools/Heppy/python/analyzers/core/TriggerObjectsAnalyzer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import ROOT

from PhysicsTools.Heppy.analyzers.core.Analyzer import Analyzer
from PhysicsTools.Heppy.analyzers.core.AutoHandle import AutoHandle
from PhysicsTools.Heppy.analyzers.core.AutoFillTreeProducer import NTupleVariable
from PhysicsTools.HeppyCore.utils.deltar import matchObjectCollection, matchObjectCollection3
import PhysicsTools.HeppyCore.framework.config as cfg

""" FindTrigger: check if HLT path triggerName is names (using wildcard)"""
def FindTrigger(triggerName,names):
if triggerName=="": return True
triggerName = triggerName.replace("*","")
triggerName = triggerName.replace("$","")
for name in names:
if triggerName in name: return True
return False

"""
triggerCollection is a class that interprets the triggerObjectsCfgs elements.
Example:
trColl = triggerCollection(("hltMet","","HLT"),"hltMET90","HLT_PFMET90_PFMHT90_IDTight*")
It gives:
trColl.collectionText ="hltMet::HLT"
trColl.collectionName ="hltMet"
trColl.filterName ="hltMET90"
trColl.path ="HLT_PFMET90_PFMHT90_IDTight*"
"""
class triggerCollection(object):
def __init__(self, triggerObjectsCfg):
collectionInfo = triggerObjectsCfg[0]
collectionLabel = collectionInfo[0] if len(collectionInfo)>0 else ""
collectionInstance = collectionInfo[1] if len(collectionInfo)>1 else ""
collectionProcess = collectionInfo[2] if len(collectionInfo)>2 else "HLT"
self.collectionText = collectionLabel + ":" + collectionInstance + ":" + collectionProcess

self.collectionName = collectionLabel
if collectionInstance != "": self.collectionName = self.collectionName + "_" + collectionInstance
if collectionProcess != "HLT": self.collectionName = self.collectionName + "_" + collectionProcess

self.filterName = triggerObjectsCfg[1] if len(triggerObjectsCfg)>1 else ""
self.path = triggerObjectsCfg[2] if len(triggerObjectsCfg)>2 else ""

"""
TriggerObjectsAnalyzer is a class that saves the trigger objects matching the parameters defined in triggerObjectsCfgs.
Example
triggerObjectsCfgs = {"caloMet":(("hltMet","","HLT"),"hltMET90","HLT_PFMET90_PFMHT90_IDTight*") )}
means:
- caloMet is just a name
- ("hltMet","","HLT") is the label, instance and process name of the EDProducer that produced the trigger objects
- hltMET90 is the label of the EDFilter that saves the trigger objects
- HLT_PFMET90_PFMHT90_IDTight* is the name of the HLT path that we require was running the EDFilter module
"""
class TriggerObjectsAnalyzer( Analyzer ):
def __init__(self, cfg_ana, cfg_comp, looperName ):
super(TriggerObjectsAnalyzer,self).__init__(cfg_ana,cfg_comp,looperName)
triggerObjectsCfgs = getattr(self.cfg_ana,"triggerObjectsCfgs",[])
self.triggerObjectInputTag = getattr(self.cfg_ana,"triggerObjectInputTag",("","",""))
self.triggerBitsInputTag = getattr(self.cfg_ana,"triggerBitsInputTag",("","",""))
self.triggerObjectsInfos = {}
self.runNumber = -1
self.names = None
for collectionName in triggerObjectsCfgs.keys():
self.triggerObjectsInfos[collectionName] = triggerCollection(triggerObjectsCfgs[collectionName])

def declareHandles(self):
super(TriggerObjectsAnalyzer, self).declareHandles()
self.handles['TriggerBits'] = AutoHandle( self.triggerBitsInputTag, 'edm::TriggerResults' )
self.handles['TriggerObjects'] = AutoHandle( self.triggerObjectInputTag, 'std::vector<pat::TriggerObjectStandAlone>' )

def beginLoop(self, setup):
super(TriggerObjectsAnalyzer,self).beginLoop(setup)

def process(self, event):
self.readCollections( event.input )
run = event.input.eventAuxiliary().id().run()
# get the trigger names (only for the first event of each run)
if self.runNumber!= run:
triggerBits = self.handles['TriggerBits'].product()
self.names = event.input.object().triggerNames(triggerBits)
self.runNumber = run
# get the trigger object
allTriggerObjects = self.handles['TriggerObjects'].product()

# init objects
objects = {}
for collectionName in self.triggerObjectsInfos.keys():
objects[collectionName]=[]
# for each collection name save the trigger object matching the triggerObjectsInfo
for ob in allTriggerObjects:
for collectionName in self.triggerObjectsInfos.keys():
triggerObjectsInfo = self.triggerObjectsInfos[collectionName]
if (triggerObjectsInfo.collectionText!="::HLT") and triggerObjectsInfo.collectionText!=ob.collection(): continue
if (triggerObjectsInfo.path!=""):
if not hasattr(ob,"unpacked"):
ob.unpacked = True
ob.unpackPathNames(self.names)
if not FindTrigger(triggerObjectsInfo.path, ob.pathNames()): continue
if (triggerObjectsInfo.filterName!="") and not (ob.hasFilterLabel(triggerObjectsInfo.filterName)): continue
objects[collectionName].append(ob)
# add object variables in event
for collectionName in self.triggerObjectsInfos.keys():
setattr(event,'trgObjects_'+collectionName,objects[collectionName])

setattr(TriggerObjectsAnalyzer,"defaultConfig",cfg.Analyzer(
TriggerObjectsAnalyzer, name="TriggerObjectsAnalyzerDefault",
triggerObjectsCfgs = {"caloJets":(("hltAK4CaloJetsCorrectedIDPassed")),"caloMet":(("hltMet","","HLT"),"hltMET90","HLT_PFMET90_PFMHT90_IDTight*")},
triggerObjectInputTag = ('selectedPatTrigger','','PAT'),
triggerBitsInputTag = ('TriggerResults','','HLT')
)
)


55 changes: 41 additions & 14 deletions PhysicsTools/Heppy/python/analyzers/core/autovars.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,33 @@ def fillBranches(self,treeNumpy,object,isMC):
def __repr__(self):
return "<NTupleObject[%s]>" % self.name

def get_py_wrapper_class(self, isMC):
s = "class %s:\n" % self.name
s += " \"\"\"\n"
s += " {0}\n".format(self.help)
s += " \"\"\"\n"

s += " @staticmethod\n"
s += " def make_obj(tree):\n"
vs = []
helps = []
for v in self.objectType.allVars(isMC):
if len(v.name)>0:
s += " _{1} = getattr(tree, \"{0}_{1}\", None)\n".format(self.name, v.name)
vs += [v.name]
helps += [v.help]
else:
s += " _{0} = getattr(tree, \"{0}\", None);\n".format(self.name)
vs += [self.name]
helps += [self.help]
vecstring = ", ".join(["_{0}".format(v) for v in vs])

s += " return {0}({1})\n".format(self.name, vecstring)

s += " def __init__(self, {0}):\n".format(",".join(vs))
for v, h in zip(vs, helps):
s += " self.{0} = {0} #{1}\n".format(v, h)
return s

class NTupleCollection:
"""Type defining a set of branches associated to a list of objects (i.e. an instance of NTupleObjectType)"""
Expand Down Expand Up @@ -228,17 +255,17 @@ def get_cpp_wrapper_class(self, isMC):
return s

def get_py_wrapper_class(self, isMC):
s = "class %s:\n" % self.name
s += " def __init__(self, tree, n):\n"
for v in self.objectType.allVars(isMC):
if len(v.name)>0:
s += " self.{0} = tree.{1}_{2}[n];\n".format(v.name, self.name, v.name)
else:
s += " self.{0} = tree.{0}[n];\n".format(self.name)

s += " @staticmethod\n"
s += " def make_array(event):\n"
s += " return [{0}(event.input, i) for i in range(event.input.n{0})]\n".format(self.name)
return s


s = "class %s:\n" % self.name
if len(self.objectType.allVars(isMC)):
s += " def __init__(self, tree, n):\n"
for v in self.objectType.allVars(isMC):
if len(v.name)>0:
s += " self.{0} = tree.{1}_{2}[n];\n".format(v.name, self.name, v.name)
else:
s += " self.{0} = tree.{0}[n];\n".format(self.name)

s += " @staticmethod\n"
s += " def make_array(event):\n"
s += " return [{0}(event.input, i) for i in range(event.input.n{0})]\n".format(self.name)
return s
2 changes: 2 additions & 0 deletions PhysicsTools/Heppy/python/analyzers/gen/GeneratorAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@ def makeMCInfo(self, event):
event.genbquarksFromTop = []
event.genbquarksFromH = []
event.genlepsFromTop = []
event.genvertex = 0
if len(event.generatorSummary)>2: event.genvertex=event.generatorSummary[2].vertex().z()
for p in event.generatorSummary:
id = abs(p.pdgId())
if id == 25:
Expand Down
Loading

0 comments on commit 730c7d5

Please sign in to comment.