示例#1
0
// clone this node, make its supertree a child, and clone all children
// other than oldNode, leaving this node as a child of nodeToAddTo
static void tree_cloneFlippedTree(stTree *node, stTree *oldNode,
                                  stTree *nodeToAddTo,
                                  double branchLength) {
    if(stTree_getParent(node) != NULL) {
        // This node isn't the root
        stTree *clonedNode = stTree_cloneNode(node);
        stTree_setParent(clonedNode, nodeToAddTo);
        stTree_setBranchLength(clonedNode, branchLength);
        // Clone its children (other than oldNode) and their subtrees
        for(int64_t i = 0; i < stTree_getChildNumber(node); i++) {
            stTree *child = stTree_getChild(node, i);
            if(child != oldNode) {
                stTree *clonedChild = stTree_clone(child);
                stTree_setParent(clonedChild, clonedNode);
            }
        }
        
        // Recurse on the parent of this node.
        tree_cloneFlippedTree(stTree_getParent(node), node,
                              clonedNode, stTree_getBranchLength(node));
    } else {
        // We have to treat the root specially, because we're going to
        // eliminate it. Just add all the other children of the root
        // as children of nodeToAddTo.
        for(int64_t i = 0; i < stTree_getChildNumber(node); i++) {
            stTree *child = stTree_getChild(node, i);
            if(child != oldNode) {
                stTree *clonedChild = stTree_clone(child);
                stTree_setParent(clonedChild, nodeToAddTo);
                stTree_setBranchLength(clonedChild, stTree_getBranchLength(child) + branchLength);
            }
        }
    }
}
示例#2
0
void stTree_setParent(stTree *tree, stTree *parent) {
    if(stTree_getParent(tree) != NULL) {
        stList_removeItem(stTree_getParent(tree)->nodes, tree);
    }
    tree->parent = parent;
    if(parent != NULL) {
        stList_append(parent->nodes, tree);
    }
}
示例#3
0
/* Join at the specified components, returning new root */
static stTree *joinAtNodes(stTree *root1, stTree *node1, stTree *root2, stTree *node2, struct malnCompCompMap *srcDestCompMap) {
    if ((stTree_getParent(node1) == NULL) && (stTree_getParent(node2) == NULL)) {
        assert((root1 == node1) && (root2 == node2));
        return joinTrees(root1, node1, node2, srcDestCompMap);
    } else if (stTree_getParent(node1) == NULL) {
        assert(root1 == node1);
        return joinTrees(root2, node2, node1, srcDestCompMap);
    } else if (stTree_getParent(node2) == NULL) {
        assert(root2 == node2);
        return joinTrees(root1, node1, node2, srcDestCompMap);
    } else {
        errAbort("join nodes don't obey rules: node1: %s node2: %s", stTree_getLabel(node1), stTree_getLabel(node2));
        return NULL;
    }
}
示例#4
0
/* get location type in tree */
enum mafTreeLoc mafTreeNodeCompLink_getLoc(struct mafTreeNodeCompLink *ncLink) {
    if (stTree_getParent(ncLink->node) == NULL) {
        return mafTreeLocRoot;
    } else if (stTree_getChildNumber(ncLink->node) == 0) {
        return mafTreeLocLeaf;
    } else {
        return mafTreeLocInternal;
    }
}
示例#5
0
/* Clone tree1 and then attach the children of tree2 at the copy of the
 * specified attachment point. */
static stTree *joinTrees(stTree *srcRoot1, stTree *srcAttach1, stTree *srcRoot2, struct malnCompCompMap *srcDestCompMap) {
    assertJoinCompatible(srcAttach1, srcRoot2);
    assert(stTree_getParent(srcRoot2) == NULL);
    stTree *joinedRoot = cloneTree(srcRoot1, NULL, srcDestCompMap);
    struct mafTreeNodeCompLink *srcAttach1NcLink = getNodeCompLink(srcAttach1);
    stTree *joinLeaf = searchByComp(joinedRoot, malnCompCompMap_get(srcDestCompMap, srcAttach1NcLink->comp));
    cloneChildren(srcRoot2, joinLeaf, srcDestCompMap);
    return joinedRoot;
}
示例#6
0
stTree *stTree_getMRCA(stTree *node1, stTree *node2) {
    // Find all of node 1's parents (inclusive of node 1)
    stSet *parents = stSet_construct();
    stTree *curNode = node1;
    do {
        stSet_insert(parents, curNode);
    } while ((curNode = stTree_getParent(curNode)) != NULL);

    // Find the first parent of node 2 that is a parent of node 1
    stTree *ret = NULL;
    curNode = node2;
    do {
        if (stSet_search(parents, curNode) != NULL) {
            ret = curNode;
            break;
        }
    } while ((curNode = stTree_getParent(curNode)) != NULL);

    stSet_destruct(parents);
    return ret;
}
示例#7
0
// Return a new tree rooted a given distance above the given node.
stTree *stTree_reRoot(stTree *node, double distanceAbove) {
    if(stTree_getParent(node) == NULL) {
        // This node is already the root.
        stTree *newRoot = stTree_clone(node);
        stTree_clearClientData(newRoot, true);
        return newRoot;
    }

    assert(stTree_getBranchLength(node) >= distanceAbove);

    stTree *newRoot = stTree_construct();
    // This node and its children (if any) are fine already.
    stTree *clonedNode = stTree_clone(node);
    stTree_setParent(clonedNode, newRoot);
    stTree_setBranchLength(clonedNode, distanceAbove);
    tree_cloneFlippedTree(stTree_getParent(node), node, newRoot,
                          stTree_getBranchLength(node) - distanceAbove);
    // Having the same client data can be a problem
    stTree_clearClientData(newRoot, true);
    return newRoot;
}
示例#8
0
/* Remove a node from the tree and free.  Can't delete the root node. */
void mafTree_deleteNode(mafTree *mTree, struct mafTreeNodeCompLink *ncLink) {
    stTree *node = ncLink->node;
    stTree *parent = stTree_getParent(node);
    if (parent == NULL) {
        errAbort("BUG: can't remove tree root node");
    }
    stTree_setParent(node, NULL);
    // setParent changes node children
    while (stTree_getChildNumber(node) > 0) {
        stTree_setParent(stTree_getChild(node, 0), parent);
    }
    freeMafTreeNodeCompLinks(node);
    stTree_destruct(node);
    setCheckTreeOrder(mTree, false);
}