private void zeroSubtreeCoalCountsIntensities(PopsIONode node) {
   if (node.lft >= 0) {
     zeroSubtreeCoalCountsIntensities(pionodes[node.lft]);
     zeroSubtreeCoalCountsIntensities(pionodes[node.rgt]);
   }
   node.coalcount = 0;
   node.coalintensity = 0.0;
 }
 private void recordSubtreeLineageCounts(PopsIONode node) {
   if (node.lft < 0) {
     int spIndex = piosb.speciesId2index(node.getTaxon().getId());
     node.nlineages = piosb.nLineages(spIndex);
   } else {
     node.nlineages = 0;
     recordSubtreeLineageCounts(pionodes[node.lft]);
     node.nlineages += pionodes[node.lft].nlineages - pionodes[node.lft].coalheights.size();
     recordSubtreeLineageCounts(pionodes[node.rgt]);
     node.nlineages += pionodes[node.rgt].nlineages - pionodes[node.rgt].coalheights.size();
   }
 }
 private void accumSubtreeCoalCountsIntensities(PopsIONode node) {
   if (node.lft >= 0) {
     accumSubtreeCoalCountsIntensities(pionodes[node.lft]);
     accumSubtreeCoalCountsIntensities(pionodes[node.rgt]);
   }
   int k = node.coalheights.size();
   node.coalcount += k;
   double[] t = new double[k + 2];
   t[0] = node.height;
   for (int i = 0; i < k; i++) {
     t[i + 1] = node.coalheights.get(i);
   }
   t[k + 1] = (node.anc < 0) ? piosb.maxGeneTreeHeight() : pionodes[node.anc].height;
   int n = node.nlineages;
   for (int i = 0; i <= k; i++) {
     node.coalintensity += (t[i + 1] - t[i]) * 0.5 * (n - i) * (n - i - 1);
   }
 }
 private String subtreeAsText(PopsIONode node, String s, Stack<Integer> x, int depth, String b) {
   Integer[] y = x.toArray(new Integer[x.size()]);
   StringBuffer indent = new StringBuffer();
   for (int i = 0; i < depth; i++) {
     indent.append("  ");
   }
   for (int i = 0; i < y.length; i++) {
     indent.replace(2 * y[i], 2 * y[i] + 1, "|");
   }
   if (b.length() > 0) {
     indent.replace(indent.length() - b.length(), indent.length(), b);
   }
   s += indent;
   s += node.asText(indent.length());
   s += System.getProperty("line.separator");
   String subs = "";
   if (node.lft >= 0) {
     x.push(depth);
     subs += subtreeAsText(pionodes[node.lft], "", x, depth + 1, "-");
     x.pop();
     subs += subtreeAsText(pionodes[node.rgt], "", x, depth + 1, "`-");
   }
   return s + subs;
 }