2 from PhysicsTools.Heppy.analyzers.core.VertexHistograms
import VertexHistograms
3 from PhysicsTools.Heppy.analyzers.core.Analyzer
import Analyzer
4 from PhysicsTools.Heppy.analyzers.core.AutoHandle
import AutoHandle
5 from PhysicsTools.HeppyCore.statistics.average
import Average
6 from PhysicsTools.Heppy.physicsutils.PileUpSummaryInfo
import PileUpSummaryInfo
7 import PhysicsTools.HeppyCore.framework.config
as cfg
9 from ROOT
import TFile, TH1F
12 '''Computes pile-up weights for MC from the pile up histograms for MC and data. 13 These histograms should be set on the components as 14 puFileData, puFileMC attributes, as is done here: 16 http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/H2TauTau/Colin/test_tauMu_2012_cfg.py?view=markup 18 THESE HISTOGRAMS MUST BE CONSISTENT, SEE 19 https://twiki.cern.ch/twiki/bin/view/CMS/CMGToolsPileUpReweighting#Generating_pile_up_distributions 21 If the component is not MC, or if the puFileData and puFileMC are not 22 set for the component, the reweighting is not done. 24 The analyzer sets event.vertexWeight. 25 This weight is multiplied to the global event weight, event.eventWeight. 26 When using this analyzer, make sure that the VertexAnalyzer is disabled, 27 as you would be reweighting the MC PU distribution twice! 29 Additionally, this analyzer writes in the output an histogram containing the unweighting MC 30 pile-up distribution, to be used in input of the weighting for a later pass. 36 # build unweighted pu distribution using number of pile up interactions if False 37 # otherwise, use fill the distribution using number of true interactions 42 def __init__(self, cfg_ana, cfg_comp, looperName):
43 super(PileUpAnalyzer, self).
__init__(cfg_ana, cfg_comp, looperName)
47 if (hasattr(self.cfg_ana,
'makeHists'))
and (
not self.cfg_ana.makeHists):
50 self.
allVertices = self.cfg_ana.allVertices
if (hasattr(self.cfg_ana,
'allVertices'))
else "_AUTO_" 52 if self.cfg_comp.isMC
and self.
doHists:
57 if self.cfg_comp.isEmbed :
58 self.cfg_comp.puFileMC =
None 59 self.cfg_comp.puFileData =
None 61 if self.cfg_comp.isMC
or self.cfg_comp.isEmbed:
62 if not hasattr(self.cfg_comp,
"puFileMC")
or (self.cfg_comp.puFileMC
is None and self.cfg_comp.puFileData
is None):
65 assert( os.path.isfile(os.path.expandvars(self.cfg_comp.puFileMC)) )
66 assert( os.path.isfile(os.path.expandvars(self.cfg_comp.puFileData)) )
68 self.
mcfile = TFile( self.cfg_comp.puFileMC )
69 self.
mchist = self.mcfile.Get(
'pileup')
70 self.mchist.Scale( 1 / self.mchist.Integral() )
72 self.
datafile = TFile( self.cfg_comp.puFileData )
74 self.datahist.Scale( 1 / self.datahist.Integral() )
76 if self.mchist.GetNbinsX() != self.datahist.GetNbinsX():
77 raise ValueError(
'data and mc histograms must have the same number of bins')
78 if self.mchist.GetXaxis().GetXmin() != self.datahist.GetXaxis().GetXmin():
79 raise ValueError(
'data and mc histograms must have the same xmin')
80 if self.mchist.GetXaxis().GetXmax() != self.datahist.GetXaxis().GetXmax():
81 raise ValueError(
'data and mc histograms must have the same xmax')
85 self.mchandles[
'pusi'] = AutoHandle(
86 'slimmedAddPileupInfo',
87 'std::vector<PileupSummaryInfo>',
88 fallbackLabel=
"addPileupInfo" 92 self.handles[
'vertices'] = AutoHandle(
"offlineSlimmedPrimaryVertices",
'std::vector<reco::Vertex>', fallbackLabel=
"offlinePrimaryVertices" )
94 self.handles[
'vertices'] = AutoHandle( self.
allVertices,
'std::vector<reco::Vertex>' )
97 super(PileUpAnalyzer,self).
beginLoop(setup)
98 self.averages.add(
'puWeight',
Average(
'puWeight') )
102 self.readCollections( event.input )
104 if self.cfg_comp.isEmbed :
109 event.pileUpVertex_z = []
110 event.pileUpVertex_ptHat = []
111 if self.cfg_comp.isMC:
112 event.pileUpInfo =
map( PileUpSummaryInfo,
113 self.mchandles[
'pusi'].product() )
114 for puInfo
in event.pileUpInfo:
115 if puInfo.getBunchCrossing()==0:
117 if self.cfg_ana.true
is False:
118 event.nPU = puInfo.nPU()
120 event.nPU = puInfo.nTrueInteractions()
123 self.rawmcpileup.hist.Fill( event.nPU )
126 ptHat_zPositions =
zip(puInfo.getPU_pT_hats(),puInfo.getPU_zpositions())
127 ptHat_zPositions.sort(reverse=
True)
128 for ptHat_zPosition
in ptHat_zPositions:
129 event.pileUpVertex_z.append(ptHat_zPosition[1])
130 event.pileUpVertex_ptHat.append(ptHat_zPosition[0])
132 if event.nPU
is None:
133 raise ValueError(
'nPU cannot be None! means that no pu info has been found for bunch crossing 0.')
134 elif self.cfg_comp.isEmbed:
135 vertices = self.handles[
'vertices'].product()
136 event.nPU = len(vertices)
141 bin = self.datahist.FindBin(event.nPU)
142 if bin<1
or bin>self.datahist.GetNbinsX():
145 data = self.datahist.GetBinContent(bin)
146 mc = self.mchist.GetBinContent(bin)
149 event.puWeight = data/mc
153 event.eventWeight *= event.puWeight
154 self.averages[
'puWeight'].
add( event.puWeight )
158 super(PileUpAnalyzer, self).
write(setup)
159 if self.cfg_comp.isMC
and self.
doHists:
160 self.rawmcpileup.write()
163 setattr(PileUpAnalyzer,
"defaultConfig", cfg.Analyzer(
164 class_object = PileUpAnalyzer,
def beginLoop(self, setup)
enable
if component is embed return (has no trigger obj)
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
static std::string join(char **cmd)
def __init__(self, cfg_ana, cfg_comp, looperName)