Example #1
0
def pathdiff(paths, joiner):
    """
    Return the appropriate destination for an object.
    
    In all cases, the result will be placed in the deepest directory shared by
    all paths.  If the histogram names are the same, the result will be named
    based on the first directories that they do not share.  Otherwise, the 
    result will be named based on the names of the other histograms.

    >>> pathdiff(['/dirA/dirB/dirX/hist', '/dirA/dirB/dirY/hist'], '_div_')
    '/dirA/dirB/dirX_div_dirY'
    >>> pathdiff(['/dirA/hist1', '/dirA/hist2', '/dirA/hist3'], '_plus_')
    '/dirA/hist1_plus_hist2_plus_hist3'
    >>> pathdiff(['/hist1', '/dirA/hist2'], '_minus_')
    '/hist1_minus_hist2'
    """
    paths = [x.split('/') for x in paths]
    dest = '/'
    for i in range(len(paths[0])):
        if allsame([p[i] for p in paths]):
            dest = joined(dest, paths[0][i])
        else:
            break
    name = joiner.join([p[-1] for p in paths])
    if allsame([p[-1] for p in paths]):
        for i in range(len(paths[0])):
            if not allsame([p[i] for p in paths]):
                name = joiner.join([p[i] for p in paths])
    return joined(dest, name)
Example #2
0
def newadd(outfile, targets, dest_path=""):
    """Description."""
    if allsame([x.filename for x in targets]):
        f = ROOT.TFile(targets[0].filename, 'read')
        paths = [x.path for x in targets]
        scales = [x.scale for x in targets]
        scale_errors = [x.scale_error for x in targets]
        if f.GetDirectory(paths[0]):
            destdir = pathdiff2(paths)    # What does this do?
            for h in [os.path.basename(x) for x in
                      rootglob(f, paths[0] + '/*')]:
                hists = [f.GetDirectory(x).Get(h) for x in paths]
                if not alltrue([x and x.InheritsFrom('TH1') for x in hists]):
                    continue
                dest = joined(destdir, h)
                add(outfile, dest, hists, scales, dest_path, scale_errors=scale_errors)
        else:
            hists = [f.Get(x) for x in paths]
            if alltrue([x and x.InheritsFrom('TH1') for x in hists]):
                dest = pathdiff2(paths)
                add(outfile, dest, hists, scales, scale_errors=scale_errors)
    else:
        dict_targets = {}  # Stores paths and scales, key = filename
        dict_tfiles = {}   # Stores map from filenames to Root.TFile() objects
        for target in targets:
            dict_targets.setdefault(target.filename, []).append((target.path, target.scale))
            if (target.filename not in dict_tfiles):
                # Only open root files once
                dict_tfiles[target.filename] = ROOT.TFile(target.filename, 'read')
        # dict_targets now a dictionary, with keys the filenames, example:
        # {'fileA.root': [('path0',scale0), ('path1', scale1)],
        #  'fileB.root': [('path3', scale3)]}
        f = ROOT.TFile(targets[0].filename, 'read')
        if f.GetDirectory(targets[0].path):
            # Create list of histograms to get
            destdir = '/'               # should probably use pathdiff2 somehow
            histnames = [os.path.basename(x) for x in
                         rootglob(f, targets[0].path + '/*')]
            f.Close()
            # For each histogram name found, grab it from
            # every file & path
            for histname in histnames:
                hists = []
                scales = []
                for filename in dict_targets:
                    tfile_cur = dict_tfiles[filename]
                    for path, scale in dict_targets[filename]:
                        hists.append(tfile_cur.GetDirectory(path).Get(histname))
                        scales.append(scale)
                        #print "%s:%s:%s:%f" % (filename, path, histname, scale)
                if not alltrue([x and x.InheritsFrom('TH1') for x in hists]):
                    continue
                dest = joined(destdir, histname)
                add(outfile, dest, hists, scales, dest_path)
        else:
            print "Code not written yet to add histograms from multiple files"
            return
        return
Example #3
0
def pathdiff3(paths, joiner='__'):
    """
    Return the appropriate destination for an object.
    
    If the final objects in each path match, then the return value will be the
    matching part of the paths.  Otherwise, the output path will simply be those
    names joined together with *joiner*.  See the examples below.
    
    >>> pathdiff3(['/dirA/dirX/hist', '/dirA/dirY/hist'])
    '/hist'
    >>> pathdiff3(['/dirA/dirX/dirB/hist', '/dirA/dirY/dirB/hist'])
    '/dirB/hist'
    >>> pathdiff3(['/dirA/hist1', '/dirA/hist2', '/dirA/hist3'], '_plus_')
    '/hist1_plus_hist2_plus_hist3'
    >>> pathdiff3(['/hist1', '/dirA/hist2'], '_div_')
    '/hist1_div_hist2'
    """
    paths = [x.split('/') for x in paths]
    if allsame([x[-1] for x in paths]):
        dest = paths[0][-1]
        for i in range(-2, min([len(x) for x in paths]) * -1, -1):
            if allsame([p[i] for p in paths]):
                dest = joined(paths[0][i], dest)
            else:
                break
        return '/' + dest
    else:
        return '/' + joiner.join([x[-1] for x in paths])
Example #4
0
def walk_rootfile(rootfile, path=''):
    #### Yield (path, folders, objects) for each directory under path.
    keys = rootfile.GetDirectory(path).GetListOfKeys()
    folders, objects = [], []
    for key in keys:
        name = key.GetName()
        classname = key.GetClassName()
        newpath = joined(path, name)
        dimension = 0
        if 'TDirectory' in classname:
            folders.append(name)
        else:
            objects.append(name)
    yield path, folders, objects
    for folder in folders:
        for x in walk_rootfile(rootfile, joined(path, folder)):
            yield x
Example #5
0
def pathdiff2(paths, joiner='__', truncate=False):
    """
    Placeholder.
    """
    paths = [x.split('/') for x in paths]
    commonbeginning = ''
    for i in range(len(paths[0])):
        if allsame([p[i] for p in paths]):
            commonbeginning = joined(commonbeginning, paths[0][i])
        else:
            break
    commonending = ''
    for i in range(-1, -1 * len(paths[0]), -1):
        if allsame([p[i] for p in paths]):
            commonending = joined(paths[0][i], commonending)
        else:
            break
    #return commonbeginning, commonending
    if truncate:
        return commonending
    else:
        return joined(commonbeginning, commonending)
Example #6
0
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('filenames', type=str, nargs='+',
                       help='root files to process')
    parser.add_argument('--dirs', type=str, nargs='+', default=['/'],
                        help='target directories in the root files; paths to '
                        'histograms will be relative to these')
    parser.add_argument('--add', default=[], action='append', nargs='*',
                        help='a list of directories or histograms to add')
    parser.add_argument('--subtract', default=[], action='append', nargs='*',
                        help='a list of directories or histograms to subtract')
    parser.add_argument('--divide', default=[], action='append', nargs='*',
                        help='2 directories or histograms to divide')
    parser.add_argument('--bayes-divide', default=[], action='append', nargs='*',
                        help='2 directories or histograms from which to make '
                        'an efficiency plot')
    args = parser.parse_args()
    separators = {'add' : '_plus_',
                  'subtract' : '_minus_',
                  'divide' : '_div_',
                  'bayes_divide' : '_eff_'}

    files = [ROOT.TFile(x, 'read') for x in args.filenames]
    outfile = ROOT.TFile('out.root', 'recreate')
    dirs = []
    for d in args.dirs:
        dirs += rootglob(files[0], d)

    if len(files) == 1:
        f = files[0]
        for thisdir in dirs:
            for operation_type, separator in separators.items():
                for arg_set in getattr(args, operation_type):
                    paths = [joined(thisdir, x) for x in arg_set]
                    if f.GetDirectory(paths[0]):
                        destdir = pathdiff(paths, separator)
                        for target in [os.path.basename(x) for x in
                                       rootglob(f, paths[0] + '/*')]:
                            hists = [f.GetDirectory(x).Get(target)
                                     for x in paths]
                            if not alltrue([x and x.InheritsFrom('TH1')
                                            for x in hists]):
                                continue
                            dest = joined(destdir, target)
                            math_func = globals()[operation_type]
                            math_func(outfile, dest, hists)
                    else:
                        hists = [f.GetDirectory(thisdir).Get(x) for x in paths]
                        if not alltrue([x and x.InheritsFrom('TH1') 
                                        for x in hists]):
                            continue
                        dest = pathdiff(paths, separator)
                        math_func = globals()[operation_type]
                        math_func(outfile, dest, hists)
    else:
        for operation_type, separator in separators.items():
            arg_sets = getattr(args, operation_type)
            if arg_sets and arg_sets != [[]]:
                raise ValueError("No arguments to --%s allowed when multiple "
                                 "files are specified" % operation_type)
            elif arg_sets:
                if 'divide' in operation_type and len(files) != 2:
                    raise ValueError("Exactly 2 files are expected with --%s; "
                                     "%i given" % (operation_type, len(files)))
                for path, folders, objects in walk_rootfile(files[0]):
                    for obj in objects:
                        hists = [x.GetDirectory(path).Get(obj) for x in files]
                        if not alltrue([x and x.InheritsFrom('TH1') 
                                        for x in hists]):
                            continue
                        math_func = globals()[operation_type]
                        math_func(outfile, joined(path, obj), hists)

    outfile.Close()