/** * Creates a new branch between node and a new node at time destTime between destBranchBase and * its parent. Colour changes are divided between the two new branches created by the split. * * @param node * @param destBranchBase * @param destTime */ public void connectBranch(Node node, Node destBranchBase, double destTime) { // Check argument validity: if (node.isRoot() || destBranchBase.isRoot()) throw new IllegalArgumentException("Illegal argument to " + "connectBranch()."); // Obtain existing parent of node and set new time: Node parent = node.getParent(); parent.setHeight(destTime); MultiTypeNode mtParent = (MultiTypeNode) parent; MultiTypeNode mtDestBranchBase = (MultiTypeNode) destBranchBase; // Determine where the split comes in the list of colour changes // attached to destBranchBase: int split; for (split = 0; split < mtDestBranchBase.getChangeCount(); split++) if (mtDestBranchBase.getChangeTime(split) > destTime) break; // Divide colour changes between new branches: mtParent.clearChanges(); for (int idx = split; idx < mtDestBranchBase.getChangeCount(); idx++) mtParent.addChange(mtDestBranchBase.getChangeType(idx), mtDestBranchBase.getChangeTime(idx)); mtDestBranchBase.truncateChanges(split); // Set colour at split: mtParent.setNodeType(mtDestBranchBase.getFinalType()); // Implement topology changes: replace(destBranchBase.getParent(), destBranchBase, parent); destBranchBase.setParent(parent); if (parent.getLeft() == node) parent.setRight(destBranchBase); else if (parent.getRight() == node) parent.setLeft(destBranchBase); // Ensure BEAST knows to update affected likelihoods: node.makeDirty(Tree.IS_FILTHY); parent.makeDirty(Tree.IS_FILTHY); destBranchBase.makeDirty(Tree.IS_FILTHY); }