Skip to content

Commit

Permalink
Merge pull request #259 from CERN-PH-CMG/heppy_7_2_2_patch2
Browse files Browse the repository at this point in the history
Allow running full CMSSW before Heppy, and performance improvement in LHEAnalyzer
  • Loading branch information
gpetruc committed Feb 13, 2015
2 parents 1ccf461 + 6520f24 commit cffd269
Show file tree
Hide file tree
Showing 9 changed files with 311 additions and 34 deletions.
13 changes: 12 additions & 1 deletion PhysicsTools/Heppy/python/analyzers/core/PileUpAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from PhysicsTools.Heppy.analyzers.core.AutoHandle import AutoHandle
from PhysicsTools.HeppyCore.statistics.average import Average
from PhysicsTools.Heppy.physicsutils.PileUpSummaryInfo import PileUpSummaryInfo
import PhysicsTools.HeppyCore.framework.config as cfg

from ROOT import TFile, TH1F

class PileUpAnalyzer( Analyzer ):
Expand Down Expand Up @@ -57,7 +59,7 @@ def __init__(self, cfg_ana, cfg_comp, looperName):
self.cfg_comp.puFileData = None

if self.cfg_comp.isMC or self.cfg_comp.isEmbed:
if self.cfg_comp.puFileMC is None and self.cfg_comp.puFileData is None:
if not hasattr(self.cfg_comp,"puFileMC") or (self.cfg_comp.puFileMC is None and self.cfg_comp.puFileData is None):
self.enable = False
else:
assert( os.path.isfile(self.cfg_comp.puFileMC) )
Expand Down Expand Up @@ -145,3 +147,12 @@ def write(self, setup):
super(PileUpAnalyzer, self).write(setup)
if self.cfg_comp.isMC and self.doHists:
self.rawmcpileup.write()


setattr(PileUpAnalyzer,"defaultConfig", cfg.Analyzer(
class_object = PileUpAnalyzer,
true = True, # use number of true interactions for reweighting
makeHists=False
)
)

11 changes: 7 additions & 4 deletions PhysicsTools/Heppy/python/analyzers/gen/LHEAnalyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class LHEAnalyzer( Analyzer ):
""" """
def __init__(self, cfg_ana, cfg_comp, looperName ):
super(LHEAnalyzer,self).__init__(cfg_ana,cfg_comp,looperName)
self.lheh=Handle('LHEEventProduct')

def declareHandles(self):
super(LHEAnalyzer, self).declareHandles()
Expand All @@ -24,12 +25,14 @@ def process(self, event):
event.lheHT=0
event.lheNj=0
event.lheV_pt = 0
h=Handle('LHEEventProduct')
event.input.getByLabel( 'externalLHEProducer',h)
if not h.isValid() :
try:
event.input.getByLabel( 'externalLHEProducer',self.lheh)
except :
return True
if not self.lheh.isValid() :
return True
self.readCollections( event.input )
hepeup=h.product().hepeup()
hepeup=self.lheh.product().hepeup()
pup=hepeup.PUP
l=None
lBar=None
Expand Down
46 changes: 46 additions & 0 deletions PhysicsTools/Heppy/python/utils/cmsswPreprocessor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import os
import re
import imp
from PhysicsTools.HeppyCore.framework.config import CFG
class CmsswPreprocessor :
def __init__(self,configFile,command="cmsRun") :
self.configFile=configFile
self.command=command

def run(self,component,wd,firstEvent,nEvents):
print wd,firstEvent,nEvents
if nEvents is None:
nEvents = -1
cmsswConfig = imp.load_source("cmsRunProcess",self.configFile)
inputfiles= []
for fn in component.files :
if not re.match("file:.*",fn) and not re.match("root:.*",fn) :
fn="file:"+fn
inputfiles.append(fn)
cmsswConfig.process.source.fileNames = inputfiles
cmsswConfig.process.maxEvents.input=nEvents
#fixme: implement skipEvent / firstevent

outfilename=wd+"/cmsswPreProcessing.root"
for outName in cmsswConfig.process.endpath.moduleNames() :
out = getattr(cmsswConfig.process,outName)
out.fileName = outfilename
if not hasattr(component,"options"):
component.options = CFG(name="postCmsrunOptions")
#use original as primary and new as secondary
#component.options.inputFiles= component.files
#component.options.secondaryInputFiles=[outfilename]

#use new as primary and original as secondary
component.options.secondaryInputFiles= component.files
component.options.inputFiles=[outfilename]
component.files=[outfilename]

configfile=wd+"/cmsRun_config.py"
f = open(configfile, 'w')
f.write(cmsswConfig.process.dumpPython())
f.close()
runstring="%s %s >& %s/cmsRun.log" % (self.command,configfile,wd)
print "Running pre-processor: %s " %runstring
os.system(runstring)
return component
94 changes: 69 additions & 25 deletions PhysicsTools/Heppy/test/example_autofill.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,82 +2,126 @@
import ROOT
import PhysicsTools.HeppyCore.framework.config as cfg

# The content of the output tree is defined here
# the definitions of the NtupleObjects are located under PhysicsTools/Heppy/pythonanalyzers/objects/autophobj.py

from PhysicsTools.Heppy.analyzers.core.AutoFillTreeProducer import *
treeProducer= cfg.Analyzer(
class_object=AutoFillTreeProducer,
verbose=False,
vectorTree = True,
#here the list of simple event variables (floats, int) can be specified
globalVariables = [
NTupleVariable("rho", lambda ev: ev.rho, float, help="jets rho"),
],
#here one can specify compound objects
globalObjects = {
"met" : NTupleObject("met", metType, help="PF E_{T}^{miss}, after default type 1 corrections"),
},
collections = {
#copying input collection p4 information
"slimmedMuons" : ( AutoHandle( ("slimmedMuons",), "std::vector<pat::Muon>" ),
NTupleCollection("mu", particleType, 4, help="patMuons, directly from MINIAOD") ),
"slimmedElectron" : ( AutoHandle( ("slimmedElectrons",), "std::vector<pat::Electron>" ),
NTupleCollection("ele", particleType, 4, help="patElectron, directly from MINIAOD") ),
#The following would just store the electrons and muons from miniaod without any selection or cleaning
# only the basice particle information is saved
#"slimmedMuons" : ( AutoHandle( ("slimmedMuons",), "std::vector<pat::Muon>" ),
# NTupleCollection("mu", particleType, 4, help="patMuons, directly from MINIAOD") ),
#"slimmedElectron" : ( AutoHandle( ("slimmedElectrons",), "std::vector<pat::Electron>" ),
# NTupleCollection("ele", particleType, 4, help="patElectron, directly from MINIAOD") ),

#standard dumping of objects
"selectedLeptons" : NTupleCollection("leptons", leptonType, 8, help="Leptons after the preselection"),
"selectedTaus" : NTupleCollection("TauGood", tauType, 3, help="Taus after the preselection"),
"cleanJets" : NTupleCollection("Jet", jetType, 8, sortDescendingBy = lambda jet : jet.btag('combinedSecondaryVertexBJetTags'),
help="Cental jets after full selection and cleaning, sorted by b-tag"),
"cleanJets" : NTupleCollection("Jet", jetType, 8, help="Cental jets after full selection and cleaning, sorted by b-tag"),
#dump of gen objects
"gentopquarks" : NTupleCollection("GenTop", genParticleType, 2, help="Generated top quarks from hard scattering"),
"genbquarks" : NTupleCollection("GenBQuark", genParticleType, 2, help="Generated bottom quarks from top quark decays"),
"genwzquarks" : NTupleCollection("GenQuark", genParticleType, 6, help="Generated quarks from W/Z decays"),
"genleps" : NTupleCollection("GenLep", genParticleType, 6, help="Generated leptons from W/Z decays"),
"genwzquarks" : NTupleCollection("GenQuark", genParticleType, 6, help="Generated quarks from W/Z decays"),
"genleps" : NTupleCollection("GenLep", genParticleType, 6, help="Generated leptons from W/Z decays"),
"gentauleps" : NTupleCollection("GenLepFromTau", genParticleType, 6, help="Generated leptons from decays of taus from W/Z/h decays"),

}
)

# Lepton Analyzer, take its default config
# Import standard analyzers and take their default config
from PhysicsTools.Heppy.analyzers.objects.LeptonAnalyzer import LeptonAnalyzer
LepAna = LeptonAnalyzer.defaultConfig
#replace one parameter
LepAna.loose_muon_pt = 10

from PhysicsTools.Heppy.analyzers.objects.VertexAnalyzer import VertexAnalyzer
VertexAna = VertexAnalyzer.defaultConfig

from PhysicsTools.Heppy.analyzers.objects.PhotonAnalyzer import PhotonAnalyzer
PhoAna = PhotonAnalyzer.defaultConfig

from PhysicsTools.Heppy.analyzers.objects.TauAnalyzer import TauAnalyzer
TauAna = TauAnalyzer.defaultConfig

from PhysicsTools.Heppy.analyzers.objects.JetAnalyzer import JetAnalyzer
JetAna = JetAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.gen.LHEAnalyzer import LHEAnalyzer
LHEAna = LHEAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.gen.GeneratorAnalyzer import GeneratorAnalyzer
GenAna = GeneratorAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.objects.METAnalyzer import METAnalyzer
METAna = METAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.core.PileUpAnalyzer import PileUpAnalyzer
PUAna = PileUpAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.core.TriggerBitAnalyzer import TriggerBitAnalyzer
FlagsAna = TriggerBitAnalyzer.defaultEventFlagsConfig

# Configure trigger bit analyzer
from PhysicsTools.Heppy.analyzers.core.TriggerBitAnalyzer import TriggerBitAnalyzer
TrigAna= cfg.Analyzer(
verbose=False,
class_object=TriggerBitAnalyzer,
triggerBits={'any':'HLT_.*'},
#grouping several paths into a single flag
# v* can be used to ignore the version of a path
triggerBits={
'ELE':["HLT_Ele23_Ele12_CaloId_TrackId_Iso_v*","HLT_Ele32_eta2p1_WP85_Gsf_v*","HLT_Ele32_eta2p1_WP85_Gsf_v*"],
'MU': ["HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_v*","HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_v*","HLT_IsoTkMu24_eta2p1_IterTrk02_v*","HLT_IsoTkMu24_IterTrk02_v*"],
},
# processName='HLT',
# outprefix='HLT'
#setting 'unrollbits' to true will not only store the OR for each set of trigger bits but also the individual bits
#caveat: this does not unroll the version numbers
unrollbits=True
)


sequence = [VertexAna,LepAna,TauAna,PhoAna,JetAna,TrigAna,treeProducer]

#replace some parameters
LepAna.loose_muon_pt = 10

sequence = [LHEAna,FlagsAna, GenAna, PUAna,TrigAna,VertexAna,LepAna,TauAna,PhoAna,JetAna,METAna,treeProducer]

#use tfile service to provide a single TFile to all modules where they
#can write any root object. If the name is 'outputfile' or the one specified in treeProducer
#also the treeProducer uses this file
from PhysicsTools.HeppyCore.framework.services.tfile import TFileService
output_service = cfg.Service(
TFileService,
'outputfile',
name="outputfile",
fname='tree.root',
option='recreate'
)

# the following two lines are just for automatic testing
# they are not needed for running on your own samples
from PhysicsTools.Heppy.utils.miniAodFiles import miniAodFiles
testfiles=miniAodFiles()

sample = cfg.Component(
# files = "/scratch/arizzi/heppy/CMSSW_7_2_0_pre8/src/PhysicsTools/Heppy/test/E21AD523-E548-E411-8DF6-00261894388F.root",
files = miniAodFiles(),
name="ATEST", isMC=False,isEmbed=False
#specify the file you want to run on
files = ["/scratch/arizzi/Hbb/CMSSW_7_2_2_patch2/src/VHbbAnalysis/Heppy/test/ZLL-8A345C56-6665-E411-9C25-1CC1DE04DF20.root"],
# files = testfiles,
name="SingleSample", isMC=False,isEmbed=False
)

# the following is declared in case this cfg is used in input to the heppy.py script
selectedComponents = [sample]
from PhysicsTools.HeppyCore.framework.eventsfwlite import Events
selectedComponents = [sample]
config = cfg.Config( components = selectedComponents,
sequence = sequence,
services = [],
services = [output_service],
events_class = Events)

# and the following runs the process directly
# and the following runs the process directly if running as with python filename.py
if __name__ == '__main__':
from PhysicsTools.HeppyCore.framework.looper import Looper
looper = Looper( 'Loop', config, nPrint = 5)
looper = Looper( 'Loop', config, nPrint = 5,nEvents=300)
looper.loop()
looper.write()
135 changes: 135 additions & 0 deletions PhysicsTools/Heppy/test/example_autofill_wCmsRun.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#! /usr/bin/env python
import ROOT
import PhysicsTools.HeppyCore.framework.config as cfg

# The content of the output tree is defined here
# the definitions of the NtupleObjects are located under PhysicsTools/Heppy/pythonanalyzers/objects/autophobj.py

from PhysicsTools.Heppy.analyzers.core.AutoFillTreeProducer import *
treeProducer= cfg.Analyzer(
class_object=AutoFillTreeProducer,
verbose=False,
vectorTree = True,
#here the list of simple event variables (floats, int) can be specified
globalVariables = [
NTupleVariable("rho", lambda ev: ev.rho, float, help="jets rho"),
],
#here one can specify compound objects
globalObjects = {
"met" : NTupleObject("met", metType, help="PF E_{T}^{miss}, after default type 1 corrections"),
},
collections = {
#The following would just store the electrons and muons from miniaod without any selection or cleaning
# only the basice particle information is saved
#"slimmedMuons" : ( AutoHandle( ("slimmedMuons",), "std::vector<pat::Muon>" ),
# NTupleCollection("mu", particleType, 4, help="patMuons, directly from MINIAOD") ),
#"slimmedElectron" : ( AutoHandle( ("slimmedElectrons",), "std::vector<pat::Electron>" ),
# NTupleCollection("ele", particleType, 4, help="patElectron, directly from MINIAOD") ),

#read product of preprocessor-cmsRun
"jetsAK5" : ( AutoHandle( ("ak5PFJetsCHS",), "std::vector<reco::PFJet>" ),
NTupleCollection("JetAk5", particleType, 8, help="AK5 jets")),

#standard dumping of objects
"selectedLeptons" : NTupleCollection("leptons", leptonType, 8, help="Leptons after the preselection"),
"selectedTaus" : NTupleCollection("TauGood", tauType, 3, help="Taus after the preselection"),
"cleanJets" : NTupleCollection("Jet", jetType, 8, help="Cental jets after full selection and cleaning, sorted by b-tag"),
#dump of gen objects
"gentopquarks" : NTupleCollection("GenTop", genParticleType, 2, help="Generated top quarks from hard scattering"),
"genbquarks" : NTupleCollection("GenBQuark", genParticleType, 2, help="Generated bottom quarks from top quark decays"),
"genwzquarks" : NTupleCollection("GenQuark", genParticleType, 6, help="Generated quarks from W/Z decays"),
"genleps" : NTupleCollection("GenLep", genParticleType, 6, help="Generated leptons from W/Z decays"),
"gentauleps" : NTupleCollection("GenLepFromTau", genParticleType, 6, help="Generated leptons from decays of taus from W/Z/h decays"),

}
)

# Import standard analyzers and take their default config
from PhysicsTools.Heppy.analyzers.objects.LeptonAnalyzer import LeptonAnalyzer
LepAna = LeptonAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.objects.VertexAnalyzer import VertexAnalyzer
VertexAna = VertexAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.objects.PhotonAnalyzer import PhotonAnalyzer
PhoAna = PhotonAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.objects.TauAnalyzer import TauAnalyzer
TauAna = TauAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.objects.JetAnalyzer import JetAnalyzer
JetAna = JetAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.gen.LHEAnalyzer import LHEAnalyzer
LHEAna = LHEAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.gen.GeneratorAnalyzer import GeneratorAnalyzer
GenAna = GeneratorAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.objects.METAnalyzer import METAnalyzer
METAna = METAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.core.PileUpAnalyzer import PileUpAnalyzer
PUAna = PileUpAnalyzer.defaultConfig
from PhysicsTools.Heppy.analyzers.core.TriggerBitAnalyzer import TriggerBitAnalyzer
FlagsAna = TriggerBitAnalyzer.defaultEventFlagsConfig

# Configure trigger bit analyzer
from PhysicsTools.Heppy.analyzers.core.TriggerBitAnalyzer import TriggerBitAnalyzer
TrigAna= cfg.Analyzer(
verbose=False,
class_object=TriggerBitAnalyzer,
#grouping several paths into a single flag
# v* can be used to ignore the version of a path
triggerBits={
'ELE':["HLT_Ele23_Ele12_CaloId_TrackId_Iso_v*","HLT_Ele32_eta2p1_WP85_Gsf_v*","HLT_Ele32_eta2p1_WP85_Gsf_v*"],
'MU': ["HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_v*","HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_v*","HLT_IsoTkMu24_eta2p1_IterTrk02_v*","HLT_IsoTkMu24_IterTrk02_v*"],
},
# processName='HLT',
# outprefix='HLT'
#setting 'unrollbits' to true will not only store the OR for each set of trigger bits but also the individual bits
#caveat: this does not unroll the version numbers
unrollbits=True
)



#replace some parameters
LepAna.loose_muon_pt = 10

sequence = [LHEAna,FlagsAna, GenAna, PUAna,TrigAna,VertexAna,LepAna,TauAna,PhoAna,JetAna,METAna,treeProducer]

#use tfile service to provide a single TFile to all modules where they
#can write any root object. If the name is 'outputfile' or the one specified in treeProducer
#also the treeProducer uses this file
from PhysicsTools.HeppyCore.framework.services.tfile import TFileService
output_service = cfg.Service(
TFileService,
'outputfile',
name="outputfile",
fname='tree.root',
option='recreate'
)

# the following two lines are just for automatic testing
# they are not needed for running on your own samples
from PhysicsTools.Heppy.utils.miniAodFiles import miniAodFiles
testfiles=miniAodFiles()

sample = cfg.Component(
#specify the file you want to run on
files = ["/scratch/arizzi/Hbb/CMSSW_7_2_2_patch2/src/VHbbAnalysis/Heppy/test/ZLL-8A345C56-6665-E411-9C25-1CC1DE04DF20.root"],
# files = testfiles,
name="SingleSample", isMC=False,isEmbed=False
)

from PhysicsTools.Heppy.utils.cmsswPreprocessor import CmsswPreprocessor
preprocessor = CmsswPreprocessor("makeAK5Jets.py")

# the following is declared in case this cfg is used in input to the heppy.py script
from PhysicsTools.HeppyCore.framework.eventsfwlite import Events
selectedComponents = [sample]
config = cfg.Config( components = selectedComponents,
sequence = sequence,
services = [output_service],
preprocessor=preprocessor, #this would run cmsRun makeAK5Jets.py before running Heppy
events_class = Events)

# and the following runs the process directly if running as with python filename.py
if __name__ == '__main__':
from PhysicsTools.HeppyCore.framework.looper import Looper
looper = Looper( 'Loop', config, nPrint = 5,nEvents=300)
looper.loop()
looper.write()
Loading

0 comments on commit cffd269

Please sign in to comment.