public void forwardIBD() { int numNodes = treeModel.getNodeCount(); int stateCount = substitutionModel.getStateCount(); getDiagonalRates(diag); for (int nodeId = 0; nodeId < numNodes; ++nodeId) { NodeRef node = treeModel.getNode(nodeId); NodeRef parent = treeModel.getParent(node); if (parent == null) { // handle the root } else if (treeModel.isExternal(node)) { // Handle the tip double branchTime = branchRateModel.getBranchRate(treeModel, node) * (treeModel.getNodeHeight(parent) - treeModel.getNodeHeight(node)); for (int state = 0; state < stateCount; ++state) { ibdForward[nodeId][state] = Math.exp(-diag[state] * branchTime); } } else { // Handle internal node double branchTime = branchRateModel.getBranchRate(treeModel, node) * (treeModel.getNodeHeight(parent) - treeModel.getNodeHeight(node)); int childCount = treeModel.getChildCount(node); for (int state = 0; state < stateCount; ++state) { ibdForward[nodeId][state] = 0; for (int child = 0; child < childCount; ++child) { int childNodeId = treeModel.getChild(node, child).getNumber(); ibdForward[nodeId][state] += ibdForward[childNodeId][state]; } ibdForward[nodeId][state] *= Math.exp(-diag[state] * branchTime); } } } }
private boolean eligibleForMove(NodeRef node, TreeModel tree, BranchMapModel branchMap) { // to be eligible for this move, the node's parent and grandparent, or parent and other child, // must be in the same partition (so removing the parent has no effect on the remaining links of // the TT), // and the node and its parent must be in different partitions (such that the move does not // disconnect anything) return ((tree.getParent(tree.getParent(node)) != null && branchMap.get(tree.getParent(node).getNumber()) == branchMap.get(tree.getParent(tree.getParent(node)).getNumber())) || branchMap.get(tree.getParent(node).getNumber()) == branchMap.get(getOtherChild(tree, tree.getParent(node), node).getNumber())) && branchMap.get(tree.getParent(node).getNumber()) != branchMap.get(node.getNumber()); }
public static void checkTree(TreeModel treeModel) { // todo Should only be run if there exists a zero-length interval // TreeModel treeModel = (TreeModel) tree; for (int i = 0; i < treeModel.getInternalNodeCount(); i++) { NodeRef node = treeModel.getInternalNode(i); if (node != treeModel.getRoot()) { double parentHeight = treeModel.getNodeHeight(treeModel.getParent(node)); double childHeight0 = treeModel.getNodeHeight(treeModel.getChild(node, 0)); double childHeight1 = treeModel.getNodeHeight(treeModel.getChild(node, 1)); double maxChild = childHeight0; if (childHeight1 > maxChild) maxChild = childHeight1; double newHeight = maxChild + MathUtils.nextDouble() * (parentHeight - maxChild); treeModel.setNodeHeight(node, newHeight); } } treeModel.pushTreeChangedEvent(); }
private void setup() { DataType dataType = baseSubstitutionModel.getDataType(); FrequencyModel freqModel = baseSubstitutionModel.getFrequencyModel(); Parameter kappaParameter = new Parameter.Default("kappa", 1, baseSubstitutionModel.getKappa()); substitutionModels = new LinkedList<SubstitutionModel>(); branchAssignmentMap = new LinkedHashMap<NodeRef, Integer>(); int branchClass = 0; for (NodeRef node : treeModel.getNodes()) { if (!treeModel.isRoot(node)) { double nodeHeight = treeModel.getNodeHeight(node); double parentHeight = treeModel.getNodeHeight(treeModel.getParent(node)); double time = 0.5 * (parentHeight + nodeHeight); double baseOmega = baseSubstitutionModel.getOmega(); double fixed = baseOmega * time; double epsilon = (Math.log(1 - random.nextDouble()) / (-rate)); // Math.exp((random.nextGaussian() * stdev + mean)); double value = fixed + epsilon; Parameter omegaParameter = new Parameter.Default("omega", 1, value); GY94CodonModel gy94 = new GY94CodonModel((Codons) dataType, omegaParameter, kappaParameter, freqModel); substitutionModels.add(gy94); branchAssignmentMap.put(node, branchClass); branchClass++; } // END: root check } // END: nodes loop } // END: setup
public void proposeTree() throws OperatorFailedException { TreeModel tree = c2cLikelihood.getTreeModel(); BranchMapModel branchMap = c2cLikelihood.getBranchMap(); NodeRef i; double oldMinAge, newMinAge, newRange, oldRange, newAge, q; // choose a random node avoiding root, and nodes that are ineligible for this move because they // have nowhere to // go final int nodeCount = tree.getNodeCount(); do { i = tree.getNode(MathUtils.nextInt(nodeCount)); } while (tree.getRoot() == i || !eligibleForMove(i, tree, branchMap)); final NodeRef iP = tree.getParent(i); // this one can go anywhere NodeRef j = tree.getNode(MathUtils.nextInt(tree.getNodeCount())); NodeRef k = tree.getParent(j); while ((k != null && tree.getNodeHeight(k) <= tree.getNodeHeight(i)) || (i == j)) { j = tree.getNode(MathUtils.nextInt(tree.getNodeCount())); k = tree.getParent(j); } if (iP == tree.getRoot() || j == tree.getRoot()) { throw new OperatorFailedException("Root changes not allowed!"); } if (k == iP || j == iP || k == i) throw new OperatorFailedException("move failed"); final NodeRef CiP = getOtherChild(tree, iP, i); NodeRef PiP = tree.getParent(iP); newMinAge = Math.max(tree.getNodeHeight(i), tree.getNodeHeight(j)); newRange = tree.getNodeHeight(k) - newMinAge; newAge = newMinAge + (MathUtils.nextDouble() * newRange); oldMinAge = Math.max(tree.getNodeHeight(i), tree.getNodeHeight(CiP)); oldRange = tree.getNodeHeight(PiP) - oldMinAge; q = newRange / Math.abs(oldRange); // need to account for the random repainting of iP if (branchMap.get(PiP.getNumber()) != branchMap.get(CiP.getNumber())) { q *= 0.5; } if (branchMap.get(k.getNumber()) != branchMap.get(j.getNumber())) { q *= 2; } tree.beginTreeEdit(); if (j == tree.getRoot()) { // 1. remove edges <iP, CiP> tree.removeChild(iP, CiP); tree.removeChild(PiP, iP); // 2. add edges <k, iP>, <iP, j>, <PiP, CiP> tree.addChild(iP, j); tree.addChild(PiP, CiP); // iP is the new root tree.setRoot(iP); } else if (iP == tree.getRoot()) { // 1. remove edges <k, j>, <iP, CiP>, <PiP, iP> tree.removeChild(k, j); tree.removeChild(iP, CiP); // 2. add edges <k, iP>, <iP, j>, <PiP, CiP> tree.addChild(iP, j); tree.addChild(k, iP); // CiP is the new root tree.setRoot(CiP); } else { // 1. remove edges <k, j>, <iP, CiP>, <PiP, iP> tree.removeChild(k, j); tree.removeChild(iP, CiP); tree.removeChild(PiP, iP); // 2. add edges <k, iP>, <iP, j>, <PiP, CiP> tree.addChild(iP, j); tree.addChild(k, iP); tree.addChild(PiP, CiP); } tree.setNodeHeight(iP, newAge); tree.endTreeEdit(); // logq = Math.log(q); // repaint the parent to match either its new parent or its new child (50% chance of each). if (MathUtils.nextInt(2) == 0) { branchMap.set(iP.getNumber(), branchMap.get(k.getNumber()), true); } else { branchMap.set(iP.getNumber(), branchMap.get(j.getNumber()), true); } if (DEBUG) { c2cLikelihood.checkPartitions(); } }