'walking a tree bottom-up based on dictionary'

def calc_prob(self, tree, parent=None):

    endog = self.endog
    datadict = self.datadict
    paramsind = self.paramsind
    branchsum = self.branchsum
    if isinstance(tree, tuple):
        (name, subtree) = tree
        self.branchleaves[name] = []
        tau = self.recursionparams[self.paramsidx[('tau_' + name)]]
        if DEBUG:
            print('-----------    starting    next    branch-----------')
            print(name, datadict[name], 'tau=', tau)
            print('subtree', subtree)
        branchvalue = []
        if (testxb == 2):
            branchsum = 0
        elif (testxb == 1):
            branchsum = datadict[name]
        else:
            branchsum = name
        for b in subtree:
            if DEBUG:
                print(b)
            bv = self.calc_prob(b, name)
            bv = np.exp((bv / tau))
            branchvalue.append(bv)
            branchsum = (branchsum + bv)
        self.branchvalues[name] = branchvalue
        if DEBUG:
            print('-----------    returning    to    branch-----------')
            print(name)
            print('branchsum    in    branch', name, branchsum)
        if parent:
            if DEBUG:
                print('parent', parent)
            self.branchleaves[parent].extend(self.branchleaves[name])
        if 0:
            tmpsum = 0
            for k in self.branchleaves[name]:
                tmpsum += self.probs[k]
                iv = np.log(tmpsum)
            for k in self.branchleaves[name]:
                self.probstxt[k] = (self.probstxt[k] + [((('*' + name) + '-prob') + ('(%s)' % ',    '.join(self.paramsind[name])))])
                self.probs[k] = (self.probs[k] / tmpsum)
                if (np.size(self.datadict[name]) > 0):
                    if DEBUG:
                        print('self.datadict[name],    self.probs[k]')
                        print(self.datadict[name], self.probs[k])
        self.bprobs[name] = []
        for (bidx, b) in enumerate(subtree):
            if DEBUG:
                print('repr(b)', repr(b), bidx)
            if (not isinstance(b, tuple)):
                self.bprobs[name].append(self.probs[b])
                self.probs[b] = (self.probs[b] / branchsum)
                if DEBUG:
                    print('***********    branchsum    at    bottom    branch', branchsum)
            else:
                bname = b[0]
                branchsum2 = sum(self.branchvalues[name])
                assert (np.abs((branchsum - branchsum2)).sum() < 1e-08)
                bprob = (branchvalue[bidx] / branchsum)
                self.bprobs[name].append(bprob)
                for k in self.branchleaves[bname]:
                    if DEBUG:
                        print('branchprob', bname, k, bprob, branchsum)
                    self.probs[k] = (self.probs[k] * np.maximum(bprob, 0.0001))
        if DEBUG:
            print('working    on    branch', tree, branchsum)
        if (testxb < 2):
            return branchsum
        else:
            self.branchsums[name] = branchsum
            if (np.size(self.datadict[name]) > 0):
                branchxb = np.sum((self.datadict[name] * self.recursionparams[self.parinddict[name]]))
            else:
                branchxb = 0
            if (not (name == 'top')):
                tau = self.recursionparams[self.paramsidx[('tau_' + name)]]
            else:
                tau = 1
            iv = (branchxb + (tau * branchsum))
            return (branchxb + (tau * np.log(branchsum)))
    else:
        tau = self.recursionparams[self.paramsidx[('tau_' + parent)]]
        if DEBUG:
            print('parent', parent)
        self.branchleaves[parent].append(tree)
        self.probstxt[tree] = [((tree + '-prob') + ('(%s)' % ',    '.join(self.paramsind[tree])))]
        leafprob = np.exp((np.sum((self.datadict[tree] * self.recursionparams[self.parinddict[tree]])) / tau))
        self.probs[tree] = leafprob
        if (testxb == 2):
            return np.log(leafprob)
        elif (testxb == 1):
            leavessum = np.array(datadict[tree])
            if DEBUG:
                print('final    branch    with', tree, ''.join(tree), leavessum)
            return leavessum
        elif (testxb == 0):
            return ''.join(tree)
