@Override
  protected void finish() {
    multiCollector.finish();

    final MetricsFile<InsertSizeMetrics, Integer> file = getMetricsFile();
    multiCollector.addAllLevelsToFile(file);

    if (file.getNumHistograms() == 0) {
      // can happen if user sets MINIMUM_PCT = 0.5, etc.
      log.warn(
          "All data categories were discarded because they contained < "
              + MINIMUM_PCT
              + " of the total aligned paired data.");
      final InsertSizeMetricsCollector.PerUnitInsertSizeMetricsCollector allReadsCollector =
          (InsertSizeMetricsCollector.PerUnitInsertSizeMetricsCollector)
              multiCollector.getAllReadsCollector();
      log.warn(
          "Total mapped pairs in all categories: "
              + (allReadsCollector == null
                  ? allReadsCollector
                  : allReadsCollector.getTotalInserts()));
    } else {
      file.write(OUTPUT);

      final int rResult;
      if (HISTOGRAM_WIDTH == null) {
        rResult =
            RExecutor.executeFromClasspath(
                HISTOGRAM_R_SCRIPT,
                OUTPUT.getAbsolutePath(),
                HISTOGRAM_FILE.getAbsolutePath(),
                INPUT.getName());
      } else {
        rResult =
            RExecutor.executeFromClasspath(
                HISTOGRAM_R_SCRIPT,
                OUTPUT.getAbsolutePath(),
                HISTOGRAM_FILE.getAbsolutePath(),
                INPUT.getName(),
                String.valueOf(
                    HISTOGRAM_WIDTH)); // HISTOGRAM_WIDTH is passed because R automatically sets
                                       // histogram width to the last
        // bin that has data, which may be less than HISTOGRAM_WIDTH and confuse the user.
      }

      if (rResult != 0) {
        throw new PicardException(
            "R script " + HISTOGRAM_R_SCRIPT + " failed with return code " + rResult);
      }
    }
  }
  /**
   * Asserts that files are readable and writable and then fires off an HsMetricsCalculator instance
   * to do the real work.
   */
  protected int doWork() {
    IoUtil.assertFileIsReadable(getProbeIntervals());
    IoUtil.assertFileIsReadable(TARGET_INTERVALS);
    IoUtil.assertFileIsReadable(INPUT);
    IoUtil.assertFileIsWritable(OUTPUT);
    if (PER_TARGET_COVERAGE != null) IoUtil.assertFileIsWritable(PER_TARGET_COVERAGE);

    final SAMFileReader samReader = new SAMFileReader(INPUT);

    final File probeIntervals = getProbeIntervals();

    // Validate that the targets and baits have the same references as the reads file
    SequenceUtil.assertSequenceDictionariesEqual(
        samReader.getFileHeader().getSequenceDictionary(),
        IntervalList.fromFile(TARGET_INTERVALS).getHeader().getSequenceDictionary(),
        INPUT,
        TARGET_INTERVALS);
    SequenceUtil.assertSequenceDictionariesEqual(
        samReader.getFileHeader().getSequenceDictionary(),
        IntervalList.fromFile(probeIntervals).getHeader().getSequenceDictionary(),
        INPUT,
        probeIntervals);

    ReferenceSequenceFile ref = null;
    if (REFERENCE_SEQUENCE != null) {
      IoUtil.assertFileIsReadable(REFERENCE_SEQUENCE);
      ref = ReferenceSequenceFileFactory.getReferenceSequenceFile(REFERENCE_SEQUENCE);
      SequenceUtil.assertSequenceDictionariesEqual(
          samReader.getFileHeader().getSequenceDictionary(),
          ref.getSequenceDictionary(),
          INPUT,
          REFERENCE_SEQUENCE);
    }

    final TargetMetricsCollector collector =
        makeCollector(
            METRIC_ACCUMULATION_LEVEL,
            samReader.getFileHeader().getReadGroups(),
            ref,
            PER_TARGET_COVERAGE,
            TARGET_INTERVALS,
            probeIntervals,
            getProbeSetName());

    // Add each record to the requested collectors
    final Iterator<SAMRecord> records = samReader.iterator();
    final ProgressLogger progress = new ProgressLogger(log);

    while (records.hasNext()) {
      final SAMRecord sam = records.next();
      collector.acceptRecord(sam, null);
      progress.record(sam);
    }

    // Write the output file
    final MetricsFile<HsMetrics, Integer> metrics = getMetricsFile();
    collector.finish();

    collector.addAllLevelsToFile(metrics);

    metrics.write(OUTPUT);

    return 0;
  }
 @Override
 public void addMetricsToFile(
     final MetricsFile<TotalNumberMetric, Integer> totalNumberMetricIntegerMetricsFile) {
   totalNumberMetricIntegerMetricsFile.addMetric(metric);
 }