def setupForkItem(doRemoveUnselected = False, outputdump=[]):
    if obs:
        if not outputdump:
            outputdump = []
        kw = {}
        kw['DeclareFork'] = ''
        kw['InitVectors'] = ''
        kw['BackupContent'] = ''
        kw['RestoreContent'] = ''
        kw['SaveContent'] = ''
        kw['LoadContent'] = ''
        for name in sorted(obs.keys()):
            if obs[name].n and (obs[name].modifiable is True or 'Selected' in obs[name].modifiable):
                kw['DeclareFork'] += oneContent('vector<bool>', name.lower()+'_original_selected')
                kw['DeclareFork'] += oneContent('vector<bool>', name.lower()+'_saved_selected')
                kw['DeclareFork'] += oneContent('vector<int>', name.lower()+'_original_order')
                kw['DeclareFork'] += oneContent('vector<int>', name.lower()+'_saved_order')
                kw['InitVectors'] += oneInitVector2(name.lower()+'_original_selected', 'vector<bool>')
                kw['InitVectors'] += oneInitVector2(name.lower()+'_saved_selected', 'vector<bool>')
                kw['InitVectors'] += oneInitVector2(name.lower()+'_original_order', 'vector<int>')
                kw['InitVectors'] += oneInitVector2(name.lower()+'_saved_order', 'vector<int>')
                kw['BackupContent'] += oneCopy('ao->'+name.lower()+'.Selected', name.lower()+'_original_selected', 'vector<bool>')
                kw['RestoreContent'] += oneCopy(name.lower()+'_original_selected', 'ao->'+name.lower()+'.Selected', 'vector<bool>')
                kw['BackupContent'] += oneCopy('ao->'+name.lower()+'.Order', name.lower()+'_original_order', 'vector<int>')
                kw['RestoreContent'] += oneCopy(name.lower()+'_original_order', 'ao->'+name.lower()+'.Order', 'vector<int>')
                kw['SaveContent'] += oneCopy('ao->'+name.lower()+'.Selected', name.lower()+'_saved_selected', 'vector<bool>')
                kw['LoadContent'] += oneCopy(name.lower()+'_saved_selected', 'ao->'+name.lower()+'.Selected', 'vector<bool>')
                kw['SaveContent'] += oneCopy('ao->'+name.lower()+'.Order', name.lower()+'_saved_order', 'vector<int>')
                kw['LoadContent'] += oneCopy(name.lower()+'_saved_order', 'ao->'+name.lower()+'.Order', 'vector<int>')
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[name].findBranch(bname)
                if  obs[name].modifiable is True or \
                    bname in obs[name].modifiable or \
                    ( \
                        (obs[name].isNElems(bname) or baddress == obs[name].n) and \
                        doRemoveUnselected and \
                        (outputdump is True or name in outputdump) and \
                        (obs[name].dumplist is True or bname in obs[name].dumplist)
                    ):
                    kw['DeclareFork'] += oneContent(btype, name.lower()+'_original_'+bname)
                    kw['DeclareFork'] += oneContent(btype, name.lower()+'_saved_'+bname)
                    kw['InitVectors'] += oneInitVector2(name.lower()+'_original_'+bname, btype)
                    kw['InitVectors'] += oneInitVector2(name.lower()+'_saved_'+bname, btype)
                    kw['BackupContent'] += oneCopy('ao->'+name.lower()+'.'+bname, name.lower()+'_original_'+bname, btype)
                    kw['RestoreContent'] += oneCopy(name.lower()+'_original_'+bname, 'ao->'+name.lower()+'.'+bname, btype)
                    kw['SaveContent'] += oneCopy('ao->'+name.lower()+'.'+bname, name.lower()+'_saved_'+bname, btype)
                    kw['LoadContent'] += oneCopy(name.lower()+'_saved_'+bname, 'ao->'+name.lower()+'.'+bname, btype)
        full_str = template_fork % kw
        filepath = filedir+'/../libs/ForkItem_generated.C'
        if not os.path.isfile(filepath) or not open(filepath, 'r').read() == full_str:
            open(filepath, 'w').write(full_str)
        compileC(filepath)
        return True
    return False
Example #2
0
def setupForkItem(doRemoveUnselected=False, outputdump=[]):
    if obs:
        if not outputdump:
            outputdump = []
        kw = {}
        kw['DeclareFork'] = ''
        kw['InitVectors'] = ''
        kw['BackupContent'] = ''
        kw['RestoreContent'] = ''
        kw['SaveContent'] = ''
        kw['LoadContent'] = ''
        for name in sorted(obs.keys()):
            if obs[name].n and (obs[name].modifiable is True
                                or 'Selected' in obs[name].modifiable):
                kw['DeclareFork'] += oneContent(
                    'vector<bool>',
                    name.lower() + '_original_selected')
                kw['DeclareFork'] += oneContent(
                    'vector<bool>',
                    name.lower() + '_saved_selected')
                kw['DeclareFork'] += oneContent(
                    'vector<int>',
                    name.lower() + '_original_order')
                kw['DeclareFork'] += oneContent('vector<int>',
                                                name.lower() + '_saved_order')
                kw['InitVectors'] += oneInitVector2(
                    name.lower() + '_original_selected', 'vector<bool>')
                kw['InitVectors'] += oneInitVector2(
                    name.lower() + '_saved_selected', 'vector<bool>')
                kw['InitVectors'] += oneInitVector2(
                    name.lower() + '_original_order', 'vector<int>')
                kw['InitVectors'] += oneInitVector2(
                    name.lower() + '_saved_order', 'vector<int>')
                kw['BackupContent'] += oneCopy(
                    'ao->' + name.lower() + '.Selected',
                    name.lower() + '_original_selected', 'vector<bool>')
                kw['RestoreContent'] += oneCopy(
                    name.lower() + '_original_selected',
                    'ao->' + name.lower() + '.Selected', 'vector<bool>')
                kw['BackupContent'] += oneCopy(
                    'ao->' + name.lower() + '.Order',
                    name.lower() + '_original_order', 'vector<int>')
                kw['RestoreContent'] += oneCopy(
                    name.lower() + '_original_order',
                    'ao->' + name.lower() + '.Order', 'vector<int>')
                kw['SaveContent'] += oneCopy(
                    'ao->' + name.lower() + '.Selected',
                    name.lower() + '_saved_selected', 'vector<bool>')
                kw['LoadContent'] += oneCopy(
                    name.lower() + '_saved_selected',
                    'ao->' + name.lower() + '.Selected', 'vector<bool>')
                kw['SaveContent'] += oneCopy('ao->' + name.lower() + '.Order',
                                             name.lower() + '_saved_order',
                                             'vector<int>')
                kw['LoadContent'] += oneCopy(name.lower() + '_saved_order',
                                             'ao->' + name.lower() + '.Order',
                                             'vector<int>')
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[
                    name].findBranch(bname)
                if  obs[name].modifiable is True or \
                    bname in obs[name].modifiable or \
                    ( \
                        (obs[name].isNElems(bname) or baddress == obs[name].n) and \
                        doRemoveUnselected and \
                        (outputdump is True or name in outputdump) and \
                        (obs[name].dumplist is True or bname in obs[name].dumplist)
                    ):
                    kw['DeclareFork'] += oneContent(
                        btype,
                        name.lower() + '_original_' + bname)
                    kw['DeclareFork'] += oneContent(
                        btype,
                        name.lower() + '_saved_' + bname)
                    kw['InitVectors'] += oneInitVector2(
                        name.lower() + '_original_' + bname, btype)
                    kw['InitVectors'] += oneInitVector2(
                        name.lower() + '_saved_' + bname, btype)
                    kw['BackupContent'] += oneCopy(
                        'ao->' + name.lower() + '.' + bname,
                        name.lower() + '_original_' + bname, btype)
                    kw['RestoreContent'] += oneCopy(
                        name.lower() + '_original_' + bname,
                        'ao->' + name.lower() + '.' + bname, btype)
                    kw['SaveContent'] += oneCopy(
                        'ao->' + name.lower() + '.' + bname,
                        name.lower() + '_saved_' + bname, btype)
                    kw['LoadContent'] += oneCopy(
                        name.lower() + '_saved_' + bname,
                        'ao->' + name.lower() + '.' + bname, btype)
        full_str = template_fork % kw
        filepath = filedir + '/../libs/ForkItem_generated.C'
        if not os.path.isfile(filepath) or not open(filepath,
                                                    'r').read() == full_str:
            open(filepath, 'w').write(full_str)
        compileC(filepath)
        return True
    return False
Example #3
0
def setupBranches(modules, name=None, location=None, outputdump=[]):
    global AllObjects
    global obs

    if not outputdump:
        outputdump = []
    obs = {}

    # Populate physics objects, merging them if more than one provided
    for m in modules:
        for o in m.__dict__.values():
            if not hasattr(o, '__bases__'):
                continue
            if not PhysicsObjectBase in o.__bases__:
                continue

            if o.__name__ in obs:
                print "\tDuplicate objects found:", obs[
                    o.__name__], "with", o, "... will merge contents"
                for attrname in o.__dict__:
                    if attrname.startswith('__') and attrname.endswith('__'):
                        continue

                    storedattr = None
                    if hasattr(obs[o.__name__], attrname):
                        storedattr = getattr(obs[o.__name__], attrname)
                    currentattr = getattr(o, attrname)

                    if storedattr == currentattr:
                        continue
                    print "\t\tWARNING:", "'" + attrname + "'", "is inconsistent ... preferring the latter"

                    if storedattr is None:
                        print "\t\t\tElement", storedattr, "was replaced with", currentattr
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif not storedattr and type(currentattr) is list:
                        print "\t\t\tElement", storedattr, "was replaced with a list of", len(
                            currentattr), "items"
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif type(storedattr) is list and currentattr is True:
                        print "\t\t\tElement with", len(
                            storedattr), "items was replaced with", currentattr
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif not type(storedattr) is list and not type(
                            currentattr) is list:
                        print "\t\t\tElement", storedattr, "was replaced with", currentattr
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif type(storedattr) is list and type(
                            currentattr) is list:
                        for el in currentattr:
                            if type(el) is tuple:
                                found = False
                                for i in range(len(storedattr)):
                                    if el[0] == storedattr[i][0]:
                                        if not storedattr[i] == el:
                                            print "\t\t\tElement", storedattr[
                                                i], "was replaced with", el
                                            storedattr[i] = el
                                        found = True
                                        break
                                if not found:
                                    print "\t\t\tElement", el, "is added"
                                    storedattr.append(el)
                            else:
                                if not el in storedattr:
                                    print "\t\t\tElement '" + el + "'", "is added"
                                    storedattr.append(el)
                    else:
                        print "\t\tERROR: don't know how to handle inconsistencies in", "'" + attr + "'", "... report this problem to the devs!"
            else:
                obs[o.__name__] = o

    # Search for duplicates in D3PD addresses - this will cause memory issues!
    d3pdlist = {}
    d3pdduplicates = []
    for oname in obs:
        o = obs[oname]
        for attrname in o.__dict__:
            if attrname.startswith('__') and attrname.endswith('__'):
                continue
            currentattr = getattr(o, attrname)
            if type(currentattr) is list:
                for el in currentattr:
                    if not type(el) is tuple:
                        continue
                    if el[1] in d3pdlist:
                        d3pdduplicates.append(el[1])
                        d3pdlist[el[1]].append(oname + '.' + attrname + '.' +
                                               el[0])
                    else:
                        d3pdlist[el[1]] = [
                            oname + '.' + attrname + '.' + el[0]
                        ]
    if d3pdduplicates:
        print "\tERROR: Duplicates found in D3PD branch addresses!"
        print "\tPlease resolve the following D3PD branches:"
        for d in d3pdduplicates:
            print "\t\t", d, "used in", ", ".join(d3pdlist[d])
        print "\tStopping program as this will cause memory issues with TChain.GetEntry!"
        sys.exit(1)

    # Make a list of branches and their types
    inputtree_branches = {}
    inputtree_branches_num = {}
    tree = None
    if name and location:
        from ROOT import TFile, AddressOf
        for filepath in location:
            treefile = TFile.Open(filepath)
            tree = treefile.Get(name)
            for leaf in tree.GetListOfLeaves():
                inputtree_branches[leaf.GetName()] = leaf.GetTypeName()
                inputtree_branches_num.setdefault(leaf.GetName(), 0)
                inputtree_branches_num[leaf.GetName()] += 1
            treefile.Close()
    numfiles = len(location)

    exist_in_inputtree = []
    if obs:
        error = False
        for name in sorted(obs.keys()):
            # Expand branches with wildcards
            elems_new = []
            n_elems_new = []
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[
                    name].findBranch(bname)
                if baddress == obs[name].n:
                    continue
                if not baddress.endswith('*'):
                    if obs[name].isNElems(bname):
                        n_elems_new.append(
                            (bname, baddress, btype[len('vector<'):-1].strip(),
                             bdefault, bbranch))
                    else:
                        elems_new.append(
                            (bname, baddress, btype, bdefault, bbranch))
                    continue

                if not tree:
                    print "@@@@@ WARNING: Need to load ntuple to declare wildcard branches! Skipping branch:", bd3pd
                    return False

                for l in inputtree_branches:
                    if l.startswith(baddress[:-1]):
                        bname2 = bname + l[len(baddress) - 1:].replace(
                            '::', '__')
                        baddress2 = l
                        btype2 = inputtree_branches[l]
                        if l == obs[name].n:
                            continue
                        if obs[name].n:
                            n_elems_new.append(obs[name].makeFullTuple(
                                (bname2, baddress2,
                                 btype2[len('vector<'):-1].strip())))
                        else:
                            elems_new.append(obs[name].makeFullTuple(
                                (bname2, baddress2, btype2)))
            obs[name].n_elems = n_elems_new
            obs[name].elems = elems_new

            # Find unstable branches
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[
                    name].findBranch(bname)
                if baddress in inputtree_branches:
                    exist_in_inputtree.append(baddress)
                    if not inputtree_branches_num[baddress] == numfiles:
                        obs[name].unstable.append(bname)

            # Make dumplist
            if obs[name].dumplist is None and obs[name].nodumplist is None:
                obs[name].dumplist = True
            elif obs[name].dumplist is None:
                obs[name].dumplist = []
                for bname in obs[name].elemsList():
                    bname, baddress, btype, bdefault, bbranch = obs[
                        name].findBranch(bname)
                    if not bname in obs[name].nodumplist:
                        obs[name].dumplist.append(bname)
            elif obs[name].nodumplist is None:
                pass  # already right configuration - do nothing
            else:
                print "@@@@@ ERROR: Only nodumplist OR dumplist may be set, not both at once. Object name:", name
                error = True
            if type(obs[name].dumplist) is list and obs[
                    name].n and not 'n' in obs[name].dumplist:
                obs[name].dumplist.insert(0, 'n')
        if error:
            return False

        # Generate the code
        kw = {}
        kw['PhysicsObjects'] = ''
        kw['AllObjectsContent'] = ''
        kw['AllObjectsPrivateContent'] = ''
        kw['ResetDefaultValues'] = ''
        kw['ForceResetDefaultValues'] = ''
        kw['InitialiseVectors'] = ''
        kw['ResetSelected'] = ''
        kw['RemoveSelected'] = ''
        for name in sorted(obs.keys()):
            kw['StructName'] = name
            kw['StructContent'] = ''
            kw['InstanceName'] = name.lower()
            kw['CopyOrdered'] = ''
            kw['RemoveContentOrdered'] = ''
            kw['RemoveContent'] = ''
            kw['RemoveResize'] = ''
            missing_in_inputtree = []
            inconsistent_type = []

            if obs[name].n:
                kw['StructContent'] += oneContent('vector<bool>', 'Selected')
                kw['StructContent'] += oneContent('vector<int>', 'Order')
                kw['InitialiseVectors'] += oneInitVector(
                    name.lower(), 'Selected', 'vector<bool>')
                kw['InitialiseVectors'] += oneInitVector(
                    name.lower(), 'Order', 'vector<int>')
                kw['ResetSelected'] += oneSelected(name.lower())
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[
                    name].findBranch(bname)
                kw['StructContent'] += oneContent(btype, bname)
                kw['InitialiseVectors'] += oneInitVector(
                    name.lower(), bname, btype)
                if not baddress in exist_in_inputtree or bname in obs[
                        name].unstable:
                    if btype.startswith('vector<'):
                        kw['ResetDefaultValues'] += oneDefault(
                            name.lower(), bname, 'CLEAR')
                        if obs[name].n and not bdefault == 'CLEAR':
                            kw['ResetSelected'] += oneDefault(
                                name.lower(), bname, bdefault, btype)
                    elif baddress in exist_in_inputtree and \
                            bname in obs[name].unstable and \
                            not (obs[name].modifiable is True or bname in obs[name].modifiable):
                        kw['ForceResetDefaultValues'] += oneDefault(
                            name.lower(), bname, bdefault)
                    else:
                        kw['ResetDefaultValues'] += oneDefault(
                            name.lower(), bname, bdefault)
                if not baddress in exist_in_inputtree:
                    missing_in_inputtree.append((bname, baddress))
                else:
                    btype2 = inputtree_branches[baddress]
                    if not btype2 == btype:
                        inconsistent_type.append((bname, btype, btype2))

                if obs[name].isNElems(bname) and (obs[name].dumplist is True or
                                                  bname in obs[name].dumplist):
                    kw['AllObjectsPrivateContent'] += oneContent(
                        btype, '__copy_' + name.lower() + '_' + bname)
                    kw['InitialiseVectors'] += oneInitVector2(
                        '__copy_' + name.lower() + '_' + bname, btype)
                    kw['CopyOrdered'] += oneCopy(
                        name.lower() + '.' + bname,
                        '__copy_' + name.lower() + '_' + bname, btype)
                    if not baddress in exist_in_inputtree or bname in obs[
                            name].unstable:
                        kw['RemoveContentOrdered'] += oneRemoveContentOrderedCheck(
                            name.lower(), bname)
                        kw['RemoveContent'] += oneRemoveContentCheck(
                            name.lower(), bname)
                        kw['RemoveResize'] += oneRemoveResizeCheck(
                            name.lower(), bname)
                    else:
                        kw['RemoveContentOrdered'] += oneRemoveContentOrdered(
                            name.lower(), bname)
                        kw['RemoveContent'] += oneRemoveContent(
                            name.lower(), bname)
                        kw['RemoveResize'] += oneRemoveResize(
                            name.lower(), bname)

            kw['PhysicsObjects'] += template_struct % kw
            kw['AllObjectsContent'] += oneContent(name, name.lower())
            if obs[name].n and (outputdump is True or name in outputdump):
                kw['RemoveSelected'] += template_remove % kw
            if missing_in_inputtree:
                print "@@@@@ WARNING: The following branches are missing from input files in", name, ":"
                for btuple in missing_in_inputtree:
                    print "     %30s : %s" % btuple
            if inconsistent_type:
                print "@@@@@ WARNING: The following branches have inconsistent types in", name, ":"
                for btuple in inconsistent_type:
                    print "     %30s : Declared as: %-30s In input file: %-30s" % btuple

        full_str = template_full % kw
        filepath = filedir + '/../libs/Branches_generated.C'
        if not os.path.isfile(filepath) or not open(filepath,
                                                    'r').read() == full_str:
            open(filepath, 'w').write(full_str)
        compileC(filepath)
        from ROOT import AnalysisFramework
        AllObjects = AnalysisFramework.Branches.AllObjects
        return True
    return False
def setupBranches(modules, name=None, location=None, outputdump=[]):
    global AllObjects
    global obs

    if not outputdump:
        outputdump = []
    obs = {}

    # Populate physics objects, merging them if more than one provided
    for m in modules:
        for o in m.__dict__.values():
            if not hasattr(o, '__bases__'):
                continue
            if not PhysicsObjectBase in o.__bases__:
                continue

            if o.__name__ in obs:
                print "\tDuplicate objects found:", obs[o.__name__], "with", o, "... will merge contents"
                for attrname in o.__dict__:
                    if attrname.startswith('__') and attrname.endswith('__'):
                        continue
                    
                    storedattr = None
                    if hasattr(obs[o.__name__], attrname):
                        storedattr = getattr(obs[o.__name__], attrname)
                    currentattr = getattr(o, attrname)

                    if storedattr == currentattr:
                        continue
                    print "\t\tWARNING:", "'"+attrname+"'", "is inconsistent ... preferring the latter"

                    if storedattr is None:
                        print "\t\t\tElement", storedattr, "was replaced with", currentattr
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif not storedattr and type(currentattr) is list:
                        print "\t\t\tElement", storedattr, "was replaced with a list of", len(currentattr), "items"
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif type(storedattr) is list and currentattr is True:
                        print "\t\t\tElement with", len(storedattr), "items was replaced with", currentattr
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif not type(storedattr) is list and not type(currentattr) is list:
                        print "\t\t\tElement", storedattr, "was replaced with", currentattr
                        setattr(obs[o.__name__], attrname, currentattr)
                    elif type(storedattr) is list and type(currentattr) is list:
                        for el in currentattr:
                            if type(el) is tuple:
                                found = False
                                for i in range(len(storedattr)):
                                    if el[0] == storedattr[i][0]:
                                        if not storedattr[i] == el:
                                            print "\t\t\tElement", storedattr[i], "was replaced with", el
                                            storedattr[i] = el
                                        found = True
                                        break
                                if not found:
                                    print "\t\t\tElement", el, "is added"
                                    storedattr.append(el)
                            else:
                                if not el in storedattr:
                                    print "\t\t\tElement '"+el+"'", "is added"
                                    storedattr.append(el)
                    else:
                        print "\t\tERROR: don't know how to handle inconsistencies in", "'"+attr+"'", "... report this problem to the devs!"
            else:
                obs[o.__name__] = o

    # Search for duplicates in D3PD addresses - this will cause memory issues!
    d3pdlist = {}
    d3pdduplicates = []
    for oname in obs:
        o = obs[oname]
        for attrname in o.__dict__:
            if attrname.startswith('__') and attrname.endswith('__'):
                continue
            currentattr = getattr(o, attrname)
            if type(currentattr) is list:
                for el in currentattr:
                    if not type(el) is tuple:
                        continue
                    if el[1] in d3pdlist:
                        d3pdduplicates.append(el[1])
                        d3pdlist[el[1]].append(oname + '.' + attrname + '.' + el[0])
                    else:
                        d3pdlist[el[1]] = [oname + '.' + attrname + '.' + el[0]]
    if d3pdduplicates:
        print "\tERROR: Duplicates found in D3PD branch addresses!"
        print "\tPlease resolve the following D3PD branches:"
        for d in d3pdduplicates:
            print "\t\t", d, "used in", ", ".join(d3pdlist[d])
        print "\tStopping program as this will cause memory issues with TChain.GetEntry!"
        sys.exit(1)

    # Make a list of branches and their types
    inputtree_branches = {}
    inputtree_branches_num = {}
    tree = None
    if name and location:
        from ROOT import TFile, AddressOf
        for filepath in location:
            treefile = TFile.Open(filepath)
            tree = treefile.Get(name)
            for leaf in tree.GetListOfLeaves():
                inputtree_branches[leaf.GetName()] = leaf.GetTypeName()
                inputtree_branches_num.setdefault(leaf.GetName(), 0)
                inputtree_branches_num[leaf.GetName()] += 1
            treefile.Close()
    numfiles = len(location)

    exist_in_inputtree = []
    if obs:
        error = False
        for name in sorted(obs.keys()):
            # Expand branches with wildcards
            elems_new = []
            n_elems_new = []
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[name].findBranch(bname)
                if baddress == obs[name].n:
                    continue
                if not baddress.endswith('*'):
                    if obs[name].isNElems(bname):
                        n_elems_new.append( (bname, baddress, btype[len('vector<'):-1].strip(), bdefault, bbranch) )
                    else:
                        elems_new.append( (bname, baddress, btype, bdefault, bbranch) )
                    continue

                if not tree:
                    print "@@@@@ WARNING: Need to load ntuple to declare wildcard branches! Skipping branch:", bd3pd
                    return False

                for l in inputtree_branches:
                    if l.startswith(baddress[:-1]):
                        bname2 = bname + l[len(baddress)-1:].replace('::', '__')
                        baddress2 = l
                        btype2 = inputtree_branches[l]
                        if l == obs[name].n:
                            continue
                        if obs[name].n:
                            n_elems_new.append( obs[name].makeFullTuple( (bname2, baddress2, btype2[len('vector<'):-1].strip()) ) )
                        else:
                            elems_new.append( obs[name].makeFullTuple( (bname2, baddress2, btype2) ) )
            obs[name].n_elems = n_elems_new
            obs[name].elems = elems_new

            # Find unstable branches
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[name].findBranch(bname)
                if baddress in inputtree_branches:
                    exist_in_inputtree.append(baddress)
                    if not inputtree_branches_num[baddress] == numfiles:
                        obs[name].unstable.append(bname)

            # Make dumplist
            if obs[name].dumplist is None and obs[name].nodumplist is None:
                obs[name].dumplist = True
            elif obs[name].dumplist is None:
                obs[name].dumplist = []
                for bname in obs[name].elemsList():
                    bname, baddress, btype, bdefault, bbranch = obs[name].findBranch(bname)
                    if not bname in obs[name].nodumplist:
                        obs[name].dumplist.append(bname)  
            elif obs[name].nodumplist is None:
                pass # already right configuration - do nothing
            else:
                print "@@@@@ ERROR: Only nodumplist OR dumplist may be set, not both at once. Object name:", name
                error = True
            if type(obs[name].dumplist) is list and obs[name].n and not 'n' in obs[name].dumplist:
                obs[name].dumplist.insert(0, 'n')
        if error:
            return False

        # Generate the code
        kw = {}
        kw['PhysicsObjects'] = ''
        kw['AllObjectsContent'] = ''
        kw['AllObjectsPrivateContent'] = ''
        kw['ResetDefaultValues'] = ''
        kw['ForceResetDefaultValues'] = ''
        kw['InitialiseVectors'] = ''
        kw['ResetSelected'] = ''
        kw['RemoveSelected'] = ''
        for name in sorted(obs.keys()):
            kw['StructName'] = name
            kw['StructContent'] = ''
            kw['InstanceName'] = name.lower()
            kw['CopyOrdered'] = ''
            kw['RemoveContentOrdered'] = ''
            kw['RemoveContent'] = ''
            kw['RemoveResize'] = ''
            missing_in_inputtree = []
            inconsistent_type = []

            if obs[name].n:
                kw['StructContent'] += oneContent('vector<bool>', 'Selected')
                kw['StructContent'] += oneContent('vector<int>', 'Order')
                kw['InitialiseVectors'] += oneInitVector(name.lower(), 'Selected', 'vector<bool>')
                kw['InitialiseVectors'] += oneInitVector(name.lower(), 'Order', 'vector<int>')
                kw['ResetSelected'] += oneSelected(name.lower())
            for bname in obs[name].elemsList():
                bname, baddress, btype, bdefault, bbranch = obs[name].findBranch(bname)
                kw['StructContent'] += oneContent(btype, bname)
                kw['InitialiseVectors'] += oneInitVector(name.lower(), bname, btype)
                if not baddress in exist_in_inputtree or bname in obs[name].unstable:
                    if btype.startswith('vector<'):
                        kw['ResetDefaultValues'] += oneDefault(name.lower(), bname, 'CLEAR')
                        if obs[name].n and not bdefault == 'CLEAR':
                            kw['ResetSelected'] += oneDefault(name.lower(), bname, bdefault, btype)
                    elif baddress in exist_in_inputtree and \
                            bname in obs[name].unstable and \
                            not (obs[name].modifiable is True or bname in obs[name].modifiable):
                        kw['ForceResetDefaultValues'] += oneDefault(name.lower(), bname, bdefault)
                    else:
                        kw['ResetDefaultValues'] += oneDefault(name.lower(), bname, bdefault)
                if not baddress in exist_in_inputtree:
                    missing_in_inputtree.append( (bname, baddress) )
                else:
                    btype2 = inputtree_branches[baddress]
                    if not btype2 == btype:
                        inconsistent_type.append( (bname, btype, btype2) )

                if obs[name].isNElems(bname) and (obs[name].dumplist is True or bname in obs[name].dumplist):
                    kw['AllObjectsPrivateContent'] += oneContent(btype, '__copy_'+name.lower()+'_'+bname)
                    kw['InitialiseVectors'] += oneInitVector2('__copy_'+name.lower()+'_'+bname, btype)
                    kw['CopyOrdered'] += oneCopy(name.lower()+'.'+bname, '__copy_'+name.lower()+'_'+bname, btype)
                    if not baddress in exist_in_inputtree or bname in obs[name].unstable:
                        kw['RemoveContentOrdered'] += oneRemoveContentOrderedCheck(name.lower(), bname)
                        kw['RemoveContent'] += oneRemoveContentCheck(name.lower(), bname)
                        kw['RemoveResize'] += oneRemoveResizeCheck(name.lower(), bname)
                    else:
                        kw['RemoveContentOrdered'] += oneRemoveContentOrdered(name.lower(), bname)
                        kw['RemoveContent'] += oneRemoveContent(name.lower(), bname)
                        kw['RemoveResize'] += oneRemoveResize(name.lower(), bname)

            kw['PhysicsObjects'] += template_struct % kw
            kw['AllObjectsContent'] += oneContent(name, name.lower())
            if obs[name].n and (outputdump is True or name in outputdump):
                kw['RemoveSelected'] += template_remove % kw
            if missing_in_inputtree:
                print "@@@@@ WARNING: The following branches are missing from input files in", name, ":"
                for btuple in missing_in_inputtree:
                    print "     %30s : %s" % btuple
            if inconsistent_type:
                print "@@@@@ WARNING: The following branches have inconsistent types in", name, ":"
                for btuple in inconsistent_type:
                    print "     %30s : Declared as: %-30s In input file: %-30s" % btuple

        full_str = template_full % kw
        filepath = filedir+'/../libs/Branches_generated.C'
        if not os.path.isfile(filepath) or not open(filepath, 'r').read() == full_str:
            open(filepath, 'w').write(full_str)
        compileC(filepath)
        from ROOT import AnalysisFramework
        AllObjects = AnalysisFramework.Branches.AllObjects
        return True
    return False