String probsToString() {
   List<Pair<String, Double>> sorted =
       Counters.toDescendingMagnitudeSortedListWithCounts(typeProbabilities);
   StringBuffer os = new StringBuffer();
   os.append("{");
   boolean first = true;
   for (Pair<String, Double> lv : sorted) {
     if (!first) os.append("; ");
     os.append(lv.first + ", " + lv.second);
     first = false;
   }
   os.append("}");
   return os.toString();
 }
  /**
   * Returns true if it's worth saving/printing this object This happens in two cases: 1. The type
   * of the object is not nilLabel 2. The type of the object is nilLabel but the second ranked label
   * is within the given beam (0 -- 100) of the first choice
   *
   * @param beam
   * @param nilLabel
   */
  public boolean printableObject(double beam, String nilLabel) {
    if (typeProbabilities == null) {
      return false;
    }
    List<Pair<String, Double>> sorted =
        Counters.toDescendingMagnitudeSortedListWithCounts(typeProbabilities);

    // first choice not nil
    if (sorted.size() > 0 && !sorted.get(0).first.equals(nilLabel)) {
      return true;
    }

    // first choice is nil, but second is within beam
    if (sorted.size() > 1
        && sorted.get(0).first.equals(nilLabel)
        && beam > 0
        && 100.0 * (sorted.get(0).second - sorted.get(1).second) < beam) {
      return true;
    }

    return false;
  }