CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
AutoFillTreeProducer.py
Go to the documentation of this file.
1 from PhysicsTools.Heppy.analyzers.core.TreeAnalyzerNumpy import TreeAnalyzerNumpy
2 from PhysicsTools.Heppy.analyzers.core.AutoHandle import AutoHandle
3 #from ROOT import TriggerBitChecker
6 
7 
8 class AutoFillTreeProducer( TreeAnalyzerNumpy ):
9 
10  #-----------------------------------
11  # BASIC TREE PRODUCER
12  #-----------------------------------
13  def __init__(self, cfg_ana, cfg_comp, looperName):
14  super(AutoFillTreeProducer,self).__init__(cfg_ana, cfg_comp, looperName)
15 
16  ## Read whether we want vectors or flat trees
17  self.scalar = not self.cfg_ana.vectorTree
18 
19  ## Read whether we want 4-vectors
20  if not getattr(self.cfg_ana, 'saveTLorentzVectors', False):
21  fourVectorType.removeVariable("p4")
22 
23 
24  self.collections = {}
25  self.globalObjects = {}
26  self.globalVariables = []
27  if hasattr(cfg_ana,"collections"):
28  self.collections.update(cfg_ana.collections)
29  if hasattr(cfg_ana,"globalObjects"):
30  self.globalObjects.update(cfg_ana.globalObjects)
31  if hasattr(cfg_ana,"globalVariables"):
32  self.globalVariables=cfg_ana.globalVariables[:]
33 
34  def beginLoop(self, setup) :
35  super(AutoFillTreeProducer, self).beginLoop(setup)
36 
37  def declareHandles(self):
38  super(AutoFillTreeProducer, self).declareHandles()
39 # self.handles['TriggerResults'] = AutoHandle( ('TriggerResults','','HLT'), 'edm::TriggerResults' )
40  self.mchandles['GenInfo'] = AutoHandle( ('generator','',''), 'GenEventInfoProduct' )
41  for k,v in self.collections.iteritems():
42  if type(v) == tuple and isinstance(v[0], AutoHandle):
43  self.handles[k] = v[0]
44 
45  def declareCoreVariables(self, tr, isMC):
46  """Here we declare the variables that we always want and that are hard-coded"""
47  tr.var('run', int, storageType="i")
48  tr.var('lumi', int, storageType="i")
49  tr.var('evt', int, storageType="l")
50  tr.var('isData', int)
51 
52  # self.triggerBitCheckers = []
53  # if hasattr(self.cfg_ana, 'triggerBits'):
54  # for T, TL in self.cfg_ana.triggerBits.iteritems():
55  # trigVec = ROOT.vector(ROOT.string)()
56  # for TP in TL:
57  # trigVec.push_back(TP)
58  # tr.var( 'HLT_'+T, int )
59 # self.triggerBitCheckers.append( (T, TriggerBitChecker(trigVec)) )
60 
61  if not isMC:
62  tr.var('intLumi', int, storageType="i")
63 
64  if isMC:
65  ## cross section
66  tr.var('xsec', float)
67  ## PU weights
68  tr.var("puWeight")
69  ## number of true interactions
70  tr.var("nTrueInt",int)
71  ## generator weight
72  tr.var("genWeight")
73  ## PDF weights
74  self.pdfWeights = []
75  if hasattr(self.cfg_ana, "PDFWeights") and len(self.cfg_ana.PDFWeights) > 0:
76  self.pdfWeights = self.cfg_ana.PDFWeights
77  for (pdf,nvals) in self.pdfWeights:
78  if self.scalar:
79  for i in range(nvals): tr.var('pdfWeight_%s_%d' % (pdf,i))
80  else:
81  tr.vector('pdfWeight_%s' % pdf, nvals)
82 
83  def declareVariables(self,setup):
84  isMC = self.cfg_comp.isMC
85  tree = self.tree
86  self.declareCoreVariables(tree, isMC)
87 
88  if not hasattr(self.cfg_ana,"ignoreAnalyzerBookings") or not self.cfg_ana.ignoreAnalyzerBookings :
89  #import variables declared by the analyzers
90  if hasattr(setup,"globalVariables"):
91  self.globalVariables+=setup.globalVariables
92  if hasattr(setup,"globalObjects"):
93  self.globalObjects.update(setup.globalObjects)
94  if hasattr(setup,"collections"):
95  self.collections.update(setup.collections)
96 
97  for v in self.globalVariables:
98  v.makeBranch(tree, isMC)
99  for o in self.globalObjects.itervalues():
100  o.makeBranches(tree, isMC)
101  for c in self.collections.itervalues():
102  if type(c) == tuple: c = c[-1]
103  if self.scalar:
104  c.makeBranchesScalar(tree, isMC)
105  else:
106  c.makeBranchesVector(tree, isMC)
107 
108  def fillCoreVariables(self, tr, event, isMC):
109  """Here we fill the variables that we always want and that are hard-coded"""
110  tr.fill('run', event.input.eventAuxiliary().id().run())
111  tr.fill('lumi',event.input.eventAuxiliary().id().luminosityBlock())
112  tr.fill('evt', event.input.eventAuxiliary().id().event())
113  tr.fill('isData', 0 if isMC else 1)
114 
115 # triggerResults = self.handles['TriggerResults'].product()
116 # for T,TC in self.triggerBitCheckers:
117 # tr.fill("HLT_"+T, TC.check(event.object(), triggerResults))
118 
119  if not isMC:
120  tr.fill('intLumi', getattr(self.cfg_comp,'intLumi',1.0))
121 
122  if isMC:
123  ## xsection, if available
124  tr.fill('xsec', getattr(self.cfg_comp,'xSection',1.0))
125  ## PU weights, check if a PU analyzer actually filled it
126  if hasattr(event,"nPU"):
127  tr.fill("nTrueInt", event.nPU)
128  tr.fill("puWeight", event.puWeight)
129  else :
130  tr.fill("nTrueInt", -1)
131  tr.fill("puWeight", 1.0)
132 
133  tr.fill("genWeight", self.mchandles['GenInfo'].product().weight())
134  ## PDF weights
135  if hasattr(event,"pdfWeights") :
136  for (pdf,nvals) in self.pdfWeights:
137  if len(event.pdfWeights[pdf]) != nvals:
138  raise RuntimeError, "PDF lenght mismatch for %s, declared %d but the event has %d" % (pdf,nvals,event.pdfWeights[pdf])
139  if self.scalar:
140  for i,w in enumerate(event.pdfWeights[pdf]):
141  tr.fill('pdfWeight_%s_%d' % (pdf,i), w)
142  else:
143  tr.vfill('pdfWeight_%s' % pdf, event.pdfWeights[pdf])
144 
145  def process(self, event):
146  if hasattr(self.cfg_ana,"filter") :
147  if not self.cfg_ana.filter(event) :
148  return True #do not stop processing, just filter myself
149  self.readCollections( event.input)
150  self.fillTree(event)
151 
152  def fillTree(self, event, resetFirst=True):
153  isMC = self.cfg_comp.isMC
154  if resetFirst: self.tree.reset()
155 
156  self.fillCoreVariables(self.tree, event, isMC)
157 
158  for v in self.globalVariables:
159  if not isMC and v.mcOnly: continue
160  v.fillBranch(self.tree, event, isMC)
161 
162  for on, o in self.globalObjects.iteritems():
163  if not isMC and o.mcOnly: continue
164  o.fillBranches(self.tree, getattr(event, on), isMC)
165 
166  for cn, c in self.collections.iteritems():
167  if type(c) == tuple and isinstance(c[0], AutoHandle):
168  if not isMC and c[-1].mcOnly: continue
169  objects = self.handles[cn].product()
170  setattr(event, cn, [objects[i] for i in xrange(objects.size())])
171  c = c[-1]
172  if not isMC and c.mcOnly: continue
173  if self.scalar:
174  c.fillBranchesScalar(self.tree, getattr(event, cn), isMC)
175  else:
176  c.fillBranchesVector(self.tree, getattr(event, cn), isMC)
177 
178  self.tree.tree.Fill()
179 
180  def getPythonWrapper(self):
181  """
182  This function produces a string that contains a Python wrapper for the event.
183  The wrapper is automatically generated based on the collections and allows the full
184  event contents to be accessed from subsequent Analyzers using e.g.
185 
186  leps = event.selLeptons #is of type selLeptons
187  pt0 = leps[0].pt
188 
189  One just needs to add the EventAnalyzer to the sequence.
190  """
191 
192  isMC = self.cfg_comp.isMC
193 
194  classes = ""
195  anclass = ""
196  anclass += "from PhysicsTools.HeppyCore.framework.analyzer import Analyzer\n"
197  anclass += "class EventAnalyzer(Analyzer):\n"
198  anclass += " def __init__(self, cfg_ana, cfg_comp, looperName):\n"
199  anclass += " super(EventAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)\n"
200 
201  anclass += " def process(self, event):\n"
202 
203  for cname, coll in self.collections.items():
204  classes += coll.get_py_wrapper_class(isMC)
205  anclass += " event.{0} = {0}.make_array(event)\n".format(coll.name)
206 
207  return classes + "\n" + anclass
208 
scalar
Read whether we want vectors or flat trees.
Definition: weight.py:1
Definition: event.py:1