def prep_reco(TTree, host_file, name): """Create the "reco" (~AdSimple) TTree and fill buffer. Parameters ---------- host_file : ROOT.TFile The TFile that will hold the reco TTree name : str The name of this TTree Returns ------- (reco_ttree, buffer) : tuple The TTree object and the buffer used to fill its TBranches """ buf = root_util.TreeBuffer() buf.triggerType = root_util.unsigned_int_value() buf.site = root_util.int_value() buf.energy = root_util.float_value() buf.x = root_util.float_value() buf.y = root_util.float_value() buf.z = root_util.float_value() host_file.cd() event_subdir = host_file.Get("Event") if not bool(event_subdir): event_subdir = host_file.mkdir("Event") event_subdir.cd() rec_subdir = event_subdir.Get("Rec") if not bool(rec_subdir): rec_subdir = event_subdir.mkdir("Rec") rec_subdir.cd() long_name = "Tree at /Event/Rec/{name} holding Rec_{name}".format( name=name) reco = TTree(name, long_name) reco.Branch("context.mSite", buf.site, "context.mSite/I") reco.Branch("triggerType", buf.triggerType, "triggerType/i") reco.Branch("energy", buf.energy, "energy/F") reco.Branch("x", buf.x, "x/F") reco.Branch("y", buf.y, "y/F") reco.Branch("z", buf.z, "z/F") return reco, buf
def prep_truth(TTree, host_file): """Create the MC Truth TTree (named MCTruth) and fill buffer. Parameters ---------- host_file : ROOT.TFile The TFile that will hold the MC Truth TTree Returns ------- (mc_truth_ttree, buffer) : tuple The TTree object and the buffer used to fill its TBranches """ buf = root_util.TreeBuffer() buf.truth_index = root_util.unsigned_int_value() host_file.cd() name = "MCTruth" long_name = "Monte Carlo Truth information for each entry" mc_truth = TTree(name, long_name) mc_truth.Branch("truth_index", buf.truth_index, "truth_index/i") return mc_truth, buf
def prep_truth_lookup(TTree, host_file, event_types): """Create the MC Truth Lookup TTree (named MCTruthLookup) and fill buffer. Each TBranch has a name which is either an integer, in which case the value on that TBranch is an array of chars describing the event subtype represented by that integer, or the converse: a subtype name with an integer value. This way the expression ``MCTruthLookup->Show(0)`` will print out both directions of lookup. Parameters ---------- host_file : ROOT.TFile The TFile that will hold the MC Truth Lookup TTree event_types : list of :py:class:`EventType` The list of EventType objects to add to the lookup table Returns ------- (mc_truth_lookup ttree, buffer) : tuple The TTree object and the buffer used to fill its TBranches """ labels_by_number = [] numbers_by_label = [] for event_type in event_types: event_labels = event_type.labels() for number, label in event_labels.items(): if number is None or number < 0 or not isinstance(number, int): raise InvalidLookupError(event_type.name, label, number) numbers_by_label.append((label, number)) labels_by_number.append((number, label)) numbers_by_label.sort() labels_by_number.sort() max_label_length = max(len(x[0]) for x in numbers_by_label) buf_size = max_label_length + 1 buf = root_util.TreeBuffer() def new_singleton_array(value): """Return a simple singleton array with value of type char*. There's no root-util function for char arrays so I'm making my own here. Further, python's built-in array.arrays are super inconvenient for bytestrings/char arrays so I'm using numpy.array instead. The "S{}" typecode means null-terminated bytes array with max length of buf_size. """ type_format = "S{}".format(buf_size) return np.array([value], type_format) # Create and initialize the TreeBuffer buffers to the only # values they'll ever take for label, number in numbers_by_label: setattr(buf, label, root_util.unsigned_int_value()) root_util.assign_value(getattr(buf, label), number) for number, label in labels_by_number: setattr(buf, "_{}".format(number), new_singleton_array(label)) host_file.cd() name = "MCTruthLookup" long_name = "Monte Carlo Truth lookup table" mc_truth = TTree(name, long_name) for label, number in numbers_by_label: mc_truth.Branch(label, getattr(buf, label), "{}/i".format(label)) for number, label in labels_by_number: name = "_{}".format(number) mc_truth.Branch(name, getattr(buf, name), "{}[{}]/C".format(name, buf_size)) mc_truth.Fill() return mc_truth, buf
def create_computed_TTree(name, host_file, selection_name, title=None): from ROOT import TTree git_description = git_describe() if title is None: title = ('Computed quantities by Sam Kohn (git: %s)' % git_description) else: try: title = title % git_description except: pass host_file.cd() outdata = TTree(name, title) # Initialize the "buffer" used to fill values into the TTree buffer_depth = 20 fill_buf = TreeBuffer() fill_buf.loopIndex = unsigned_int_value(buffer_depth) fill_buf.multiplicity = unsigned_int_value() fill_buf.timestamp = long_value(buffer_depth) fill_buf.timestamp_seconds = int_value(buffer_depth) fill_buf.timestamp_nanoseconds = int_value(buffer_depth) fill_buf.detector = int_value(buffer_depth) fill_buf.dt_to_prompt = long_value(buffer_depth) fill_buf.dr_to_prompt = float_value(buffer_depth) fill_buf.dt_cluster_to_prev_ADevent = long_value() fill_buf.site = int_value() fill_buf.run = unsigned_int_value() fill_buf.fileno = unsigned_int_value() fill_buf.triggerNumber = int_value(buffer_depth) fill_buf.triggerType = unsigned_int_value(buffer_depth) fill_buf.nHit = int_value(buffer_depth) fill_buf.charge = float_value(buffer_depth) fill_buf.fQuad = float_value(buffer_depth) fill_buf.fMax = float_value(buffer_depth) fill_buf.fPSD_t1 = float_value(buffer_depth) fill_buf.fPSD_t2 = float_value(buffer_depth) fill_buf.f2inch_maxQ = float_value(buffer_depth) fill_buf.Q1 = float_value(buffer_depth) fill_buf.Q2 = float_value(buffer_depth) fill_buf.energy = float_value(buffer_depth) fill_buf.x = float_value(buffer_depth) fill_buf.y = float_value(buffer_depth) fill_buf.z = float_value(buffer_depth) fill_buf.fID = float_value(buffer_depth) fill_buf.fPSD = float_value(buffer_depth) fill_buf.dt_previous_WSMuon = long_value(buffer_depth) fill_buf.dt_previous_ADMuon = long_value(buffer_depth) fill_buf.dt_previous_ShowerMuon = long_value(buffer_depth) def branch_multiple(name, typecode): outdata.Branch(name, getattr(fill_buf, name), '{}[multiplicity]/{}'.format( name, typecode)) return def branch(name, typecode): outdata.Branch(name, getattr(fill_buf, name), '{}/{}'.format(name, typecode)) return # Initialize the new TTree so that each TBranch reads from the # appropriate TreeBuffer attribute branch('multiplicity', 'i') branch_multiple('loopIndex', 'i') branch_multiple('timestamp', 'L') branch_multiple('timestamp_seconds', 'I') branch_multiple('timestamp_nanoseconds', 'I') branch_multiple('detector', 'I') branch_multiple('dt_to_prompt', 'L') branch_multiple('dr_to_prompt', 'F') branch('dt_cluster_to_prev_ADevent', 'L') branch('site', 'I') branch('run', 'i') branch('fileno', 'i') branch_multiple('triggerNumber', 'I') branch_multiple('triggerType', 'I') branch_multiple('nHit', 'I') branch_multiple('charge', 'F') branch_multiple('fQuad', 'F') branch_multiple('fMax', 'F') branch_multiple('fPSD_t1', 'F') branch_multiple('fPSD_t2', 'F') branch_multiple('f2inch_maxQ', 'F') branch_multiple('Q1', 'F') branch_multiple('Q2', 'F') branch_multiple('energy', 'F') branch_multiple('x', 'F') branch_multiple('y', 'F') branch_multiple('z', 'F') branch_multiple('dt_previous_WSMuon', 'L') branch_multiple('dt_previous_ADMuon', 'L') branch_multiple('dt_previous_ShowerMuon', 'L') return outdata, fill_buf