CMS 3D CMS Logo

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