def __init__(self, line): Definition.__init__( self, line, '([a-zA-Z_][a-zA-Z0-9_]*)(|\\[.+\\])/([^ ]+)Ref(?:|/([!m]+))$') self.refname = self.matches.group(1) arrdef = self.matches.group(2) self.objname = self.matches.group(3) try: objdef = PhysicsObject.get(self.objname) except KeyError: raise Definition.NoMatch() if objdef.is_singlet(): raise RuntimeError('Cannot create reference to single object ' + objdef.name) modifier = self.matches.group(4) if modifier is None: mod = '' else: mod = '/' + modifier # create a branch for the index with name {name}_ Branch.__init__( self, '{name}_{arrdef}/S{mod} = -1'.format(name=self.refname, arrdef=arrdef, mod=mod))
def plot_set(objdef): """ Get the set of members of an object to plot """ to_plot = [] acceptable = ['bool', 'char', 'int', 'float', 'double', 'Bool_t', 'Char_t', 'UChar_t', 'UShort_t', 'Short_t', 'UInt_t', 'Int_t', 'Long64_t', 'ULong64_t', 'Float_t', 'Double_t'] # Regular branches to plot to_plot += [b.name for b in objdef.branches \ if 'packed' not in b.name and \ not b.name.endswith('_') and \ not b.is_array() and \ Branch.TYPE_MAP.get(b.type, b.type) in acceptable] # Functions to plot to_plot += [f.signature.split()[0] for f in objdef.functions \ if '() const' in f.signature and \ f.type in acceptable] # Get inherited members to plot if objdef.parent not in ['Element', 'Singlet', 'TreeEntry', 'EventBase']: to_plot += plot_set(PhysicsObject.get(objdef.parent)) return set(to_plot)
def __init__(self, line): Definition.__init__( self, line, '([a-zA-Z_][a-zA-Z0-9_]*)/([^ \\(]+)(\\([0-9]+\\)|)$') self.name = self.matches.group(1) self.objname = self.matches.group(2) if self.objname.endswith('Collection'): self.objname = self.objname.replace('Collection', '') self.conttype = 'Collection' elif self.objname.endswith('Array'): self.objname = self.objname.replace('Array', '') self.conttype = 'Array' else: self.conttype = '' self.init_size = self.matches.group(3).strip('()') try: # is this a valid object? objdef = PhysicsObject.get(self.objname) except KeyError: raise Definition.NoMatch() if objdef.is_singlet() and (self.conttype != '' or self.init_size != ''): raise RuntimeError('Cannot create container of object ' + objdef.name) if self.conttype == 'Array' and self.init_size == '': raise RuntimeError('Array object ' + objdef.name + ' needs a size')
def parents(objdef): """ Get all parents and self recursively """ output = [objdef] if objdef.parent not in ['Element', 'Singlet', 'TreeEntry', 'EventBase']: output.extend(parents(PhysicsObject.get(objdef.parent))) return output
def write_def(self, out, objbranches): """ Part of the tree entry constructor code to pass the target collection pointer to the reference. """ if len(self.ref_name) == 1: out.writeline('{rname}Container_ = &{target};'.format( rname='.'.join(self.ref_name), target=self.target)) else: bname = self.ref_name[-2] branch = next(b for b in objbranches if b.name == bname) objdef = PhysicsObject.get(branch.objname) if objdef.is_singlet(): out.writeline('{rname}Container_ = &{target};'.format( rname='.'.join(self.ref_name), target=self.target)) else: out.writeline( '{rname}.data.{bname}Container_ = &{target};'.format( rname='.'.join(self.ref_name[:-1]), bname=self.ref_name[-1], target=self.target))
def write_header(trees, file_name): # Track the number of plots and which objects have been plotted thus far num_plots = 0 parsed_objs = set() # Open the writing tool writer = FileOutput(file_name) writer.writeline(header) for tree in trees: # We only want to write stuff in 'events' TTree with this tool if tree.name in ['Event', 'EventBase']: # Plot first branches of single variables in suep::Event (like npv, eventNum, etc.) for plot in plot_set(tree): if plot in parsed_objs: continue parsed_objs.add(plot) writer.writeline( template % (num_plots, # Which plot we're defining 'common', # The output directory of the plot plot.rstrip('()'), # The name of the plot file (without extension) 'std::vector<float> output {float(event.%s)};' % plot)) # The vector of values that fills the histogram num_plots += 1 for obj in tree.objbranches: if obj.name in parsed_objs: continue parsed_objs.add(obj.name) objdef = PhysicsObject.get(obj.objname) set_to_plot = plot_set(objdef) # Two ways to fill the histograms whether or not this is a collection action_string = 'std::vector<float> output {{float(event.' + obj.name + '.{branch})}};' if obj.conttype == 'Collection': # Throw in size of the collection plot = 'size()' writer.writeline(template % (num_plots, obj.name, plot.rstrip('()'), action_string.format(branch=plot))) num_plots += 1 action_string = """std::vector<float> output; for (auto& i : event.{objname}) output.push_back(i.{{branch}});""".format(objname=obj.name) # Print sizes of references for refbranch in [b for o in parents(objdef) for b in o.branches]: # Check if actually a refbranch if hasattr(refbranch, 'refname'): name = refbranch.name.rstrip('_') member = 'size' if 'std::vector' in refbranch.type else 'isValid' writer.writeline(template % (num_plots, obj.name, '%s_%s' % (name, member), action_string.format(init='', branch='%s.%s()' % (name, member)))) num_plots += 1 for plot in set_to_plot: assertion = '' sortedby = obj.modifiers.get('sortedby', '').split(',') if sortedby[0] == plot.rstrip('()'): compare = sortedby[1] if len(sortedby) > 1 else 'greater' assertion = '\n assert(std::is_sorted(output.begin(), output.end(), std::{compare}<float>()));'.format(compare=compare) writer.writeline(template % (num_plots, obj.name, plot.rstrip('()'), action_string.format(branch=plot) + assertion)) num_plots += 1 writer.writeline('\n#define NUM_PLOTS %i' % num_plots) writer.writeline(footer)