private T processActiveRegion( final ActiveRegion activeRegion, final LinkedHashSet<GATKSAMRecord> reads, final Queue<ActiveRegion> workQueue, final T sum, final ActiveRegionWalker<M, T> walker) { final ArrayList<GATKSAMRecord> placedReads = new ArrayList<GATKSAMRecord>(); for (final GATKSAMRecord read : reads) { final GenomeLoc readLoc = this.engine.getGenomeLocParser().createGenomeLoc(read); if (activeRegion.getLocation().overlapsP(readLoc)) { // The region which the highest amount of overlap is chosen as the primary region for the // read (tie breaking is done as right most region) long maxOverlap = activeRegion.getLocation().sizeOfOverlap(readLoc); ActiveRegion bestRegion = activeRegion; for (final ActiveRegion otherRegionToTest : workQueue) { if (otherRegionToTest.getLocation().sizeOfOverlap(readLoc) >= maxOverlap) { maxOverlap = otherRegionToTest.getLocation().sizeOfOverlap(readLoc); bestRegion = otherRegionToTest; } } bestRegion.add(read); // The read is also added to all other regions in which it overlaps but marked as // non-primary if (walker.wantsNonPrimaryReads()) { if (!bestRegion.equals(activeRegion)) { activeRegion.add(read); } for (final ActiveRegion otherRegionToTest : workQueue) { if (!bestRegion.equals(otherRegionToTest) && otherRegionToTest.getExtendedLoc().overlapsP(readLoc)) { otherRegionToTest.add(read); } } } placedReads.add(read); } else if (activeRegion.getExtendedLoc().overlapsP(readLoc) && walker.wantsNonPrimaryReads()) { activeRegion.add(read); } } reads.removeAll( placedReads); // remove all the reads which have been placed into their active region // WARNING: This hashset relies on reads being exactly equal when they are placed in the list as // when they are removed. So the ActiveRegionWalker can't modify the reads in any way. logger.debug( ">> Map call with " + activeRegion.getReads().size() + " " + (activeRegion.isActive ? "active" : "inactive") + " reads @ " + activeRegion.getLocation() + " with full extent: " + activeRegion.getReferenceLoc()); final M x = walker.map(activeRegion, null); return walker.reduce(x, sum); }