// Helper method for updateM( boolean, Node, Node ) // Calculates M for Node n, given that M for the two children // of n has been calculated. // (Last modified: 10/02/01) private void calculateMforNode(Node n) { if (!n.isExternal()) { boolean was_duplication = n.isDuplication(); Node a = n.getChild1().getLink(), b = n.getChild2().getLink(); while (a != b) { if (a.getID() > b.getID()) { a = a.getParent(); } else { b = b.getParent(); } } n.setLink(a); if (a == n.getChild1().getLink() || a == n.getChild2().getLink()) { n.setDuplication(true); if (!was_duplication) { increaseDuplications(); } } else { n.setDuplication(false); if (was_duplication) { decreaseDuplications(); } } } } // calculateMforNode( Node )
/** * Traverses the subtree of Node g in postorder, calculating the mapping function M, and * determines which nodes represent speciation events and which ones duplication events. * * <p>Preconditions: Mapping M for external nodes must have been calculated and the species tree * must be labelled in preorder. * * <p>(Last modified: 01/11/01) * * @param g starting node of a gene tree - normally the root */ void geneTreePostOrderTraversal(Node g) { Node a, b; if (!g.isExternal()) { geneTreePostOrderTraversal(g.getChild1()); geneTreePostOrderTraversal(g.getChild2()); a = g.getChild1().getLink(); b = g.getChild2().getLink(); while (a != b) { if (a.getID() > b.getID()) { a = a.getParent(); } else { b = b.getParent(); } } g.setLink(a); // Determines whether dup. or spec. g.setDuplicationOrSpecAssigned(true); if (a == g.getChild1().getLink() || a == g.getChild2().getLink()) { g.setDuplication(true); increaseDuplications(); } else { g.setDuplication(false); } } } // geneTreePostOrderTraversal( Node )
/** * Updates the mapping function M after the root of the gene tree has been moved by one branch. It * calculates M for the root of the gene tree and one of its two children. * * <p>To be used ONLY by method "SDIunrooted.fastInfer(Tree,Tree)". * * <p>(Last modfied: 10/02/01) * * @param prev_root_was_dup true if the previous root was a duplication, false otherwise * @param prev_root_c1 child 1 of the previous root * @param prev_root_c2 child 2 of the previous root * @return number of duplications which have been assigned in gene tree */ int updateM(boolean prev_root_was_dup, Node prev_root_c1, Node prev_root_c2) { Node root = getGeneTree().getRoot(); if (root.getChild1() == prev_root_c1 || root.getChild2() == prev_root_c1) { calculateMforNode(prev_root_c1); } else { calculateMforNode(prev_root_c2); } root.setDuplication(prev_root_was_dup); calculateMforNode(root); return getDuplications(); } // updateM( boolean, Node, Node )