/** * Root source by creating a new internal node whose children are (the adjacent) left and right. * * @param source * @param left * @param right * @param fromLeft branch from new root to left node. */ public RootedFromUnrooted( @Param(name = "source", description = "auto converted jebl2 parameter") Tree source, @Param(name = "left", description = "auto converted jebl2 parameter") Node left, @Param(name = "right", description = "auto converted jebl2 parameter") Node right, @Param(name = "fromLeft", description = "auto converted jebl2 parameter") Double fromLeft) { this.source = source; intentUnrooted = false; topLeft = left; topRight = right; rootToLeft = fromLeft; try { rootToRight = source.getEdgeLength(left, right) - rootToLeft; } catch (NoEdgeException e) { // bug } parents = new LinkedHashMap<>(); // This is just a handle used to refer to the root so create the simplest possible // implementation... root = new BaseNode() { @Override public int getDegree() { return 2; } }; parents.put(root, null); setParent(left, root); setParent(right, root); this.left = left; this.right = right; this.fromLeft = fromLeft; }
@Override public double getLength(Node node) { if (node == root) return 0.0; if (node == topLeft) return rootToLeft; if (node == topRight) return rootToRight; double l = 0.0; try { l = source.getEdgeLength(node, getParent(node)); } catch (NoEdgeException e) { // bug, should not happen } return l; }
@Override public double getEdgeLength(Node node1, Node node2) throws NoEdgeException { // special case when syntetic root if (topLeft != null) { if (node2 == root) { Node tmp = node1; node1 = node2; node2 = tmp; } if (node1 == root) { if (!(node2 == topLeft || node2 == topRight)) { throw new NoEdgeException(); } return node2 == topLeft ? rootToLeft : rootToRight; } } return source.getEdgeLength(node1, node2); }