/** * Method used by convertLengthToHeight(node) to remove negative offset from node heights that * is produced by convertLengthToHeight(node, height). * * @param node node of clade to offset * @param delta offset */ private void offset(final Node node, final double delta) { node.setHeight(node.getHeight() + delta); if (node.isLeaf()) { if (node.getHeight() < thresholdInput.get()) { node.setHeight(0); } } if (!node.isLeaf()) { offset(node.getLeft(), delta); if (node.getRight() != null) { offset(node.getRight(), delta); } } }
// identify nodes that can serve as graft branches as part of a coordinated exchange move private boolean findGraftBranches( Node geneTreeNode, Set<Node> graftNodes, Set<String> branchDescendants) { if (geneTreeNode.isLeaf()) { final String descendantName = geneTreeNode.getID(); return branchDescendants.contains(descendantName); } final Node leftChild = geneTreeNode.getLeft(); final Node rightChild = geneTreeNode.getRight(); final boolean leftOverlaps = findGraftBranches(leftChild, graftNodes, branchDescendants); final boolean rightOverlaps = findGraftBranches(rightChild, graftNodes, branchDescendants); // subtree defined by a child node overlaps species subtree defined by branch if (leftOverlaps || rightOverlaps) { if (leftOverlaps) { graftNodes.add(leftChild); } if (rightOverlaps) { graftNodes.add(rightChild); } return true; } return false; }
private boolean pickNarrow() { zNode = speciesTreeNodes[nLeafNodes + Randomizer.nextInt(nInternalNodes)]; while (zNode.getLeft().isLeaf() && zNode.getRight().isLeaf()) { zNode = speciesTreeNodes[nLeafNodes + Randomizer.nextInt(nInternalNodes)]; } yNode = zNode.getLeft(); cNode = zNode.getRight(); if (yNode.getHeight() < cNode.getHeight()) { yNode = zNode.getRight(); cNode = zNode.getLeft(); } if (yNode.isLeaf()) { return false; } else if (Randomizer.nextBoolean()) { aNode = yNode.getLeft(); bNode = yNode.getRight(); } else { aNode = yNode.getRight(); bNode = yNode.getLeft(); } return true; }
/** * extract coalescent times and tip information into array times from beast.tree. * * @param tree the beast.tree * @param times the times of the nodes in the beast.tree * @param childCounts the number of children of each node */ protected static void collectTimes(Tree tree, double[] times, int[] childCounts) { Node[] nodes = tree.getNodesAsArray(); for (int i = 0; i < nodes.length; i++) { Node node = nodes[i]; times[i] = node.getHeight(); childCounts[i] = node.isLeaf() ? 0 : 2; } }
/** * Number any nodes in a clade which were not explicitly numbered by the parsed string. * * @param node clade parent */ private void numberUnnumberedNodes(Node node) { if (node.isLeaf()) return; for (Node child : node.getChildren()) { numberUnnumberedNodes(child); } if (node.getNr() < 0) node.setNr(numberedNodeCount); numberedNodeCount += 1; }
/** * Recursive method used to convert lengths to heights. Applied to the root, results in heights * from 0 to -total_height_of_tree. * * @param node node of a clade to convert * @param height Parent height. * @return total height of clade */ private double convertLengthToHeight(final Node node, final double height) { final double length = node.getHeight(); node.setHeight((height - length) * scaleInput.get()); if (node.isLeaf()) { return node.getHeight(); } else { final double left = convertLengthToHeight(node.getLeft(), height - length); if (node.getRight() == null) { return left; } final double right = convertLengthToHeight(node.getRight(), height - length); return Math.min(left, right); } }
// identify nodes to be moved as part of a coordinated exchange move private boolean findMovedPairs( Node geneTreeNode, Map<Node, Node> movedNodes, Set<String> chosenDescendants, double lowerHeight, double upperHeight) { if (geneTreeNode.isLeaf()) { final String descendantName = geneTreeNode.getID(); // returns true if this leaf is a descendant of the chosen species return chosenDescendants.contains(descendantName); } final Node leftChild = geneTreeNode.getLeft(); final Node rightChild = geneTreeNode.getRight(); // left child descendants are exclusively descendants of the chosen species tree node final boolean leftExclusive = findMovedPairs(leftChild, movedNodes, chosenDescendants, lowerHeight, upperHeight); // right child descendants are exclusively descendants of the chosen species tree node final boolean rightExclusive = findMovedPairs(rightChild, movedNodes, chosenDescendants, lowerHeight, upperHeight); final double nodeHeight = geneTreeNode.getHeight(); if (nodeHeight >= lowerHeight && nodeHeight < upperHeight) { if (leftExclusive ^ rightExclusive) { if (leftExclusive) { // leave right child attached to original parent movedNodes.put(geneTreeNode, rightChild); } else { // leaf left child attached to original parent movedNodes.put(geneTreeNode, leftChild); } } } // returns true if all descendants of this gene tree node are also descendants of the chosen // species tree node return leftExclusive && rightExclusive; }
@Override public Node visitNode(NewickParser.NodeContext ctx) { Node node = newNode(); for (NewickParser.NodeContext ctxChild : ctx.node()) { node.addChild(visit(ctxChild)); } NewickParser.PostContext postCtx = ctx.post(); // Process metadata if (postCtx.meta() != null) { node.metaDataString = ""; for (int i = 0; i < postCtx.meta().attrib().size(); i++) { if (i > 0) node.metaDataString += ","; node.metaDataString += postCtx.meta().attrib().get(i).getText(); } if (!suppressMetadata) { for (NewickParser.AttribContext attribctx : postCtx.meta().attrib()) { String key = attribctx.attribKey.getText(); if (attribctx.attribValue().number() != null) { node.setMetaData(key, Double.parseDouble(attribctx.attribValue().number().getText())); } else if (attribctx.attribValue().STRING() != null) { String stringValue = attribctx.attribValue().STRING().getText(); if (stringValue.startsWith("\"") || stringValue.startsWith("\'")) ; stringValue = stringValue.substring(1, stringValue.length() - 1); node.setMetaData(key, stringValue); } else { // BEAST doesn't do anything with vectors yet. } } } } // Process edge length if (postCtx.length != null) node.setHeight(Double.parseDouble(postCtx.length.getText())); else node.setHeight(DEFAULT_LENGTH); // Process label node.setNr(-1); if (postCtx.label() != null) { node.setID(postCtx.label().getText()); if (postCtx.label().number() == null || postCtx.label().number().INT() == null) integerLeafLabels = false; // RRB: next line is for debugging only? @SuppressWarnings("unused") String postText = postCtx.getText(); // Treat labels as node numbers in certain situations if (!isLabelledNewickInput.get() && postCtx.label().number() != null && postCtx.label().number().INT() != null) { int nodeNr = Integer.parseInt(postCtx.label().getText()) - offsetInput.get(); if (nodeNr < 0) throw new ParseCancellationException( "Node number given " + "is smaller than current offset (" + offsetInput.get() + "). Perhaps offset is " + "too high?"); node.setNr(nodeNr); numberedNodeCount += 1; } else { if (node.isLeaf()) { node.setNr(getLabelIndex(postCtx.label().getText())); numberedNodeCount += 1; } } } if (node.getChildCount() == 1 && !allowSingleChildInput.get()) throw new ParseCancellationException("Node with single child found."); if (node.getChildCount() > 2) throw new ParseCancellationException("Node with two or more children found."); return node; }
private int sisg(final Node n) { return n.isLeaf() ? 0 : isg(n); }