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=cfg_ana.collections
29  if hasattr(cfg_ana,"globalObjects"):
30  self.globalObjects=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="i")
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 isMC:
62  ## cross section
63  tr.var('xsec', float)
64  ## PU weights
65  tr.var("puWeight")
66  ## number of true interactions
67  tr.var("nTrueInt",int)
68  ## generator weight
69  tr.var("genWeight")
70  ## PDF weights
71  self.pdfWeights = []
72  if hasattr(self.cfg_ana, "PDFWeights") and len(self.cfg_ana.PDFWeights) > 0:
73  self.pdfWeights = self.cfg_ana.PDFWeights
74  for (pdf,nvals) in self.pdfWeights:
75  if self.scalar:
76  for i in range(nvals): tr.var('pdfWeight_%s_%d' % (pdf,i))
77  else:
78  tr.vector('pdfWeight_%s' % pdf, nvals)
79 
80  def declareVariables(self,setup):
81  isMC = self.cfg_comp.isMC
82  tree = self.tree
83  self.declareCoreVariables(tree, isMC)
84 
85  if not hasattr(self.cfg_ana,"ignoreAnalyzerBookings") or not self.cfg_ana.ignoreAnalyzerBookings :
86  #import variables declared by the analyzers
87  if hasattr(setup,"globalVariables"):
88  self.globalVariables+=setup.globalVariables
89  if hasattr(setup,"globalObjects"):
90  self.globalObjects.update(setup.globalObjects)
91  if hasattr(setup,"collections"):
92  self.collections.update(setup.collections)
93 
94  for v in self.globalVariables:
95  v.makeBranch(tree, isMC)
96  for o in self.globalObjects.itervalues():
97  o.makeBranches(tree, isMC)
98  for c in self.collections.itervalues():
99  if type(c) == tuple: c = c[-1]
100  if self.scalar:
101  c.makeBranchesScalar(tree, isMC)
102  else:
103  c.makeBranchesVector(tree, isMC)
104 
105  def fillCoreVariables(self, tr, event, isMC):
106  """Here we fill the variables that we always want and that are hard-coded"""
107  tr.fill('run', event.input.eventAuxiliary().id().run())
108  tr.fill('lumi',event.input.eventAuxiliary().id().luminosityBlock())
109  tr.fill('evt', event.input.eventAuxiliary().id().event())
110  tr.fill('isData', 0 if isMC else 1)
111 
112 # triggerResults = self.handles['TriggerResults'].product()
113 # for T,TC in self.triggerBitCheckers:
114 # tr.fill("HLT_"+T, TC.check(event.object(), triggerResults))
115 
116  if isMC:
117  ## xsection, if available
118  tr.fill('xsec', getattr(self.cfg_comp,'xSection',1.0))
119  ## PU weights, check if a PU analyzer actually filled it
120  if hasattr(event,"nPU"):
121  tr.fill("nTrueInt", event.nPU)
122  tr.fill("puWeight", event.eventWeight)
123  else :
124  tr.fill("nTrueInt", -1)
125  tr.fill("puWeight", 1.0)
126 
127  tr.fill("genWeight", self.mchandles['GenInfo'].product().weight())
128  ## PDF weights
129  if hasattr(event,"pdfWeights") :
130  for (pdf,nvals) in self.pdfWeights:
131  if len(event.pdfWeights[pdf]) != nvals:
132  raise RuntimeError, "PDF lenght mismatch for %s, declared %d but the event has %d" % (pdf,nvals,event.pdfWeights[pdf])
133  if self.scalar:
134  for i,w in enumerate(event.pdfWeights[pdf]):
135  tr.fill('pdfWeight_%s_%d' % (pdf,i), w)
136  else:
137  tr.vfill('pdfWeight_%s' % pdf, event.pdfWeights[pdf])
138 
139  def process(self, event):
140  if hasattr(self.cfg_ana,"filter") :
141  if not self.cfg_ana.filter(event) :
142  return True #do not stop processing, just filter myself
143  self.readCollections( event.input)
144  self.fillTree(event)
145 
146  def fillTree(self, event, resetFirst=True):
147  isMC = self.cfg_comp.isMC
148  if resetFirst: self.tree.reset()
149 
150  self.fillCoreVariables(self.tree, event, isMC)
151 
152  for v in self.globalVariables:
153  if not isMC and v.mcOnly: continue
154  v.fillBranch(self.tree, event, isMC)
155 
156  for on, o in self.globalObjects.iteritems():
157  if not isMC and o.mcOnly: continue
158  o.fillBranches(self.tree, getattr(event, on), isMC)
159 
160  for cn, c in self.collections.iteritems():
161  if type(c) == tuple and isinstance(c[0], AutoHandle):
162  if not isMC and c[-1].mcOnly: continue
163  objects = self.handles[cn].product()
164  setattr(event, cn, [objects[i] for i in xrange(objects.size())])
165  c = c[-1]
166  if not isMC and c.mcOnly: continue
167  if self.scalar:
168  c.fillBranchesScalar(self.tree, getattr(event, cn), isMC)
169  else:
170  c.fillBranchesVector(self.tree, getattr(event, cn), isMC)
171 
172  self.tree.tree.Fill()
173 
174  def getPythonWrapper(self):
175  """
176  This function produces a string that contains a Python wrapper for the event.
177  The wrapper is automatically generated based on the collections and allows the full
178  event contents to be accessed from subsequent Analyzers using e.g.
179 
180  leps = event.selLeptons #is of type selLeptons
181  pt0 = leps[0].pt
182 
183  One just needs to add the EventAnalyzer to the sequence.
184  """
185 
186  isMC = self.cfg_comp.isMC
187 
188  classes = ""
189  anclass = ""
190  anclass += "from PhysicsTools.HeppyCore.framework.analyzer import Analyzer\n"
191  anclass += "class EventAnalyzer(Analyzer):\n"
192  anclass += " def __init__(self, cfg_ana, cfg_comp, looperName):\n"
193  anclass += " super(EventAnalyzer, self).__init__(cfg_ana, cfg_comp, looperName)\n"
194 
195  anclass += " def process(self, event):\n"
196 
197  for cname, coll in self.collections.items():
198  classes += coll.get_py_wrapper_class(isMC)
199  anclass += " event.{0} = {0}.make_array(event)\n".format(coll.name)
200 
201  return classes + "\n" + anclass
202 
scalar
Read whether we want vectors or flat trees.
Definition: weight.py:1
Definition: event.py:1