CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
autovars.py
Go to the documentation of this file.
1 #!/bin/env python
2 #
3 # Objects to be used with AutoFillTreeProducer
4 #
5 # the variable declaration contains both the booking information and a function to fill the variable
6 #
7 # TODO: more documentation needed here!
8 
10  """Branch containing an individual variable (either of the event or of an object), created with a name and a function to compute it
11  - name, type, help, default: obvious
12  - function: a function that taken an object computes the value to fill (e.g. lambda event : len(event.goodVertices))
13  """
14  def __init__(self, name, function, type=float, help="", default=-99, mcOnly=False, filler=None):
15  self.name = name
16  self.function = function
17  self.type = type
18  self.help = help
19  self.default = default
20  self.mcOnly = mcOnly
21  self.filler = filler
22  def __call__(self,object):
23  ret = self.function(object)
24  return ret
25  def makeBranch(self,treeNumpy,isMC):
26  if self.mcOnly and not isMC: return
27  treeNumpy.var(self.name, type=self.type, default=self.default, title=self.help, filler=self.filler)
28  def fillBranch(self,treeNumpy,object,isMC):
29  if self.mcOnly and not isMC: return
30  treeNumpy.fill(self.name, self(object))
31  def __repr__(self):
32  return "<NTupleVariable[%s]>" % self.name
33 
34 
36  """Type defining a collection of variables associated to a single object. Contans NTupleVariable and NTupleSubObject"""
37  def __init__(self,name,baseObjectTypes=[],mcOnly=[],variables=[]):
38  self.name = name
39  self.baseObjectTypes = baseObjectTypes
40  self.mcOnly = mcOnly
41  self.variables = []
42  self.subObjects = []
43  for v in variables:
44  if issubclass(v.__class__,NTupleSubObject):
45  self.subObjects.append(v)
46  else:
47  self.variables.append(v)
48  self._subObjectVars = {}
49  def ownVars(self,isMC):
50  """Return only my vars, not including the ones from the bases"""
51  vars = [ v for v in self.variables if (isMC or not v.mcOnly) ]
52  if self.subObjects:
53  if isMC not in self._subObjectVars:
54  subvars = []
55  for so in self.subObjects:
56  if so.mcOnly and not isMC: continue
57  for subvar in so.objectType.allVars(isMC):
58  subvars.append(NTupleVariable(so.name+"_"+subvar.name,
59  #DebugComposer(so,subvar),#lambda object : subvar(so(object)),
60  lambda object, subvar=subvar, so=so : subvar(so(object)),
61  # ^-- lambda object : subvar(so(object)) doesn't work due to scoping, see
62  # http://stackoverflow.com/questions/2295290/what-do-lambda-function-closures-capture-in-python/2295372#2295372
63  type = subvar.type, help = subvar.help, default = subvar.default, mcOnly = subvar.mcOnly,
64  filler = subvar.filler))
65  self._subObjectVars[isMC] = subvars
66  vars += self._subObjectVars[isMC]
67  return vars
68  def allVars(self,isMC):
69  """Return all vars, including the base ones. Duplicate bases are not added twice"""
70  ret = []; names = {}
71  if not isMC and self.mcOnly: return []
72  for base in self.allBases():
73  if not isMC and base.mcOnly: continue
74  for var in base.ownVars(isMC):
75  if var.name in names: raise RuntimeError, "Duplicate definition of variable %s from %s and %s" % (var.name, base.name, names[var.name])
76  names[var.name] = base.name
77  ret.append(var)
78  for var in self.ownVars(isMC):
79  if var.name in names: raise RuntimeError, "Duplicate definition of variable %s from %s and %s" % (var.name, self.name, names[var.name])
80  names[var.name] = self.name
81  ret.append(var)
82  return ret
83  def allBases(self):
84  ret = []
85  for b in self.baseObjectTypes:
86  if b not in ret:
87  ret.append(b)
88  for b2 in b.allBases():
89  if b2 not in ret:
90  ret.append(b2)
91  return ret
92  def removeVariable(self,name):
93  self.variables = [ v for v in self.variables if v.name != name]
94  def __repr__(self):
95  return "<NTupleObjectType[%s]>" % self.name
96 
97 
98 
99 
101  """Type to add a sub-object within an NTupleObjectType, given a name (used as prefix), a function to extract the sub-object and NTupleObjectType to define tye type"""
102  def __init__(self,name,function,objectType,mcOnly=False):
103  self.name = name
104  self.function = function
105  self.objectType = objectType
106  self.mcOnly = mcOnly
107  def __call__(self,object):
108  return self.function(object)
109 
111  """Type defining a set of branches associated to a single object (i.e. an instance of NTupleObjectType)"""
112  def __init__(self, name, objectType, help="", mcOnly=False):
113  self.name = name
114  self.objectType = objectType
115  self.mcOnly = mcOnly
116  self.help = ""
117  def makeBranches(self,treeNumpy,isMC):
118  if not isMC and self.mcOnly: return
119  allvars = self.objectType.allVars(isMC)
120  for v in allvars:
121  h = v.help
122  if self.help: h = "%s for %s" % ( h if h else v.name, self.help )
123  treeNumpy.var("%s_%s" % (self.name, v.name), type=v.type, default=v.default, title=h, filler=v.filler)
124  def fillBranches(self,treeNumpy,object,isMC):
125  if self.mcOnly and not isMC: return
126  allvars = self.objectType.allVars(isMC)
127  for v in allvars:
128  treeNumpy.fill("%s_%s" % (self.name, v.name), v(object))
129  def __repr__(self):
130  return "<NTupleObject[%s]>" % self.name
131 
132 
134  """Type defining a set of branches associated to a list of objects (i.e. an instance of NTupleObjectType)"""
135  def __init__(self, name, objectType, maxlen, help="", mcOnly=False, sortAscendingBy=None, sortDescendingBy=None, filter=None):
136  self.name = name
137  self.objectType = objectType
138  self.maxlen = maxlen
139  self.help = help
140  if objectType.mcOnly and mcOnly == False:
141  #print "collection %s is set to mcOnly since the type %s is mcOnly" % (name, objectType.name)
142  mcOnly = True
143  self.mcOnly = mcOnly
144  if sortAscendingBy != None and sortDescendingBy != None:
145  raise RuntimeError, "Cannot specify two sort conditions"
146  self.filter = filter
147  self.sortAscendingBy = sortAscendingBy
148  self.sortDescendingBy = sortDescendingBy
149  def makeBranchesScalar(self,treeNumpy,isMC):
150  if not isMC and self.objectType.mcOnly: return
151  treeNumpy.var("n"+self.name, int)
152  allvars = self.objectType.allVars(isMC)
153  for v in allvars:
154  for i in xrange(1,self.maxlen+1):
155  h = v.help
156  if self.help: h = "%s for %s [%d]" % ( h if h else v.name, self.help, i-1 )
157  treeNumpy.var("%s%d_%s" % (self.name, i, v.name), type=v.type, default=v.default, title=h, filler=v.filler)
158  def makeBranchesVector(self,treeNumpy,isMC):
159  if not isMC and self.objectType.mcOnly: return
160  treeNumpy.var("n"+self.name, int)
161  allvars = self.objectType.allVars(isMC)
162  for v in allvars:
163  h = v.help
164  if self.help: h = "%s for %s" % ( h if h else v.name, self.help )
165  name="%s_%s" % (self.name, v.name) if v.name != "" else self.name
166  treeNumpy.vector(name, "n"+self.name, self.maxlen, type=v.type, default=v.default, title=h, filler=v.filler)
167  def fillBranchesScalar(self,treeNumpy,collection,isMC):
168  if not isMC and self.objectType.mcOnly: return
169  if self.filter != None: collection = [ o for o in collection if self.filter(o) ]
170  if self.sortAscendingBy != None: collection = sorted(collection, key=self.sortAscendingBy)
171  if self.sortDescendingBy != None: collection = sorted(collection, key=self.sortDescendingBy, reverse=True)
172  num = min(self.maxlen,len(collection))
173  treeNumpy.fill("n"+self.name, num)
174  allvars = self.objectType.allVars(isMC)
175  for i in xrange(num):
176  o = collection[i]
177  for v in allvars:
178  treeNumpy.fill("%s%d_%s" % (self.name, i+1, v.name), v(o))
179  def fillBranchesVector(self,treeNumpy,collection,isMC):
180  if not isMC and self.objectType.mcOnly: return
181  if self.filter != None: collection = [ o for o in collection if self.filter(o) ]
182  if self.sortAscendingBy != None: collection = sorted(collection, key=self.sortAscendingBy)
183  if self.sortDescendingBy != None: collection = sorted(collection, key=self.sortDescendingBy, reverse=True)
184  num = min(self.maxlen,len(collection))
185  treeNumpy.fill("n"+self.name, num)
186  allvars = self.objectType.allVars(isMC)
187  for v in allvars:
188  name="%s_%s" % (self.name, v.name) if v.name != "" else self.name
189  treeNumpy.vfill(name, [ v(collection[i]) for i in xrange(num) ])
190  def __repr__(self):
191  return "<NTupleCollection[%s]>" % self.name
192 
193  def get_cpp_declaration(self, isMC):
194  s = []
195  for v in self.objectType.allVars(isMC):
196  s += ["{0} {1}__{2}[{3}];".format(v.type.__name__, self.name, v.name, self.maxlen)]
197  return "\n".join(s)
198 
199  def get_cpp_wrapper_class(self, isMC):
200  s = "class %s {\n" % self.name
201  s += "public:\n"
202  for v in self.objectType.allVars(isMC):
203  s += " {0} {1};\n".format(v.type.__name__, v.name)
204  s += "};\n"
205  return s
206 
207  def get_py_wrapper_class(self, isMC):
208  s = "class %s:\n" % self.name
209  s += " def __init__(self, tree, n):\n"
210  for v in self.objectType.allVars(isMC):
211  if len(v.name)>0:
212  s += " self.{0} = tree.{1}_{2}[n];\n".format(v.name, self.name, v.name)
213  else:
214  s += " self.{0} = tree.{0}[n];\n".format(self.name)
215 
216  s += " @staticmethod\n"
217  s += " def make_array(event):\n"
218  s += " return [{0}(event.input, i) for i in range(event.input.n{0})]\n".format(self.name)
219  return s
220 
221 
T min(T a, T b)
Definition: MathUtil.h:58
static std::string join(char **cmd)
Definition: RemoteFile.cc:18