예제 #1
0
    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))
예제 #2
0
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)
예제 #3
0
    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')
예제 #4
0
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
예제 #5
0
    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))
예제 #6
0
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)