// 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); } } } }
/* 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); }
/* recursively clone a tree */ static stTree *cloneTree(stTree *srcNode, stTree *destParent, struct malnCompCompMap *srcDestCompMap) { stTree *destNode = cloneNode(srcNode, srcDestCompMap); stTree_setParent(destNode, destParent); for (int i = 0; i < stTree_getChildNumber(srcNode); i++) { cloneTree(stTree_getChild(srcNode, i), destNode, srcDestCompMap); } return destNode; }
/* recursively clone a tree */ static stTree *tree_clonetree(stTree *node, stTree *parent2) { stTree *node2 = stTree_cloneNode(node); stTree_setParent(node2, parent2); for (int i = 0; i < stTree_getChildNumber(node); i++) { tree_clonetree(stTree_getChild(node, i), node2); } return node2; }
static stTree *eventTree_getStTree_R(Event *event) { stTree *ret = stTree_construct(); stTree_setLabel(ret, stString_print("%" PRIi64, event_getName(event))); stTree_setBranchLength(ret, event_getBranchLength(event)); for(int64_t i = 0; i < event_getChildNumber(event); i++) { Event *child = event_getChild(event, i); stTree *childStTree = eventTree_getStTree_R(child); stTree_setParent(childStTree, ret); } return ret; }
/* Construct a MafTree object from a malnBlk, assuming the last is the root and all others are descents */ mafTree *mafTree_constructFromAlignment(struct Genomes *genomes, struct malnBlk *blk, double defaultBranchLength) { struct malnComp *rootComp = malnBlk_getRootComp(blk); stTree *eRoot = malnCompToETreeNode(rootComp); for (struct malnComp *comp = blk->comps; comp != rootComp; comp = comp->next) { stTree *eLeaf = malnCompToETreeNode(comp); stTree_setParent(eLeaf, eRoot); stTree_setBranchLength(eLeaf, defaultBranchLength); } mafTree *mTree = mafTree_construct(genomes, eRoot); fillNodeCompLinks(mTree, blk); return mTree; }
// 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; }
static stTree *tree_parseNewickStringP(char **token, char **newickTreeString) { stTree *tree = stTree_construct(); if((*token)[0] == '(') { assert(strlen(*token) == 1); tree_parseNewickTreeString_getNextToken(token, newickTreeString); while(1) { stTree_setParent(tree_parseNewickStringP(token, newickTreeString), tree); assert(strlen(*token) == 1); if((*token)[0] == ',') { tree_parseNewickTreeString_getNextToken(token, newickTreeString); } else { break; } } assert((*token)[0] == ')'); //for every opening bracket we must have a close bracket. tree_parseNewickTreeString_getNextToken(token, newickTreeString); } tree_parseNewickString_getLabel(token, newickTreeString, tree); tree_parseNewickString_getBranchLength(token, newickTreeString, tree); assert(**token == ',' || **token == ';' || **token == ')'); //these are the correct termination criteria return tree; }
/* add children from pending list */ static void subrangeAddPendingChildren(stTree *destNode, stList *pendingSubtrees) { while (stList_length(pendingSubtrees) > 0) { stTree *destChild = stList_pop(pendingSubtrees); stTree_setParent(destChild, destNode); } }
/* clone child and append clones to a give parent node */ static void cloneChildren(stTree *srcParent, stTree *destParent, struct malnCompCompMap *srcDestCompMap) { for (int i = 0; i < stTree_getChildNumber(srcParent); i++) { stTree_setParent(cloneTree(stTree_getChild(srcParent, i), destParent, srcDestCompMap), destParent); } }