CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PileUpAnalyzer.py
Go to the documentation of this file.
1 import os
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
8 
9 from ROOT import TFile, TH1F
10 
11 class PileUpAnalyzer( Analyzer ):
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:
15 
16  http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/CMG/CMGTools/H2TauTau/Colin/test_tauMu_2012_cfg.py?view=markup
17 
18  THESE HISTOGRAMS MUST BE CONSISTENT, SEE
19  https://twiki.cern.ch/twiki/bin/view/CMS/CMGToolsPileUpReweighting#Generating_pile_up_distributions
20 
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.
23 
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!
28 
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.
31 
32  Example of use:
33 
34  puAna = cfg.Analyzer(
35  "PileUpAnalyzer",
36  # build unweighted pu distribution using number of pile up interactions if False
37  # otherwise, use fill the distribution using number of true interactions
38  true = True
39  )
40  '''
41 
42  def __init__(self, cfg_ana, cfg_comp, looperName):
43  super(PileUpAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)
44 
45  self.doHists=True
46 
47  if (hasattr(self.cfg_ana,'makeHists')) and (not self.cfg_ana.makeHists):
48  self.doHists=False
49 
50  self.allVertices = self.cfg_ana.allVertices if (hasattr(self.cfg_ana,'allVertices')) else "_AUTO_"
51 
52  if self.cfg_comp.isMC and self.doHists:
53  self.rawmcpileup = VertexHistograms('/'.join([self.dirName,
54  'rawMCPU.root']))
55  self.enable = True
56  ## if component is embed return (has no trigger obj)
57  if self.cfg_comp.isEmbed :
58  self.cfg_comp.puFileMC = None
59  self.cfg_comp.puFileData = None
60 
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):
63  self.enable = False
64  else:
65  assert( os.path.isfile(os.path.expandvars(self.cfg_comp.puFileMC)) )
66  assert( os.path.isfile(os.path.expandvars(self.cfg_comp.puFileData)) )
67 
68  self.mcfile = TFile( self.cfg_comp.puFileMC )
69  self.mchist = self.mcfile.Get('pileup')
70  self.mchist.Scale( 1 / self.mchist.Integral() )
71 
72  self.datafile = TFile( self.cfg_comp.puFileData )
73  self.datahist = self.datafile.Get('pileup')
74  self.datahist.Scale( 1 / self.datahist.Integral() )
75  # import pdb; pdb.set_trace()
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')
82 
83  def declareHandles(self):
84  super(PileUpAnalyzer, self).declareHandles()
85  self.mchandles['pusi'] = AutoHandle(
86  'addPileupInfo',
87  'std::vector<PileupSummaryInfo>'
88  )
89  if self.allVertices == '_AUTO_':
90  self.handles['vertices'] = AutoHandle( "offlineSlimmedPrimaryVertices", 'std::vector<reco::Vertex>', fallbackLabel="offlinePrimaryVertices" )
91  else:
92  self.handles['vertices'] = AutoHandle( self.allVertices, 'std::vector<reco::Vertex>' )
93 
94  def beginLoop(self, setup):
95  super(PileUpAnalyzer,self).beginLoop(setup)
96  self.averages.add('vertexWeight', Average('vertexWeight') )
97 
98 
99  def process(self, event):
100  self.readCollections( event.input )
101  ## if component is embed return (has no trigger obj)
102  if self.cfg_comp.isEmbed :
103  return True
104 
105  event.vertexWeight = 1
106  event.nPU = None
107  if self.cfg_comp.isMC:
108  event.pileUpInfo = map( PileUpSummaryInfo,
109  self.mchandles['pusi'].product() )
110  for puInfo in event.pileUpInfo:
111  if puInfo.getBunchCrossing()==0:
112  # import pdb; pdb.set_trace()
113  if self.cfg_ana.true is False:
114  event.nPU = puInfo.nPU()
115  else:
116  event.nPU = puInfo.nTrueInteractions()
117 
118  if self.doHists:
119  self.rawmcpileup.hist.Fill( event.nPU )
120 
121  if event.nPU is None:
122  raise ValueError('nPU cannot be None! means that no pu info has been found for bunch crossing 0.')
123  elif self.cfg_comp.isEmbed:
124  vertices = self.handles['vertices'].product()
125  event.nPU = len(vertices)
126  else:
127  return True
128 
129  if self.enable:
130  bin = self.datahist.FindBin(event.nPU)
131  if bin<1 or bin>self.datahist.GetNbinsX():
132  event.vertexWeight = 0
133  else:
134  data = self.datahist.GetBinContent(bin)
135  mc = self.mchist.GetBinContent(bin)
136  #Protect 0 division!!!!
137  if mc !=0.0:
138  event.vertexWeight = data/mc
139  else:
140  event.vertexWeight = 1
141 
142  event.eventWeight *= event.vertexWeight
143  self.averages['vertexWeight'].add( event.vertexWeight )
144  return True
145 
146  def write(self, setup):
147  super(PileUpAnalyzer, self).write(setup)
148  if self.cfg_comp.isMC and self.doHists:
149  self.rawmcpileup.write()
150 
151 
152 setattr(PileUpAnalyzer,"defaultConfig", cfg.Analyzer(
153  class_object = PileUpAnalyzer,
154  true = True, # use number of true interactions for reweighting
155  makeHists=False
156 )
157 )
158 
assert(m_qm.get())
enable
if component is embed return (has no trigger obj)
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18