A rooted tree concrete class that wraps another tree and provides a differently rooted view of that tree. @author Andrew Rambaut @version $Id$ $HeadURL$ $LastChangedBy$ $LastChangedDate$ $LastChangedRevision$
| 42 | * $LastChangedRevision$ |
| 43 | */ |
| 44 | final public class ReRootedTree implements RootedTree { |
| 45 | |
| 46 | /** |
| 47 | * Make a copy of the given unrooted tree |
| 48 | * @param source an unrooted source tree |
| 49 | * @param ingroupNode the node on one side of the root |
| 50 | * @param outgroupNode the node on the other side of the root |
| 51 | * @param ingroupBranchLength the branch length from the root to the ingroup node |
| 52 | * @throws jebl.evolution.graphs.Graph.NoEdgeException |
| 53 | */ |
| 54 | public ReRootedTree(RootedTree source, Node ingroupNode, Node outgroupNode, double ingroupBranchLength) throws NoEdgeException { |
| 55 | |
| 56 | this.source = source; |
| 57 | List<Node> children = new ArrayList<Node>(); |
| 58 | |
| 59 | Node node1 = createNodes(source, outgroupNode, ingroupNode); |
| 60 | setLength(node1, ingroupBranchLength); |
| 61 | children.add(node1); |
| 62 | |
| 63 | Node node2 = createNodes(source, ingroupNode, outgroupNode); |
| 64 | double l = source.getEdgeLength(ingroupNode, outgroupNode); |
| 65 | if (outgroupNode == source.getRootNode()) { |
| 66 | // the tree is already rooted at the required location |
| 67 | for (Node adj : source.getAdjacencies(outgroupNode)) { |
| 68 | if (adj != ingroupNode) { |
| 69 | l += source.getEdgeLength(outgroupNode, adj); |
| 70 | } |
| 71 | } |
| 72 | } |
| 73 | setLength(node2, Math.max(l - ingroupBranchLength, 0.0)); |
| 74 | children.add(node2); |
| 75 | |
| 76 | createInternalNode(null, children); |
| 77 | } |
| 78 | |
| 79 | /** |
| 80 | * Clones the entire tree structure from the given (unrooted) Tree. |
| 81 | * @param tree the unrooted tree |
| 82 | * @param parent the parent node |
| 83 | * @param child the child node |
| 84 | */ |
| 85 | public Node createNodes(RootedTree tree, Node parent, Node child) throws NoEdgeException { |
| 86 | |
| 87 | Node newNode = null; |
| 88 | double length; |
| 89 | |
| 90 | if (tree.isExternal(child)) { |
| 91 | newNode = createExternalNode(child, tree.getTaxon(child)); |
| 92 | length = tree.getEdgeLength(parent, child); |
| 93 | } else { |
| 94 | List<Node> adjacencies = tree.getAdjacencies(child); |
| 95 | |
| 96 | if (adjacencies.size() == 2) { |
| 97 | // this is the root node so skip over it... |
| 98 | if (adjacencies.get(0) == parent) { |
| 99 | newNode = createNodes(tree, child, adjacencies.get(1)); |
| 100 | } else { |
| 101 | newNode = createNodes(tree, child, adjacencies.get(0)); |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…