Loading Dockerfile +1 −1 Original line number Diff line number Diff line FROM broadinstitute/java-baseimage FROM openjdk:8 MAINTAINER Broad Institute DSDE <dsde-engineering@broadinstitute.org> ARG build_command=shadowJar Loading build.gradle +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ def ensureBuildPrerequisites(requiredJavaVersion, buildPrerequisitesMessage) { } ensureBuildPrerequisites(requiredJavaVersion, buildPrerequisitesMessage) final htsjdkVersion = System.getProperty('htsjdk.version', '2.16.1') final htsjdkVersion = System.getProperty('htsjdk.version', '2.18.2') // We use a custom shaded build of the NIO library to avoid a regression in the authentication layer. // GATK does the same, see https://github.com/broadinstitute/gatk/issues/3591 Loading src/main/java/picard/sam/AddOATag.java 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * The MIT License * * Copyright (c) 2018 The Broad Institute * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package picard.sam; import htsjdk.samtools.*; import htsjdk.samtools.util.*; import org.broadinstitute.barclay.argparser.Argument; import org.broadinstitute.barclay.argparser.CommandLineProgramProperties; import org.broadinstitute.barclay.help.DocumentedFeature; import picard.PicardException; import picard.cmdline.CommandLineProgram; import picard.cmdline.StandardOptionDefinitions; import picard.cmdline.programgroups.ReadDataManipulationProgramGroup; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Optional; @CommandLineProgramProperties( summary = AddOATag.USAGE_DETAILS, oneLineSummary = AddOATag.USAGE_SUMMARY, programGroup = ReadDataManipulationProgramGroup.class) @DocumentedFeature public class AddOATag extends CommandLineProgram { static final String USAGE_SUMMARY = "Record current alignment information to OA tag."; static final String USAGE_DETAILS = "This tool takes in an aligned SAM or BAM and adds the " + "OA tag to every aligned read unless an interval list is specified, where it only adds the tag to reads " + "that fall within the intervals in the interval list. This can be useful if you are about to realign but want " + "to keep the original alignment information as a separate tag." + "<br />"+ "<h4>Usage example:</h4>" + "<pre>" + "java -jar picard.jar AddOATag \\<br />" + " L=some_picard.interval_list \\<br />" + " I=sorted.bam \\<br />" + " O=fixed.bam <br />"+ "</pre>"; @Argument(shortName = StandardOptionDefinitions.INPUT_SHORT_NAME, doc = "SAM or BAM input file") public String INPUT; @Argument(shortName = StandardOptionDefinitions.OUTPUT_SHORT_NAME, doc = "SAM or BAM file to write merged result to") public String OUTPUT; @Argument(shortName = "L", doc = "If provided, only records that overlap given interval list will have the OA tag added.", optional = true) public File INTERVAL_LIST; /** * Original Alignment tag key. */ public static final String OA = "OA"; private static final Log log = Log.getInstance(AddOATag.class); @Override protected int doWork() { try (final SamReader reader = SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(IOUtil.getPath(INPUT)); final SAMFileWriter writer = new SAMFileWriterFactory().makeWriter(reader.getFileHeader(), true, IOUtil.getPath(OUTPUT), REFERENCE_SEQUENCE)) { writer.setProgressLogger( new ProgressLogger(log, (int) 1e7, "Wrote", "records")); final OverlapDetector overlapDetector = getOverlapDetectorFromIntervalListFile(INTERVAL_LIST, 0, 0); for (final SAMRecord rec : reader) { if (overlapDetector == null || overlapDetector.overlapsAny(rec)) { setOATag(rec); } writer.addAlignment(rec); } } catch (IOException e) { log.error(e); return 1; } return 0; } // Take an interval list file and convert it to an overlap detector, can add left and right padding static OverlapDetector<Interval> getOverlapDetectorFromIntervalListFile(File intervalList, int lhsBuffer, int rhsBuffer) { if (intervalList == null) { return null; } List<Interval> intervals = IntervalList.fromFile(intervalList).uniqued().getIntervals(); OverlapDetector<Interval> detector = new OverlapDetector<>(lhsBuffer, rhsBuffer); detector.addAll(intervals, intervals); return detector; } // format OA tag string according to the spec //TODO: Move this to htsjdk once https://github.com/samtools/hts-specs/pull/193 is merged private void setOATag(SAMRecord rec) { if (rec.getReferenceName().contains(",")) { throw new PicardException(String.format("Reference name for record %s contains a comma character.", rec.getReadName())); } final String oaValue; if (rec.getReadUnmappedFlag()) { oaValue = String.format("*,0,%s,*,255,;", rec.getReadNegativeStrandFlag() ? "-" : "+"); } else { oaValue = String.format("%s,%s,%s,%s,%s,%s;", rec.getReferenceName(), rec.getAlignmentStart(), rec.getReadNegativeStrandFlag() ? "-" : "+", rec.getCigarString(), rec.getMappingQuality(), Optional.ofNullable(rec.getAttribute(SAMTag.NM.name())).orElse("")); } rec.setAttribute(OA, Optional.ofNullable(rec.getAttribute(OA)).orElse("") + oaValue); } } src/main/java/picard/sam/markduplicates/MarkDuplicates.java +14 −12 Original line number Diff line number Diff line Loading @@ -756,23 +756,14 @@ public class MarkDuplicates extends AbstractMarkDuplicatesCommandLineProgram { if (firstOfNextChunk != null && areComparableForDuplicates(firstOfNextChunk, next, true, useBarcodes)) { nextChunk.add(next); } else { if (nextChunk.size() > 1) { markDuplicatePairs(nextChunk); if (TAG_DUPLICATE_SET_MEMBERS) { addRepresentativeReadIndex(nextChunk); } } handleChunk(nextChunk); nextChunk.clear(); nextChunk.add(next); firstOfNextChunk = next; } } if (nextChunk.size() > 1) { markDuplicatePairs(nextChunk); if (TAG_DUPLICATE_SET_MEMBERS) { addRepresentativeReadIndex(nextChunk); } } handleChunk(nextChunk); this.pairSort.cleanup(); this.pairSort = null; Loading Loading @@ -813,6 +804,17 @@ public class MarkDuplicates extends AbstractMarkDuplicatesCommandLineProgram { } } private void handleChunk(List<ReadEndsForMarkDuplicates> nextChunk) { if (nextChunk.size() > 1) { markDuplicatePairs(nextChunk); if (TAG_DUPLICATE_SET_MEMBERS) { addRepresentativeReadIndex(nextChunk); } } else if (nextChunk.size() == 1) { addSingletonToCount(libraryIdGenerator); } } private boolean areComparableForDuplicates(final ReadEndsForMarkDuplicates lhs, final ReadEndsForMarkDuplicates rhs, final boolean compareRead2, final boolean useBarcodes) { boolean areComparable = lhs.libraryId == rhs.libraryId; Loading src/main/java/picard/sam/markduplicates/util/AbstractMarkDuplicatesCommandLineProgram.java +46 −7 Original line number Diff line number Diff line Loading @@ -188,6 +188,11 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO file.setHistogram(metricsByLibrary.values().iterator().next().calculateRoiHistogram()); } // Add set size histograms - the set size counts are printed on adjacent columns to the ROI metric. file.addHistogram(libraryIdGenerator.getDuplicateCountHist()); file.addHistogram(libraryIdGenerator.getOpticalDuplicateCountHist()); file.addHistogram(libraryIdGenerator.getNonOpticalDuplicateCountHist()); file.write(METRICS_FILE); } Loading Loading @@ -260,6 +265,7 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO } // Check if we need to partition since the orientations could have changed final int nOpticalDup; if (hasFR && hasRF) { // need to track them independently // Variables used for optical duplicate detection and tracking final List<ReadEnds> trackOpticalDuplicatesF = new ArrayList<>(); Loading @@ -277,11 +283,26 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO } // track the duplicates trackOpticalDuplicates(trackOpticalDuplicatesF, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); trackOpticalDuplicates(trackOpticalDuplicatesR, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); final int nOpticalDupF = trackOpticalDuplicates(trackOpticalDuplicatesF, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); final int nOpticalDupR = trackOpticalDuplicates(trackOpticalDuplicatesR, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); nOpticalDup = nOpticalDupF + nOpticalDupR; } else { // No need to partition AbstractMarkDuplicatesCommandLineProgram.trackOpticalDuplicates(ends, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); nOpticalDup = trackOpticalDuplicates(ends, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); } trackDuplicateCounts(ends.size(), nOpticalDup, libraryIdGenerator); } public static void addSingletonToCount(final LibraryIdGenerator libraryIdGenerator) { libraryIdGenerator.getDuplicateCountHist().increment(1.0); libraryIdGenerator.getNonOpticalDuplicateCountHist().increment(1.0); } /** Loading @@ -294,7 +315,7 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO * optical duplicate detection, we do not consider them duplicates if one read as FR and the other RF when we order orientation by the * first mate sequenced (read #1 of the pair). */ private static void trackOpticalDuplicates(final List<? extends ReadEnds> list, private static int trackOpticalDuplicates(final List<? extends ReadEnds> list, final ReadEnds keeper, final OpticalDuplicateFinder opticalDuplicateFinder, final Histogram<Short> opticalDuplicatesByLibraryId) { Loading @@ -311,5 +332,23 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO if (opticalDuplicates > 0) { opticalDuplicatesByLibraryId.increment(list.get(0).getLibraryId(), opticalDuplicates); } return opticalDuplicates; } private static void trackDuplicateCounts(final int listSize, final int optDupCnt, final LibraryIdGenerator libraryIdGenerator) { final Histogram<Double> duplicatesCountHist = libraryIdGenerator.getDuplicateCountHist(); final Histogram<Double> nonOpticalDuplicatesCountHist = libraryIdGenerator.getNonOpticalDuplicateCountHist(); final Histogram<Double> opticalDuplicatesCountHist = libraryIdGenerator.getOpticalDuplicateCountHist(); duplicatesCountHist.increment((double) listSize); if ((listSize - optDupCnt) > 0) { nonOpticalDuplicatesCountHist.increment((double) (listSize - optDupCnt)); } if (optDupCnt > 0) { opticalDuplicatesCountHist.increment((double) (optDupCnt + 1.0)); } } } Loading
Dockerfile +1 −1 Original line number Diff line number Diff line FROM broadinstitute/java-baseimage FROM openjdk:8 MAINTAINER Broad Institute DSDE <dsde-engineering@broadinstitute.org> ARG build_command=shadowJar Loading
build.gradle +1 −1 Original line number Diff line number Diff line Loading @@ -64,7 +64,7 @@ def ensureBuildPrerequisites(requiredJavaVersion, buildPrerequisitesMessage) { } ensureBuildPrerequisites(requiredJavaVersion, buildPrerequisitesMessage) final htsjdkVersion = System.getProperty('htsjdk.version', '2.16.1') final htsjdkVersion = System.getProperty('htsjdk.version', '2.18.2') // We use a custom shaded build of the NIO library to avoid a regression in the authentication layer. // GATK does the same, see https://github.com/broadinstitute/gatk/issues/3591 Loading
src/main/java/picard/sam/AddOATag.java 0 → 100644 +131 −0 Original line number Diff line number Diff line /* * The MIT License * * Copyright (c) 2018 The Broad Institute * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package picard.sam; import htsjdk.samtools.*; import htsjdk.samtools.util.*; import org.broadinstitute.barclay.argparser.Argument; import org.broadinstitute.barclay.argparser.CommandLineProgramProperties; import org.broadinstitute.barclay.help.DocumentedFeature; import picard.PicardException; import picard.cmdline.CommandLineProgram; import picard.cmdline.StandardOptionDefinitions; import picard.cmdline.programgroups.ReadDataManipulationProgramGroup; import java.io.File; import java.io.IOException; import java.util.List; import java.util.Optional; @CommandLineProgramProperties( summary = AddOATag.USAGE_DETAILS, oneLineSummary = AddOATag.USAGE_SUMMARY, programGroup = ReadDataManipulationProgramGroup.class) @DocumentedFeature public class AddOATag extends CommandLineProgram { static final String USAGE_SUMMARY = "Record current alignment information to OA tag."; static final String USAGE_DETAILS = "This tool takes in an aligned SAM or BAM and adds the " + "OA tag to every aligned read unless an interval list is specified, where it only adds the tag to reads " + "that fall within the intervals in the interval list. This can be useful if you are about to realign but want " + "to keep the original alignment information as a separate tag." + "<br />"+ "<h4>Usage example:</h4>" + "<pre>" + "java -jar picard.jar AddOATag \\<br />" + " L=some_picard.interval_list \\<br />" + " I=sorted.bam \\<br />" + " O=fixed.bam <br />"+ "</pre>"; @Argument(shortName = StandardOptionDefinitions.INPUT_SHORT_NAME, doc = "SAM or BAM input file") public String INPUT; @Argument(shortName = StandardOptionDefinitions.OUTPUT_SHORT_NAME, doc = "SAM or BAM file to write merged result to") public String OUTPUT; @Argument(shortName = "L", doc = "If provided, only records that overlap given interval list will have the OA tag added.", optional = true) public File INTERVAL_LIST; /** * Original Alignment tag key. */ public static final String OA = "OA"; private static final Log log = Log.getInstance(AddOATag.class); @Override protected int doWork() { try (final SamReader reader = SamReaderFactory.makeDefault().referenceSequence(REFERENCE_SEQUENCE).open(IOUtil.getPath(INPUT)); final SAMFileWriter writer = new SAMFileWriterFactory().makeWriter(reader.getFileHeader(), true, IOUtil.getPath(OUTPUT), REFERENCE_SEQUENCE)) { writer.setProgressLogger( new ProgressLogger(log, (int) 1e7, "Wrote", "records")); final OverlapDetector overlapDetector = getOverlapDetectorFromIntervalListFile(INTERVAL_LIST, 0, 0); for (final SAMRecord rec : reader) { if (overlapDetector == null || overlapDetector.overlapsAny(rec)) { setOATag(rec); } writer.addAlignment(rec); } } catch (IOException e) { log.error(e); return 1; } return 0; } // Take an interval list file and convert it to an overlap detector, can add left and right padding static OverlapDetector<Interval> getOverlapDetectorFromIntervalListFile(File intervalList, int lhsBuffer, int rhsBuffer) { if (intervalList == null) { return null; } List<Interval> intervals = IntervalList.fromFile(intervalList).uniqued().getIntervals(); OverlapDetector<Interval> detector = new OverlapDetector<>(lhsBuffer, rhsBuffer); detector.addAll(intervals, intervals); return detector; } // format OA tag string according to the spec //TODO: Move this to htsjdk once https://github.com/samtools/hts-specs/pull/193 is merged private void setOATag(SAMRecord rec) { if (rec.getReferenceName().contains(",")) { throw new PicardException(String.format("Reference name for record %s contains a comma character.", rec.getReadName())); } final String oaValue; if (rec.getReadUnmappedFlag()) { oaValue = String.format("*,0,%s,*,255,;", rec.getReadNegativeStrandFlag() ? "-" : "+"); } else { oaValue = String.format("%s,%s,%s,%s,%s,%s;", rec.getReferenceName(), rec.getAlignmentStart(), rec.getReadNegativeStrandFlag() ? "-" : "+", rec.getCigarString(), rec.getMappingQuality(), Optional.ofNullable(rec.getAttribute(SAMTag.NM.name())).orElse("")); } rec.setAttribute(OA, Optional.ofNullable(rec.getAttribute(OA)).orElse("") + oaValue); } }
src/main/java/picard/sam/markduplicates/MarkDuplicates.java +14 −12 Original line number Diff line number Diff line Loading @@ -756,23 +756,14 @@ public class MarkDuplicates extends AbstractMarkDuplicatesCommandLineProgram { if (firstOfNextChunk != null && areComparableForDuplicates(firstOfNextChunk, next, true, useBarcodes)) { nextChunk.add(next); } else { if (nextChunk.size() > 1) { markDuplicatePairs(nextChunk); if (TAG_DUPLICATE_SET_MEMBERS) { addRepresentativeReadIndex(nextChunk); } } handleChunk(nextChunk); nextChunk.clear(); nextChunk.add(next); firstOfNextChunk = next; } } if (nextChunk.size() > 1) { markDuplicatePairs(nextChunk); if (TAG_DUPLICATE_SET_MEMBERS) { addRepresentativeReadIndex(nextChunk); } } handleChunk(nextChunk); this.pairSort.cleanup(); this.pairSort = null; Loading Loading @@ -813,6 +804,17 @@ public class MarkDuplicates extends AbstractMarkDuplicatesCommandLineProgram { } } private void handleChunk(List<ReadEndsForMarkDuplicates> nextChunk) { if (nextChunk.size() > 1) { markDuplicatePairs(nextChunk); if (TAG_DUPLICATE_SET_MEMBERS) { addRepresentativeReadIndex(nextChunk); } } else if (nextChunk.size() == 1) { addSingletonToCount(libraryIdGenerator); } } private boolean areComparableForDuplicates(final ReadEndsForMarkDuplicates lhs, final ReadEndsForMarkDuplicates rhs, final boolean compareRead2, final boolean useBarcodes) { boolean areComparable = lhs.libraryId == rhs.libraryId; Loading
src/main/java/picard/sam/markduplicates/util/AbstractMarkDuplicatesCommandLineProgram.java +46 −7 Original line number Diff line number Diff line Loading @@ -188,6 +188,11 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO file.setHistogram(metricsByLibrary.values().iterator().next().calculateRoiHistogram()); } // Add set size histograms - the set size counts are printed on adjacent columns to the ROI metric. file.addHistogram(libraryIdGenerator.getDuplicateCountHist()); file.addHistogram(libraryIdGenerator.getOpticalDuplicateCountHist()); file.addHistogram(libraryIdGenerator.getNonOpticalDuplicateCountHist()); file.write(METRICS_FILE); } Loading Loading @@ -260,6 +265,7 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO } // Check if we need to partition since the orientations could have changed final int nOpticalDup; if (hasFR && hasRF) { // need to track them independently // Variables used for optical duplicate detection and tracking final List<ReadEnds> trackOpticalDuplicatesF = new ArrayList<>(); Loading @@ -277,11 +283,26 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO } // track the duplicates trackOpticalDuplicates(trackOpticalDuplicatesF, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); trackOpticalDuplicates(trackOpticalDuplicatesR, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); final int nOpticalDupF = trackOpticalDuplicates(trackOpticalDuplicatesF, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); final int nOpticalDupR = trackOpticalDuplicates(trackOpticalDuplicatesR, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); nOpticalDup = nOpticalDupF + nOpticalDupR; } else { // No need to partition AbstractMarkDuplicatesCommandLineProgram.trackOpticalDuplicates(ends, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); nOpticalDup = trackOpticalDuplicates(ends, keeper, opticalDuplicateFinder, libraryIdGenerator.getOpticalDuplicatesByLibraryIdMap()); } trackDuplicateCounts(ends.size(), nOpticalDup, libraryIdGenerator); } public static void addSingletonToCount(final LibraryIdGenerator libraryIdGenerator) { libraryIdGenerator.getDuplicateCountHist().increment(1.0); libraryIdGenerator.getNonOpticalDuplicateCountHist().increment(1.0); } /** Loading @@ -294,7 +315,7 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO * optical duplicate detection, we do not consider them duplicates if one read as FR and the other RF when we order orientation by the * first mate sequenced (read #1 of the pair). */ private static void trackOpticalDuplicates(final List<? extends ReadEnds> list, private static int trackOpticalDuplicates(final List<? extends ReadEnds> list, final ReadEnds keeper, final OpticalDuplicateFinder opticalDuplicateFinder, final Histogram<Short> opticalDuplicatesByLibraryId) { Loading @@ -311,5 +332,23 @@ public abstract class AbstractMarkDuplicatesCommandLineProgram extends AbstractO if (opticalDuplicates > 0) { opticalDuplicatesByLibraryId.increment(list.get(0).getLibraryId(), opticalDuplicates); } return opticalDuplicates; } private static void trackDuplicateCounts(final int listSize, final int optDupCnt, final LibraryIdGenerator libraryIdGenerator) { final Histogram<Double> duplicatesCountHist = libraryIdGenerator.getDuplicateCountHist(); final Histogram<Double> nonOpticalDuplicatesCountHist = libraryIdGenerator.getNonOpticalDuplicateCountHist(); final Histogram<Double> opticalDuplicatesCountHist = libraryIdGenerator.getOpticalDuplicateCountHist(); duplicatesCountHist.increment((double) listSize); if ((listSize - optDupCnt) > 0) { nonOpticalDuplicatesCountHist.increment((double) (listSize - optDupCnt)); } if (optDupCnt > 0) { opticalDuplicatesCountHist.increment((double) (optDupCnt + 1.0)); } } }