MCPcopy Create free account
hub / github.com/rambaut/figtree / rootTreeAtCenter

Method rootTreeAtCenter

src/figtree/treeviewer/ReRootedTree.java:609–660  ·  view source on GitHub ↗

Root any tree by locating the "center" of tree and adding a new root node at that point for any point on the tree x let D(x) = Max{distance between x and t : for all tips t} The "center" c is the point with the smallest distance, i.e. D(c) = min{ D(x) : x in tree } @param tree to root @return

(RootedTree tree)

Source from the content-addressed store, hash-verified

607 * @return rooted tree
608 */
609 public static RootedTree rootTreeAtCenter(RootedTree tree) {
610 // Method - find the pair of tips with the longest distance. It is easy to see that the center
611 // is at the midpoint of the path between them.
612
613 HashMap<HashPair<Node>, Double> dists = new LinkedHashMap<HashPair<Node>, Double>();
614 try {
615 double maxDistance = -Double.MAX_VALUE;
616 // node on maximal path
617 Node current = null;
618 // next node on maximal path
619 Node direction = null;
620
621 // locate one terminal node of longest path
622 for (Node e : tree.getExternalNodes()) {
623 for (Node n : tree.getAdjacencies(e)) {
624 final double d = dist(tree, e, n, dists);
625 if (d > maxDistance) {
626 maxDistance = d;
627 current = e;
628 direction = n;
629 }
630 }
631 }
632
633 // traverse along maximal path to it's middle
634 double distanceLeft = maxDistance / 2.0;
635
636 while (true) {
637 final double len = tree.getEdgeLength(current, direction);
638 if (distanceLeft <= len) {
639 //System.out.println(toNewick(rtree));
640 return new ReRootedTree(tree, current, direction, distanceLeft);
641 }
642 distanceLeft -= len;
643
644 maxDistance = -Double.MAX_VALUE;
645 Node next = null;
646 for (Node n : tree.getAdjacencies(direction)) {
647 if (n == current) continue;
648 final double d = dist(tree, direction, n, dists);
649 if (d > maxDistance) {
650 maxDistance = d;
651 next = n;
652 }
653 }
654 current = direction;
655 direction = next;
656 }
657 } catch (Graph.NoEdgeException e1) {
658 return null; // serious bug, should not happen
659 }
660 }
661
662 private static double dist(Tree tree, Node root, Node node, Map<HashPair<Node>, Double> dists) throws Graph.NoEdgeException {
663 HashPair<Node> p = new HashPair<Node>(root, node);

Callers 1

Calls 4

distMethod · 0.95
getExternalNodesMethod · 0.80
getEdgeLengthMethod · 0.80
getAdjacenciesMethod · 0.45

Tested by

no test coverage detected