Program: 30691
Project: 30691
Buggy source:
/** 
 * Main work method.  Reads the BAM file once and collects sorted information about the 5' ends of both ends of each read (or just one end in the case of pairs). Then makes a pass through those determining duplicates before re-reading the input file and writing it out with duplication flags set correctly.
 */
protected int doWork(){
  reportMemoryStats("String_Node_Str");
  log.info("String_Node_Str");
  buildSortedReadEndLists();
  reportMemoryStats("String_Node_Str");
  generateDuplicateIndexes();
  reportMemoryStats("String_Node_Str");
  log.info("String_Node_Str" + this.numDuplicateIndices + "String_Node_Str");
  Map<String,DuplicationMetrics> metricsByLibrary=new HashMap<String,DuplicationMetrics>();
  final SAMFileReader in=new SAMFileReader(INPUT);
  final SAMFileHeader header=in.getFileHeader();
  final SAMFileWriter out=new SAMFileWriterFactory().makeSAMOrBAMWriter(in.getFileHeader(),true,OUTPUT);
  long pairedReadsExamined=0;
  long pairedReadDuplicates=0;
  long recordInFileIndex=0;
  long nextDuplicateIndex=(this.duplicateIndexes.hasNext() ? this.duplicateIndexes.next() : -1);
  for (  final SAMRecord rec : in) {
    String library=getLibraryName(header,rec);
    DuplicationMetrics metrics=metricsByLibrary.get(library);
    if (metrics == null) {
      metrics=new DuplicationMetrics();
      metrics.LIBRARY=library;
      metricsByLibrary.put(library,metrics);
    }
    if (rec.getReadUnmappedFlag()) {
      ++metrics.UNMAPPED_READS;
    }
 else     if (!rec.getReadPairedFlag() || rec.getMateUnmappedFlag()) {
      ++metrics.UNPAIRED_READS_EXAMINED;
    }
 else {
      ++pairedReadsExamined;
    }
    if (recordInFileIndex++ == nextDuplicateIndex) {
      rec.setDuplicateReadFlag(true);
      if (!rec.getReadPairedFlag() || rec.getMateUnmappedFlag()) {
        ++metrics.UNPAIRED_READ_DUPLICATES;
      }
 else {
        ++pairedReadDuplicates;
      }
      if (this.duplicateIndexes.hasNext()) {
        nextDuplicateIndex=this.duplicateIndexes.next();
      }
 else {
        nextDuplicateIndex=-1;
      }
    }
 else {
      rec.setDuplicateReadFlag(false);
    }
    if (this.REMOVE_DUPLICATES && rec.getDuplicateReadFlag()) {
    }
 else {
      out.addAlignment(rec);
    }
  }
  reportMemoryStats("String_Node_Str");
  out.close();
  reportMemoryStats("String_Node_Str");
  final MetricsFile<DuplicationMetrics,Double> file=getMetricsFile();
  for (  DuplicationMetrics metrics : metricsByLibrary.values()) {
    metrics.READ_PAIRS_EXAMINED=pairedReadsExamined / 2;
    metrics.READ_PAIR_DUPLICATES=pairedReadDuplicates / 2;
    metrics.calculateDerivedMetrics();
    file.addMetric(metrics);
  }
  if (metricsByLibrary.size() == 1) {
    file.setHistogram(metricsByLibrary.values().iterator().next().calculateRoiHistogram());
  }
  file.write(METRICS_FILE);
  return 0;
}

Fixed version (ground truth):
/** 
 * Main work method.  Reads the BAM file once and collects sorted information about the 5' ends of both ends of each read (or just one end in the case of pairs). Then makes a pass through those determining duplicates before re-reading the input file and writing it out with duplication flags set correctly.
 */
protected int doWork(){
  reportMemoryStats("String_Node_Str");
  log.info("String_Node_Str");
  buildSortedReadEndLists();
  reportMemoryStats("String_Node_Str");
  generateDuplicateIndexes();
  reportMemoryStats("String_Node_Str");
  log.info("String_Node_Str" + this.numDuplicateIndices + "String_Node_Str");
  Map<String,DuplicationMetrics> metricsByLibrary=new HashMap<String,DuplicationMetrics>();
  final SAMFileReader in=new SAMFileReader(INPUT);
  final SAMFileHeader header=in.getFileHeader();
  final SAMFileWriter out=new SAMFileWriterFactory().makeSAMOrBAMWriter(in.getFileHeader(),true,OUTPUT);
  long recordInFileIndex=0;
  long nextDuplicateIndex=(this.duplicateIndexes.hasNext() ? this.duplicateIndexes.next() : -1);
  for (  final SAMRecord rec : in) {
    String library=getLibraryName(header,rec);
    DuplicationMetrics metrics=metricsByLibrary.get(library);
    if (metrics == null) {
      metrics=new DuplicationMetrics();
      metrics.LIBRARY=library;
      metricsByLibrary.put(library,metrics);
    }
    if (rec.getReadUnmappedFlag()) {
      ++metrics.UNMAPPED_READS;
    }
 else     if (!rec.getReadPairedFlag() || rec.getMateUnmappedFlag()) {
      ++metrics.UNPAIRED_READS_EXAMINED;
    }
 else {
      ++metrics.READ_PAIRS_EXAMINED;
    }
    if (recordInFileIndex++ == nextDuplicateIndex) {
      rec.setDuplicateReadFlag(true);
      if (!rec.getReadPairedFlag() || rec.getMateUnmappedFlag()) {
        ++metrics.UNPAIRED_READ_DUPLICATES;
      }
 else {
        ++metrics.READ_PAIR_DUPLICATES;
      }
      if (this.duplicateIndexes.hasNext()) {
        nextDuplicateIndex=this.duplicateIndexes.next();
      }
 else {
        nextDuplicateIndex=-1;
      }
    }
 else {
      rec.setDuplicateReadFlag(false);
    }
    if (this.REMOVE_DUPLICATES && rec.getDuplicateReadFlag()) {
    }
 else {
      out.addAlignment(rec);
    }
  }
  reportMemoryStats("String_Node_Str");
  out.close();
  reportMemoryStats("String_Node_Str");
  final MetricsFile<DuplicationMetrics,Double> file=getMetricsFile();
  for (  DuplicationMetrics metrics : metricsByLibrary.values()) {
    metrics.READ_PAIRS_EXAMINED=metrics.READ_PAIRS_EXAMINED / 2;
    metrics.READ_PAIR_DUPLICATES=metrics.READ_PAIR_DUPLICATES / 2;
    metrics.calculateDerivedMetrics();
    file.addMetric(metrics);
  }
  if (metricsByLibrary.size() == 1) {
    file.setHistogram(metricsByLibrary.values().iterator().next().calculateRoiHistogram());
  }
  file.write(METRICS_FILE);
  return 0;
}