private boolean pickWide() {
    final int nNodesExceptRoot = nSpeciesNodes - 1;
    final Node rootNode = speciesTreeNodes[nNodesExceptRoot];

    // pick an internal node at random (excluding the root)
    final int yNodeNumber = nLeafNodes + Randomizer.nextInt(nInternalNodes - 1);
    yNode = speciesTreeNodes[yNodeNumber];
    final double yNodeHeight = yNode.getHeight();
    if (Randomizer.nextBoolean()) {
      aNode = yNode.getLeft();
      bNode = yNode.getRight();
    } else {
      aNode = yNode.getRight();
      bNode = yNode.getLeft();
    }

    // for all internal nodes (excluding the root)
    final Node[] zNodes = new Node[nNodesExceptRoot];

    czNodeFinder(yNode, rootNode, yNodeHeight, zNodes);

    // pick a cousin from the available candidates
    int cousinNodeNumber = Randomizer.nextInt(nNodesExceptRoot);
    zNode = zNodes[cousinNodeNumber];
    while (zNode == null) {
      cousinNodeNumber = Randomizer.nextInt(nNodesExceptRoot);
      // System.out.println(String.format("%d/%d", cousinNodeNumber, nNodesExceptRoot));
      zNode = zNodes[cousinNodeNumber];
    }

    cNode = speciesTreeNodes[cousinNodeNumber];

    return true;
  }
  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;
  }
 /**
  * Obtain the sister of node "child" having parent "parent".
  *
  * @param parent the parent
  * @param child the child that you want the sister of
  * @return the other child of the given parent.
  */
 protected Node getOtherChild(Node parent, Node child) {
   if (parent.getLeft().getNr() == child.getNr()) {
     return parent.getRight();
   } else {
     return parent.getLeft();
   }
 }
  // 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;
  }
Пример #5
0
 /**
  * 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);
     }
   }
 }
Пример #6
0
 /**
  * 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);
   }
 }
  private List<Integer> czNodeFinder(
      final Node parentNode,
      final Node currentNode,
      final double parentNodeHeight,
      final Node[] zNodes) {
    // valid graft nodes (nodes defining branches which include the height of the parent node)
    final List<Integer> candidateList = new ArrayList<>();
    final double currentNodeHeight = currentNode.getHeight();

    if (parentNode == currentNode) {
      return null;
    } else if (parentNodeHeight >= currentNodeHeight) {
      // this is a candidate node (would be a valid choice to graft parentNode to)
      candidateList.add(currentNode.getNr());
      return candidateList;
    } else {
      final List<Integer> leftCandidateNodeNumbers =
          czNodeFinder(parentNode, currentNode.getLeft(), parentNodeHeight, zNodes);
      final List<Integer> rightCandidateNodeNumbers =
          czNodeFinder(parentNode, currentNode.getRight(), parentNodeHeight, zNodes);

      if (leftCandidateNodeNumbers
          == null) { // parent is the left child or descendant of the left child
        // therefore the current node is the most recent common ancestor connecting the parent and
        // right candidates
        for (final Integer candidateNodeNumber : rightCandidateNodeNumbers) {
          zNodes[candidateNodeNumber] = currentNode;
        }
        return null;
      } else if (rightCandidateNodeNumbers
          == null) { // parent is the right child or descendant of the right child
        // therefore the current node is the most recent common ancestor connecting the parent and
        // left candidates
        for (final Integer candidateNodeNumber : leftCandidateNodeNumbers) {
          zNodes[candidateNodeNumber] = currentNode;
        }
        return null;
      } else {
        candidateList.addAll(leftCandidateNodeNumbers);
        candidateList.addAll(rightCandidateNodeNumbers);
        return candidateList;
      }
    }
  }
  /**
   * 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);
  }
  // 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;
  }
  /**
   * Set up node's parent as the new root with a height of destTime, with oldRoot as node's new
   * sister.
   *
   * @param node
   * @param oldRoot
   * @param destTime
   */
  public void connectBranchToRoot(Node node, Node oldRoot, double destTime) {

    // Check argument validity:
    if (node.isRoot() || !oldRoot.isRoot())
      throw new IllegalArgumentException("Illegal argument " + "to connectBranchToRoot().");

    // Obtain existing parent of node and set new time:
    Node newRoot = node.getParent();
    newRoot.setHeight(destTime);

    // Implement topology changes:

    newRoot.setParent(null);

    if (newRoot.getLeft() == node) newRoot.setRight(oldRoot);
    else if (newRoot.getRight() == node) newRoot.setLeft(oldRoot);

    oldRoot.setParent(newRoot);

    // Ensure BEAST knows to recalculate affected likelihood:
    newRoot.makeDirty(Tree.IS_FILTHY);
    oldRoot.makeDirty(Tree.IS_FILTHY);
    node.makeDirty(Tree.IS_FILTHY);
  }
 private int isg(final Node n) {
   return (n.getLeft().isLeaf() && n.getRight().isLeaf()) ? 0 : 1;
 }
Пример #12
0
  /** Recalculates all the intervals for the given beast.tree. */
  @SuppressWarnings("unchecked")
  protected void calculateIntervals() {
    Tree tree = treeInput.get();

    final int nodeCount = tree.getNodeCount();

    times = new double[nodeCount];
    int[] childCounts = new int[nodeCount];

    collectTimes(tree, times, childCounts);

    indices = new int[nodeCount];

    HeapSort.sort(times, indices);

    if (intervals == null || intervals.length != nodeCount) {
      intervals = new double[nodeCount];
      lineageCounts = new int[nodeCount];
      lineagesAdded = new List[nodeCount];
      lineagesRemoved = new List[nodeCount];
      //            lineages = new List[nodeCount];

      storedIntervals = new double[nodeCount];
      storedLineageCounts = new int[nodeCount];

    } else {
      for (List<Node> l : lineagesAdded) {
        if (l != null) {
          l.clear();
        }
      }
      for (List<Node> l : lineagesRemoved) {
        if (l != null) {
          l.clear();
        }
      }
    }

    // start is the time of the first tip
    double start = times[indices[0]];
    int numLines = 0;
    int nodeNo = 0;
    intervalCount = 0;
    while (nodeNo < nodeCount) {

      int lineagesRemoved = 0;
      int lineagesAdded = 0;

      double finish = times[indices[nodeNo]];
      double next;

      do {
        final int childIndex = indices[nodeNo];
        final int childCount = childCounts[childIndex];
        // don't use nodeNo from here on in do loop
        nodeNo += 1;
        if (childCount == 0) {
          addLineage(intervalCount, tree.getNode(childIndex));
          lineagesAdded += 1;
        } else {
          lineagesRemoved += (childCount - 1);

          // record removed lineages
          final Node parent = tree.getNode(childIndex);
          // assert childCounts[indices[nodeNo]] == beast.tree.getChildCount(parent);
          // for (int j = 0; j < lineagesRemoved + 1; j++) {
          for (int j = 0; j < childCount; j++) {
            Node child = j == 0 ? parent.getLeft() : parent.getRight();
            removeLineage(intervalCount, child);
          }

          // record added lineages
          addLineage(intervalCount, parent);
          // no mix of removed lineages when 0 th
          if (multifurcationLimit == 0.0) {
            break;
          }
        }

        if (nodeNo < nodeCount) {
          next = times[indices[nodeNo]];
        } else break;
      } while (Math.abs(next - finish) <= multifurcationLimit);

      if (lineagesAdded > 0) {

        if (intervalCount > 0 || ((finish - start) > multifurcationLimit)) {
          intervals[intervalCount] = finish - start;
          lineageCounts[intervalCount] = numLines;
          intervalCount += 1;
        }

        start = finish;
      }

      // add sample event
      numLines += lineagesAdded;

      if (lineagesRemoved > 0) {

        intervals[intervalCount] = finish - start;
        lineageCounts[intervalCount] = numLines;
        intervalCount += 1;
        start = finish;
      }
      // coalescent event
      numLines -= lineagesRemoved;
    }

    intervalsKnown = true;
  }