예제 #1
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;
  }