9 from builtins
import range
11 """Branch containing an individual variable (either of the event or of an object), created with a name and a function to compute it
12 - name, type, help, default: obvious
13 - function: a function that taken an object computes the value to fill (e.g. lambda event : len(event.goodVertices))
15 def __init__(self, name, function, type=float, help="", default=-99, mcOnly=False, filler=None):
27 if self.
mcOnly and not isMC:
return
30 if self.
mcOnly and not isMC:
return
31 treeNumpy.fill(self.
name, self(object))
33 return "<NTupleVariable[%s]>" % self.
name
37 """Type defining a collection of variables associated to a single object. Contans NTupleVariable and NTupleSubObject"""
38 def __init__(self,name,baseObjectTypes=[],mcOnly=[],variables=[]):
45 if issubclass(v.__class__,NTupleSubObject):
51 """Return only my vars, not including the ones from the bases"""
52 vars = [ v
for v
in self.
variables if (isMC
or not v.mcOnly) ]
57 if so.mcOnly
and not isMC:
continue
58 for subvar
in so.objectType.allVars(isMC):
61 lambda object, subvar=subvar, so=so : subvar(so(object)),
64 type = subvar.type, help = subvar.help, default = subvar.default, mcOnly = subvar.mcOnly,
65 filler = subvar.filler))
70 """Return all vars, including the base ones. Duplicate bases are not added twice"""
72 if not isMC
and self.
mcOnly:
return []
74 if not isMC
and base.mcOnly:
continue
75 for var
in base.ownVars(isMC):
76 if var.name
in names:
raise RuntimeError(
"Duplicate definition of variable %s from %s and %s" % (var.name, base.name, names[var.name]))
77 names[var.name] = base.name
80 if var.name
in names:
raise RuntimeError(
"Duplicate definition of variable %s from %s and %s" % (var.name, self.
name, names[var.name]))
81 names[var.name] = self.
name
89 for b2
in b.allBases():
94 currentnames = [v.name
for v
in self.
allVars(
True)]
97 if var.name
in uniquenewvars:
raise RuntimeError(
"Duplicate definition of variable %s while adding variables to object type %s" % (var.name,self.
name))
98 uniquenewvars.append(var.name)
99 if var.name
not in currentnames:
102 raise RuntimeError(
"Variable %s is already present in object type %s" % (var.name,self.
name))
104 currentnames = [v.name
for v
in self.
subObjects]
107 if ob.name
in uniquenewobjs:
raise RuntimeError(
"Duplicate definition of sub-object %s while adding it to object type %s" % (ob.name,self.
name))
108 uniquenewobjs.append(ob.name)
109 if ob.name
not in currentnames:
112 raise RuntimeError(
"Sub-object %s is already present in object type %s" % (ob.name,self.
name))
115 mynewvars = self.
allVars(
False)
119 return "<NTupleObjectType[%s]>" % self.
name
125 """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"""
126 def __init__(self,name,function,objectType,mcOnly=False):
135 """Type defining a set of branches associated to a single object (i.e. an instance of NTupleObjectType)"""
136 def __init__(self, name, objectType, help="", mcOnly=False):
142 if not isMC
and self.
mcOnly:
return
146 if self.
help: h =
"%s for %s" % ( h
if h
else v.name, self.
help )
147 treeNumpy.var(
"%s_%s" % (self.
name, v.name), type=v.type, default=v.default, title=h, filler=v.filler)
149 if self.
mcOnly and not isMC:
return
152 treeNumpy.fill(
"%s_%s" % (self.
name, v.name),
v(object))
154 return "<NTupleObject[%s]>" % self.
name
158 """Type defining a set of branches associated to a list of objects (i.e. an instance of NTupleObjectType)"""
159 def __init__(self, name, objectType, maxlen, help="", mcOnly=False, sortAscendingBy=None, sortDescendingBy=None, filter=None):
164 if objectType.mcOnly
and mcOnly ==
False:
168 if sortAscendingBy !=
None and sortDescendingBy !=
None:
169 raise RuntimeError(
"Cannot specify two sort conditions")
174 if not isMC
and self.
objectType.mcOnly:
return
175 treeNumpy.var(
"n"+self.
name, int)
180 if self.
help: h =
"%s for %s [%d]" % ( h
if h
else v.name, self.
help, i-1 )
181 treeNumpy.var(
"%s%d_%s" % (self.
name, i, v.name), type=v.type, default=v.default, title=h, filler=v.filler)
183 if not isMC
and self.
objectType.mcOnly:
return
184 treeNumpy.var(
"n"+self.
name, int)
188 if self.
help: h =
"%s for %s" % ( h
if h
else v.name, self.
help )
189 name=
"%s_%s" % (self.
name, v.name)
if v.name !=
"" else self.
name
190 treeNumpy.vector(name,
"n"+self.
name, self.
maxlen, type=v.type, default=v.default, title=h, filler=v.filler)
192 if not isMC
and self.
objectType.mcOnly:
return
193 if self.
filter !=
None: collection = [ o
for o
in collection
if self.
filter(o) ]
197 treeNumpy.fill(
"n"+self.
name, num)
202 treeNumpy.fill(
"%s%d_%s" % (self.
name, i+1, v.name),
v(o))
204 if not isMC
and self.
objectType.mcOnly:
return
205 if self.
filter !=
None: collection = [ o
for o
in collection
if self.
filter(o) ]
209 treeNumpy.fill(
"n"+self.
name, num)
212 name=
"%s_%s" % (self.
name, v.name)
if v.name !=
"" else self.
name
213 treeNumpy.vfill(name, [
v(collection[i])
for i
in range(num) ])
215 return "<NTupleCollection[%s]>" % self.
name
220 s += [
"{0} {1}__{2}[{3}];".
format(v.type.__name__, self.
name, v.name, self.
maxlen)]
224 s =
"class %s {\n" % self.
name
227 s +=
" {0} {1};\n".
format(v.type.__name__, v.name)
232 s =
"class %s:\n" % self.
name
233 s +=
" def __init__(self, tree, n):\n"
236 s +=
" self.{0} = tree.{1}_{2}[n];\n".
format(v.name, self.
name, v.name)
238 s +=
" self.{0} = tree.{0}[n];\n".
format(self.
name)
240 s +=
" @staticmethod\n"
241 s +=
" def make_array(event):\n"
242 s +=
" return [{0}(event.input, i) for i in range(event.input.n{0})]\n".
format(self.
name)