From 9afa99876cb865fec732f8901db809ecc76f7732 Mon Sep 17 00:00:00 2001 From: jamesemery Date: Tue, 21 Mar 2023 13:32:00 -0400 Subject: [PATCH] Checkpoint of necessary changes for DRAGEN v3.7.8 concordance (#8083) Added a new mode to HaplotypeCaller: --dragen-378-concordance-mode - Rewrote the pileup-detection code to support DRAGEN based heuristics for filtering out pileup alleles - Extended pileup-detection code to support both insertions and deletions. - Added a new HMM model, the "PDHMM" or the "Partially Determined" HMM. This new model treats only one allele at a time as "determined" and everything else in a region is a wildcard that allows for no-penalty passage through the HMM matrix for reads with any wildcard allele represented, greatly reducing the combinatorial complexity at messy assembly regions. - Added a PartiallyDeterminedHaplotypeComputationEngine.java class for managing the construction of PDHaplotypes from the union (plus filtering) of both assembly alleles and pileup-detection alleles. - Added a series of extra debugging arguments to the HaplotypeCaller and PDHMM to facilitate future development. --- .../engine/AlignmentAndReferenceContext.java | 9 + .../engine/AssemblyRegionIterator.java | 10 +- .../AssemblyBasedCallerUtils.java | 100 +- .../haplotypecaller/AssemblyResultSet.java | 48 +- .../haplotypecaller/HaplotypeCaller.java | 12 +- .../HaplotypeCallerArgumentCollection.java | 75 +- .../HaplotypeCallerEngine.java | 113 +- .../HaplotypeCallerGenotypingEngine.java | 22 +- .../PDPairHMMLikelihoodCalculationEngine.java | 372 +++++++ ...yDeterminedHaplotypeComputationEngine.java | 987 ++++++++++++++++++ .../PileupDetectionArgumentCollection.java | 75 +- .../RampedHaplotypeCallerEngine.java | 6 +- .../ReadLikelihoodCalculationEngine.java | 3 +- .../ReferenceConfidenceModel.java | 3 +- .../tools/walkers/mutect/Mutect2Engine.java | 31 +- .../FilterAlignmentArtifacts.java | 3 +- .../activityprofile/ActivityProfileState.java | 10 + .../hellbender/utils/haplotype/EventMap.java | 14 +- .../hellbender/utils/haplotype/Haplotype.java | 16 +- .../PartiallyDeterminedHaplotype.java | 227 ++++ .../utils/pairhmm/LoglessPDPairHMM.java | 227 ++++ .../utils/pairhmm/N2MemoryPDPairHMM.java | 65 ++ .../hellbender/utils/pairhmm/PDPairHMM.java | 374 +++++++ .../utils/pileup/PileupBasedAlleles.java | 240 +++-- .../HaplotypeCallerIntegrationTest.java | 102 ++ ...nedHaplotypeComputationEngineUnitTest.java | 223 ++++ .../mutect/Mutect2IntegrationTest.java | 35 + ...MMLikelihoodCalculationEngineUnitTest.java | 67 ++ .../large/expected.PDHMM.hmmresults.txt | 3 + .../expected.pileupCallerDRAGEN.378.gatk4.vcf | 278 +++++ ...ected.pileupCallerDRAGEN.378.gatk4.vcf.idx | Bin 0 -> 2923 bytes ...ed.pileupCallerDRAGEN.WithIndels.gatk4.vcf | 133 ++- .../expected.pileupCallerDRAGEN.gatk4.vcf | 102 +- .../expected.pileupCallerDRAGEN.gatk4.vcf.idx | Bin 1611 -> 1611 bytes .../expected.pileupCallerDefaults.gatk4.vcf | 136 ++- ...xpected.pileupCallerDefaults.gatk4.vcf.idx | Bin 2877 -> 2920 bytes 36 files changed, 3834 insertions(+), 287 deletions(-) create mode 100644 src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PDPairHMMLikelihoodCalculationEngine.java create mode 100644 src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngine.java create mode 100644 src/main/java/org/broadinstitute/hellbender/utils/haplotype/PartiallyDeterminedHaplotype.java create mode 100644 src/main/java/org/broadinstitute/hellbender/utils/pairhmm/LoglessPDPairHMM.java create mode 100644 src/main/java/org/broadinstitute/hellbender/utils/pairhmm/N2MemoryPDPairHMM.java create mode 100644 src/main/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMM.java create mode 100644 src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngineUnitTest.java create mode 100644 src/test/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMMLikelihoodCalculationEngineUnitTest.java create mode 100644 src/test/resources/large/expected.PDHMM.hmmresults.txt create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.378.gatk4.vcf create mode 100644 src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.378.gatk4.vcf.idx diff --git a/src/main/java/org/broadinstitute/hellbender/engine/AlignmentAndReferenceContext.java b/src/main/java/org/broadinstitute/hellbender/engine/AlignmentAndReferenceContext.java index 4e235e964fb..7a543d59ca1 100644 --- a/src/main/java/org/broadinstitute/hellbender/engine/AlignmentAndReferenceContext.java +++ b/src/main/java/org/broadinstitute/hellbender/engine/AlignmentAndReferenceContext.java @@ -7,6 +7,7 @@ public class AlignmentAndReferenceContext { private final AlignmentContext alignmentContext; private final ReferenceContext referenceContext; + private double activityScore = 0.0; public AlignmentAndReferenceContext(final AlignmentContext alignmentContext, final ReferenceContext referenceContext) { @@ -29,4 +30,12 @@ public AlignmentContext getAlignmentContext() { public ReferenceContext getReferenceContext() { return referenceContext; } + + public double getActivityScore() { + return activityScore; + } + + public void setActivityScore(double activityScore) { + this.activityScore = activityScore; + } } diff --git a/src/main/java/org/broadinstitute/hellbender/engine/AssemblyRegionIterator.java b/src/main/java/org/broadinstitute/hellbender/engine/AssemblyRegionIterator.java index 2aea2b7e240..9b6a050f9c2 100644 --- a/src/main/java/org/broadinstitute/hellbender/engine/AssemblyRegionIterator.java +++ b/src/main/java/org/broadinstitute/hellbender/engine/AssemblyRegionIterator.java @@ -137,14 +137,18 @@ private AssemblyRegion loadNextAssemblyRegion() { final SimpleInterval pileupInterval = new SimpleInterval(pileup); final ReferenceContext pileupRefContext = new ReferenceContext(reference, pileupInterval); final FeatureContext pileupFeatureContext = new FeatureContext(features, pileupInterval); - if (pendingAlignmentData!=null) { - pendingAlignmentData.add(new AlignmentAndReferenceContext(pileup, pileupRefContext)); - } + final ActivityProfileState profile = evaluator.isActive(pileup, pileupRefContext, pileupFeatureContext); logger.debug(() -> profile.toString()); activityProfile.add(profile); + if (pendingAlignmentData!=null) { + AlignmentAndReferenceContext alignmentAndRefContext = new AlignmentAndReferenceContext(pileup, pileupRefContext); + alignmentAndRefContext.setActivityScore(profile.getOriginalActiveProb()); + pendingAlignmentData.add(alignmentAndRefContext); + } + // A pending region only becomes ready once our locus iterator has advanced beyond the end of its extended span // (this ensures that we've loaded all reads that belong in the new region) if ( ! pendingRegions.isEmpty() && IntervalUtils.isAfter(pileup.getLocation(), pendingRegions.peek().getPaddedSpan(), readHeader.getSequenceDictionary()) ) { diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyBasedCallerUtils.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyBasedCallerUtils.java index f791f8d0c70..2ff402a0bc2 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyBasedCallerUtils.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyBasedCallerUtils.java @@ -31,8 +31,11 @@ import org.broadinstitute.hellbender.utils.genotyper.SampleList; import org.broadinstitute.hellbender.utils.haplotype.Haplotype; import org.broadinstitute.hellbender.utils.haplotype.HaplotypeBAMWriter; +import org.broadinstitute.hellbender.utils.haplotype.PartiallyDeterminedHaplotype; import org.broadinstitute.hellbender.utils.io.IOUtils; import org.broadinstitute.hellbender.utils.locusiterator.LocusIteratorByState; +import org.broadinstitute.hellbender.utils.logging.OneShotLogger; +import org.broadinstitute.hellbender.utils.pileup.PileupBasedAlleles; import org.broadinstitute.hellbender.utils.pileup.ReadPileup; import org.broadinstitute.hellbender.utils.read.*; import org.broadinstitute.hellbender.utils.smithwaterman.SmithWatermanAligner; @@ -72,6 +75,8 @@ public final class AssemblyBasedCallerUtils { // get realigned incorrectly. See https://github.com/broadinstitute/gatk/issues/5060 public static final int MINIMUM_READ_LENGTH_AFTER_TRIMMING = 10; + public static final OneShotLogger haplotypeDeletionWarningLogger = new OneShotLogger(AssemblyBasedCallerUtils.class); + // Phase group notation can be interpreted as a representation of the alleles present on the two phased haplotypes at the site: // "0": REF or '*'; "1": site-specific alt allele enum PhaseGroup { @@ -263,8 +268,7 @@ public static ReadLikelihoodCalculationEngine createLikelihoodCalculationEngine( final boolean handleSoftclips, final ReadLikelihoodCalculationEngine.Implementation implementation) { //AlleleLikelihoods::normalizeLikelihoods uses Double.NEGATIVE_INFINITY as a flag to disable capping - final double log10GlobalReadMismappingRate = likelihoodArgs.phredScaledGlobalReadMismappingRate < 0 ? Double.NEGATIVE_INFINITY - : QualityUtils.qualToErrorProbLog10(likelihoodArgs.phredScaledGlobalReadMismappingRate); + final double log10GlobalReadMismappingRate = getGlobalMismatchingRateFromArgs(likelihoodArgs); switch ( implementation) { // TODO these constructors should eventually be matched so they both incorporate all the same ancilliary arguments @@ -284,6 +288,14 @@ public static ReadLikelihoodCalculationEngine createLikelihoodCalculationEngine( } } + /** + * Exposed so that PDHMM can be constructed outside of this class + */ + public static double getGlobalMismatchingRateFromArgs(LikelihoodEngineArgumentCollection likelihoodArgs) { + return likelihoodArgs.phredScaledGlobalReadMismappingRate < 0 ? Double.NEGATIVE_INFINITY + : QualityUtils.qualToErrorProbLog10(likelihoodArgs.phredScaledGlobalReadMismappingRate); + } + public static Optional createBamWriter(final AssemblyBasedCallerArgumentCollection args, final boolean createBamOutIndex, final boolean createBamOutMD5, @@ -320,7 +332,6 @@ public static VariantContext makeMergedVariantContext(final List * for further HC steps */ public static AssemblyResultSet assembleReads(final AssemblyRegion region, - final List forcedPileupAlleles, final AssemblyBasedCallerArgumentCollection argumentCollection, final SAMFileHeader header, final SampleList sampleList, @@ -397,10 +408,6 @@ public static AssemblyResultSet assembleReads(final AssemblyRegion region, haplotypeCollapsing); assemblyResultSet.setHaplotypeCollapsingEngine(haplotypeCollapsing); - - if (!forcedPileupAlleles.isEmpty()) { - processPileupAlleles(region, forcedPileupAlleles, argumentCollection.pileupDetectionArgs.snpAdajacentToAssemblyIndel, argumentCollection.maxMnpDistance, aligner, refHaplotype, assemblyResultSet, argumentCollection.pileupDetectionArgs.numHaplotypesToIterate, argumentCollection.pileupDetectionArgs.filteringKmerSize, argumentCollection.getHaplotypeToReferenceSWParameters()); - } assemblyResultSet.setDebug(argumentCollection.assemblerArgs.debugAssembly); assemblyResultSet.debugDump(logger); return assemblyResultSet; @@ -429,15 +436,76 @@ private static int determineFlowAssemblyColapseHmer(SAMFileHeader readsHeader) { return result; } + /** + * Helper method that handles the actual "GGA-like" Merging of haplotype alleles into an assembly result set. + * + * First this method will filter out haplotypes that contain alleles that have failed the pileup calling filtering steps, + * Then the list will attempt to poke into the haplotype list artificial haplotypes that have the found alleles present. + * + * @param region + * @param argumentCollection + * @param aligner + * @param refHaplotype + * @param assemblyResultSet + * @param pileupAllelesFoundShouldFilter + * @param pileupAllelesPassingFilters + * @return + */ + public static AssemblyResultSet applyPileupEventsAsForcedAlleles(final AssemblyRegion region, final AssemblyBasedCallerArgumentCollection argumentCollection, + final SmithWatermanAligner aligner, final Haplotype refHaplotype, + final AssemblyResultSet assemblyResultSet, final List pileupAllelesFoundShouldFilter, + final List pileupAllelesPassingFilters, final boolean debug) { + List haplotypesWithFilterAlleles = new ArrayList<>(); + // IF we find pileup alleles that we want to filter... AND we are not generating the partially determined haplotypes, + // we resort to a messy approach where we filter alleles by throwing away every haplotype supporting an allele. This is + // very dangerous since this could easily destroy phased variants with the haplotype. + if (!pileupAllelesFoundShouldFilter.isEmpty() && !argumentCollection.pileupDetectionArgs.generatePDHaplotypes) { + // TODO this is a bad algorithm for bad people + for(VariantContext delVariant : pileupAllelesFoundShouldFilter) { + for (Haplotype hap : assemblyResultSet.getHaplotypeList()) { + if (hap.getEventMap()==null) { + // NOTE: This check should be a reasonable sanity check on the inputs. However, there edge cases in the assembly engine + SW realignment that can cause + // haplotypes to re-merge into the reference and end up with an empty event map. (Also the event map code explicitly expects to fail in some instances) + // thus we can't enforce that the haplotypes no variants. +// if (!hap.isReference()) { +// //throw new RuntimeException("empty event map for haplotype" + hap); +// } + } else { + if (hap.getEventMap().getVariantContexts().stream().anyMatch(v -> v.getStart() == delVariant.getStart() + && delVariant.getReference().equals(v.getReference()) + && delVariant.getAlternateAllele(0).equals(v.getAlternateAllele(0)))) { + if (argumentCollection.pileupDetectionArgs.debugPileupStdout) System.err.println("Flagging hap " + hap + " for containing variant " + delVariant); + haplotypesWithFilterAlleles.add(hap); + } + } + } + } + } + // TODO removing haplotypes whole-cloth is messy and will likely lead to errors and dropped variants in this code + if (!haplotypesWithFilterAlleles.isEmpty()) { + if (debug) System.out.println("Found Assembly Haps with filtered Variants:\n"+haplotypesWithFilterAlleles.stream().map(Haplotype::toString).collect(Collectors.joining("\n"))); + + haplotypeDeletionWarningLogger.warn(() -> "Haplotypes from Assembly are being filtered by heuristics from the PileupCaller. This can lead to missing variants. See --"+PileupDetectionArgumentCollection.PILEUP_DETECTION_FILTER_ASSEMBLY_HAPS_THRESHOLD+" for more details"); + + for (Haplotype hap : haplotypesWithFilterAlleles) { + assemblyResultSet.removeHapltotype(hap); + } + } + if (!pileupAllelesPassingFilters.isEmpty()) { + processPileupAlleles(region, pileupAllelesPassingFilters, argumentCollection.maxMnpDistance, argumentCollection.pileupDetectionArgs.snpAdajacentToAssemblyIndel, aligner, refHaplotype, assemblyResultSet, argumentCollection.pileupDetectionArgs.numHaplotypesToIterate, argumentCollection.pileupDetectionArgs.filteringKmerSize, argumentCollection.getHaplotypeToReferenceSWParameters(), debug); + } + return assemblyResultSet; + } + /** * Handle pileup detected alternate alleles. */ @VisibleForTesting @SuppressWarnings("deprecation") - static void processPileupAlleles(final AssemblyRegion region, final List givenAlleles, final int maxMnpDistance, + static void processPileupAlleles(final AssemblyRegion region, final List pileupVC, final int maxMnpDistance, final int snpAdjacentToIndelLimit, final SmithWatermanAligner aligner, final Haplotype refHaplotype, final AssemblyResultSet assemblyResultSet, final int numHaplotypesPerIteration, final int hapFilteringKmerSize, - final SWParameters haplotypeToReferenceSWParameters) { + final SWParameters haplotypeToReferenceSWParameters, final boolean debug) { final int activeRegionStart = refHaplotype.getAlignmentStartHapwrtRef(); final Map assembledVariants = assemblyResultSet.getVariationEvents(maxMnpDistance).stream() .collect(Collectors.groupingBy(VariantContext::getStart, Collectors.collectingAndThen(Collectors.toList(), AssemblyBasedCallerUtils::makeMergedVariantContext))); @@ -455,7 +523,7 @@ static void processPileupAlleles(final AssemblyRegion region, final List kmerReadCounts = getKmerReadCounts(region.getHardClippedPileupReads(), hapFilteringKmerSize); // Remove SNPs that are too close to assembled indels. - final List givenAllelesFiltered = givenAlleles.stream().filter(vc -> vc.isIndel() || assembledIndels.stream().noneMatch(indel -> vc.withinDistanceOf(indel, snpAdjacentToIndelLimit))).collect(Collectors.toList()); + final List givenAllelesFiltered = pileupVC.stream().filter(vc -> vc.isIndel() || assembledIndels.stream().noneMatch(indel -> vc.withinDistanceOf(indel, snpAdjacentToIndelLimit))).collect(Collectors.toList()); for (final VariantContext givenVC : givenAllelesFiltered) { final VariantContext assembledVC = assembledVariants.get(givenVC.getStart()); @@ -470,6 +538,7 @@ static void processPileupAlleles(final AssemblyRegion region, final List newPileupHaplotypes = new ArrayList<>(); for (final Allele givenAllele : unassembledNonSymbolicAlleles) { + if (debug) System.out.println("Processing new Haplotypes for Pileup Allele that was not in the assembly: "+givenVC); for (final Haplotype baseHaplotype : baseHaplotypes) { // make sure this allele doesn't collide with a variant on the haplotype if (baseHaplotype.getEventMap() == null || baseHaplotype.getEventMap().getVariantContexts().stream().noneMatch(vc -> vc.overlaps(givenVC))) { @@ -490,7 +559,9 @@ static void processPileupAlleles(final AssemblyRegion region, final List refactoredHaps = filterPileupHaplotypes(newPileupHaplotypes, kmerReadCounts, numHaplotypesPerIteration, hapFilteringKmerSize); + baseHaplotypes.addAll(refactoredHaps); + if (debug) System.out.println("Constructed the following new Pileup Haplotypes after filtering:\n"+refactoredHaps.stream().map(Haplotype::toString).collect(Collectors.joining("\n"))); } baseHaplotypes.forEach(assemblyResultSet::add); @@ -556,7 +627,8 @@ private static List getAllelesNotPresentInAssembly(VariantContext givenV ReferenceConfidenceVariantContextMerger.remapAlleles(assembledVC, longerRef)); final Set givenAlleleSet = new HashSet<>(longerRef.length() == givenVCRefLength ? givenVC.getAlternateAlleles() : ReferenceConfidenceVariantContextMerger.remapAlleles(givenVC, longerRef)); - unassembledGivenAlleles = givenAlleleSet.stream().filter(a -> !assembledAlleleSet.contains(a)).collect(Collectors.toList()); + //We must filter out the Ref alleles here to protect against edge cases and undexpected behavior from the pileupcalling code + unassembledGivenAlleles = givenAlleleSet.stream().filter(a -> !assembledAlleleSet.contains(a)).filter(a -> !a.isReference()).collect(Collectors.toList()); } return unassembledGivenAlleles; } @@ -856,6 +928,10 @@ public static Map> createAlleleMapper(final VariantConte for (final Haplotype h : haplotypes) { + // Partially determined haplotypes know at what position they are determined, only determined position haps should be considered for genotyping + if (h.isPartiallyDetermined() && ((PartiallyDeterminedHaplotype) h).getDeterminedPosition() != loc) { + continue; + } final List spanningEvents = h.getEventMap().getOverlappingEvents(loc); if (spanningEvents.isEmpty()) { //no events --> this haplotype supports the reference at this locus diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyResultSet.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyResultSet.java index 8e8c25a248e..574ea5f562b 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyResultSet.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/AssemblyResultSet.java @@ -33,8 +33,13 @@ */ public final class AssemblyResultSet { + public static final Comparator HAPLOTYPE_VARIANT_CONTEXT_COMPARATOR = Comparator.comparingInt(VariantContext::getStart) + // Decide arbitrarily so as not to accidentally throw away overlapping variants + .thenComparingInt(vc -> vc.getReference().length()) + .thenComparing(vc -> vc.getAlternateAllele(0)); private final Map assemblyResultByKmerSize; private final Set haplotypes; + private Set originalAssemblyHaps = new LinkedHashSet<>(); private final Map assemblyResultByHaplotype; private AssemblyRegion regionForGenotyping; private byte[] fullReferenceWithPadding; @@ -47,6 +52,7 @@ public final class AssemblyResultSet { private boolean debug; private static final Logger logger = LogManager.getLogger(AssemblyResultSet.class); private LongHomopolymerHaplotypeCollapsingEngine haplotypeCollapsingEngine; // this is nullable - indicating no collapsing engine (flow-based specific) + private boolean isPartiallyDeterminedList = false; /** * Constructs a new empty assembly result set. @@ -552,10 +558,7 @@ public void regenerateVariationEvents(int maxMnpDistance) { private static SortedSet getAllVariantContexts( final List haplotypes ) { // Using the cigar from each called haplotype figure out what events need to be written out in a VCF file final TreeSet vcs = new TreeSet<>( - Comparator.comparingInt(VariantContext::getStart) - // Decide arbitrarily so as not to accidentally throw away overlapping variants - .thenComparingInt(vc -> vc.getReference().length()) - .thenComparing(vc -> vc.getAlternateAllele(0))); + HAPLOTYPE_VARIANT_CONTEXT_COMPARATOR); for( final Haplotype h : haplotypes ) { vcs.addAll(h.getEventMap().getVariantContexts()); @@ -583,8 +586,43 @@ public void clearHaplotypes() { public void replaceAllHaplotypes(Set list) { haplotypes.clear();; refHaplotype = null; - for ( Haplotype h : list ) + for ( Haplotype h : list ) { add(h); + if (h.isNonReference()) { + variationPresent = true; + } + } + } + + // For PDHMM use: Remove a haplotype from this AssemblyResultSet and update all of the various references in the + // object to that haplotype to be current. + // WARNING: Deleting haplotypes in this manner is highly dangerous and will likely lead to lost variants + public void removeHapltotype(final Haplotype hap) { + + haplotypes.remove(hap); + assemblyResultByHaplotype.remove(hap); + for (Integer kmerSize : assemblyResultByKmerSize.keySet()) { + Set discovered = assemblyResultByKmerSize.get(kmerSize).getDiscoveredHaplotypes(); + discovered.remove(hap); + assemblyResultByKmerSize.get(kmerSize).setDiscoveredHaplotypes(discovered); + } } + public void setPartiallyDeterminedMode() { + this.isPartiallyDeterminedList = true; + } + + public boolean isPartiallyDeterminedList() { + return isPartiallyDeterminedList; + } + + // For PDHMM use: store original assembly haplotypes if we are injecting artificial haplotypes later + // WARNING: This is likely not set in every case, use with caution + public void storeAssemblyHaplotypes() { + originalAssemblyHaps = new LinkedHashSet<>(haplotypes); + } + + public boolean hasOverwrittenHaps() { + return !originalAssemblyHaps.isEmpty(); + } } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCaller.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCaller.java index 8e7a15e43fd..f504d400b13 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCaller.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCaller.java @@ -20,11 +20,9 @@ import org.broadinstitute.hellbender.tools.walkers.annotator.Annotation; import org.broadinstitute.hellbender.tools.walkers.annotator.HaplotypeFilteringAnnotation; import org.broadinstitute.hellbender.tools.walkers.annotator.VariantAnnotatorEngine; -import org.broadinstitute.hellbender.tools.walkers.genotyper.GenotypeAssignmentMethod; import org.broadinstitute.hellbender.transformers.DRAGENMappingQualityReadTransformer; import org.broadinstitute.hellbender.transformers.ReadTransformer; import org.broadinstitute.hellbender.utils.fasta.CachingIndexedFastaSequenceFile; -import org.broadinstitute.hellbender.cmdline.ModeArgumentUtils; import java.util.Collection; import java.util.List; @@ -172,21 +170,21 @@ public List getDefaultReadFilters() { */ @Override protected String[] customCommandLineValidation() { - if (hcArgs.dragenMode && hcArgs.flowMode != HaplotypeCallerArgumentCollection.FlowMode.NONE ) { + if ((hcArgs.isDragenGATKMode()) && hcArgs.isFlowBasedCallingMode()) { throw new UserException("dragen mode and flow mode can't be both specified"); } - if (hcArgs.dragenMode) { + if (hcArgs.isDragenGATKMode()) { final GATKReadFilterPluginDescriptor readFilterPlugin = getCommandLineParser().getPluginDescriptor(GATKReadFilterPluginDescriptor.class); Optional filterOptional = readFilterPlugin.getResolvedInstances().stream().filter(rf -> rf instanceof MappingQualityReadFilter).findFirst(); filterOptional.ifPresent(readFilter -> ((MappingQualityReadFilter) readFilter).minMappingQualityScore = 1); ModeArgumentUtils.setArgValues( getCommandLineParser(), - hcArgs.getDragenNameValuePairs(), - HaplotypeCallerArgumentCollection.DRAGEN_GATK_MODE_LONG_NAME); + hcArgs.dragen378Mode? hcArgs.getDragenVersion378NameValuePairs() : hcArgs.getDragenVersion3412NameValuePairs(), + hcArgs.dragen378Mode? HaplotypeCallerArgumentCollection.DRAGEN_378_GATK_MODE_LONG_NAME : HaplotypeCallerArgumentCollection.DRAGEN_3412_GATK_MODE_LONG_NAME); } - if (hcArgs.flowMode != HaplotypeCallerArgumentCollection.FlowMode.NONE) { + if (hcArgs.isFlowBasedCallingMode()) { ModeArgumentUtils.setArgValues( getCommandLineParser(), hcArgs.flowMode.getNameValuePairs(), diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerArgumentCollection.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerArgumentCollection.java index d3f6c794472..7ab58d73264 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerArgumentCollection.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerArgumentCollection.java @@ -30,7 +30,8 @@ public class HaplotypeCallerArgumentCollection extends AssemblyBasedCallerArgume public static final String GQ_BAND_SHORT_NAME = "GQB"; public static final String DO_NOT_CORRECT_OVERLAPPING_BASE_QUALITIES_LONG_NAME = "do-not-correct-overlapping-quality"; public static final String OUTPUT_BLOCK_LOWER_BOUNDS = "floor-blocks"; - public static final String DRAGEN_GATK_MODE_LONG_NAME = "dragen-mode"; + public static final String DRAGEN_3412_GATK_MODE_LONG_NAME = "dragen-mode"; + public static final String DRAGEN_378_GATK_MODE_LONG_NAME = "dragen-378-concordance-mode"; public static final String APPLY_BQD_LONG_NAME = "apply-bqd"; public static final String APPLY_FRD_LONG_NAME = "apply-frd"; public static final String TRANSFORM_DRAGEN_MAPPING_QUALITY_LONG_NAME = "transform-dragen-mapping-quality"; @@ -151,30 +152,44 @@ protected ReadThreadingAssemblerArgumentCollection getReadThreadingAssemblerArgu * * */ - @Argument(fullName = DRAGEN_GATK_MODE_LONG_NAME, optional = true, doc="Single argument for enabling the bulk of DRAGEN-GATK features. NOTE: THIS WILL OVERWRITE PROVIDED ARGUMENT CHECK TOOL INFO TO SEE WHICH ARGUMENTS ARE SET).") - public Boolean dragenMode = false; + @Argument(fullName = DRAGEN_3412_GATK_MODE_LONG_NAME, optional = true, doc="Single argument for enabling the bulk of DRAGEN-GATK features. NOTE: THIS WILL OVERWRITE PROVIDED ARGUMENT CHECK TOOL INFO TO SEE WHICH ARGUMENTS ARE SET).", mutex = {DRAGEN_378_GATK_MODE_LONG_NAME}) + public Boolean dragen3412mode = false; + + /** + * DRAGEN-GATK version 2: This includes PDHMM and Columnwise detection (with hopes to add Joint Detection and new STRE as well in the future) + */ + @Advanced + @Argument(fullName = DRAGEN_378_GATK_MODE_LONG_NAME, optional = true, doc="Single argument for enabling the bulk of DRAGEN-GATK features including new developments for concordance against DRAGEN 3.7.8. NOTE: THIS WILL OVERWRITE PROVIDED ARGUMENT CHECK TOOL INFO TO SEE WHICH ARGUMENTS ARE SET).", mutex = {DRAGEN_3412_GATK_MODE_LONG_NAME}) + public Boolean dragen378Mode = false; + @Advanced @Argument(fullName = FLOW_GATK_MODE_LONG_NAME, optional = true, doc="Single argument for enabling the bulk of Flow Based features. NOTE: THIS WILL OVERWRITE PROVIDED ARGUMENT CHECK TOOL INFO TO SEE WHICH ARGUMENTS ARE SET).") public FlowMode flowMode = FlowMode.NONE; + @Advanced @Argument(fullName = APPLY_BQD_LONG_NAME, doc = "If enabled this argument will apply the DRAGEN-GATK BaseQualityDropout model to the genotyping model for filtering sites due to Linked Error mode.", optional = true) public boolean applyBQD = false; + @Advanced @Argument(fullName = APPLY_FRD_LONG_NAME, doc = "If enabled this argument will apply the DRAGEN-GATK ForeignReadDetection model to the genotyping model for filtering sites.", optional = true) public boolean applyFRD = false; + @Advanced @Argument(fullName = DISABLE_SPANNING_EVENT_GENOTYPING_LONG_NAME, doc = "If enabled this argument will disable inclusion of the '*' spanning event when genotyping events that overlap deletions", optional = true) public boolean disableSpanningEventGenotyping = false; + @Advanced @Argument(fullName = TRANSFORM_DRAGEN_MAPPING_QUALITY_LONG_NAME, doc = "If enabled this argument will map DRAGEN aligner aligned reads with mapping quality <=250 to scale up to MQ 50", optional = true) public boolean transformDRAGENMapQ = false; - //TODO NOTE TO THE REVIEWER, THIS ARGUMENT IS INSUFFICIENT BOTH THIS AND --minimum-mapping-quality must be set, unfortunatley + + //TODO NOTE TO THE REVIEWER, THIS ARGUMENT IS INSUFFICIENT BOTH THIS AND --minimum-mapping-quality must be set, unfortunately //TODO they can't be unified since the toolDefaultReadFilters get instantiated before this field gets populated, and we can't //TODO pull the threshold from that filter since it might or might not exist by the time we go to filter for threading, really - //TODO we should unify on the readFilter version of this check i think but perhaps they are seperate for athropological historical reasons and it is thus culturally protected? + //TODO we should unify on the readFilter version of this check i think but perhaps they are separate for anthropological historical reasons and it is thus culturally protected? @Advanced @Argument(fullName = MAPPING_QUALITY_THRESHOLD_FOR_GENOTYPING_LONG_NAME, doc = "Control the threshold for discounting reads from the genotyper due to mapping quality after the active region detection and assembly steps but before genotyping. NOTE: this is in contrast to the --"+ ReadFilterArgumentDefinitions.MINIMUM_MAPPING_QUALITY_NAME+" argument which filters reads from all parts of the HaplotypeCaller. If you would like to call genotypes with a different threshold both arguments must be set.", optional = true) public int mappingQualityThreshold = HaplotypeCallerEngine.DEFAULT_READ_QUALITY_FILTER_THRESHOLD; + @Advanced @Argument(fullName = MAX_EFFECTIVE_DEPTH_ADJUSTMENT_FOR_FRD_LONG_NAME, doc = "Set the maximum depth to modify FRD adjustment to in the event of high depth sites (0 to disable)", optional = false) public int maxEffectiveDepthAdjustment = 0; @@ -226,7 +241,7 @@ protected ReadThreadingAssemblerArgumentCollection getReadThreadingAssemblerArgu @Argument(fullName= USE_FILTERED_READS_FOR_ANNOTATIONS_LONG_NAME, doc = "Use the contamination-filtered read maps for the purposes of annotating variants", optional=true) public boolean useFilteredReadMapForAnnotations = false; - public String[] getDragenNameValuePairs() { + public String[] getDragenVersion3412NameValuePairs() { return new String[]{ APPLY_BQD_LONG_NAME, "true", APPLY_FRD_LONG_NAME, "true", @@ -245,11 +260,59 @@ public String[] getDragenNameValuePairs() { }; } + /** + * Extra arguments required for DRAGEN-GATK to be Functionally-Equivalent to DRAGEN v3.7.8. These are a super-set + * of the arguments above required for DRAGEN v3.4.12 Functional-Equivalence. + * The notable differences in the two versions are as follows: + * - v3.7.8 is run with Pileup-Calling enabled which is equivalent to DRAGEN "Joint Detection" in function + * - v3.7.8 adds heuristics to the Pileup-Caller to filter out false-positives. These heuristics may also filter out false positives from the assembly graphs. + * - v3.7.8 is run with the PartiallyDetermined HMM (or "PDHMM") in place of the normal HMM for assigning allele likelihoods + */ + public String[] getDragenVersion378NameValuePairs() { + return new String[]{ + APPLY_BQD_LONG_NAME, "true", + APPLY_FRD_LONG_NAME, "true", + TRANSFORM_DRAGEN_MAPPING_QUALITY_LONG_NAME, "true", + SOFT_CLIP_LOW_QUALITY_ENDS_LONG_NAME, "true", + MAPPING_QUALITY_THRESHOLD_FOR_GENOTYPING_LONG_NAME, "1", + ReadFilterArgumentDefinitions.MINIMUM_MAPPING_QUALITY_NAME, "1", + ALLELE_EXTENSION_LONG_NAME, "1", + LikelihoodEngineArgumentCollection.DISABLE_CAP_BASE_QUALITIES_TO_MAP_QUALITY_LONG_NAME, "true", + LikelihoodEngineArgumentCollection.ENABLE_DYNAMIC_READ_DISQUALIFICATION_FOR_GENOTYPING_LONG_NAME, "true", + LikelihoodEngineArgumentCollection.EXPECTED_MISMATCH_RATE_FOR_READ_DISQUALIFICATION_LONG_NAME, "0.03", + GenotypeCalculationArgumentCollection.GENOTYPE_ASSIGNMENT_METHOD_LONG_NAME, String.valueOf(GenotypeAssignmentMethod.USE_POSTERIOR_PROBABILITIES), + AssemblyRegionArgumentCollection.INDEL_PADDING_LONG_NAME, "150", + GenotypeCalculationArgumentCollection.CALL_CONFIDENCE_LONG_NAME, "1.0", //NOTE: this is different from the above mode, we find it results in slightly less noise with DRAGEN + GenotypeCalculationArgumentCollection.USE_POSTERIORS_TO_CALCULATE_QUAL_LONG_NAME, "true", + + // Pileup caller and PDHMM arguments + PileupDetectionArgumentCollection.PILEUP_DETECTION_LONG_NAME, "true", + PileupDetectionArgumentCollection.PILEUP_DETECTION_ABSOLUTE_ALT_DEPTH, "0", + PileupDetectionArgumentCollection.PILEUP_DETECTION_BAD_READ_RATIO_LONG_NAME, "0.40", + PileupDetectionArgumentCollection.PILEUP_DETECTION_ENABLE_INDELS, "true", + PileupDetectionArgumentCollection.PILEUP_DETECTION_ACTIVE_REGION_PHRED_THRESHOLD_LONG_NAME, "3.0", + PileupDetectionArgumentCollection.GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME, "true", + PileupDetectionArgumentCollection.PILEUP_DETECTION_FILTER_ASSEMBLY_HAPS_THRESHOLD, "0.4" + }; + } + + @Advanced @Hidden @Argument(fullName = STEPWISE_FITLERING_ARGUMENT, doc = "If enabled, this will create a FlowBasedAligner to use for filtering haplotypes before using another likelihoods engine for scoring.") public boolean stepwiseFiltering = false; + // Should we make any alterations to the pipeline for DRAGEN-GATK + boolean isDragenGATKMode() { + return dragen3412mode || dragen378Mode; + } + + // Should we make any alterations to the pipeline for FlowBasedCalling + boolean isFlowBasedCallingMode() { + return flowMode != FlowMode.NONE; + } + + /** * the different flow modes, in terms of their parameters and their values * diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerEngine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerEngine.java index a7d8e2e33c2..df55b7b1477 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerEngine.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerEngine.java @@ -4,6 +4,7 @@ import htsjdk.samtools.SAMSequenceDictionary; import htsjdk.samtools.reference.ReferenceSequenceFile; import htsjdk.samtools.util.RuntimeIOException; +import htsjdk.samtools.util.Tuple; import htsjdk.variant.variantcontext.*; import htsjdk.variant.variantcontext.writer.Options; import htsjdk.variant.variantcontext.writer.VariantContextWriter; @@ -89,6 +90,8 @@ public class HaplotypeCallerEngine implements AssemblyRegionEvaluator { protected ReadLikelihoodCalculationEngine likelihoodCalculationEngine = null; private ReadLikelihoodCalculationEngine filterStepLikelihoodCalculationEngine = null; + // If we are in PDHMM mode we need to hold onto two likelihoods engines for the fallback + private ReadLikelihoodCalculationEngine pdhmmLikelihoodCalculationEngine = null; protected HaplotypeCallerGenotypingEngine genotypingEngine = null; @@ -285,6 +288,13 @@ private void initialize(boolean createBamOutIndex, final boolean createBamOutMD5 filterStepLikelihoodCalculationEngine = (hcArgs.stepwiseFiltering? AssemblyBasedCallerUtils.createLikelihoodCalculationEngine(hcArgs.likelihoodArgs, hcArgs.fbargs, !hcArgs.softClipLowQualityEnds, ReadLikelihoodCalculationEngine.Implementation.FlowBased) : null); + pdhmmLikelihoodCalculationEngine = (hcArgs.pileupDetectionArgs.generatePDHaplotypes? + new PDPairHMMLikelihoodCalculationEngine((byte) hcArgs.likelihoodArgs.gcpHMM, hcArgs.likelihoodArgs.dontUseDragstrPairHMMScores ? null : DragstrParamUtils.parse(hcArgs.likelihoodArgs.dragstrParams), + hcArgs.likelihoodArgs.pairHMMNativeArgs.getPairHMMArgs(), hcArgs.likelihoodArgs.pairHMM, hcArgs.pileupDetectionArgs.pdhmmDebugOutputResults, AssemblyBasedCallerUtils.getGlobalMismatchingRateFromArgs(hcArgs.likelihoodArgs), hcArgs.likelihoodArgs.pcrErrorModel, + hcArgs.likelihoodArgs.BASE_QUALITY_SCORE_THRESHOLD, hcArgs.likelihoodArgs.enableDynamicReadDisqualification, hcArgs.likelihoodArgs.readDisqualificationThresholdConstant, + hcArgs.likelihoodArgs.expectedErrorRatePerBase, !hcArgs.likelihoodArgs.disableSymmetricallyNormalizeAllelesToReference, hcArgs.likelihoodArgs.disableCapReadQualitiesToMapQ, !hcArgs.softClipLowQualityEnds, + hcArgs.pileupDetectionArgs.pdhmmOptimization? hcArgs.informativeReadOverlapMargin : -1) //Logic to control whether we apply the pdhmm optimization + : null); } private boolean isVCFMode() { @@ -550,6 +560,10 @@ public ActivityProfileState isActive(final AlignmentContext context, final Refer final GenotypesContext genotypes = GenotypesContext.create(splitContexts.keySet().size()); final MathUtils.RunningAverage averageHQSoftClips = new MathUtils.RunningAverage(); for (final Map.Entry sample : splitContexts.entrySet()) { + // We summarize the reads mismatches vs the ref at this stage to avoid issues due to reads being hardclipped down the road. + if (hcArgs.pileupDetectionArgs.usePileupDetection) { + sample.getValue().getBasePileup().forEach(p -> PileupBasedAlleles.addMismatchPercentageToRead(p.getRead(), readsHeader, ref)); + } // The ploidy here is not dictated by the sample but by the simple genotyping-engine used to determine whether regions are active or not. final int activeRegionDetectionHackishSamplePloidy = activeRegionEvaluationGenotyperEngine.getConfiguration().genotypeArgs.samplePloidy; final double[] genotypeLikelihoods = ((RefVsAnyResult) referenceConfidenceModel.calcGenotypeLikelihoodsOfRefVsAny( @@ -571,7 +585,17 @@ public ActivityProfileState isActive(final AlignmentContext context, final Refer isActiveProb = vcOut == null ? 0.0 : QualityUtils.qualToProb(vcOut.getPhredScaledQual()); } - return new ActivityProfileState(ref.getInterval(), isActiveProb, averageHQSoftClips.mean() > AVERAGE_HQ_SOFTCLIPS_HQ_BASES_THRESHOLD ? ActivityProfileState.Type.HIGH_QUALITY_SOFT_CLIPS : ActivityProfileState.Type.NONE, averageHQSoftClips.mean() ); + // Here we store the crude fast-likelihood score used to determine positional activity for the ActivityProfileState. + // We need to use this score later for DRAGEN-GATK, as one of the Heuristics applied by the new Pileup-Caller is that + // now we optionally will ignore pileup events from positions on the genome that did not ping as being "active," thus + // we must take care to preserve this information for later. + //TODO If you dare, the entire ##PileupBasedAlleles.getPileupVariantContexts() step could be moved here to cut down on storing these intermediate scores for later + //TODO This equivalent operation does not currently exist in the #Mutect2.isActive() method + ActivityProfileState output = new ActivityProfileState(ref.getInterval(), isActiveProb, averageHQSoftClips.mean() > AVERAGE_HQ_SOFTCLIPS_HQ_BASES_THRESHOLD ? ActivityProfileState.Type.HIGH_QUALITY_SOFT_CLIPS : ActivityProfileState.Type.NONE, averageHQSoftClips.mean()); + double[] gts = genotypes.get(0).getLikelihoods().getAsVector(); + int maxElementIndex = MathUtils.maxElementIndex(gts); + output.setOriginalActiveProb(gts[maxElementIndex] - gts[0]); + return output; } @@ -626,11 +650,11 @@ public List callRegion(final AssemblyRegion region, final Featur List forcedPileupAlleles = Collections.emptyList(); if(hcArgs.pileupDetectionArgs.usePileupDetection){ - forcedPileupAlleles = PileupBasedAlleles.getPileupVariantContexts(region.getAlignmentData(), hcArgs.pileupDetectionArgs, readsHeader); + forcedPileupAlleles = PileupBasedAlleles.getPileupVariantContexts(region.getAlignmentData(), hcArgs.pileupDetectionArgs, readsHeader, hcArgs.minBaseQualityScore); } // run the local assembler, getting back a collection of information on how we should proceed - final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(region, forcedPileupAlleles, hcArgs, readsHeader, samplesList, logger, referenceReader, assemblyEngine, aligner, !hcArgs.doNotCorrectOverlappingBaseQualities, hcArgs.fbargs, false); + final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(region, hcArgs, readsHeader, samplesList, logger, referenceReader, assemblyEngine, aligner, !hcArgs.doNotCorrectOverlappingBaseQualities, hcArgs.fbargs, false); ReadThreadingAssembler.addAssembledVariantsToEventMapOutput(untrimmedAssemblyResult, assembledEventMapVariants, hcArgs.maxMnpDistance, assembledEventMapVcfOutputWriter); if (assemblyDebugOutStream != null) { @@ -645,10 +669,35 @@ public List callRegion(final AssemblyRegion region, final Featur } } - final SortedSet allVariationEvents = untrimmedAssemblyResult.getVariationEvents(hcArgs.maxMnpDistance); + // PileupCaller events if we need them + List pileupAllelesFoundShouldFilter = forcedPileupAlleles.stream() + .filter(v -> PileupBasedAlleles.shouldFilterAssemblyVariant(hcArgs.pileupDetectionArgs, v)) + .collect(Collectors.toList()); + List pileupAllelesPassingFilters = forcedPileupAlleles.stream() + .filter(v -> PileupBasedAlleles.passesFilters(hcArgs.pileupDetectionArgs, v)) + .collect(Collectors.toList()); + + // Regenerate the list of AllVariationEvents, filtering out assembled variants that must be filtered according to the pileupcaller code. + final SortedSet allVariationEvents = new TreeSet<>( + AssemblyResultSet.HAPLOTYPE_VARIANT_CONTEXT_COMPARATOR); + allVariationEvents.addAll(untrimmedAssemblyResult.getVariationEvents(hcArgs.maxMnpDistance).stream() + .filter(outerVC -> { return pileupAllelesFoundShouldFilter.stream() // Stream over the PileupAllelesThatMustBeFiltered + // Does the variant match? + .noneMatch(filterAllle -> filterAllle.getStart() == outerVC.getStart() + && filterAllle.getReference().equals(outerVC.getReference()) + && filterAllle.getAlternateAllele(0).equals(outerVC.getAlternateAllele(0))); + }).collect(Collectors.toList())); + // Add any new pileupcaller alleles to the variation events + for (final VariantContext pileupAllele : pileupAllelesPassingFilters) { + //these are events from single haplotypes, so we can do a simple comparison without trimming + if (allVariationEvents.stream().noneMatch(vc -> vc.getStart() == pileupAllele.getStart() && vc.getReference().basesMatch(pileupAllele.getReference()) && vc.getAlternateAllele(0).basesMatch(pileupAllele.getAlternateAllele(0)))) { + allVariationEvents.add(pileupAllele); + } + } + // Add given alleles to the variation events for (final VariantContext given : givenAlleles) { //these are events from single haplotypes, so we can do a simple comparison without trimming - if (allVariationEvents.stream().noneMatch(vc -> vc.getStart() == given.getStart() && vc.getAlternateAllele(0).basesMatch(given.getAlternateAllele(0)))) { + if (allVariationEvents.stream().noneMatch(vc -> vc.getStart() == given.getStart() && vc.getReference().basesMatch(given.getReference()) && vc.getAlternateAllele(0).basesMatch(given.getAlternateAllele(0)))) { allVariationEvents.add(given); } } @@ -659,9 +708,48 @@ public List callRegion(final AssemblyRegion region, final Featur return referenceModelForNoVariation(region, false, VCpriors); } - final AssemblyResultSet assemblyResult = untrimmedAssemblyResult.trimTo(trimmingResult.getVariantRegion()); + AssemblyResultSet assemblyResult = untrimmedAssemblyResult.trimTo(trimmingResult.getVariantRegion()); AssemblyBasedCallerUtils.addGivenAlleles(givenAlleles, hcArgs.maxMnpDistance, aligner, hcArgs.getHaplotypeToReferenceSWParameters(), assemblyResult); + // Pre-work for the PDHMM, if we are in PDHMM mode then here is where we re-compute the haplotypes as PD haplotypes. + if (hcArgs.pileupDetectionArgs.generatePDHaplotypes) { + // Note: we ignore maxMNPDistance here because the PartiallyDeterminedHaplotypeComputationEngine does not currently handle MNPs + SortedSet assemblyVariants = assemblyResult.getVariationEvents(0); + if (hcArgs.pileupDetectionArgs.debugPileupStdout) { + System.out.println("Generating PDHaplotypes for PDHMM"); + System.out.println("Assembled Variants to use:"); + assemblyVariants.forEach(System.out::println); + System.out.println("Pileup Variants to use:"); + forcedPileupAlleles.forEach(System.out::println); + System.out.println("Adding Variants To Reference Haplotype:"); + System.out.println(assemblyResult.getReferenceHaplotype()); + System.out.println("FinalSpan: " + assemblyResult.getReferenceHaplotype().getGenomeLocation()); + System.out.println("CallingSpan: " + region.getSpan()); + } + assemblyResult = PartiallyDeterminedHaplotypeComputationEngine.generatePDHaplotypes(assemblyResult, + region.getSpan(), + assemblyResult.getReferenceHaplotype(), + assemblyVariants, + pileupAllelesFoundShouldFilter, + pileupAllelesPassingFilters, + hcArgs.pileupDetectionArgs.snpAdajacentToAssemblyIndel, + aligner, + hcArgs.getHaplotypeToReferenceSWParameters(), + hcArgs.pileupDetectionArgs.determinePDHaps, + hcArgs.pileupDetectionArgs.debugPileupStdout); + } + + // Legacy Pileupcaller code. Supplement the assembly haps with artifical haps constructed from the discovered pileupcaller + // alleles based off of the GenotypeGivenAlleles code approach. + // NOTE: We might also call this if hcArgs.pileupDetectionArgs.useGGAFallback is set and we are making PD haplotypes. This + // fallback handles edge cases where the PartiallyDeterminedHaplotypeComputationEngine generates too-many haplotypes + // from a very complex assebmly region and we want to fall back to assembly. + if ((!pileupAllelesFoundShouldFilter.isEmpty() || !pileupAllelesPassingFilters.isEmpty()) && // Assert that we did find pileup events to process before calling this code + (!hcArgs.pileupDetectionArgs.generatePDHaplotypes || + (hcArgs.pileupDetectionArgs.useGGAFallback && !assemblyResult.hasOverwrittenHaps()))) { // If we are generating PDHaps assert that it failed before calling this + if (hcArgs.pileupDetectionArgs.debugPileupStdout) { System.out.println("Falling back to GGA based Pileup Allele mode!"); } + assemblyResult = AssemblyBasedCallerUtils.applyPileupEventsAsForcedAlleles(region, hcArgs, aligner, assemblyResult.getReferenceHaplotype(), assemblyResult, pileupAllelesFoundShouldFilter, pileupAllelesPassingFilters, hcArgs.pileupDetectionArgs.debugPileupStdout); + } final AssemblyRegion regionForGenotyping = assemblyResult.getRegionForGenotyping(); final List readStubs = regionForGenotyping.getReads().stream() .filter(r -> AlignmentUtils.unclippedReadLength(r) < AssemblyBasedCallerUtils.MINIMUM_READ_LENGTH_AFTER_TRIMMING).collect(Collectors.toList()); @@ -725,7 +813,9 @@ public List callRegion(final AssemblyRegion region, final Featur readLikelihoods = possiblyUncollapseHaplotypesInReadLikelihoods(untrimmedAssemblyResult, hcArgs.stepwiseFiltering ? filterStepLikelihoodCalculationEngine.computeReadLikelihoods(assemblyResult, samplesList, reads, true) - : likelihoodCalculationEngine.computeReadLikelihoods(assemblyResult, samplesList, reads, true)); + : ( assemblyResult.isPartiallyDeterminedList() ? + pdhmmLikelihoodCalculationEngine.computeReadLikelihoods(assemblyResult, samplesList, reads, true) : + likelihoodCalculationEngine.computeReadLikelihoods(assemblyResult, samplesList, reads, true))); alleleLikelihoodWriter.ifPresent( writer -> writer.writeAlleleLikelihoods(readLikelihoods)); @@ -768,8 +858,12 @@ public List callRegion(final AssemblyRegion region, final Featur //Realign reads to their best haplotype. final SWParameters readToHaplotypeSWParameters = hcArgs.getReadToHaplotypeSWParameters(); - final Map readRealignments = AssemblyBasedCallerUtils.realignReadsToTheirBestHaplotype(subsettedReadLikelihoodsFinal, assemblyResult.getReferenceHaplotype(), assemblyResult.getPaddedReferenceLoc(), aligner, readToHaplotypeSWParameters); - subsettedReadLikelihoodsFinal.changeEvidence(readRealignments); + // TODO Yes we skip realignment entirely when we are in DRAGEN-GATK PDHMM mode. Realignment of the reads makes no sense when + // TODO the bases of the haplotypes used for calling no longer reflect specified variants present. + if (!(hcArgs.pileupDetectionArgs.generatePDHaplotypes && !hcArgs.pileupDetectionArgs.determinePDHaps)) { + final Map readRealignments = AssemblyBasedCallerUtils.realignReadsToTheirBestHaplotype(subsettedReadLikelihoodsFinal, assemblyResult.getReferenceHaplotype(), assemblyResult.getPaddedReferenceLoc(), aligner, readToHaplotypeSWParameters); + subsettedReadLikelihoodsFinal.changeEvidence(readRealignments); + } if (HaplotypeCallerGenotypingDebugger.isEnabled()) { for (int counter = 0; counter < readLikelihoods.sampleEvidence(0).size(); counter++) { @@ -914,6 +1008,7 @@ protected List referenceModelForNoVariation(final AssemblyRegion */ public void shutdown() { likelihoodCalculationEngine.close(); + if (pdhmmLikelihoodCalculationEngine != null) pdhmmLikelihoodCalculationEngine.close(); aligner.close(); haplotypeBAMWriter.ifPresent(HaplotypeBAMWriter::close); assembledEventMapVcfOutputWriter.ifPresent(writer -> {assembledEventMapVariants.get().forEach(writer::add); writer.close();}); diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerGenotypingEngine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerGenotypingEngine.java index d02c11d5a1f..15dbcf86c19 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerGenotypingEngine.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerGenotypingEngine.java @@ -181,7 +181,6 @@ public CalledHaplotypes assignGenotypeLikelihoods(final List haplotyp int mergedAllelesListSizeBeforePossibleTrimming = mergedVC.getAlleles().size(); final Map> alleleMapper = AssemblyBasedCallerUtils.createAlleleMapper(mergedVC, loc, haplotypes, !hcArgs.disableSpanningEventGenotyping); - if( hcArgs.assemblerArgs.debugAssembly && logger != null ) { logger.info("Genotyping event at " + loc + " with alleles = " + mergedVC.getAlleles()); } @@ -221,7 +220,7 @@ public CalledHaplotypes assignGenotypeLikelihoods(final List haplotyp HaplotypeCallerGenotypingDebugger.println(allele_string); for (int sn = 0 ; sn < readAlleleLikelihoods.numberOfSamples(); sn++){ for (int evn = 0 ; evn < readAlleleLikelihoods.sampleEvidence(sn).size(); evn++) { - String outputStr = readAlleleLikelihoods.sampleEvidence(sn).get(evn).getName(); + String outputStr = "read: " + readLikelihoods.sampleEvidence(sn).indexOf(readAlleleLikelihoods.sampleEvidence(sn).get(evn)) + " " + readAlleleLikelihoods.sampleEvidence(sn).get(evn).getName(); for (Allele curAllele : readAlleleLikelihoods.alleles()) { int idx = readAlleleLikelihoods.indexOfAllele(curAllele); @@ -230,6 +229,25 @@ public CalledHaplotypes assignGenotypeLikelihoods(final List haplotyp HaplotypeCallerGenotypingDebugger.println(outputStr); } } + + HaplotypeCallerGenotypingDebugger.println("Normalized Read-Allele matrix:"); + for (int sn = 0 ; sn < readAlleleLikelihoods.numberOfSamples(); sn++){ + for (int evn = 0 ; evn < readAlleleLikelihoods.sampleEvidence(sn).size(); evn++) { + String outputStr = "read: " + readLikelihoods.sampleEvidence(sn).indexOf(readAlleleLikelihoods.sampleEvidence(sn).get(evn)) + " " + readAlleleLikelihoods.sampleEvidence(sn).get(evn).getName(); + + double max = Double.NEGATIVE_INFINITY; + for (Allele curAllele : readAlleleLikelihoods.alleles()) { + int idx = readAlleleLikelihoods.indexOfAllele(curAllele); + max = Math.max(readAlleleLikelihoods.sampleMatrix(sn).get(idx, evn), max); + } + + for (Allele curAllele : readAlleleLikelihoods.alleles()) { + int idx = readAlleleLikelihoods.indexOfAllele(curAllele); + outputStr = outputStr + " " + (readAlleleLikelihoods.sampleMatrix(sn).get(idx, evn) - max); + } + HaplotypeCallerGenotypingDebugger.println(outputStr); + } + } } if (emitReferenceConfidence) { diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PDPairHMMLikelihoodCalculationEngine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PDPairHMMLikelihoodCalculationEngine.java new file mode 100644 index 00000000000..93b586c40ae --- /dev/null +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PDPairHMMLikelihoodCalculationEngine.java @@ -0,0 +1,372 @@ +package org.broadinstitute.hellbender.tools.walkers.haplotypecaller; + +import com.google.common.annotations.VisibleForTesting; +import htsjdk.samtools.SAMFileHeader; +import org.broadinstitute.gatk.nativebindings.pairhmm.PairHMMNativeArguments; +import org.broadinstitute.hellbender.engine.GATKPath; +import org.broadinstitute.hellbender.exceptions.GATKException; +import org.broadinstitute.hellbender.utils.SimpleInterval; +import org.broadinstitute.hellbender.utils.dragstr.DragstrParams; +import org.broadinstitute.hellbender.utils.MathUtils; +import org.broadinstitute.hellbender.utils.QualityUtils; +import org.broadinstitute.hellbender.utils.Utils; +import org.broadinstitute.hellbender.utils.clipping.ReadClipper; +import org.broadinstitute.hellbender.utils.genotyper.*; +import org.broadinstitute.hellbender.utils.haplotype.Haplotype; +import org.broadinstitute.hellbender.utils.haplotype.PartiallyDeterminedHaplotype; +import org.broadinstitute.hellbender.utils.pairhmm.LoglessPDPairHMM; +import org.broadinstitute.hellbender.utils.pairhmm.PDPairHMM; +import org.broadinstitute.hellbender.utils.pairhmm.PairHMM; +import org.broadinstitute.hellbender.utils.pairhmm.PairHMMInputScoreImputator; +import org.broadinstitute.hellbender.utils.read.GATKRead; +import org.broadinstitute.hellbender.utils.read.ReadUtils; + +import java.io.OutputStreamWriter; +import java.util.*; +import java.util.function.ToDoubleFunction; +import java.util.stream.Collectors; + +/** + * Classic likelihood computation: full pair-hmm all haplotypes vs all reads. + * + * Note this is the "Partially Determined" Pair hmm engine, which means the haplotypes it sees are expected to be + * PartiallyDeterminedHaplotype objects. These are special in that they all have a subset of "determined" or present + * bases corresponding to variants and everything else is "undetermined." The likelihood scores are computed by taking + * the maximum possible score for the read vs the un-determined bases and behaving normally over the determined ones + * that have a real subset of alleles from the assembly region. + * + * Since the operations and methods differ from the normal PairHMM significantly we have opted to create an entirely seperate + * codepath of PD___HMM classes to handle the differences. + */ +public final class PDPairHMMLikelihoodCalculationEngine implements ReadLikelihoodCalculationEngine { + + + private static final int MIN_ADJUSTED_QSCORE = 10; + + @VisibleForTesting + static final double INITIAL_QSCORE = 40.0; + public static final String HMM_BASE_QUALITIES_TAG = "HMMQuals"; + + private final byte constantGCP; + + private final double log10globalReadMismappingRate; + + private final PDPairHMM pdPairHMM; + public static final String UNCLIPPED_ORIGINAL_SPAN_ATTR = "originalAlignment"; + + // DRAGEN-GATK related parameters + private final DragstrParams dragstrParams; + private final boolean dynamicDisqualification; + private final double readDisqualificationScale; + private final double expectedErrorRatePerBase; + private final boolean disableCapReadQualitiesToMapQ; + private final boolean symmetricallyNormalizeAllelesToReference; + private final boolean modifySoftclippedBases; + private final int rangeForReadOverlapToDeterminedBases; + + private final PairHMMLikelihoodCalculationEngine.PCRErrorModel pcrErrorModel; + + private final byte baseQualityScoreThreshold; + + /** + * Create a new PairHMMLikelihoodCalculationEngine using provided parameters and hmm to do its calculations + * + * @param constantGCP the gap continuation penalty to use with the PairHMM + * @param hmmType the type of the HMM to use + * @param resultsFile output file to dump per-read, per-haplotype inputs and outputs for debugging purposes (null if not enabled). + * @param log10globalReadMismappingRate the global mismapping probability, in log10(prob) units. A value of + * -3 means that the chance that a read doesn't actually belong at this + * location in the genome is 1 in 1000. The effect of this parameter is + * to cap the maximum likelihood difference between the reference haplotype + * and the best alternative haplotype by -3 log units. So if the best + * haplotype is at -10 and this parameter has a value of -3 then even if the + * reference haplotype gets a score of -100 from the pairhmm it will be + * assigned a likelihood of -13. + * @param pcrErrorModel model to correct for PCR indel artifacts + * @param baseQualityScoreThreshold Base qualities below this threshold will be reduced to the minimum usable base + * quality. + */ + public PDPairHMMLikelihoodCalculationEngine(final byte constantGCP, + final DragstrParams dragstrParams, + final PairHMMNativeArguments arguments, + final PairHMM.Implementation hmmType, + final GATKPath resultsFile, + final double log10globalReadMismappingRate, + final PairHMMLikelihoodCalculationEngine.PCRErrorModel pcrErrorModel, + final byte baseQualityScoreThreshold, + final boolean dynamicReadDisqualificaiton, + final double readDisqualificationScale, + final double expectedErrorRatePerBase, + final boolean symmetricallyNormalizeAllelesToReference, + final boolean disableCapReadQualitiesToMapQ, + final boolean modifySoftclippedBases, + final int rangeForReadOverlapToDeterminedBases) { + Utils.nonNull(hmmType, "hmmType is null"); + Utils.nonNull(pcrErrorModel, "pcrErrorModel is null"); + if (constantGCP < 0){ + throw new IllegalArgumentException("gap continuation penalty must be non-negative"); + } + if (log10globalReadMismappingRate > 0){ + throw new IllegalArgumentException("log10globalReadMismappingRate must be negative"); + } + this.dragstrParams = dragstrParams; + this.constantGCP = constantGCP; + this.log10globalReadMismappingRate = log10globalReadMismappingRate; + this.pcrErrorModel = this.dragstrParams == null ? pcrErrorModel : PairHMMLikelihoodCalculationEngine.PCRErrorModel.NONE; + // TODO later we probably need a LOG and LOGLESS version for parsimony with DRAGEN + this.pdPairHMM = new LoglessPDPairHMM(); + if (resultsFile != null) { + pdPairHMM.setAndInitializeDebugOutputStream(new OutputStreamWriter(resultsFile.getOutputStream())); + } + this.dynamicDisqualification = dynamicReadDisqualificaiton; + this.readDisqualificationScale = readDisqualificationScale; + this.symmetricallyNormalizeAllelesToReference = symmetricallyNormalizeAllelesToReference; + this.expectedErrorRatePerBase = expectedErrorRatePerBase; + this.disableCapReadQualitiesToMapQ = disableCapReadQualitiesToMapQ; + this.modifySoftclippedBases = modifySoftclippedBases; + this.rangeForReadOverlapToDeterminedBases = rangeForReadOverlapToDeterminedBases; + + initializePCRErrorModel(); + + if (baseQualityScoreThreshold < QualityUtils.MIN_USABLE_Q_SCORE) { + throw new IllegalArgumentException("baseQualityScoreThreshold must be greater than or equal to " + QualityUtils.MIN_USABLE_Q_SCORE + " (QualityUtils.MIN_USABLE_Q_SCORE)"); + } + this.baseQualityScoreThreshold = baseQualityScoreThreshold; + } + + + @Override + public void close() { + pdPairHMM.close(); + } + + @Override + public void filterPoorlyModeledEvidence(AlleleLikelihoods result, boolean dynamicDisqualification, double expectedErrorRatePerBase, double readDisqualificationScale) { + ReadLikelihoodCalculationEngine.super.filterPoorlyModeledEvidence(result, dynamicDisqualification, expectedErrorRatePerBase, readDisqualificationScale); + } + + @Override + public ToDoubleFunction log10MinTrueLikelihood(double maximumErrorPerBase, boolean capLikelihoods) { + return ReadLikelihoodCalculationEngine.super.log10MinTrueLikelihood(maximumErrorPerBase, capLikelihoods); + } + + @Override + public AlleleLikelihoods computeReadLikelihoods(List haplotypeList, SAMFileHeader hdr, SampleList samples, Map> perSampleReadList, boolean filterPoorly) { + throw new GATKException.ShouldNeverReachHereException("We should never get here, this HMM engine exists only for PD haplotype computation"); + } + + + @Override + @SuppressWarnings("unchecked") + // NOTE that the PairHMM doesn't need to interrogate the header so we skip checking it for this version + public AlleleLikelihoods computeReadLikelihoods(AssemblyResultSet assemblyResultSet, SampleList samples, + Map> perSampleReadList, + boolean filterPoorly) { + Utils.nonNull(assemblyResultSet, "assemblyResultSet is null"); + if (assemblyResultSet.getHaplotypeList().stream().anyMatch(haplotype -> !haplotype.isPartiallyDetermined())) { + throw new GATKException("PDHMM engine requires PartiallyDeterminedHaplotype objects as input"); + } + final List haplotypeList = assemblyResultSet.getHaplotypeList().stream().map(h -> (PartiallyDeterminedHaplotype)h).collect(Collectors.toList()); + + AlleleLikelihoods resut = (AlleleLikelihoods) computeReadLikelihoodsPartiallyDetermined(haplotypeList, null, samples, perSampleReadList, filterPoorly); + return resut; + } + + public AlleleLikelihoods computeReadLikelihoodsPartiallyDetermined(final List haplotypeList, + final SAMFileHeader hdr, + final SampleList samples, + final Map> perSampleReadList, final boolean filterPoorly) { + Utils.nonNull(samples, "samples is null"); + Utils.nonNull(perSampleReadList, "perSampleReadList is null"); + Utils.nonNull(haplotypeList, "haplotypeList is null"); + + final AlleleList haplotypes = new IndexedAlleleList<>(haplotypeList); + + initializePairHMM(haplotypeList, perSampleReadList); + + // Add likelihoods for each sample's reads to our result + final AlleleLikelihoods result = new AlleleLikelihoods<>(samples, haplotypes, perSampleReadList); + final int sampleCount = result.numberOfSamples(); + for (int i = 0; i < sampleCount; i++) { + computeReadLikelihoods(result.sampleMatrix(i)); + } + + result.normalizeLikelihoods(log10globalReadMismappingRate, symmetricallyNormalizeAllelesToReference); + filterPoorlyModeledEvidence(result, dynamicDisqualification, expectedErrorRatePerBase, readDisqualificationScale); + return result; + } + + + /** + * Creates a new GATKRead with the source read's header, read group and mate + * information, but with the following fields set to user-supplied values: + * - Read Bases + * - Base Qualities + * - Base Insertion Qualities + * - Base Deletion Qualities + * + * Cigar string is empty (not-null) + * + * Use this method if you want to create a new GATKRead based on + * another GATKRead, but with modified bases and qualities + * + * @param read a read to copy the header from + * @param readBases an array containing the new bases you wish use in place of the originals + * @param baseQualities an array containing the new base qualities you wish use in place of the originals + * @param baseInsertionQualities an array containing the new base insertion qaulities + * @param baseDeletionQualities an array containing the new base deletion qualities + * @return a read with modified bases and qualities, safe for the GATK + */ + private static GATKRead createQualityModifiedRead(final GATKRead read, + final byte[] readBases, + final byte[] baseQualities, + final byte[] baseInsertionQualities, + final byte[] baseDeletionQualities) { + Utils.validateArg( baseQualities.length == readBases.length && baseInsertionQualities.length == readBases.length && baseDeletionQualities.length == readBases.length, + () -> String.format("Read bases and read quality arrays aren't the same size: Bases: %d vs Base Q's: %d vs Insert Q's: %d vs Delete Q's: %d.", + readBases.length, baseQualities.length, baseInsertionQualities.length, baseDeletionQualities.length)); + + final GATKRead processedRead = ReadUtils.emptyRead(read); + processedRead.setBases(readBases); + processedRead.setBaseQualities(baseQualities); + ReadUtils.setInsertionBaseQualities(processedRead, baseInsertionQualities); + ReadUtils.setDeletionBaseQualities(processedRead, baseDeletionQualities); + return processedRead; + } + + /** + * Initialize our pairHMM with parameters appropriate to the haplotypes and reads we're going to evaluate + * + * After calling this routine the PairHMM will be configured to best evaluate all reads in the samples + * against the set of haplotypes + * + * @param haplotypes a non-null list of haplotypes + * @param perSampleReadList a mapping from sample -> reads + */ + private void initializePairHMM(final List haplotypes, final Map> perSampleReadList) { + final int readMaxLength = perSampleReadList.entrySet().stream().flatMap(e -> e.getValue().stream()).mapToInt(GATKRead::getLength).max().orElse(0); + final int haplotypeMaxLength = haplotypes.stream().mapToInt(h -> h.getBases().length).max().orElse(0); + + // initialize arrays to hold the probabilities of being in the match, insertion and deletion cases + pdPairHMM.initialize(haplotypes, perSampleReadList, readMaxLength, haplotypeMaxLength); + } + + private void computeReadLikelihoods(final LikelihoodMatrix likelihoods) { + // Modify the read qualities by applying the PCR error model and capping the minimum base,insertion,deletion qualities + final List processedReads = modifyReadQualities(likelihoods.evidence()); + + if (HaplotypeCallerGenotypingDebugger.isEnabled()) { + for(int counter = 0; counter < processedReads.size(); counter++) { + GATKRead read = processedReads.get(counter); + HaplotypeCallerGenotypingDebugger.println("Range for Overlaps to Variants for consideration: "+rangeForReadOverlapToDeterminedBases); + HaplotypeCallerGenotypingDebugger.println("read "+counter +": "+read.getName()+" cigar: "+read.getCigar()+" mapQ: "+read.getMappingQuality()+" loc: ["+read.getStart() +"-"+ read.getEnd()+"] unclippedloc: ["+read.getUnclippedStart()+"-"+read.getUnclippedEnd()+"]"); + HaplotypeCallerGenotypingDebugger.println(Arrays.toString(read.getBaseQualitiesNoCopy())); + } + } + // Run the PairHMM to calculate the log10 likelihood of each (processed) reads' arising from each haplotype + pdPairHMM.computeLog10Likelihoods(likelihoods, processedReads, inputScoreImputator, rangeForReadOverlapToDeterminedBases); + } + + /** + * Pre-processing of the reads to be evaluated at the current location from the current sample. + * We apply the PCR Error Model, and cap the minimum base, insertion, and deletion qualities of each read. + * Modified copies of reads are packed into a new list, while original reads are retained for downstream use + * + * @param reads The original list of unmodified reads + * @return processedReads. A new list of reads, in the same order, whose qualities have been altered by PCR error model and minimal quality thresholding + */ + private List modifyReadQualities(final List reads) { + final List result = new ArrayList<>(reads.size()); + + for (final GATKRead read : reads) { + final GATKRead maybeUnclipped = modifySoftclippedBases ? read : ReadClipper.hardClipSoftClippedBases(read); //Clip the bases here to remove hap + final byte[] readBases = maybeUnclipped.getBases(); + //For FRD we want to have scores for reads that don't overlap + final SimpleInterval readSpan = new SimpleInterval(read.getContig(), read.getUnclippedStart(), read.getUnclippedEnd()); + + // NOTE -- must clone anything that gets modified here so we don't screw up future uses of the read + //Using close here is justified - it's an array of primitives. + final byte[] readQuals = maybeUnclipped.getBaseQualities().clone(); + final byte[] readInsQuals = ReadUtils.getBaseInsertionQualities(maybeUnclipped).clone(); + final byte[] readDelQuals = ReadUtils.getBaseDeletionQualities(maybeUnclipped).clone(); + + applyPCRErrorModel(readBases, readInsQuals, readDelQuals); + capMinimumReadQualities(maybeUnclipped, readQuals, readInsQuals, readDelQuals, baseQualityScoreThreshold, disableCapReadQualitiesToMapQ); + + // Store the actual qualities + read.setTransientAttribute(HMM_BASE_QUALITIES_TAG, readQuals); + // Create a new copy of the read and sets its base qualities to the modified versions. + GATKRead qualityModifiedRead = createQualityModifiedRead(maybeUnclipped, readBases, readQuals, readInsQuals, readDelQuals); + qualityModifiedRead.setTransientAttribute(UNCLIPPED_ORIGINAL_SPAN_ATTR, readSpan); + result.add(qualityModifiedRead); + } + return result; + } + + private static void capMinimumReadQualities(final GATKRead read, final byte[] readQuals, final byte[] readInsQuals, final byte[] readDelQuals, final byte baseQualityScoreThreshold, final boolean disableCapReadQualitiesToMapQ) { + for( int i = 0; i < readQuals.length; i++ ) { + if (!disableCapReadQualitiesToMapQ) { + readQuals[i] = (byte) Math.min(0xff & readQuals[i], read.getMappingQuality()); // cap base quality by mapping quality, as in UG + } + readQuals[i] = setToFixedValueIfTooLow( readQuals[i], baseQualityScoreThreshold, QualityUtils.MIN_USABLE_Q_SCORE ); + readInsQuals[i] = setToFixedValueIfTooLow( readInsQuals[i], QualityUtils.MIN_USABLE_Q_SCORE, QualityUtils.MIN_USABLE_Q_SCORE ); + readDelQuals[i] = setToFixedValueIfTooLow( readDelQuals[i], QualityUtils.MIN_USABLE_Q_SCORE, QualityUtils.MIN_USABLE_Q_SCORE ); + } + } + + private static byte setToFixedValueIfTooLow(final byte currentVal, final byte minQual, final byte fixedQual){ + return currentVal < minQual ? fixedQual : currentVal; + } + + private static Map buildGapContinuationPenalties(final List reads, final byte gapPenalty) { + final Map result = new HashMap<>(reads.size()); + reads.stream().forEach(read -> result.put(read, Utils.dupBytes(gapPenalty, read.getLength()))); + return result; + } + + /* -------------------------------------------------------------------------------- + * + * Experimental attempts at PCR error rate modeling + * + -------------------------------------------------------------------------------- */ + + private byte[] pcrIndelErrorModelCache; + private PairHMMInputScoreImputator inputScoreImputator; + + private void initializePCRErrorModel() { + + inputScoreImputator = dragstrParams == null + ? StandardPairHMMInputScoreImputator.newInstance(constantGCP) + : DragstrPairHMMInputScoreImputator.of(dragstrParams) ; + + if ( !pcrErrorModel.hasRateFactor() ) { + return; + } + + pcrIndelErrorModelCache = new byte[ReadLikelihoodCalculationEngine.MAX_REPEAT_LENGTH + 1]; + + final double rateFactor = pcrErrorModel.getRateFactor(); + + for(int i = 0; i <= ReadLikelihoodCalculationEngine.MAX_REPEAT_LENGTH; i++ ) { + pcrIndelErrorModelCache[i] = getErrorModelAdjustedQual(i, rateFactor); + } + } + + static byte getErrorModelAdjustedQual(final int repeatLength, final double rateFactor) { + return (byte) Math.max(MIN_ADJUSTED_QSCORE, MathUtils.fastRound(INITIAL_QSCORE - Math.exp(repeatLength / (rateFactor * Math.PI)) + 1.0)); + } + + @VisibleForTesting + void applyPCRErrorModel( final byte[] readBases, final byte[] readInsQuals, final byte[] readDelQuals ) { + if ( pcrErrorModel == PairHMMLikelihoodCalculationEngine.PCRErrorModel.NONE ) { + return; + } + + for ( int i = 1; i < readBases.length; i++ ) { + final int repeatLength = ReadLikelihoodCalculationEngine.findTandemRepeatUnits(readBases, i-1).getRight(); + readInsQuals[i-1] = (byte) Math.min(0xff & readInsQuals[i - 1], 0xff & pcrIndelErrorModelCache[repeatLength]); + readDelQuals[i-1] = (byte) Math.min(0xff & readDelQuals[i - 1], 0xff & pcrIndelErrorModelCache[repeatLength]); + } + } + +} diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngine.java new file mode 100644 index 00000000000..621b4ad6404 --- /dev/null +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngine.java @@ -0,0 +1,987 @@ +package org.broadinstitute.hellbender.tools.walkers.haplotypecaller; + +import com.google.common.annotations.VisibleForTesting; +import htsjdk.samtools.CigarElement; +import htsjdk.samtools.CigarOperator; +import htsjdk.samtools.util.Locatable; +import htsjdk.samtools.util.Tuple; +import htsjdk.variant.variantcontext.Allele; +import htsjdk.variant.variantcontext.VariantContext; +import org.apache.commons.lang3.ArrayUtils; +import org.broadinstitute.gatk.nativebindings.smithwaterman.SWOverhangStrategy; +import org.broadinstitute.gatk.nativebindings.smithwaterman.SWParameters; +import org.broadinstitute.hellbender.exceptions.GATKException; +import org.broadinstitute.hellbender.utils.bwa.InvalidInputException; +import org.broadinstitute.hellbender.utils.haplotype.EventMap; +import org.broadinstitute.hellbender.utils.haplotype.Haplotype; +import org.broadinstitute.hellbender.utils.haplotype.PartiallyDeterminedHaplotype; +import org.broadinstitute.hellbender.utils.read.CigarBuilder; +import org.broadinstitute.hellbender.utils.read.CigarUtils; +import org.broadinstitute.hellbender.utils.smithwaterman.SmithWatermanAligner; + +import java.util.*; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Class that manages the complicated steps involved in generating artifical haplotypes for the PDHMM: + * + * The primary method to this class is {@link #generatePDHaplotypes} which will be called with an existing AssemblyResultSet object + * as well as the list of alleles that were found from the pileupcaller code. The method attempts to replace the existing haplotypes + * from the provided result set object with new haplotyeps that were artificially generated from merging the assembled alleles + * with those found by the pileup caller. Crucially, the constructed haplotypes will be PartiallyDeterminedHaplotype objects + * which have markers indicating what bases are "undetermined" and should not be penalized in the HMM when computing likelihoods + * The method might hit one of a few heuristic barriers and chose to fallback on only the assembled haplotypes if the + * processing would become too complicated. + */ +public class PartiallyDeterminedHaplotypeComputationEngine { + final static int MAX_PD_HAPS_TO_GENERATE = 256*2;; //(2048 is illuminas #) (without optimizing the hmm to some degree this is probably unattainable) + final static int MAX_BRANCH_PD_HAPS = 128; //(128 is illuminas #) + final static int MAX_VAR_IN_EVENT_GROUP = 17; // (20 is illuminas #) + + //To make this somewhat cleaner of a port from Illumina, we have two base spaces. R and U space. R space is vcf coordinate space, + //U is a 0->N (N = region size) based space where Insertions are +0.5 and deletions are + 1 from their original position + + // We use this comparator for haplotype construcion to make it slightly easier to build compound haplotypes (i.e. snp+insertion/deletion at the same anchor base) + public static final Comparator HAPLOTYPE_SNP_FIRST_COMPARATOR = Comparator.comparingInt(VariantContext::getStart) + // Decide arbitrarily so as not to accidentally throw away overlapping variants + .thenComparingInt(vc -> vc.getReference().length()) + .thenComparingInt(vc -> vc.getAlternateAllele(0).length()) + .thenComparing(vc -> vc.getAlternateAllele(0)); + + + /** + * The workhorse method for the PDHMM branching code. This method is responsible for the lionshare of the work in taking a list of + * assembly haplotypes/alleles and the alleles found in the ColumnwiseDetection code and converting them into the artificial haplotypes + * that are necessary for variant calling. This code might fail due to having too complex a site, if that happens it will return + * the input sourceSet object without anything being changed. + * + * Overall pattern is as follows: + * 1. Generate the combined list of variants from assembly and pileup-caller that pass the heuristic filers + * 2. Generate lists of variants that overlap in groups + * 3. Use SmithWaterman to realign pairs of 2/3 events that contain an indel, recording pairs that realign in a better + * set of sub-events or result in the reference. + * 4. Merge event groups that have equivalent events. + * 5. Iterate over every start position and attempt to build determined variants: + * 5a. Select an allele at a position (ref or one of the alts) + * 5b. Ask each event group for branches of mutually exclusive events (overlapping or from the equivalent event code) for the determined variants. + * 5c. Merge all event groups into distinct branches (combinatorially) + * 5d. For each branch, build a PDHaplotype with the determined allele and the allowed variants for that branch. + * + * @param sourceSet AssemblyResultSet to be modified with the new haplotypes + * @param callingSpan Calling span to subset determined events to (to handle padding) + * @param referenceHaplotype Reference haplotype against which to build artifical haps + * @param assemblyVariants Assembly variants. + * @param pileupAllelesFoundShouldFilter Pileup alleles that should be filtered if they are part of the assembly + * @param pileupAllelesPassingFilters Pileup alleles that pass the heuristics to be included in genotyping + * @param snpAdjacentToIndelLimit If pileup allele snps are too close to assembled indels we thorw them out. + * @param aligner SmithWatermanAligner to use for filtering out equivalent event sets + * @param swParameters Parameters for hap-hap comparisons + * @param makeDeterminedHapsInstead If true, generate regular haplotypes to be handed to the PairHMM (note this will result in a lot more failures due to combinitorial expansion) + * @param debugSite If true, print out all the details of how this code is functioning for debugging. + * @return unchanged assembly result set if failed, updated haplotyeps otherwise + */ + public static AssemblyResultSet generatePDHaplotypes(final AssemblyResultSet sourceSet, + final Locatable callingSpan, + final Haplotype referenceHaplotype, + final SortedSet assemblyVariants, + final List pileupAllelesFoundShouldFilter, + final List pileupAllelesPassingFilters, + final int snpAdjacentToIndelLimit, + final SmithWatermanAligner aligner, + final SWParameters swParameters, + final boolean makeDeterminedHapsInstead, + final boolean debugSite) { + + //We currently don't support MNPs in here, assert nothing coming in IS a MNP + if (assemblyVariants.stream().anyMatch(VariantContext::isMNP) || pileupAllelesPassingFilters.stream().anyMatch(VariantContext::isMNP)) { + throw new InvalidInputException("PartiallyDeterminedHaplotypeComputationEngine currently doesn't support any MNP variants"); + } + + final TreeSet variantsInOrder = new TreeSet<>( + HAPLOTYPE_SNP_FIRST_COMPARATOR); + + // First we filter the assembly variants based on badness from the graph + for (VariantContext delVariant : pileupAllelesFoundShouldFilter) { + + List variantsToRemove = assemblyVariants.stream().filter( + v -> v.getStart() == delVariant.getStart() && + delVariant.getReference().equals(v.getReference()) && + delVariant.getAlternateAllele(0).equals(v.getAlternateAllele(0))).collect(Collectors.toList()); + + if (!variantsToRemove.isEmpty()) { + if (debugSite) System.out.println("Removing assembly variants due to columnwise heuristics: " + variantsToRemove); + variantsToRemove.forEach(assemblyVariants::remove); + } + } + + // Ignore any snps from pileups that were close to indels + final List givenAllelesFiltered = pileupAllelesPassingFilters.stream() + .filter(vc -> vc.isIndel() || + assemblyVariants.stream().filter(VariantContext::isIndel).noneMatch(indel -> vc.withinDistanceOf(indel, snpAdjacentToIndelLimit))).collect(Collectors.toList()); + + // TODO make sure this TREE-SET is properly comparing the VCs + variantsInOrder.addAll(assemblyVariants); + variantsInOrder.addAll(givenAllelesFiltered); + + if (debugSite) System.out.println("Variants to PDHapDetermination:\n"+ + variantsInOrder.stream().map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())).collect(Collectors.joining("\n"))); + + // TODO this is where we filter out if indels > 32 (a heuristic known from DRAGEN that is not implemented here) + List vcsAsList = new ArrayList<>(variantsInOrder); + + // NOTE: we iterate over this several times and expect it to be sorted. + Map> eventsByDRAGENCoordinates = new LinkedHashMap<>(); + SortedMap> variantsByStartPos = new TreeMap<>(); + List eventGroups = new ArrayList<>(); + int lastEventEnd = -1; + for (VariantContext vc : variantsInOrder) { + // Break everything into independent groups (don't worry about transitivitiy right now) + Double eventKey = vc.getStart() + (vc.isSimpleInsertion()? 0.5:0) + (vc.isSimpleDeletion()? 1 : 0) - referenceHaplotype.getStartPosition(); + eventsByDRAGENCoordinates.putIfAbsent(eventKey, new ArrayList<>()); + eventsByDRAGENCoordinates.get(eventKey).add(vc); + variantsByStartPos.putIfAbsent(vc.getStart(), new ArrayList<>()); + variantsByStartPos.get(vc.getStart()).add(vc); + if (debugSite) System.out.println("testing:"+vc); + if (debugSite) System.out.println("EventKey:"+eventKey); + if (eventKey <= lastEventEnd + 0.5) { + eventGroups.get(eventGroups.size()-1).addEvent(vc); + } else { + eventGroups.add(new EventGroup(vc)); + } + int newEnd = (int) (vc.getEnd() - referenceHaplotype.getStartPosition()); + if (debugSite) System.out.println("LastEventEnd:"+lastEventEnd+" newEventEnd:"+newEnd); + lastEventEnd = Math.max(newEnd, lastEventEnd); + } + //Print the event groups + if (debugSite) eventsByDRAGENCoordinates.entrySet().stream().map(e -> { + return String.format("%.1f", e.getKey()) + " -> " + e.getValue().stream() + .map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())) + .collect(Collectors.joining(",")); + }).forEach(System.out::println); + + // Iterate over all events starting with all indels + + List> disallowedPairs = smithWatermanRealignPairsOfVariantsForEquivalentEvents(referenceHaplotype, aligner, swParameters, debugSite, variantsInOrder, vcsAsList); + if (debugSite) { + System.out.println("disallowed Variant pairs:"); + disallowedPairs.stream().map(l -> l.stream().map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())).collect(Collectors.joining("->"))).forEach(System.out::println); + } + + if (debugSite) { + System.out.println("Event groups before merging:\n"+eventGroups.stream().map(eg -> eg.toDisplayString((int)referenceHaplotype.getStartPosition())).collect(Collectors.joining("\n"))); + } + //Now that we have the disallowed groups, lets merge any of them from seperate groups: + //TODO this is not an efficient way of doing this + for (List pair : disallowedPairs) { + EventGroup eventGrpLeft = null; + for (VariantContext event : pair) { + EventGroup grpForEvent = eventGroups.stream().filter(grp -> grp.contains(event)).findFirst().get(); + // If the event isn't in the same event group as its predicessor, merge this group with that one and + if (eventGrpLeft != grpForEvent) { + if (eventGrpLeft == null) { + eventGrpLeft = grpForEvent; + } else { + eventGrpLeft.mergeEvent(grpForEvent); + eventGroups.remove(grpForEvent); + } + } + } + } + if (debugSite) { + System.out.println("Event groups after merging:\n"+eventGroups.stream().map(eg -> eg.toDisplayString((int)referenceHaplotype.getStartPosition())).collect(Collectors.joining("\n"))); + } + + //Now we have finished with the work of merging event groups transitively by position and mutually exclusiveness. Now every group should be entirely independant of one another: + if (eventGroups.stream().map(eg -> eg.populateBitset(disallowedPairs)).anyMatch(b->!b)) { + // if any of our event groups is too large, abort. + if (debugSite ) System.out.println("Found event group with too many variants! Aborting haplotype building"); + return sourceSet; + }; + + Set outputHaplotypes = new LinkedHashSet<>(); + if (makeDeterminedHapsInstead) { + // only add the reference haplotype if we are producing regular haplotype objects (not PD haplotypes for the haplotype alleles) + outputHaplotypes.add(referenceHaplotype); + } + + //Iterate over very VCF start position in R space + List>> entriesRInOrder = new ArrayList<>(variantsByStartPos.entrySet()); + /** + * Overall Loop: + * Iterate over every cluster of variants with the same start position. + */ + for (int indexOfDeterminedInR = 0; indexOfDeterminedInR < entriesRInOrder.size(); indexOfDeterminedInR++) { + Map.Entry> variantSiteGroup = entriesRInOrder.get(indexOfDeterminedInR); + if (debugSite) System.out.println("working with variants of the group: " + variantSiteGroup); + // Skip + if (entriesRInOrder.get(indexOfDeterminedInR).getKey() < callingSpan.getStart() || entriesRInOrder.get(indexOfDeterminedInR).getKey() > callingSpan.getEnd()) { + if (debugSite) System.out.println("Skipping determined hap construction! otside of span: "+callingSpan); + continue; + } + + final List determinedVariants = variantSiteGroup.getValue(); + + /** + * Determined Event Loop: + * We iterate over every ref position and select single alleles (including ref) from that reference position (in R space) to be "determined" + * + * NOTE: we skip the reference allele in the event that we are making determined haplotypes instead of undetermined haplotypes + */ + for (int IndexOfAllele = (makeDeterminedHapsInstead?0:-1); IndexOfAllele < determinedVariants.size(); IndexOfAllele++) { //note -1 for I here corresponds to the reference allele at this site + if (debugSite) System.out.println("Working with allele at site: "+(IndexOfAllele ==-1? "[ref:"+(variantSiteGroup.getKey()-referenceHaplotype.getStartPosition())+"]" : PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int)referenceHaplotype.getStartPosition()).apply(determinedVariants.get(IndexOfAllele)))); + // This corresponds to the DRAGEN code for + // 0 0 + // 0 1 + // 1 0 + final boolean isRef = IndexOfAllele == -1; + final VariantContext determinedEventToTest = determinedVariants.get(isRef ? 0 : IndexOfAllele); + + /* + * Here we handle any of the necessary work to deal with the event groups and maybe forming compund branches out of the groups + */ + //Set Determined pairs: + List> determinedPairs = new ArrayList<>(); + for(int j = 0; j < determinedVariants.size(); j++) { + determinedPairs.add(new Tuple<>(determinedVariants.get(j), IndexOfAllele == j)); + } + + // Loop over eventGroups, have each of them return a list of VariantContexts + List> branchExcludeAlleles = new ArrayList<>(); + branchExcludeAlleles.add(new HashSet<>()); // Add the null branch (assuming no exclusions) + + /* Note for future posterity: + * An assembly region could potentially have any number of (within some limitations) of event groups. When we are constructing + * haplotypes out of the assembled variants we want to take the dot product of the branches for each set of event groups that + * we find. I.E. if an event group with mutex variants (B,C) requires two branches for Variant A and Variant A also leads to two branches in + * another event group with mutex variants (D,E). Then we would want to ultimately generate the branches A,B,D -> A,B,E -> A,C,D -> A,C,E. + * This is why we iterate over branchExcludeAlleles internally here. + */ + for(EventGroup group : eventGroups ) { + if (group.causesBranching()) { + List>> groupVCs = group.getVariantGroupsForEvent(determinedPairs, true); + // Combinatorially expand the branches as necessary + List> newBranchesToAdd = new ArrayList<>(); + for (Set excludedVars : branchExcludeAlleles) { + //For every exclude group, fork it by each subset we have: + for (int i = 1; i < groupVCs.size(); i++) { //NOTE: iterate starting at 1 here because we special case that branch at the end + Set newSet = new HashSet<>(excludedVars); + groupVCs.get(i).stream().filter(t -> !t.b).forEach(t -> newSet.add(t.a)); + newBranchesToAdd.add(newSet); + } + // Be careful since this event group might have returned nothing + if (!groupVCs.isEmpty()) { + groupVCs.get(0).stream().filter(t -> !t.b).forEach(t -> excludedVars.add(t.a)); + } + } + branchExcludeAlleles.addAll(newBranchesToAdd); + + if (branchExcludeAlleles.size() > MAX_BRANCH_PD_HAPS) { + if (debugSite ) System.out.println("Found too many branches for variants at: "+determinedEventToTest.getStart()+" aborting and falling back to Assembly Varinats!"); + return sourceSet; + } + } + } + + if (debugSite) { + System.out.println("Branches:"); + for (int i = 0; i < branchExcludeAlleles.size(); i++) { + final int ifinal = i; + System.out.println("Branch "+i+" VCs:"); + System.out.println("exclude:"+branchExcludeAlleles.get(i).stream().map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int)referenceHaplotype.getStartPosition())).collect(Collectors.joining("->"))); + //to match dragen debug output for personal sanity + System.out.println("include:"+variantsInOrder.stream().filter(variantContext -> !branchExcludeAlleles.get(ifinal).contains(variantContext)).map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int)referenceHaplotype.getStartPosition())).collect(Collectors.joining("->"))); + } + } + + + /** + * Now handle each branch independently of the others. (the logic is the same in every case except we must ensure that none of the excluded alleles get included when constructing haps. + */ + for (Set excludeEvents : branchExcludeAlleles) { + + List branchHaps = new ArrayList<>(); + List newBranch = new ArrayList<>(); + + // Handle the simple case of making PD haplotypes + if (!makeDeterminedHapsInstead) { + for (int secondRIndex = 0; secondRIndex < entriesRInOrder.size(); secondRIndex++) { + if (secondRIndex != indexOfDeterminedInR) { + // We know here that nothing illegally overlaps because there are no groups. + // Also exclude any events that overlap the determined allele since we cant construct them (also this stops compound alleles from being formed) + // NOTE: it is important that we allow reference alleles to overlap undetermined variants as it leads to mismatches against DRAGEN otherwise. + entriesRInOrder.get(secondRIndex).getValue().stream() + .filter(vc -> !excludeEvents.contains(vc)) + .forEach(newBranch::add); + } else { + newBranch.add(determinedEventToTest); + } + } + newBranch.sort(HAPLOTYPE_SNP_FIRST_COMPARATOR); + PartiallyDeterminedHaplotype newPDHaplotypeFromEvents = createNewPDHaplotypeFromEvents(referenceHaplotype, determinedEventToTest, isRef, newBranch); + newPDHaplotypeFromEvents.setAllDeterminedEventsAtThisSite(determinedVariants); // accounting for determined variants for later in case we are in optimization mode + branchHaps.add(newPDHaplotypeFromEvents); + + } else { + // TODO currently this approach doesn't properly handle a bunch of duplicate events... + // If we are producing determined bases, then we want to enforce that every new event at least has THIS event as a variant. + List> variantGroupsCombinatorialExpansion = new ArrayList<>(); + variantGroupsCombinatorialExpansion.add(new ArrayList<>()); + // We can drastically cut down on combinatorial expansion here by saying each allele is the FIRST variant in the list, thus preventing double counting. + for (int secondRIndex = indexOfDeterminedInR; secondRIndex < entriesRInOrder.size(); secondRIndex++) { + if (variantGroupsCombinatorialExpansion.size() > MAX_BRANCH_PD_HAPS) { + if(debugSite ) System.out.println("Too many branch haplotypes ["+variantGroupsCombinatorialExpansion.size()+"] generated from site, falling back on assebmly variants!"); + return sourceSet; + } + // Iterate through the growing combinatorial expansion of haps, split it into either having or not having the variant. + if (secondRIndex == indexOfDeterminedInR) { + for (List hclist : variantGroupsCombinatorialExpansion) { + hclist.add(determinedEventToTest); + } + // Othewise make sure to include the combinatorial expansion of events at the other site + } else { + List> hapsPerVCsAtRSite = new ArrayList<>(); + for (VariantContext vc : entriesRInOrder.get(secondRIndex).getValue()) { + for (List hclist : variantGroupsCombinatorialExpansion) { + if (!excludeEvents.contains(vc)) { + List newList = new ArrayList<>(hclist); + newList.add(vc); + hapsPerVCsAtRSite.add(newList); + } + } + } + //Add them after to prevent accidentally adding duplicates of events at a site + variantGroupsCombinatorialExpansion.addAll(hapsPerVCsAtRSite); + } + } + + for (List subset : variantGroupsCombinatorialExpansion) { + subset.sort(HAPLOTYPE_SNP_FIRST_COMPARATOR); + if (debugSite) System.out.println("Construcing Hap From Events:"+ subset.stream().map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())).collect(Collectors.joining("->"))); + branchHaps.add(constructHaplotypeFromVariants(referenceHaplotype, subset, true)); + } + } + // Add the branch haps to the results: + if (debugSite) { + System.out.println("Constructed Haps for Branch"+excludeEvents.stream().map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())).collect(Collectors.joining(",")) + ":"); + System.out.println(branchHaps.stream().map(h -> h.getCigar() + " " + h.toString()).collect(Collectors.joining("\n"))); + } + + outputHaplotypes.addAll(branchHaps); + if (outputHaplotypes.size() > MAX_PD_HAPS_TO_GENERATE) { + if (debugSite) System.out.println("Too many Haps ["+outputHaplotypes.size()+"] generated at this site! Aborting!"); + return sourceSet; + } + } + } + } + + if (outputHaplotypes.size() > MAX_PD_HAPS_TO_GENERATE) { + if (debugSite) System.out.println("Too many branch haplotypes found, aborting ["+outputHaplotypes.size()+"]"); + return sourceSet; + } + sourceSet.storeAssemblyHaplotypes(); + Set result = new LinkedHashSet<>(); + // TODO this is an entirely unnecessary step that can be done away with but i leave in because it makes debugging against previous versions much easier. + outputHaplotypes.stream().sorted(new Comparator() { + @Override + public int compare(Haplotype o1, Haplotype o2) { + return new String(o1.getBases()).compareTo(new String(o2.getBases())); + } + }).forEach(h -> result.add(h)); + sourceSet.replaceAllHaplotypes(result); + if (debugSite) System.out.println("Constructed Haps for Branch"+sourceSet.getHaplotypeList().stream().map(Haplotype::toString).collect(Collectors.joining("\n"))); + if (!makeDeterminedHapsInstead) { + // Setting a boolean on the source-set to indicate to downstream code that we have PD haplotypes + sourceSet.setPartiallyDeterminedMode(); + } + if (debugSite ) System.out.println("Returning "+outputHaplotypes.size()+" to the HMM"); + return sourceSet; + } + + /** + * Helper method that handles one of the Heuristics baked by DRAGEN into this artifical haplotype genration code. + * + * To help mitigate the risk of generating combinatorial haplotypes with SNPs/Indels that that might or might not add + * up to equivalent events, DRAGEN enforces that events are NOT allowed to be present in the same haplotype if they + * (when run through smith waterman) add up to other events that were found at this assembly region. + * + * To cut down on the complexity of the task; we (and DRAGEN) follow this procedure: + * 1. look at all sets of 2 variants where at least one is an indel and none overlap. + * a) for each set construct an artifical haplotype with only those two variants on it + * b) SmithWtarman align it against the reference to generate the cheapest cigar string representation + * c) Construct the event map for the new artificial haplotype, if any events in the new event map are in our list of variants + * but are NOT the constituent events that were used to construct the haplotype then disallow the pair + * 2. Look at all sets of 3 variants that do not contain disallowed pairs found in step 1. + * a-b-c) repeat steps 1a,1b,and 1c on the 3 evetn sets + * + * @return A list of lists of variant contexts that correspond to disallowed groups. This list may be empty if none are found. + */ + private static List> smithWatermanRealignPairsOfVariantsForEquivalentEvents(Haplotype referenceHaplotype, SmithWatermanAligner aligner, SWParameters swParameters, boolean debugSite, TreeSet variantsInOrder, List vcsAsList) { + List> disallowedPairs = new ArrayList<>(); + + //Iterate over all 2 element permutations in which one element is an indel and test for alignments + for (int i = 0; i < vcsAsList.size(); i++) { + final VariantContext firstEvent = vcsAsList.get(i); + if (firstEvent.isIndel()) { + // For every indel, make every 2-3 element subset (without overlapping) of variants to test for equivalency + for (int j = 0; j < vcsAsList.size(); j++) { + final VariantContext secondEvent = vcsAsList.get(j); + // Don't compare myslef, any overlappers to myself, or indels i've already examined me (to prevent double counting) + if (j != i && !eventsOverlapForPDHapsCode(firstEvent, secondEvent, true) && ((!secondEvent.isIndel()) || j > i)) { + final List events = new ArrayList<>(Arrays.asList(firstEvent, secondEvent)); + events.sort(HAPLOTYPE_SNP_FIRST_COMPARATOR); + if (debugSite) System.out.println("Testing events: "+ events.stream().map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())).collect(Collectors.joining("->"))); + if (constructArtificialHaplotypeAndTestEquivalentEvents(referenceHaplotype, aligner, swParameters, variantsInOrder, events, debugSite)) { + disallowedPairs.add(events); + } + } + } + } + } + + //TODO NOTE: there are some discrepancies with the iteration over 3x variants in some complicated cases involving + //TODO lots of transitively disallowed pairs. Hopefully this is a minor effect. + //Now iterate over all 3 element pairs and make sure none of the + for (int i = 0; i < vcsAsList.size(); i++) { + final VariantContext firstEvent = vcsAsList.get(i); + if (firstEvent.isIndel()) { + // For every indel, make every 2-3 element subset (without overlapping) of variants to test for equivalency + for (int j = 0; j < vcsAsList.size(); j++) { + final VariantContext secondEvent = vcsAsList.get(j); + // Don't compare myslef, any overlappers to myself, or indels i've already examined me (to prevent double counting) + if (j != i && !eventsOverlapForPDHapsCode(firstEvent, secondEvent, true) && ((!secondEvent.isIndel()) || j > i)) { + // if i and j area lready disalowed keep going + if (disallowedPairs.stream().anyMatch(p -> p.contains(firstEvent) && p.contains(secondEvent))) { + continue; + } + final List events = new ArrayList<>(Arrays.asList(firstEvent, secondEvent)); + // If our 2 element arrays weren't inequivalent, test subsets of 3 including this: + for (int k = j+1; k < vcsAsList.size(); k++) { + final VariantContext thirdEvent = vcsAsList.get(k); + if (k != i && !eventsOverlapForPDHapsCode(thirdEvent, firstEvent, true) && !eventsOverlapForPDHapsCode(thirdEvent, secondEvent, true)) { + // if k and j or k and i are disallowed, keep looking + if (disallowedPairs.stream().anyMatch(p -> (p.contains(firstEvent) && p.contains(thirdEvent)) || (p.contains(secondEvent) && p.contains(thirdEvent)))) { + continue; + } + List subList = new ArrayList<>(events); + subList.add(thirdEvent); + subList.sort(HAPLOTYPE_SNP_FIRST_COMPARATOR); + if (debugSite) System.out.println("Testing events: " + subList.stream().map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())).collect(Collectors.joining("->"))); + if (constructArtificialHaplotypeAndTestEquivalentEvents(referenceHaplotype, aligner, swParameters, variantsInOrder, subList, debugSite)) { + disallowedPairs.add(subList); + } + } + } + } + } + } + } + + return disallowedPairs; + } + + /** + * Overlaps method to handle indels and snps correctly. Specifically for this branching codes purposes, SNPS never overlap other SNPS, + * indels don't overlap on their anchor bases and insertions don't overlap anything except deletions spanning them or other insertions + * at the same base. + * + * @param snpsOverlap if false, don't ever evaluate snps as overlapping other snps (we do this because sometimes we need to construct artifical haps where we don't allow overlapping) + */ + static boolean eventsOverlapForPDHapsCode(VariantContext vc1, VariantContext vc2, boolean snpsOverlap){ + if (!snpsOverlap && vc2.isSNP() && vc1.isSNP()) { + return false; + } + if (!vc1.getContig().equals(vc2.getContig())) { + return false; + } + double vc1start = vc1.isIndel() ? (vc1.isSimpleDeletion() ? vc1.getStart() + 1 : vc1.getStart() + 0.5) : vc1.getStart(); + double vc1end = vc1.isSimpleInsertion() ? vc1.getEnd() + 0.5 : vc1.getEnd(); + double vc2start = vc2.isIndel() ? (vc2.isSimpleDeletion() ? vc2.getStart() + 1 : vc2.getStart() + 0.5) : vc2.getStart(); + double vc2end = vc2.isSimpleInsertion() ? vc2.getEnd() + 0.5 : vc2.getEnd(); + + //Pulled directly from CoordMath.java (not using here because of doubles) + return (vc2start >= vc1start && vc2start <= vc1end) || (vc2end >=vc1start && vc2end <= vc1end) || vc1start >= vc2start && vc1end <= vc2end; + } + + + /** + * This method is the helper that manages the actual SW alignment and testing of a group of variants vs the reference haplotype. + * + * The method is as follows, construct and artificial haplotype of the provided events, then realign it vs the reference and test + * if any of the resulting variants are present in the inputs (but doesn't match) + * + * NOTE: as per DRAGEN impelmeneation, a set is considered invalid if we re-SmithWaterman align and we get: + * 1) A different result hap from the ref + alleles we added + * 2) At least one of the resulting events is NOT in the initial set of alleles we added to the ref + * 3) Was at least one of the resulting alleles a variant we discovered in the pileups/assembly + * + * #3 means that if we add alleles to the ref and realign to get a different representation that was NOT found in the assemblies + * we don't consider the events to be a problem, we only care in the even that they add up to a variant that is going to be + * in our PDhaplotypes anyway! + * + * @return true if we SHOULD NOT allow the eventsToTest alleles to appear as alleles together in determined haplotypes + */ + @VisibleForTesting + private static boolean constructArtificialHaplotypeAndTestEquivalentEvents(Haplotype referenceHaplotype, SmithWatermanAligner aligner, SWParameters swParameters, TreeSet vcs, List eventsToTest, boolean debugSite) { + final Haplotype realignHap = constructHaplotypeFromVariants(referenceHaplotype, eventsToTest, false); + //Special case to capture events that equal the reference (and thus have empty event maps). + if (Arrays.equals(realignHap.getBases(), referenceHaplotype.getBases())) { + if (debugSite) System.out.println("Events add up to the reference! disallowing pair"); + return true; + } + //ALIGN! + realignHap.setCigar(CigarUtils.calculateCigar(referenceHaplotype.getBases(), realignHap.getBases(), aligner, swParameters, SWOverhangStrategy.INDEL)); + EventMap.buildEventMapsForHaplotypes(Collections.singletonList(realignHap), referenceHaplotype.getBases(), referenceHaplotype.getGenomeLocation(), false,0); + //TODO this differs from DRAGEN, specifically in DRAGEN they do the realignment and compare the SmithWatermanScore with the SWscore of the + //TODO non-realigned haplotypes, then they only call an event set equivalent if the score for the new found alignment is less than the score + //TODO for the existing ones. Since we are simply realigning and checking the event map outputs its possible that we consider events to + //TODO be disallowed that have an equal SmithWaterman score to the original but a different (but equivalent) variant representation. + //TODO This is likely a minor effect on the overall correctness. + final boolean wasEquivalentEvent = realignHap.getEventMap().getVariantContexts().stream().filter(eMapVC -> + // Are there any variants NOT in our initial list + eventsToTest.stream().noneMatch(v -> { + return doVariantsMatch(eMapVC, v); + })) + // Do any of variants (that were not in our set of 2-3 targets) appear in our overall list of alleles + .anyMatch(eMapVc -> vcs.stream().anyMatch(v -> { + return doVariantsMatch(eMapVc, v); + })); + if (debugSite) System.out.println( + realignHap.getEventMap().getVariantContexts().stream() + .map(PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString((int) referenceHaplotype.getStartPosition())) + .collect(Collectors.joining("\n"))); + if (wasEquivalentEvent) { + if (debugSite) System.out.println("Events mismatched!"); + } + + return wasEquivalentEvent; + } + + // A helper method to assert that variant contexts in the event map match those outside of it. + private static boolean doVariantsMatch(VariantContext eMapVC, VariantContext v) { + return eMapVC.getStart() == v.getStart() && + eMapVC.getReference().equals(v.getReference()) && + eMapVC.getAlternateAllele(0).equals(v.getAlternateAllele(0)) && + eMapVC.getAlternateAlleles().size() == v.getAlternateAlleles().size(); + } + + + /** + * NOTE: this accepts multiple alleles stacked up at the same base (assuming the order is SNP -> INDEL) + * NOTE: However this class does NOT accept multiple SNPS overlapping or SNPs overlapping deletions + */ + @VisibleForTesting + public static Haplotype constructHaplotypeFromVariants(final Haplotype refHap, final List variantContexts, final boolean setEventMap) { + //ASSERT that the base is ref and cool + if (!refHap.isReference() || refHap.getCigar().numCigarElements() > 1) { + throw new GATKException("This is not a valid base haplotype for construction"); + } + //ASSERT that everything is fully overlapping the reference. + variantContexts.stream().forEach(v -> {if (!refHap.getGenomeLocation().contains(v)) throw new GATKException("Provided Variant Context"+v+"doesn't overlap haplotype "+refHap);}); + + final long genomicStartPosition = refHap.getStartPosition(); + long refOffsetOfNextBaseToAdd = genomicStartPosition; + + byte[] refbases = refHap.getBases(); + CigarBuilder runningCigar = new CigarBuilder(); + byte[] newRefBases = {}; + + //ASSUME sorted for now + // use the reverse list to save myself figuring out cigars for right now + for (VariantContext vc : variantContexts) { + if (vc.getAlternateAlleles().size() > 1) { + throw new GATKException("too may alt alleles"); + } + Allele refAllele = vc.getReference(); + Allele altAllele = vc.getAlternateAllele(0); + + int intermediateRefStartPosition = (int) (refOffsetOfNextBaseToAdd - genomicStartPosition); + int intermediateRefEndPosition = Math.toIntExact(vc.getStart() - genomicStartPosition); + + if ((vc.isIndel() && intermediateRefEndPosition - intermediateRefStartPosition < -1) || (!vc.isIndel() && intermediateRefEndPosition - intermediateRefStartPosition < 0)) {//todo clean this up + throw new GATKException("Variant "+vc+" is out of order in the PD event list: "+variantContexts); + } + if (intermediateRefEndPosition - intermediateRefStartPosition > 0) { // Append the cigar element for the anchor base if necessary. + runningCigar.add(new CigarElement(intermediateRefEndPosition - intermediateRefStartPosition, CigarOperator.M)); + } + // Include the ref base for indel if the base immediately proceeding this event is not already tracked + boolean includeRefBaseForIndel = vc.isIndel() && (intermediateRefStartPosition <= intermediateRefEndPosition); + + CigarElement newCigarElement; + if (refAllele.length() == altAllele.length()) { + newCigarElement = new CigarElement(refAllele.length(), CigarOperator.X); + } else { + // If the last base was filled by another event, don't attempt to fill in the indel ref base. + if (includeRefBaseForIndel) { + runningCigar.add(new CigarElement(1, CigarOperator.M)); //When we add an indel we end up inserting a matching base + } + newCigarElement = new CigarElement(Math.abs(altAllele.length() - refAllele.length()), + refAllele.length() > altAllele.length() ? + CigarOperator.D : CigarOperator.I); + } + runningCigar.add(newCigarElement); + + if (intermediateRefEndPosition - intermediateRefStartPosition > 0) { + newRefBases = ArrayUtils.addAll(newRefBases, ArrayUtils.subarray(refbases, intermediateRefStartPosition, (int) (vc.getStart() - genomicStartPosition))); // bases before the variant + } + // Handle the ref base for indels that exlcude their ref bases + if (refAllele.length() != altAllele.length() && !includeRefBaseForIndel) { + newRefBases = ArrayUtils.addAll(newRefBases, Arrays.copyOfRange(altAllele.getBases(),1, altAllele.length())); + // else add the snp + } else { + newRefBases = ArrayUtils.addAll(newRefBases, altAllele.getBases()); // refbases added + } + refOffsetOfNextBaseToAdd = vc.getEnd() + 1; //TODO this is probably not set for future reference + } + + // Finish off the haplotype with the final bases + int refStartIndex = (int) (refOffsetOfNextBaseToAdd - genomicStartPosition); + newRefBases = ArrayUtils.addAll(newRefBases, ArrayUtils.subarray(refbases, refStartIndex, refbases.length)); + runningCigar.add(new CigarElement(refbases.length - refStartIndex, CigarOperator.M)); + + final Haplotype outHaplotype = new Haplotype(newRefBases, false, refHap.getGenomeLocation(), runningCigar.make()); + if (setEventMap) { + EventMap.buildEventMapsForHaplotypes(Collections.singletonList(outHaplotype), refHap.getBases(), refHap.getGenomeLocation(), false,0); + // NOTE: we set this AFTER generating the event maps because hte event map code above is being generated from the ref hap so this offset will cause out of bounds errors + outHaplotype.setAlignmentStartHapwrtRef(refHap.getAlignmentStartHapwrtRef()); //TODO better logic here + } + return outHaplotype; + } + + /** + * Construct a PD haplotype from scratch + * + * Generally we are constructing a new haplotype with all the reference bases for SNP events and with the longest possible allele for INDEL events. + * For deletions, we extend the haplotype by the ref length + * + * NOTE: we assume each provided VC is in start position order, and only ever contains one allele (and that if there are overlapping SNPs and indels that the SNPs come fist) + */ + @VisibleForTesting + //TODO When we implement JointDetection we will need to allow multiple eventWithVariants to be prsent... + static PartiallyDeterminedHaplotype createNewPDHaplotypeFromEvents(final Haplotype base, final VariantContext eventWithVariant, final boolean useRef, final List constituentEvents) { + //ASSERT that the base is ref and cool + if (!base.isReference() || base.getCigar().numCigarElements() > 1) { + throw new RuntimeException("This is not a valid base haplotype for construction"); + } + //TODO add a more stringent check that the format of constituentEvents works + long genomicStartPosition = base.getStartPosition(); + long refOffsetOfNextBaseToAdd = genomicStartPosition; + + byte[] refBasesToAddTo = base.getBases(); + CigarBuilder runningCigar = new CigarBuilder(false); // NOTE: in some incredibly rare edge cases involving the legacy assembly region trimmer a deletion can hang past the edge of an active window. + byte[] newHaplotypeBasees = {}; + byte[] pdBytes = {}; + + //ASSUME sorted for now + // use the reverse list to save myself figuring out cigars for right now + for (VariantContext vc : constituentEvents) { + int intermediateRefStartPosition = (int) (refOffsetOfNextBaseToAdd - genomicStartPosition); + int intermediateRefEndPosition = Math.toIntExact(vc.getStart() - genomicStartPosition); + + // An extra special case if we are a SNP following a SNP + if (vc.isSNP() && intermediateRefEndPosition - intermediateRefStartPosition == -1 && ((pdBytes[pdBytes.length-1] & PartiallyDeterminedHaplotype.SNP) != 0) ) { + byte[] array = PartiallyDeterminedHaplotype.getPDBytesForHaplotypes(vc.getReference(), vc.getAlternateAllele(0)); + pdBytes[pdBytes.length-1] = (byte) (pdBytes[pdBytes.length-1] | array[0]); // adding any partial bases if necessary + continue; + } + + // Ref alleles (even if they overlap undetermined events) should be skipped + if (vc.getStart()==eventWithVariant.getStart() && useRef) { + continue; + } + + //Check that we are allowed to add this event (and if not we are) + if ((vc.isIndel() && intermediateRefEndPosition - intermediateRefStartPosition < -1) || (!vc.isIndel() && intermediateRefEndPosition - intermediateRefStartPosition < 0)) {//todo clean this up + throw new RuntimeException("Variant "+vc+" is out of order in the PD event list: "+constituentEvents); + } + + // Add the cigar for bases we skip over + if (intermediateRefEndPosition - intermediateRefStartPosition > 0) { + runningCigar.add(new CigarElement(intermediateRefEndPosition - intermediateRefStartPosition, CigarOperator.M)); + } + + // Include the ref base for indel if the base immediately proceeding this event is not already tracked + boolean includeRefBaseForIndel = vc.isIndel() && (intermediateRefStartPosition <= intermediateRefEndPosition); + + // Determine the alleles to add + Allele refAllele = vc.getReference(); + Allele altAllele = vc.getAlternateAllele(0); + boolean isInsertion = altAllele.length() > refAllele.length(); // If its an insertion we flip to "ADD" the bases to the ref. + boolean isEvent = false; + byte[] basesToAdd; + // If this is the blessed variant, add + if (vc.getStart()==eventWithVariant.getStart()) { + if (!useRef && eventWithVariant.getAlternateAlleles().size() > 1) { + throw new RuntimeException("the eventWithVariant variant must be monoallelic"); + } + isEvent = true; + basesToAdd = useRef? refAllele.getBases() : altAllele.getBases(); + // Otherwise make sure we are adding the longest allele (for indels) or the ref allele for snps. + } else { + basesToAdd = refAllele.length() >= altAllele.length() ? refAllele.getBases() : altAllele.getBases(); + } + + // Remove anchor base if necessary + if (vc.isIndel() && !includeRefBaseForIndel) { + basesToAdd = Arrays.copyOfRange(basesToAdd, 1, basesToAdd.length); + } + + // Figure out the cigar to add: + // - If we are in the ref, simply add the cigar corresponding to the allele we are using + // - + CigarElement newCigarElement; + // if this is the event special case + if (isEvent) { + if (vc.isSNP()) { + newCigarElement = new CigarElement(refAllele.length(), useRef? CigarOperator.M : CigarOperator.X); + } else { + if (vc.isIndel() && includeRefBaseForIndel) { + runningCigar.add(new CigarElement( 1, CigarOperator.M)); + } + // For Insertions: mark the Cigar as I if we aren't in ref + if (isInsertion) { + newCigarElement = new CigarElement(useRef ? 0 : Math.max(refAllele.length(), altAllele.length()) - 1, CigarOperator.I); + // For Deletions: Always include the bases, however mark them as M or D accordingly + } else { + newCigarElement = new CigarElement(Math.max(refAllele.length(), altAllele.length()) - 1, useRef ? CigarOperator.M : CigarOperator.D); + } + } + // If we aren't in the blessed variant, add a match and make sure the array is set accordingly + } else { + if (!vc.isIndel()) { + newCigarElement = new CigarElement(refAllele.length() , CigarOperator.M); + } else { + // Maybe add the cigar for the anchor base + if (includeRefBaseForIndel) { + runningCigar.add(new CigarElement(1, CigarOperator.M)); + } + // Add the cigar for the indel allele bases + if (isInsertion) { + // Insertions stay in the cigar since they are added relative to the reference + newCigarElement = new CigarElement(Math.abs(altAllele.length() - refAllele.length()), CigarOperator.I); + } else { + // Deletions become matches because they still exist as bases on the reference + newCigarElement = new CigarElement(Math.abs(altAllele.length() - refAllele.length()), CigarOperator.M); + } + } + } + runningCigar.add(newCigarElement); + + // Add ref basses up to this if necessary + if (intermediateRefEndPosition - intermediateRefStartPosition > 0) { + newHaplotypeBasees = ArrayUtils.addAll(newHaplotypeBasees, ArrayUtils.subarray(refBasesToAddTo, intermediateRefStartPosition, (int) (vc.getStart() - genomicStartPosition))); // bases before the variant + pdBytes = ArrayUtils.addAll(pdBytes, new byte[vc.getStart() - (int)refOffsetOfNextBaseToAdd]); // bases before the variant + } + newHaplotypeBasees = ArrayUtils.addAll(newHaplotypeBasees, basesToAdd); // refbases added + if (includeRefBaseForIndel) { + pdBytes = ArrayUtils.add(pdBytes, (byte)0); + } + pdBytes = ArrayUtils.addAll(pdBytes, isEvent? + new byte[basesToAdd.length - (includeRefBaseForIndel?1:0)] : + PartiallyDeterminedHaplotype.getPDBytesForHaplotypes(isInsertion? + altAllele : + refAllele, + isInsertion? refAllele : + altAllele)); // refbases added + refOffsetOfNextBaseToAdd = vc.getEnd() + 1; //TODO this is probably not set for future reference + } + + // Finish off the haplotype with the final bases + int refStartIndex = (int) (refOffsetOfNextBaseToAdd - genomicStartPosition); + newHaplotypeBasees = ArrayUtils.addAll(newHaplotypeBasees, ArrayUtils.subarray(refBasesToAddTo, refStartIndex, refBasesToAddTo.length)); + pdBytes = ArrayUtils.addAll(pdBytes, new byte[refBasesToAddTo.length - refStartIndex]); + runningCigar.add(new CigarElement(refBasesToAddTo.length - refStartIndex, CigarOperator.M)); + + return new PartiallyDeterminedHaplotype( + new Haplotype(newHaplotypeBasees, false, base.getGenomeLocation(), runningCigar.make()), + useRef, + pdBytes, + constituentEvents, + eventWithVariant, + runningCigar.make(), + eventWithVariant.getStart(), + base.getAlignmentStartHapwrtRef()); + } + + // A helper class for managing mutually exclusive event clusters and the logic arround forming valid events vs eachother. + private static class EventGroup { + List variantsInBitmapOrder; + HashSet variantContextSet; + //From Illumina (there is a LOT of math that will eventually go into these)/ + BitSet allowedEvents = null; + + // Optimizaiton to save ourselves recomputing the subsets at every point its necessary to do so. + List>> cachedEventLitsts = null; + + public EventGroup(final VariantContext variantContext) { + variantsInBitmapOrder = new ArrayList<>(); + variantContextSet = new HashSet<>(); + variantsInBitmapOrder.add(variantContext); + variantContextSet.add(variantContext); + } + public EventGroup() { + variantsInBitmapOrder = new ArrayList<>(); + variantContextSet = new HashSet<>(); + } + + /** + * This is the primary method for handling mutually exclusive events in this subgroup. This code amd methods comes directly from DRAGEN: + * + * Create a #Variants bitset to store valid pairings: + * - The index of each element corresponds to an enumerated subset of alleles in this group + * - Each bit in the index corresponds to the presence or absence of a variant from the vcf list. + * - For example with variants [A,B,C] the number 5 corresponds to subset [A,C] + * - A false in the bitset corresponds to a disallowed pair. + * - NOTE: we can use 32bit ints for these bitshift operations by virtue of the fact that we limit ourselves to at most 22 variants per group. + * Iterate through pairs of Variants that overlap and mark off any pairings including this. + * Iterate through the mutex variants and ensure pairs containing all mutex variant groups are marked as true + * + * @param disallowedEvents Pairs of events disallowed + * @return false if the event group is too large to process + */ + public boolean populateBitset(List> disallowedEvents) { + if (variantsInBitmapOrder.size() > MAX_VAR_IN_EVENT_GROUP) { + return false; + } + if (variantsInBitmapOrder.size() < 2) { + return true; + } + + allowedEvents = new BitSet(variantsInBitmapOrder.size()); + allowedEvents.flip(1, 1 << variantsInBitmapOrder.size()); + // initialize all events as being allowed and then disallow them in turn . + + // Ensure the list is in positional order before commencing. + variantsInBitmapOrder.sort(HAPLOTYPE_SNP_FIRST_COMPARATOR); + List bitmasks = new ArrayList<>(); + // Mark as disallowed all events that overlap eachother + for (int i = 0; i < variantsInBitmapOrder.size(); i++) { + for (int j = i+1; j < variantsInBitmapOrder.size(); j++) { + if (eventsOverlapForPDHapsCode(variantsInBitmapOrder.get(i), variantsInBitmapOrder.get(j), false)) { + bitmasks.add(1 << i | 1 << j); + } + } + } + // mark as disallowed any sets of variants from the bitmask. + for (List disallowed : disallowedEvents) { + // + if (disallowed.stream().anyMatch(v -> variantContextSet.contains(v))){ + int bitmask = 0; + for (VariantContext v : disallowed) { + int indexOfV = variantsInBitmapOrder.indexOf(v); + if (indexOfV < 0) { + throw new RuntimeException("Something went wrong in event group merging, variant "+v+" is missing from the event group despite being in a mutex pair: "+disallowed+"\n"+this); + } + bitmask += 1 << variantsInBitmapOrder.indexOf(v); + } + bitmasks.add(bitmask); + } + } + + // Now iterate through the list and disallow all events with every bitmask + //TODO This method is potentially very inefficient! We don't technically have to iterate over every i, + //TODO we know there is an optimization involving minimizing the number of checks necessary here by iterating + //TODO using the bitmask values themselves for the loop + if (!bitmasks.isEmpty()) { + events: + for (int i = 1; i < allowedEvents.length(); i++) { + for (final int mask : bitmasks) { + if ((i & mask) == mask) { // are the bits form the mask true? + allowedEvents.set(i, false); + continue events; + // Once i is set we don't need to keep checking bitmasks + } + } + } + } + + return true; + } + + /** + * This method handles the logic involved in getting all of the allowed subsets of alleles for this event group. + * + * @param disallowSubsets + * @return + */ + public List>> getVariantGroupsForEvent(final List> eventsForMask, final boolean disallowSubsets) { + // If we are dealing with an external to this list event + int eventMask = 0; + int maskValues = 0; + for(Tuple event : eventsForMask) { + if (variantContextSet.contains(event.a)) { + int index = variantsInBitmapOrder.indexOf(event.a); + eventMask = eventMask | (1 << index); + maskValues = maskValues | ((event.b ? 1 : 0) << index); + } + } + // Special case (if we are determining bases outside of this mutex cluster we can reuse the work from previous iterations) + if (eventMask == 0 && cachedEventLitsts != null) { + return cachedEventLitsts; + } + + List ints = new ArrayList<>(); + // Iterate from the BACK of the list (i.e. ~supersets -> subsets) + // NOTE: we skip over 0 here since that corresponds to ref-only events, handle those externally to this code + outerLoop: + for (int i = allowedEvents.length(); i > 0; i--) { + // If the event is allowed AND if we are looking for a particular event to be present or absent. + if (allowedEvents.get(i) && (eventMask == 0 || ((i & eventMask) == maskValues))) { + // Only check for subsets if we need to + if (disallowSubsets) { + for (Integer group : ints) { + // if the current i is a subset of an existing group + if ((i | group) == group) { + continue outerLoop; + } + } + } + ints.add(i); + } + } + + // Now that we have all the mutex groups, unpack them into lists of variants + List>> output = new ArrayList<>(); + for (Integer grp : ints) { + List> newGrp = new ArrayList<>(); + for (int i = 0; i < variantsInBitmapOrder.size(); i++) { + // if the corresponding bit is 1, set it as such, otherwise set it as 0. + newGrp.add(new Tuple<>(variantsInBitmapOrder.get(i), ((1< 1; + } + + //Print The event group in Illumina indexed ordering: + public String toDisplayString(int startPos) { + return "EventGroup: " + variantsInBitmapOrder.stream().map(vc -> PartiallyDeterminedHaplotype.getDRAGENDebugVariantContextString(startPos).apply(vc)).collect(Collectors.joining("->")); + } + + public boolean contains(final VariantContext event) { + return variantContextSet.contains(event); + } + + public void addEvent(final VariantContext event) { + variantsInBitmapOrder.add(event); + variantContextSet.add(event); + allowedEvents = null; + } + + public EventGroup mergeEvent(final EventGroup other) { + variantsInBitmapOrder.addAll(other.variantsInBitmapOrder); + variantContextSet.addAll(other.variantsInBitmapOrder); + allowedEvents = null; + return this; + } + } +} diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PileupDetectionArgumentCollection.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PileupDetectionArgumentCollection.java index 2c3fffaa027..9350d48f470 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PileupDetectionArgumentCollection.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PileupDetectionArgumentCollection.java @@ -3,6 +3,7 @@ import org.broadinstitute.barclay.argparser.Advanced; import org.broadinstitute.barclay.argparser.Argument; import org.broadinstitute.barclay.argparser.Hidden; +import org.broadinstitute.hellbender.engine.GATKPath; /** * Set of arguments for configuring the pileup detection code @@ -15,9 +16,9 @@ public final class PileupDetectionArgumentCollection { public static final String PILEUP_DETECTION_ABSOLUTE_ALT_DEPTH = "pileup-detection-absolute-alt-depth"; public static final String PILEUP_DETECTION_INDEL_THRESHOLD = "pileup-detection-indel-alt-threshold"; public static final String PILEUP_DETECTION_FILTER_COVERAGE_LONG_NAME = "pileup-detection-filter-coverage-threshold"; + public static final String PILEUP_DETECTION_SNP_BASEQUALITY_THRESHOLD = "pileup-detection-snp-basequality-filter"; - //TODO we currently don't see the same threshold from active region determination... - public static final String PILEUP_DETECTION_ACETIVE_REGION_LOD_THRESHOLD_LONG_NAME = "pileup-detection-active-region-lod-threshold"; + public static final String PILEUP_DETECTION_ACTIVE_REGION_PHRED_THRESHOLD_LONG_NAME = "pileup-detection-active-region-phred-threshold"; // Arguments related to DRAGEN heuristics related to "read badness" intended to filter out false positives from the pileup detection code public static final String PILEUP_DETECTION_BAD_READ_RATIO_LONG_NAME = "pileup-detection-bad-read-tolerance"; @@ -25,12 +26,26 @@ public final class PileupDetectionArgumentCollection { public static final String PILEUP_DETECTION_EDIT_DISTANCE_BADNESS_LONG_NAME = "pileup-detection-edit-distance-read-badness-threshold"; public static final String PILEUP_DETECTION_CHIMERIC_READ_BADNESS_LONG_NAME = "pileup-detection-chimeric-read-badness"; //TODO these need to be implemented with some input from Illumina + //TODO for the most part as far as we can tell this is a hypothetical necessity but we don't currently have these + //TODO values available to the haplotype caller and almost certianly to do this correctly would involve unifying TLEN and STDLEN public static final String PILEUP_DETECTION_TLEN_MEAN_LONG_NAME = "pileup-detection-template-mean-badness-threshold"; public static final String PILEUP_DETECTION_TLEN_STD_LONG_NAME = "pileup-detection-template-std-badness-threshold"; // Argumetns related to filtering the list at the assembly graph level public static final String PILEUP_DETECTION_INDEL_SNP_BLOCKING_RANGE = "pileup-detection-snp-adjacent-to-assembled-indel-range"; + // Arguments related to post-assembly filtering heuristics. + public static final String PILEUP_DETECTION_FILTER_ASSEMBLY_HAPS_THRESHOLD = "pileup-detection-filter-assembly-alt-bad-read-tolerance"; + public static final String PILEUP_DETECTION_EDIT_DISTANCE_BADNESS_FOR_ASSEMBLY_LONG_NAME = "pileup-detection-edit-distance-read-badness-for-assembly-filtering-threshold"; + + + public static final String GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME = "use-pdhmm"; + public static final String DETERMINE_PD_HAPS = "make-determined-haps-from-pd-code"; + public static final String DEBUG_PILEUPCALLING_ARG = "print-pileupcalling-status"; + public static final String FALLBACK_TO_ALT_HAP_CONSTRUCITON_IF_ABORTED = "fallback-gga-if-pdhmm-fails"; + public static final String PDHMM_READ_OVERLAP_OPTIMIZATION = "use-pdhmm-overlap-optimization"; + public static final String PDHMM_DEBUG_OUTPUT = "pdhmm-results-file"; + /** * Enables pileup-based haplotype creation and variant detection * @@ -39,6 +54,38 @@ public final class PileupDetectionArgumentCollection { @Advanced @Argument(fullName= PILEUP_DETECTION_LONG_NAME, doc = "If enabled, the variant caller will create pileup-based haplotypes in addition to the assembly-based haplotype generation.", optional = true) public boolean usePileupDetection = false; + /** + * This argument enables the PartiallyDeterminedHMM. + * + * By enabling this triggers the HaplotypeCaller (not currently supported in Mutect2) to use the PDHMM to compute likelihoods instead of the PairHMM. + * This means that variants found by both pileupdetection and the assembly engine are going to be treated as equivalent and merged/filtered together + * to produce "PartiallyDetermined" Haplotype objects and produce a merged likelihoods score from multiple haplotypes being run together. + * + * This code is intended for Dragen 3.7.8 concordance and is not recommended to be run outside of that context without being optimized. + */ + @Argument(fullName= GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME, doc = "Partially Determined HMM, an alternative to the regular assembly haplotypes where we instead construct artificial haplotypes out of the union of the assembly and pileup alleles.", optional = true) + public boolean generatePDHaplotypes = false; + @Advanced + // NOTE: this optimization ASSUMES that we are not realigning reads as part of PDHMM (which is how DRAGEN works) + @Argument(fullName= PDHMM_READ_OVERLAP_OPTIMIZATION, doc = "PDHMM: An optimization to PDHMM, if set this will skip running PDHMM haplotype determination on reads that don't overlap (within a few bases) of the determined allele in each haplotype. This substantially reduces the amount of read-haplotype comparisons at the expense of ignoring read realignment mapping artifacts. (Requires '--"+GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME+"' argument)", optional = true) + public boolean pdhmmOptimization = false; + /** + * A set of debug/testing arguments related to PDHMM and various off-label configurations for running pdhmm. + */ + @Hidden + @Argument(fullName= PDHMM_DEBUG_OUTPUT, doc = "PDHMM: File to be used to dump a summary of each set of inputs and outputs generated by the PDHMM to be used for debugging", optional = true) + public GATKPath pdhmmDebugOutputResults = null; + @Hidden + @Argument(fullName= DETERMINE_PD_HAPS, doc = "PDHMM: As an alternative to using the PDHMM, run all of the haplotype branching/determination code and instead of using the PDHMM use the old HMM with determined haplotypes. NOTE: this often fails and fallsback to other code due to combinatorial expansion. (Requires '--"+GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME+"' argument)", optional = true) + public boolean determinePDHaps = false; + @Hidden + @Argument(fullName= DEBUG_PILEUPCALLING_ARG, doc = "PDHMM: If set, print to stdout a prodigious amount of debugging information about each of the steps involved in artificial haplotype construction and filtering. (Requires '--"+GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME+"' argument)", optional = true) + public boolean debugPileupStdout = false; + + //NOTE we leave this enabled in the PDHMM because our current implementation has more-strict heuristics for falling back (wrt #variants & complexity of overlap groups) than DRAGEN does for runtime reasons. Hopefully this results in fewer fallback-to-assembly sites + @Hidden + @Argument(fullName= FALLBACK_TO_ALT_HAP_CONSTRUCITON_IF_ABORTED, doc = "PDHMM: An optional fallback for PDHMM. If PDHMM encounters too much complexity in haplotype construction, instead of falling back to the regular assembly haplotypes this will attempt to fallback to the GGA-Based PileupDetection code for constructing haplotypes. This does not match DRAGEN and is not necessary for DRAGEN FE. (Requires '--"+GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME+"' argument)", optional = true) + public boolean useGGAFallback = true; /** * Enables detection of indels from the pileups in. (EXPERIMENTAL FEATURE) @@ -46,7 +93,10 @@ public final class PileupDetectionArgumentCollection { @Hidden @Argument(fullName= PILEUP_DETECTION_ENABLE_INDELS, doc = "Pileup Detection: If enabled, pileup detection code will attempt to detect indels missing from assembly. (Requires '--"+PILEUP_DETECTION_LONG_NAME+"' argument)", optional = true) public boolean detectIndels = false; - + @Advanced + @Hidden + @Argument(fullName= PILEUP_DETECTION_ACTIVE_REGION_PHRED_THRESHOLD_LONG_NAME, doc = "Pileup Detection: This argument sets the minimum fast genotyper phred score necessary in active region determination to find a pileup variant. Not compatible with Mutect2 (Requires '--"+PILEUP_DETECTION_LONG_NAME+"'` argument)", optional = true) + public double activeRegionPhredThreshold = 0; @Advanced @Hidden @Argument(fullName= "num-artificial-haplotypes-to-add-per-allele", @@ -65,7 +115,7 @@ public final class PileupDetectionArgumentCollection { public double snpThreshold = 0.1; @Hidden @Argument(fullName= PILEUP_DETECTION_INDEL_THRESHOLD, doc = "Pileup Detection: Fraction of alt supporting reads in order to consider alt indel. (Requires '--"+PILEUP_DETECTION_LONG_NAME+"' argument)", optional = true, minValue = 0D, maxValue = 1D) - public double indelThreshold = 0.5; + public double indelThreshold = 0.1; @Hidden @Argument(fullName= PILEUP_DETECTION_ABSOLUTE_ALT_DEPTH, doc = "Pileup Detection: Absolute number of alt reads necessary to be included in pileup events. (Requires '--"+PILEUP_DETECTION_LONG_NAME+"' argument)", optional = true, minValue = 0D) @@ -73,6 +123,9 @@ public final class PileupDetectionArgumentCollection { @Hidden @Argument(fullName= PILEUP_DETECTION_INDEL_SNP_BLOCKING_RANGE, doc = "Pileup Detection: Filters out pileup snps within this many bases of an assembled indel. (Requires '--"+PILEUP_DETECTION_LONG_NAME+"' argument)", optional = true, minValue = 0D) public int snpAdajacentToAssemblyIndel = 5; + @Hidden + @Argument(fullName= PILEUP_DETECTION_SNP_BASEQUALITY_THRESHOLD, doc = "Pileup Detection: Filters out reads from pileup SNPs with base quality lower than this threshold. (Requires '--"+PILEUP_DETECTION_LONG_NAME+"' argument)", optional = true) + public int qualityForSnpsInPileupDetection = 12; //WHY is this two different than the regular active region determination limit (10)? Ask DRAGEN engineers. /** * Arguments related to the "bad read filtering" where alleles that are supported primarily by reads that fail at least one of a number of heuristics will be filtered out @@ -95,4 +148,18 @@ public final class PileupDetectionArgumentCollection { @Hidden @Argument(fullName= PILEUP_DETECTION_TLEN_STD_LONG_NAME, doc = "Pileup Detection: Standard deviation template length (T LEN) to consider for read badness. Requires '--"+PILEUP_DETECTION_TLEN_MEAN_LONG_NAME+"' to also be set.", optional = true, minValue = 0D) public double templateLengthStd = 0.0; + + /** + * Enables pileup-based haplotype creation and variant detection + * + * NOTE: --pileup-detection is a beta feature. Use this mode at your own risk. + */ + @Advanced + @Hidden + @Argument(fullName= PILEUP_DETECTION_FILTER_ASSEMBLY_HAPS_THRESHOLD, doc = "If enabled (set to non-zero), will apply the \"badness\" filter to compatible assembled haplotypes. Applies the same heuristics for badness as --"+PILEUP_DETECTION_BAD_READ_RATIO_LONG_NAME+" NOTE: this can result in assembled haplotypes being deleted because they are supported by messy reads in the pileups. Exercise caution.", optional = true) + public double assemblyBadReadThreshold = 0.0; + @Hidden + @Argument(fullName= PILEUP_DETECTION_EDIT_DISTANCE_BADNESS_FOR_ASSEMBLY_LONG_NAME, doc = "Pileup Detection: Reject alt reads with greater than this fraction of mismatching bases from the reference (proxied using the NM tag). (Requires '--"+PILEUP_DETECTION_LONG_NAME+"' argument)", optional = true) + public double assemblyBadReadEditDistance = 0.12; + } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/RampedHaplotypeCallerEngine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/RampedHaplotypeCallerEngine.java index b66bc6e7202..42e2335f63e 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/RampedHaplotypeCallerEngine.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/RampedHaplotypeCallerEngine.java @@ -2,6 +2,8 @@ import htsjdk.samtools.SAMFileHeader; import htsjdk.samtools.reference.ReferenceSequenceFile; +import htsjdk.samtools.util.Tuple; +import htsjdk.samtools.util.Tuple; import htsjdk.variant.variantcontext.VariantContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -291,7 +293,7 @@ private void assemble(final CallRegionContext context) { RampUtils.logReads(rpArgs.rampsDebugReads, "onramp: reads before trimming", context.assemblyResult.getRegionForGenotyping().getReads()); RampUtils.logReads(rpArgs.rampsDebugReads, "onramp: BEFORE untrimmedAssemblyResult reads", context.region.getReads()); - final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(context.region, context.givenAlleles, hcArgs, readsHeader, samplesList, logger, referenceReader, assemblyEngine, aligner, + final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(context.region, hcArgs, readsHeader, samplesList, logger, referenceReader, assemblyEngine, aligner, !hcArgs.doNotCorrectOverlappingBaseQualities, hcArgs.fbargs, postFilterOnRamp != null); RampUtils.logReads(rpArgs.rampsDebugReads, "onramp: AFTER untrimmedAssemblyResult reads", context.region.getReads()); context.assemblyResult.setRegionForGenotyping(untrimmedAssemblyResult.getRegionForGenotyping()); @@ -322,7 +324,7 @@ private void assemble(final CallRegionContext context) { // run the local assembler, getting back a collection of information on how we should proceed RampUtils.logReads(rpArgs.rampsDebugReads, "BEFORE untrimmedAssemblyResult reads", context.region.getReads()); List forcedPileupAlleles = Collections.emptyList(); // TODO: we currently do not support pileup alleles in RampedHaplotypeCaller, this should be added - final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(context.region, forcedPileupAlleles, hcArgs, readsHeader, samplesList, logger, referenceReader, assemblyEngine, aligner, + final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(context.region, hcArgs, readsHeader, samplesList, logger, referenceReader, assemblyEngine, aligner, !hcArgs.doNotCorrectOverlappingBaseQualities, hcArgs.fbargs, postFilterOnRamp != null); RampUtils.logReads(rpArgs.rampsDebugReads, "AFTER untrimmedAssemblyResult reads", context.region.getReads()); if (postFilterOnRamp != null) { diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReadLikelihoodCalculationEngine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReadLikelihoodCalculationEngine.java index 28e637d147f..f3fd3fa3bf6 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReadLikelihoodCalculationEngine.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReadLikelihoodCalculationEngine.java @@ -8,6 +8,7 @@ import org.broadinstitute.hellbender.utils.genotyper.AlleleLikelihoods; import org.broadinstitute.hellbender.utils.genotyper.SampleList; import org.broadinstitute.hellbender.utils.haplotype.Haplotype; +import org.broadinstitute.hellbender.utils.haplotype.PartiallyDeterminedHaplotype; import org.broadinstitute.hellbender.utils.read.GATKRead; import org.broadinstitute.hellbender.utils.variant.GATKVariantContextUtils; @@ -94,7 +95,7 @@ public AlleleLikelihoods computeReadLikelihoods(final List< * @param expectedErrorRatePerBase amount of uncertainty to tolerate per read-base (in log scale) * @param readDisqualificationScale constant used to scale the dynamic read disqualificaiton threshold */ - default void filterPoorlyModeledEvidence(final AlleleLikelihoods result, final boolean dynamicDisqualification, final double expectedErrorRatePerBase, final double readDisqualificationScale) { + default void filterPoorlyModeledEvidence(final AlleleLikelihoods result, final boolean dynamicDisqualification, final double expectedErrorRatePerBase, final double readDisqualificationScale) { if (dynamicDisqualification) { result.filterPoorlyModeledEvidence(daynamicLog10MinLiklihoodModel(readDisqualificationScale, log10MinTrueLikelihood(expectedErrorRatePerBase, false))); } else { diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReferenceConfidenceModel.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReferenceConfidenceModel.java index ec2eecec4f7..887d0f2b922 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReferenceConfidenceModel.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/ReferenceConfidenceModel.java @@ -840,12 +840,11 @@ public static Haplotype createReferenceHaplotype(final AssemblyRegion activeRegi throw new IllegalStateException("Bad alignment start in createReferenceHaplotype " + alignmentStart); } final Haplotype refHaplotype = new Haplotype(refBases, true); + refHaplotype.setGenomeLocation(activeRegion.getPaddedSpan()); refHaplotype.setAlignmentStartHapwrtRef(alignmentStart); final Cigar c = new Cigar(); c.add(new CigarElement(refHaplotype.getBases().length, CigarOperator.M)); refHaplotype.setCigar(c); return refHaplotype; } - - } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2Engine.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2Engine.java index 8dff2ec509f..77ff1f67d0b 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2Engine.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2Engine.java @@ -2,6 +2,7 @@ import htsjdk.samtools.SAMFileHeader; import htsjdk.samtools.util.Locatable; +import htsjdk.samtools.util.Tuple; import htsjdk.variant.variantcontext.Allele; import htsjdk.variant.variantcontext.Genotype; import htsjdk.variant.variantcontext.VariantContext; @@ -256,28 +257,45 @@ public List callRegion(final AssemblyRegion originalAssemblyRegi .filter(vc -> MTAC.forceCallFiltered || vc.isNotFiltered()).collect(Collectors.toList()); final List forcedPileupAlleles= MTAC.pileupDetectionArgs.usePileupDetection ? - PileupBasedAlleles.getPileupVariantContexts(originalAssemblyRegion.getAlignmentData(), MTAC.pileupDetectionArgs, header) : + PileupBasedAlleles.getPileupVariantContexts(originalAssemblyRegion.getAlignmentData(), MTAC.pileupDetectionArgs, header, MTAC.minBaseQualityScore) : Collections.emptyList(); - final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(originalAssemblyRegion, forcedPileupAlleles, MTAC, header, samplesList, logger, referenceReader, assemblyEngine, aligner, false, MTAC.fbargs, false); + + final AssemblyResultSet untrimmedAssemblyResult = AssemblyBasedCallerUtils.assembleReads(originalAssemblyRegion, MTAC, header, samplesList, logger, referenceReader, assemblyEngine, aligner, false, MTAC.fbargs, false); ReadThreadingAssembler.addAssembledVariantsToEventMapOutput(untrimmedAssemblyResult, assembledEventMapVariants, MTAC.maxMnpDistance, assembledEventMapVcfOutputWriter); final LongHomopolymerHaplotypeCollapsingEngine haplotypeCollapsing = untrimmedAssemblyResult.getHaplotypeCollapsingEngine(); final SortedSet allVariationEvents = untrimmedAssemblyResult.getVariationEvents(MTAC.maxMnpDistance); + // PileupCaller events if we need to apply them + final List pileupAllelesFoundShouldFilter = forcedPileupAlleles.stream() + .filter(v -> PileupBasedAlleles.shouldFilterAssemblyVariant(MTAC.pileupDetectionArgs, v)) + .collect(Collectors.toList()); + final List pileupAllelesPassingFilters = forcedPileupAlleles.stream() + .filter(v -> PileupBasedAlleles.passesFilters(MTAC.pileupDetectionArgs, v)) + .collect(Collectors.toList()); for (final VariantContext given : givenAlleles) { - if (allVariationEvents.stream().noneMatch(vc -> vc.getStart() == given.getStart() && vc.getAlternateAllele(0).basesMatch(given.getAlternateAllele(0)))) { + if (allVariationEvents.stream().noneMatch(vc -> vc.getStart() == given.getStart() && vc.getReference().basesMatch(given.getReference()) && vc.getAlternateAllele(0).basesMatch(given.getAlternateAllele(0)) )) { allVariationEvents.add(given); } } + for (final VariantContext pileupAllele : pileupAllelesPassingFilters) { + if (allVariationEvents.stream().noneMatch(vc -> vc.getStart() == pileupAllele.getStart() && vc.getReference().basesMatch(pileupAllele.getReference()) && vc.getAlternateAllele(0).basesMatch(pileupAllele.getAlternateAllele(0)))) { + allVariationEvents.add(pileupAllele); + } + } final AssemblyRegionTrimmer.Result trimmingResult = trimmer.trim(originalAssemblyRegion, allVariationEvents, referenceContext); if (!trimmingResult.isVariationPresent()) { return emitReferenceConfidence() ? referenceModelForNoVariation(originalAssemblyRegion) : NO_CALLS; } - - final AssemblyResultSet assemblyResult = untrimmedAssemblyResult.trimTo(trimmingResult.getVariantRegion()); + AssemblyResultSet assemblyResult = untrimmedAssemblyResult.trimTo(trimmingResult.getVariantRegion()); AssemblyBasedCallerUtils.addGivenAlleles(givenAlleles, MTAC.maxMnpDistance, aligner, MTAC.getHaplotypeToReferenceSWParameters(), assemblyResult); + // Apply the forced pileup calling alleles if there are any that we must filter + if ((!pileupAllelesFoundShouldFilter.isEmpty() || !pileupAllelesPassingFilters.isEmpty())) { + AssemblyBasedCallerUtils.applyPileupEventsAsForcedAlleles(originalAssemblyRegion, MTAC, aligner, assemblyResult.getReferenceHaplotype(), assemblyResult, pileupAllelesFoundShouldFilter, pileupAllelesPassingFilters, MTAC.pileupDetectionArgs.debugPileupStdout); + } + // we might find out after assembly that the "active" region actually has no variants if( ! assemblyResult.isVariationPresent() ) { return emitReferenceConfidence() ? referenceModelForNoVariation(originalAssemblyRegion) : NO_CALLS; @@ -461,6 +479,9 @@ public ActivityProfileState isActive(final AlignmentContext context, final Refer } final ReadPileup pileup = context.getBasePileup(); + if (MTAC.pileupDetectionArgs.usePileupDetection) { + pileup.forEach(p -> PileupBasedAlleles.addMismatchPercentageToRead(p.getRead(), header, ref)); + } if (pileup.size() >= minCallableDepth) { callableSites.increment(); } diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/realignmentfilter/FilterAlignmentArtifacts.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/realignmentfilter/FilterAlignmentArtifacts.java index 9466f896e40..17f44ee899e 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/realignmentfilter/FilterAlignmentArtifacts.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/realignmentfilter/FilterAlignmentArtifacts.java @@ -5,6 +5,7 @@ import com.google.common.collect.Multisets; import htsjdk.samtools.SAMFileHeader; import htsjdk.samtools.util.Locatable; +import htsjdk.samtools.util.Tuple; import htsjdk.variant.variantcontext.VariantContext; import htsjdk.variant.variantcontext.VariantContextBuilder; import htsjdk.variant.variantcontext.writer.VariantContextWriter; @@ -213,7 +214,7 @@ public void apply(List variantContexts, ReferenceContext referen // TODO: give this tool M2 Assembler args to allow override default M2ArgumentCollection? - final AssemblyResultSet assemblyResult = AssemblyBasedCallerUtils.assembleReads(assemblyRegion, Collections.emptyList(), MTAC, bamHeader, samplesList, logger, referenceReader, assemblyEngine, smithWatermanAligner, false, null, false); + final AssemblyResultSet assemblyResult = AssemblyBasedCallerUtils.assembleReads(assemblyRegion, MTAC, bamHeader, samplesList, logger, referenceReader, assemblyEngine, smithWatermanAligner, false, null, false); final AssemblyRegion regionForGenotyping = assemblyResult.getRegionForGenotyping(); final Map> reads = AssemblyBasedCallerUtils.splitReadsBySample(samplesList, bamHeader, regionForGenotyping.getReads()); diff --git a/src/main/java/org/broadinstitute/hellbender/utils/activityprofile/ActivityProfileState.java b/src/main/java/org/broadinstitute/hellbender/utils/activityprofile/ActivityProfileState.java index eb8dd41536d..78146fee19c 100644 --- a/src/main/java/org/broadinstitute/hellbender/utils/activityprofile/ActivityProfileState.java +++ b/src/main/java/org/broadinstitute/hellbender/utils/activityprofile/ActivityProfileState.java @@ -14,6 +14,8 @@ public final class ActivityProfileState { private double activeProb; private final Type resultState; private final Number resultValue; + // TODO this is used to store the original isActive() prob (before smoothing) fast genotyping likelihood determination score which is used as a heuristic in DRAGEN-GATK for pileup-calling + private double originalActiveProb = 0.0; // When range-checking probabilities, we allow this much tolerance. private static final double PROBABILITY_TOLERANCE = 0.01; @@ -51,6 +53,14 @@ public Number getResultValue() { return resultValue; } + public double getOriginalActiveProb() { + return originalActiveProb; + } + + public void setOriginalActiveProb(double originalActiveProb) { + this.originalActiveProb = originalActiveProb; + } + /** * The type of the value returned by {@link #getResultValue} */ diff --git a/src/main/java/org/broadinstitute/hellbender/utils/haplotype/EventMap.java b/src/main/java/org/broadinstitute/hellbender/utils/haplotype/EventMap.java index 429976e34f6..bbc8bd70412 100644 --- a/src/main/java/org/broadinstitute/hellbender/utils/haplotype/EventMap.java +++ b/src/main/java/org/broadinstitute/hellbender/utils/haplotype/EventMap.java @@ -314,13 +314,19 @@ public static TreeSet buildEventMapsForHaplotypes( final List Utils.validate(vc.getAlleles().size() == 2, () -> "Error Haplotype event map Variant Context has too many alleles "+vc.getAlleles()+" for hapllotype: "+h)); + h.getEventMap().getVariantContexts().forEach(vc -> Utils.validate(vc.getAlleles().size() == 2, () -> "Error Haplotype event map Variant Context has too many alleles " + vc.getAlleles() + " for haplotype: " + h)); - if( debug ) { + if (debug) { logger.info(h.toString()); logger.info("> Cigar = " + h.getCigar()); logger.info(">> Events = " + h.getEventMap()); diff --git a/src/main/java/org/broadinstitute/hellbender/utils/haplotype/Haplotype.java b/src/main/java/org/broadinstitute/hellbender/utils/haplotype/Haplotype.java index b770842f629..627ed58e812 100644 --- a/src/main/java/org/broadinstitute/hellbender/utils/haplotype/Haplotype.java +++ b/src/main/java/org/broadinstitute/hellbender/utils/haplotype/Haplotype.java @@ -18,7 +18,7 @@ import java.util.Arrays; import java.util.Comparator; -public final class Haplotype extends SimpleAllele { +public class Haplotype extends SimpleAllele { private static final long serialVersionUID = 1L; /** @@ -31,7 +31,7 @@ public final class Haplotype extends SimpleAllele { private Locatable genomeLocation = null; private EventMap eventMap = null; private Cigar cigar; - private int alignmentStartHapwrtRef; + private int alignmentStartHapwrtRef; //NOTE: this is the offset to a supposed array of reference bases held in memory and has nothing to do with start positions private double score = Double.NaN; /** @@ -69,7 +69,7 @@ public Haplotype( final byte[] bases ) { * * @param bases a non-null array of bases * @param isRef is this the reference haplotype? - * @param alignmentStartHapwrtRef offset of this haplotype w.r.t. the reference + * @param alignmentStartHapwrtRef offset of this haplotype w.r.t. the reference (NOTE: this is NOT the aligned start, but an offset to a hypothetical reference array) * @param cigar the cigar that maps this haplotype to the reference sequence */ public Haplotype( final byte[] bases, final boolean isRef, final int alignmentStartHapwrtRef, final Cigar cigar) { @@ -78,6 +78,13 @@ public Haplotype( final byte[] bases, final boolean isRef, final int alignmentSt setCigar(cigar); } + public Haplotype( final byte[] bases, final boolean isRef, final Locatable loc, final Cigar cigar ) { + this(bases, isRef); + this.cigar = cigar; + this.genomeLocation = loc; + } + + public Haplotype( final byte[] bases, final Locatable loc ) { this(bases, false); this.genomeLocation = loc; @@ -335,4 +342,7 @@ public void setUniquenessValue(int uniquenessValue) { public void setKmerSize(int kmerSize) { this.kmerSize = kmerSize; } + + // Flag used to control how the haplotype is treated by the hmm and downstream code for the PDHMM. + public boolean isPartiallyDetermined() { return false; } } diff --git a/src/main/java/org/broadinstitute/hellbender/utils/haplotype/PartiallyDeterminedHaplotype.java b/src/main/java/org/broadinstitute/hellbender/utils/haplotype/PartiallyDeterminedHaplotype.java new file mode 100644 index 00000000000..8ea5b1e0bd0 --- /dev/null +++ b/src/main/java/org/broadinstitute/hellbender/utils/haplotype/PartiallyDeterminedHaplotype.java @@ -0,0 +1,227 @@ +package org.broadinstitute.hellbender.utils.haplotype; + +import com.google.common.annotations.VisibleForTesting; +import com.netflix.servo.util.Objects; +import htsjdk.samtools.Cigar; +import htsjdk.variant.variantcontext.Allele; +import htsjdk.variant.variantcontext.VariantContext; +import org.broadinstitute.hellbender.utils.SimpleInterval; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; + +/** + * Class for holding the PartiallyDeterminedHaplotype constructs that are needed for the PDHMM. + * + * The primary function of a "partiallyDeterminedHaplotype" is so that the PDHMM can compress the computation of Haplotype + * score max's that gets marginalized in the genotyper down into a single HMM operation. You can think of each PDHMM haplotype + * as being representative of a single allele in the genotyper (be that Ref or Alt) where every other discovered variant in the + * entire region is "undetermined." An undetermined SNP might mean that either the REF or ALT bases at that site are treated + * as matches within the HMM model. An undetermined INDEL is slightly more complicated, if its an undetermined deletion then + * we expect the haplotype bases to match the reference and the mismatches to be recorded in the jump array. If the + * undetermined event is an Insertion then we "flip" the insertion by adding the inserted bases to the reference haplotype + * and treating it as undetermined for both. + * + * Differences of note from Haplotype: + * - alternateBases array - This is a hap-length array that stores summaries of the undetermined bases. For bases that don't + * have any undetermined behavior the byte should simply be 0. Otherwise the bytes bear a representation + * of the event as a bitset (with the keys for what each bit represents at the top of this class) + * - determinedPosition/alleleBearingVariantContext - Since we construct the PDHaps with only one event "determined" this position + * and variant contexts store exactly WHAT that event is for the haplotype as + * well as what position it counts as for various bookkeping tasks. + * NOTE: these are used for EventMap construction since for PDHaplotypes the + * event map should contain ONLY this event. + * - isDeterminedAlleleRef - This variant simply accounts for whether or not this is a reference determined allele to be + * assigned to reference when genotyping later on. + * - constituentBuiltEvents - Since this object is artifically constructed form a set of constituent events we may as well + * store them here for debugging purposes. + * + * Known issues/limitations: + * - Despite having been assured by Illumina engineers that they do NOT allow undetermined SNPs to be in the middle of + * indels. I have found at least one edge case involving single base deletions competing with snps at the same base where + * DRAGEN 3.7.8 evidently breaks this rule. I'm not convinced this is terribly improtant to FE but it should be noted. + */ +public final class PartiallyDeterminedHaplotype extends Haplotype { + private static final long serialVersionUID = 1L; + + //COMMENTS DIRECTLY FROM DRAGEN CODE: + // This is the array which gives information if the base in the haplotype is + // resolved or not. + // 8-bit field + // 0 0 0 0 0 0 0 0 + // SNP DELETE A C G T N + // If SNP is true, then bits 3-7 are active indicating which bases are also possible + // Bits 1-2 indicate delete states + // 01 - Delete region start + // 10 - Delete region stops + // 11 - Delete has length 1, start and stop position is the same + // All 8 bits 0 indicate either a resolved position or if w + final public static byte SNP = 1; + final public static byte DEL_START = 2; + final public static byte DEL_END = 4; + final public static byte A = 8; + final public static byte C = 16; + final public static byte G = 32; + final public static byte T = 64; + final public static byte N = (byte) 128; + + public byte[] getAlternateBases() { + return alternateBases; + } + + private final byte[] alternateBases; + private final List constituentBuiltEvents; + // NOTE: we must store ALL of the determined events at this site (which is different than the constituent events, we expect the constituent + // events for one of these objects to only be a single element) for the purposes of the overlapping reads PDHMM optimization. + // At Multiallelic sites, we ultimately genotype all of the alleles at once. If we aren't careful, reads that only overlap some + // alleles at a site will end up with incorrect/undetermined PDHMM scores for a subset of alleles in the genotyper which can + // lead to false positives/poorly called sites. + private List allDeterminedEventsAtThisSite; + + //TODO Eventually these will have to be refactored to support multiple determined alleles per PDHaplotype + private final VariantContext alleleBearingVariantContext; // NOTE this must be in both of the previous lists + private final long determinedPosition; + private final boolean isDeterminedAlleleRef; + + private SimpleInterval cachedExtent; + + /** + * Compares two haplotypes first by their lengths and then by lexicographic order of their bases. + */ + public static final Comparator SIZE_AND_BASE_ORDER = + Comparator.comparingInt((Haplotype hap) -> hap.getBases().length) + .thenComparing(Allele::getBaseString); + + /** + * @param base base (reference) haplotype used to construct the PDHaplotype + * @param isRefAllele is the determined allele reference or alt + * @param pdBytes array of bytes indicating what bases are skips for the pdhmm + * @param constituentEvents events (both determined and undetermined) covered by this haplotype, should follow the rules for PD variants + * @param eventWithVariant event from @param constituentEvents that is determined for this pd haplotype + * @param cigar haplotype cigar agianst the reference + * @param determinedPosition position (wrt the reference contig) that the haplotype should be considered determined //TODO this will be refactored to be a range of events in JointDetection + * @param getAlignmentStartHapwrtRef alignment startHapwrtRef from baseHaplotype corresponding to the in-memory storage of reference bases (must be set for trimming/clipping ops to work) + */ + public PartiallyDeterminedHaplotype(final Haplotype base, boolean isRefAllele, byte[] pdBytes, List constituentEvents, + VariantContext eventWithVariant, Cigar cigar, long determinedPosition, int getAlignmentStartHapwrtRef) { + super(base.getBases(), false, base.getAlignmentStartHapwrtRef(), cigar); + this.setGenomeLocation(base.getGenomeLocation()); + this.alternateBases = pdBytes; + this.constituentBuiltEvents = constituentEvents; + this.alleleBearingVariantContext = eventWithVariant; + this.allDeterminedEventsAtThisSite = Collections.singletonList(eventWithVariant); + this.determinedPosition = determinedPosition; + this.isDeterminedAlleleRef = isRefAllele; + setAlignmentStartHapwrtRef(getAlignmentStartHapwrtRef); + } + + @Override + public byte[] getDisplayBases() { + byte[] bytes = getBases().clone(); + for (int i = 0; i < bytes.length; i++) { + if ((alternateBases[i] & ~7) != 0) { // Change the display byte if we have a partially determined SNP underneath it + bytes[i] = 'P'; + } + } + return bytes; + } + + @Override + public String toString() { + String output = "HapLen:"+length() +", "+new String(getDisplayBases()); + output = output + "\nUnresolved Bases["+alternateBases.length+"] "+Arrays.toString(alternateBases); + return output + "\n"+getCigar().toString()+" "+ constituentBuiltEvents.stream() + .map(v ->(v==this.alleleBearingVariantContext ?"*":"")+getDRAGENDebugVariantContextString((int)getStartPosition()).apply(v) ) + .collect(Collectors.joining("->")); + } + + /** + * A printout of the PD haplotype meant to be readable and easily comparable to the DRAGEN debug mode output for the same haplotype. + */ + public static Function getDRAGENDebugVariantContextString(final int offset) { + return v -> "(" + Integer.toString(v.getStart() - offset + (v.isSimpleDeletion()? 1 : 0))+ (v.isSimpleInsertion()?".5":"") + ",Rlen=" + v.getLengthOnReference()+"," + v.getAlternateAlleles() + ")"; + } + + @Override + public boolean equals( final Object h ) { + return h instanceof PartiallyDeterminedHaplotype + && getUniquenessValue() == ((Haplotype) h).getUniquenessValue() + && isReference() == ((Haplotype) h).isReference() + && determinedPosition == ((PartiallyDeterminedHaplotype) h).determinedPosition // (even if the basees exactly match we still want to be cautious) + && Arrays.equals(getBases(), ((Haplotype) h).getBases()) + && Arrays.equals(alternateBases, ((PartiallyDeterminedHaplotype) h).alternateBases); + } + + @Override + public int hashCode() { + return Objects.hash(Arrays.hashCode(getBases()),Arrays.hashCode(alternateBases)); + } + + public List getDeterminedAlleles() { + return isDeterminedAlleleRef ? Collections.emptyList() : Collections.singletonList(alleleBearingVariantContext); + } + + public void setAllDeterminedEventsAtThisSite(List allDeterminedEventsAtThisSite) { + this.allDeterminedEventsAtThisSite = allDeterminedEventsAtThisSite; + cachedExtent = null; + } + + //NOTE: we never want the genotyper to handle reads that were not HMM scored, caching this extent helps keep us safe from messy sites + public SimpleInterval getMaximumExtentOfSiteDeterminedAlleles() { + if (cachedExtent == null) { + cachedExtent = new SimpleInterval(alleleBearingVariantContext); + for( VariantContext variantContext : allDeterminedEventsAtThisSite) { + cachedExtent = cachedExtent.mergeWithContiguous(variantContext); + } + } + return cachedExtent; + } + + public long getDeterminedPosition() { + return determinedPosition; + } + + + /** + * A helper method for computing what the alternative bases array should look like for a particular set of alleles. + */ + @VisibleForTesting + public static byte[] getPDBytesForHaplotypes(final Allele refAllele, final Allele altAllele) { + // Asserting we are either indel OR SNP + byte[] output = new byte[altAllele.length() == refAllele.length() ? refAllele.length() : refAllele.length()-1 ]; + // SNP case + if (altAllele.length() == refAllele.length()){ + output[0] += SNP; + switch (altAllele.getBases()[0]) { + case 'A': + output[0] += A; + break; + case 'C': + output[0] += C; + break; + case 'T': + output[0] += T; + break; + case 'G': + output[0] += G; + break; + default: + throw new RuntimeException("Found unexpected base in alt alleles"); + } + + // DEL case + } else { + output[0] += DEL_START; + output[output.length - 1] += DEL_END; //TODO guardrail this + } + return output; + } + + @Override + public boolean isPartiallyDetermined() { return true; } + +} diff --git a/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/LoglessPDPairHMM.java b/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/LoglessPDPairHMM.java new file mode 100644 index 00000000000..ba9b880d2dc --- /dev/null +++ b/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/LoglessPDPairHMM.java @@ -0,0 +1,227 @@ +package org.broadinstitute.hellbender.utils.pairhmm; + +import org.broadinstitute.hellbender.utils.QualityUtils; +import org.broadinstitute.hellbender.utils.haplotype.PartiallyDeterminedHaplotype; + +import java.util.Arrays; + +import static org.broadinstitute.hellbender.utils.pairhmm.PairHMMModel.*; + +public class LoglessPDPairHMM extends N2MemoryPDPairHMM { + static final double INITIAL_CONDITION = Math.pow(2, 1020); + static final double INITIAL_CONDITION_LOG10 = Math.log10(INITIAL_CONDITION); + static final int OFF = 1; + + // we divide e by 3 because the observed base could have come from any of the non-observed alleles + static final double TRISTATE_CORRECTION = 3.0; + + //Branch Stat Arrays + protected double[][] branchMatchMatrix = null; + protected double[][] branchInsertionMatrix = null; + protected double[][] branchDeletionMatrix = null; + + enum HMMState { + // The regular state + NORMAL, + + // Idicating that we must be copying the array elements to the right + INSIDE_DEL, + + // Indicating that we must handle the special case for merging events after the del + AFTER_DEL, + } + + public double subComputeReadLikelihoodGivenHaplotypeLog10( final byte[] haplotypeBases, + final byte[] haplotypePDBases, + final byte[] readBases, + final byte[] readQuals, + final byte[] insertionGOP, + final byte[] deletionGOP, + final byte[] overallGCP, + final int hapStartIndex, + final boolean recacheReadValues, + final int nextHapStartIndex) { + + if (previousHaplotypeBases == null || previousHaplotypeBases.length != haplotypeBases.length) { + final double initialValue = INITIAL_CONDITION / haplotypeBases.length; + // set the initial value (free deletions in the beginning) for the first row in the deletion matrix + for( int j = 0; j < paddedHaplotypeLength; j++ ) { + deletionMatrix[0][j] = initialValue; + } + } + + if ( ! constantsAreInitialized || recacheReadValues ) { + initializeProbabilities(transition, insertionGOP, deletionGOP, overallGCP); + + // note that we initialized the constants + constantsAreInitialized = true; + } + + initializePriors(haplotypeBases, haplotypePDBases, readBases, readQuals, hapStartIndex); + + HMMState currentState = HMMState.NORMAL; + for (int i = 1; i < paddedReadLength; i++) { + for (int j = hapStartIndex+1; j < paddedHaplotypeLength; j++) { + switch (currentState) { + case NORMAL: + // Pre-emptively copy over from the left + branchMatchMatrix[i][j] = matchMatrix[i][j - 1]; + branchDeletionMatrix[i][j] = deletionMatrix[i][j - 1]; + branchInsertionMatrix[i][j] = insertionMatrix[i][j - 1]; + + //Inlined the code from updateCell - helps JIT to detect hotspots and produce good native code + matchMatrix[i][j] = prior[i][j] * (matchMatrix[i - 1][j - 1] * transition[i][matchToMatch] + + insertionMatrix[i - 1][j - 1] * transition[i][indelToMatch] + + deletionMatrix[i - 1][j - 1] * transition[i][indelToMatch]); + deletionMatrix[i][j] = matchMatrix[i][j - 1] * transition[i][matchToDeletion] + deletionMatrix[i][j - 1] * transition[i][deletionToDeletion]; + + // Special case since we MIGHT be at the deletion end and have to be handling jump states from above + if ((haplotypePDBases[j-OFF] & PartiallyDeterminedHaplotype.DEL_END) == PartiallyDeterminedHaplotype.DEL_END) { + insertionMatrix[i][j] = Math.max(branchMatchMatrix[i - 1][j], matchMatrix[i - 1][j]) * transition[i][matchToInsertion] + + Math.max(branchInsertionMatrix[i - 1][j], insertionMatrix[i - 1][j]) * transition[i][insertionToInsertion]; + } else { + insertionMatrix[i][j] = matchMatrix[i - 1][j] * transition[i][matchToInsertion] + insertionMatrix[i - 1][j] * transition[i][insertionToInsertion]; + } + break; + + case INSIDE_DEL: + // If we are in a deletion copy from the left + branchMatchMatrix[i][j] = branchMatchMatrix[i][j - 1]; + branchDeletionMatrix[i][j] = branchDeletionMatrix[i][j - 1]; + branchInsertionMatrix[i][j] = branchInsertionMatrix[i][j - 1]; + + + //Inlined the code from updateCell - helps JIT to detect hotspots and produce good native code + matchMatrix[i][j] = prior[i][j] * (matchMatrix[i - 1][j - 1] * transition[i][matchToMatch] + + insertionMatrix[i - 1][j - 1] * transition[i][indelToMatch] + + deletionMatrix[i - 1][j - 1] * transition[i][indelToMatch]); + deletionMatrix[i][j] = matchMatrix[i][j - 1] * transition[i][matchToDeletion] + deletionMatrix[i][j - 1] * transition[i][deletionToDeletion]; + + // Special case since we MIGHT be at the deletion end and have to be handling jump states from above + // TODO these indexes should probably be -1 + if ((haplotypePDBases[j-OFF] & PartiallyDeterminedHaplotype.DEL_END) == PartiallyDeterminedHaplotype.DEL_END) { + insertionMatrix[i][j] = Math.max(branchMatchMatrix[i - 1][j], matchMatrix[i - 1][j]) * transition[i][matchToInsertion] + + Math.max(branchInsertionMatrix[i - 1][j], insertionMatrix[i - 1][j]) * transition[i][insertionToInsertion]; + } else { + insertionMatrix[i][j] = matchMatrix[i - 1][j] * transition[i][matchToInsertion] + insertionMatrix[i - 1][j] * transition[i][insertionToInsertion]; + } + break; + + case AFTER_DEL: + // Pre-emptively copy over from the left + branchMatchMatrix[i][j] = Math.max(branchMatchMatrix[i][j - 1], matchMatrix[i][j - 1]); + branchDeletionMatrix[i][j] = Math.max(branchDeletionMatrix[i][j - 1], deletionMatrix[i][j - 1]); + branchInsertionMatrix[i][j] = Math.max(branchInsertionMatrix[i][j - 1], insertionMatrix[i][j - 1]); + + //Inlined the code from updateCell - helps JIT to detect hotspots and produce good native code + matchMatrix[i][j] = prior[i][j] * (Math.max(branchMatchMatrix[i - 1][j - 1], matchMatrix[i - 1][j - 1]) * transition[i][matchToMatch] + + Math.max(branchInsertionMatrix[i - 1][j - 1], insertionMatrix[i - 1][j - 1]) * transition[i][indelToMatch] + + Math.max(branchDeletionMatrix[i - 1][j - 1], deletionMatrix[i - 1][j - 1]) * transition[i][indelToMatch]); + deletionMatrix[i][j] = Math.max(branchMatchMatrix[i][j - 1], matchMatrix[i][j - 1]) * transition[i][matchToDeletion] + + Math.max(branchDeletionMatrix[i][j - 1], deletionMatrix[i][j - 1]) * transition[i][deletionToDeletion]; + + // Special case since we MIGHT be at the deletion end and have to be handling jump states from above + if ((haplotypePDBases[j-OFF] & PartiallyDeterminedHaplotype.DEL_END) == PartiallyDeterminedHaplotype.DEL_END) { + insertionMatrix[i][j] = Math.max(branchMatchMatrix[i - 1][j], matchMatrix[i - 1][j]) * transition[i][matchToInsertion] + + Math.max(branchInsertionMatrix[i - 1][j], insertionMatrix[i - 1][j]) * transition[i][insertionToInsertion]; + } else { + insertionMatrix[i][j] = matchMatrix[i - 1][j] * transition[i][matchToInsertion] + insertionMatrix[i - 1][j] * transition[i][insertionToInsertion]; + } + currentState = HMMState.NORMAL; + break; + } + // If we are at a deletion start base, start copying the branch states + if ((haplotypePDBases[j-1] & PartiallyDeterminedHaplotype.DEL_START) == PartiallyDeterminedHaplotype.DEL_START) { + currentState = HMMState.INSIDE_DEL; + } + // Being after a deltion overrides being inside a deletion by virtue of the fact that we allow single element deletions + if ((haplotypePDBases[j-1] & PartiallyDeterminedHaplotype.DEL_END) == PartiallyDeterminedHaplotype.DEL_END) { + currentState = HMMState.AFTER_DEL; + } + } + } + + // final log probability is the log10 sum of the last element in the Match and Insertion state arrays + // this way we ignore all paths that ended in deletions! (huge) + // but we have to sum all the paths ending in the M and I matrices, because they're no longer extended. + final int endI = paddedReadLength - 1; + double finalSumProbabilities = 0.0; + for (int j = 1; j < paddedHaplotypeLength; j++) { + finalSumProbabilities += matchMatrix[endI][j] + insertionMatrix[endI][j]; + } + return Math.log10(finalSumProbabilities) - INITIAL_CONDITION_LOG10; + } + + /** + * {@inheritDoc} + */ + @Override + public void initialize(final int readMaxLength, final int haplotypeMaxLength ) { + super.initialize(readMaxLength, haplotypeMaxLength); + + branchMatchMatrix = new double[paddedMaxReadLength][paddedMaxHaplotypeLength]; + branchInsertionMatrix = new double[paddedMaxReadLength][paddedMaxHaplotypeLength]; + branchDeletionMatrix = new double[paddedMaxReadLength][paddedMaxHaplotypeLength]; + } + + + /** + * Initializes the matrix that holds all the constants related to the editing + * distance between the read and the haplotype. + * + * @param haplotypeBases the bases of the haplotype + * @param readBases the bases of the read + * @param readQuals the base quality scores of the read + * @param startIndex where to start updating the distanceMatrix (in case this read is similar to the previous read) + */ + void initializePriors(final byte[] haplotypeBases, final byte[] haplotypePDBases, final byte[] readBases, final byte[] readQuals, final int startIndex) { + + // initialize the prior matrix for all combinations of read x haplotype bases + // Abusing the fact that java initializes arrays with 0.0, so no need to fill in rows and columns below 2. + + for (int i = 0; i < readBases.length; i++) { + final byte x = readBases[i]; + final byte qual = readQuals[i]; + for (int j = startIndex; j < haplotypeBases.length; j++) { + final byte y = haplotypeBases[j]; + final byte hapPDBase = haplotypePDBases[j]; + prior[i+1][j+1] = ( x == y || x == (byte) 'N' || y == (byte) 'N' || isBasePDMatching(x,hapPDBase) ? + QualityUtils.qualToProb(qual) : (QualityUtils.qualToErrorProb(qual) / (doNotUseTristateCorrection ? 1.0 : TRISTATE_CORRECTION)) ); + } + } + } + //Helper method for handling if a pd base counts as matching + static boolean isBasePDMatching(byte x, byte hapPDBases) { + if ((hapPDBases & PartiallyDeterminedHaplotype.SNP) != 0) { + switch (x) { + case 'A': + case 'a': + return ((hapPDBases & PartiallyDeterminedHaplotype.A) != 0); + case 'C': + case 'c': + return ((hapPDBases & PartiallyDeterminedHaplotype.C) != 0); + case 'T': + case 't': + return ((hapPDBases & PartiallyDeterminedHaplotype.T) != 0); + case 'G': + case 'g': + return ((hapPDBases & PartiallyDeterminedHaplotype.G) != 0); + default: + throw new RuntimeException("Found unexpected base in alt alleles"); + } + } + return false; + } + + + /** + * Initializes the matrix that holds all the constants related to quality scores. + * + * @param insertionGOP insertion quality scores of the read + * @param deletionGOP deletion quality scores of the read + * @param overallGCP overall gap continuation penalty + */ + static void initializeProbabilities(final double[][] transition, final byte[] insertionGOP, final byte[] deletionGOP, final byte[] overallGCP) { + PairHMMModel.qualToTransProbs(transition,insertionGOP,deletionGOP,overallGCP); + } +} diff --git a/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/N2MemoryPDPairHMM.java b/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/N2MemoryPDPairHMM.java new file mode 100644 index 00000000000..5ae92c00dce --- /dev/null +++ b/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/N2MemoryPDPairHMM.java @@ -0,0 +1,65 @@ +package org.broadinstitute.hellbender.utils.pairhmm; + +/** + * Superclass for PairHMM that want to use a full read x haplotype matrix for their match, insertion, and deletion matrix + */ +abstract class N2MemoryPDPairHMM extends PDPairHMM { + protected double[][] transition = null; // The transition probabilities cache + protected double[][] prior = null; // The prior probabilities cache + protected double[][] matchMatrix = null; + protected double[][] insertionMatrix = null; + protected double[][] deletionMatrix = null; + + @Override + public void doNotUseTristateCorrection() { + doNotUseTristateCorrection = true; + } + + /** + * Initialize this PairHMM, making it suitable to run against a read and haplotype with given lengths + * + * Note: Do not worry about padding, just provide the true max length of the read and haplotype. The HMM will take care of the padding. + * + * @param haplotypeMaxLength the max length of haplotypes we want to use with this PairHMM + * @param readMaxLength the max length of reads we want to use with this PairHMM + */ + @Override + public void initialize( final int readMaxLength, final int haplotypeMaxLength ) { + super.initialize(readMaxLength, haplotypeMaxLength); + + matchMatrix = new double[paddedMaxReadLength][paddedMaxHaplotypeLength]; + insertionMatrix = new double[paddedMaxReadLength][paddedMaxHaplotypeLength]; + deletionMatrix = new double[paddedMaxReadLength][paddedMaxHaplotypeLength]; + + transition = PairHMMModel.createTransitionMatrix(maxReadLength); + prior = new double[paddedMaxReadLength][paddedMaxHaplotypeLength]; + } + + /** + * Print out the core hmm matrices for debugging + */ + protected void dumpMatrices() { + dumpMatrix("matchMetricArray", matchMatrix); + dumpMatrix("insertionMatrix", insertionMatrix); + dumpMatrix("deletionMatrix", deletionMatrix); + } + + /** + * Print out in a human readable form the matrix for debugging + * @param name the name of this matrix + * @param matrix the matrix of values + */ + private void dumpMatrix(final String name, final double[][] matrix) { + System.out.printf("%s%n", name); + for ( int i = 0; i < matrix.length; i++) { + System.out.printf("\t%s[%d]", name, i); + for ( int j = 0; j < matrix[i].length; j++ ) { + if ( Double.isInfinite(matrix[i][j]) ) + System.out.printf(" %15s", String.format("%f", matrix[i][j])); + else + System.out.printf(" % 15.5e", matrix[i][j]); + } + System.out.println(); + } + } +} diff --git a/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMM.java b/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMM.java new file mode 100644 index 00000000000..ebb0e7ff192 --- /dev/null +++ b/src/main/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMM.java @@ -0,0 +1,374 @@ +package org.broadinstitute.hellbender.utils.pairhmm; + +import com.google.common.annotations.VisibleForTesting; +import htsjdk.samtools.SAMUtils; +import htsjdk.samtools.util.Locatable; +import htsjdk.variant.variantcontext.Allele; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.broadinstitute.gatk.nativebindings.pairhmm.PairHMMNativeArguments; +import org.broadinstitute.hellbender.exceptions.GATKException; +import org.broadinstitute.hellbender.exceptions.UserException; +import org.broadinstitute.hellbender.tools.walkers.haplotypecaller.PDPairHMMLikelihoodCalculationEngine; +import org.broadinstitute.hellbender.utils.MathUtils; +import org.broadinstitute.hellbender.utils.SimpleInterval; +import org.broadinstitute.hellbender.utils.Utils; +import org.broadinstitute.hellbender.utils.genotyper.LikelihoodMatrix; +import org.broadinstitute.hellbender.utils.haplotype.Haplotype; +import org.broadinstitute.hellbender.utils.haplotype.PartiallyDeterminedHaplotype; +import org.broadinstitute.hellbender.utils.read.GATKRead; + +import java.io.Closeable; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +/** + * Class for performing the Paritally Determined pair HMM for global alignment. + * + * NOTE: This is the PDPairHMM which is a modification on the standard PDHMM in that it allows for "undetermined" bases + * across which read mismatches are not penalized so long as they have one of the encoded PD alleles present. This + * class takes different Allele inputs as the standard HMM hierarchy. + */ +public abstract class PDPairHMM implements Closeable{ + protected static final Logger logger = LogManager.getLogger(PDPairHMM.class); + + protected boolean constantsAreInitialized = false; + + protected byte[] previousHaplotypeBases; + protected int hapStartIndex; + + protected OutputStreamWriter debugOutputStream; + + public enum Implementation { + /* Optimized version of the PairHMM which caches per-read computations and operations in real space to avoid costly sums of log10'ed likelihoods */ + LOGLESS_CACHING(args -> { + final PDPairHMM hmm = new LoglessPDPairHMM(); + logger.info("Using the non-hardware-accelerated Java LOGLESS_CACHING PairHMM implementation"); + return hmm; + }), + FASTEST_AVAILABLE(args -> { + return new LoglessPDPairHMM(); + }); + + private final Function makeHmm; + + private Implementation(final Function makeHmm){ + this.makeHmm = makeHmm; + } + + public PDPairHMM makeNewHMM(PairHMMNativeArguments args) { + return makeHmm.apply(args); + } + } + + protected int maxHaplotypeLength, maxReadLength; + protected int paddedMaxReadLength, paddedMaxHaplotypeLength; + protected int paddedReadLength, paddedHaplotypeLength; + protected boolean initialized = false; + + // only used for debugging purposes + protected boolean doNotUseTristateCorrection = false; + protected void doNotUseTristateCorrection() { doNotUseTristateCorrection = true; } + + //debug array + protected double[] mLogLikelihoodArray; + + //profiling information + protected static Boolean doProfiling = true; + protected static long pairHMMComputeTime = 0; + protected long threadLocalPairHMMComputeTimeDiff = 0; + protected long startTime = 0; + + /** + * Initialize this PairHMM, making it suitable to run against a read and haplotype with given lengths + * + * Note: Do not worry about padding, just provide the true max length of the read and haplotype. The HMM will take care of the padding. + * + * @param haplotypeMaxLength the max length of haplotypes we want to use with this PairHMM + * @param readMaxLength the max length of reads we want to use with this PairHMM + * @throws IllegalArgumentException if haplotypeMaxLength is less than or equal to zero + */ + public void initialize( final int readMaxLength, final int haplotypeMaxLength ) throws IllegalArgumentException { + Utils.validateArg(haplotypeMaxLength > 0, () -> "haplotypeMaxLength must be > 0 but got " + haplotypeMaxLength); + + maxHaplotypeLength = haplotypeMaxLength; + maxReadLength = readMaxLength; + + // M, X, and Y arrays are of size read and haplotype + 1 because of an extra column for initial conditions and + 1 to consider the final base in a non-global alignment + paddedMaxReadLength = readMaxLength + 1; + paddedMaxHaplotypeLength = haplotypeMaxLength + 1; + + previousHaplotypeBases = null; + + constantsAreInitialized = false; + initialized = true; + } + + /** + * Initialize this PairHMM, making it suitable to run against a read and haplotype with given lengths + * This function is used by the JNI implementations to transfer all data once to the native code + * @param haplotypes the list of haplotypes + * @param perSampleReadList map from sample name to list of reads + * @param haplotypeMaxLength the max length of haplotypes we want to use with this PairHMM + * @param readMaxLength the max length of reads we want to use with this PairHMM + */ + public void initialize( final List haplotypes, final Map> perSampleReadList, final int readMaxLength, final int haplotypeMaxLength ) { + initialize(readMaxLength, haplotypeMaxLength); + } + + private static int findMaxAlleleLength(final List alleles) { + int max = 0; + for (final Allele allele : alleles) { + final int alleleLength = allele.length(); + if (max < alleleLength) { + max = alleleLength; + } + } + return max; + } + + static int findMaxReadLength(final List reads) { + int listMaxReadLength = 0; + for(final GATKRead read : reads){ + final int readLength = read.getLength(); + if( readLength > listMaxReadLength ) { + listMaxReadLength = readLength; + } + } + return listMaxReadLength; + } + + /** + * Given a list of reads and haplotypes, for every read compute the total probability of said read arising from + * each haplotype given base substitution, insertion, and deletion probabilities. + * + * @param processedReads reads to analyze instead of the ones present in the destination read-likelihoods. + * @param logLikelihoods where to store the log likelihoods where position [a][r] is reserved for the log likelihood of {@code reads[r]} + * conditional to {@code alleles[a]}. + */ + public void computeLog10Likelihoods(final LikelihoodMatrix logLikelihoods, + final List processedReads, + final PairHMMInputScoreImputator inputScoreImputator, + final int rangeForReadOverlapToDeterminedBases) { + if (processedReads.isEmpty()) { + return; + } + if(doProfiling) { + startTime = System.nanoTime(); + } + // (re)initialize the pairHMM only if necessary + final int readMaxLength = findMaxReadLength(processedReads); + final int haplotypeMaxLength = findMaxAlleleLength(logLikelihoods.alleles()); + if (!initialized || readMaxLength > maxReadLength || haplotypeMaxLength > maxHaplotypeLength) { + initialize(readMaxLength, haplotypeMaxLength); + } + + final int readCount = processedReads.size(); + final List alleles = logLikelihoods.alleles(); + final int alleleCount = alleles.size(); + mLogLikelihoodArray = new double[readCount * alleleCount]; + int idx = 0; + int readIndex = 0; + for(final GATKRead read : processedReads){ + final PairHMMInputScoreImputation inputScoreImputation = inputScoreImputator.impute(read); + final byte[] readBases = read.getBases(); + + final byte[] readQuals = read.getBaseQualities(); + final byte[] readInsQuals = inputScoreImputation.insOpenPenalties(); + final byte[] readDelQuals = inputScoreImputation.delOpenPenalties(); + final byte[] overallGCP = inputScoreImputation.gapContinuationPenalties(); + + // peek at the next haplotype in the list (necessary to get nextHaplotypeBases, which is required for caching in the array implementation) + final boolean isFirstHaplotype = true; + for (int a = 0; a < alleleCount; a++) { + final PartiallyDeterminedHaplotype allele = alleles.get(a); + final double lk; + final byte[] alleleBases = allele.getBases(); + final byte[] nextAlleleBases = a == alleles.size() - 1 ? null : alleles.get(a + 1).getBases(); + final byte[] nextAllelePDBases = a == alleles.size() - 1 ? null : alleles.get(a + 1).getBases(); + // if we aren't apply the optimization (range == -1) or if the read overlaps the determined region for calling: + if (rangeForReadOverlapToDeterminedBases < 0 || allele.getMaximumExtentOfSiteDeterminedAlleles() + .overlapsWithMargin((Locatable) read.getTransientAttribute(PDPairHMMLikelihoodCalculationEngine.UNCLIPPED_ORIGINAL_SPAN_ATTR), rangeForReadOverlapToDeterminedBases + 1)) { // the +1 here is us erring on the side of caution + lk = computeReadLikelihoodGivenHaplotypeLog10(alleleBases, allele.getAlternateBases(), + readBases, readQuals, readInsQuals, readDelQuals, overallGCP, isFirstHaplotype, nextAlleleBases, nextAllelePDBases); + // Otherwise we record that the likelihood array is bogus here for later validation and set it to -infinity + } else { + lk = Double.NEGATIVE_INFINITY; + } + logLikelihoods.set(a, readIndex, lk); + mLogLikelihoodArray[idx++] = lk; + writeToResultsFileIfApplicable(readBases, readQuals, readInsQuals, readDelQuals, overallGCP, alleleBases, allele.getAlternateBases(), lk); + } + readIndex++; + } + if(doProfiling) { + threadLocalPairHMMComputeTimeDiff = (System.nanoTime() - startTime); + { + pairHMMComputeTime += threadLocalPairHMMComputeTimeDiff; + } + } + } + + + /** + * Compute the total probability of read arising from haplotypeBases given base substitution, insertion, and deletion + * probabilities. + * + * Note on using hapStartIndex. This allows you to compute the exact true likelihood of a full haplotypes + * given a read, assuming that the previous calculation read over a full haplotype, recaching the read values, + * starting only at the place where the new haplotype bases and the previous haplotype bases differ. This + * index is 0-based, and can be computed with findFirstPositionWhereHaplotypesDiffer given the two haplotypes. + * Note that this assumes that the read and all associated quals values are the same. + * + * @param haplotypeBases the full sequence (in standard SAM encoding) of the haplotype, must be >= than read bases in length + * @param readBases the bases (in standard encoding) of the read, must be <= haplotype bases in length + * @param readQuals the phred-scaled per base substitution quality scores of read. Must be the same length as readBases + * @param insertionGOP the phred-scaled per base insertion quality scores of read. Must be the same length as readBases + * @param deletionGOP the phred-scaled per base deletion quality scores of read. Must be the same length as readBases + * @param overallGCP the phred-scaled gap continuation penalties scores of read. Must be the same length as readBases + * @param recacheReadValues if false, we don't recalculate any cached results, assuming that readBases and its associated + * parameters are the same, and only the haplotype bases are changing underneath us + * @throws IllegalStateException if did not call initialize() beforehand + * @throws IllegalArgumentException haplotypeBases is null or greater than maxHaplotypeLength + * @throws IllegalArgumentException readBases is null or greater than maxReadLength + * @throws IllegalArgumentException readBases, readQuals, insertionGOP, deletionGOP and overallGCP are not the same size + * @return the log10 probability of read coming from the haplotype under the provided error model + */ + @VisibleForTesting + double computeReadLikelihoodGivenHaplotypeLog10( final byte[] haplotypeBases, + final byte[] haplotypePDBases, + final byte[] readBases, + final byte[] readQuals, + final byte[] insertionGOP, + final byte[] deletionGOP, + final byte[] overallGCP, + final boolean recacheReadValues, + final byte[] nextHaplotypeBases, + final byte[] nextHaplotypePDBases) throws IllegalStateException, IllegalArgumentException { + + Utils.validate(initialized, "Must call initialize before calling computeReadLikelihoodGivenHaplotypeLog10"); + Utils.nonNull(haplotypeBases, "haplotypeBases may not be null"); + Utils.validateArg( haplotypeBases.length <= maxHaplotypeLength, () -> "Haplotype bases is too long, got " + haplotypeBases.length + " but max is " + maxHaplotypeLength); + Utils.nonNull(readBases); + Utils.validateArg( readBases.length <= maxReadLength, () -> "readBases is too long, got " + readBases.length + " but max is " + maxReadLength); + Utils.validateArg(readQuals.length == readBases.length, () -> "Read bases and read quals aren't the same size: " + readBases.length + " vs " + readQuals.length); + Utils.validateArg( insertionGOP.length == readBases.length, () -> "Read bases and read insertion quals aren't the same size: " + readBases.length + " vs " + insertionGOP.length); + Utils.validateArg( deletionGOP.length == readBases.length, () -> "Read bases and read deletion quals aren't the same size: " + readBases.length + " vs " + deletionGOP.length); + Utils.validateArg( overallGCP.length == readBases.length, () -> "Read bases and overall GCP aren't the same size: " + readBases.length + " vs " + overallGCP.length); + + paddedReadLength = readBases.length + 1; + paddedHaplotypeLength = haplotypeBases.length + 1; + + hapStartIndex = (recacheReadValues) ? 0 : hapStartIndex; + + // Pre-compute the difference between the current haplotype and the next one to be run + // Looking ahead is necessary for the ArrayLoglessPairHMM implementation + //TODO this optimization is very dangerous if we have undetermined haps that could have the same bases but mean different things + //final int nextHapStartIndex = (nextHaplotypeBases == null || haplotypeBases.length != nextHaplotypeBases.length) ? 0 : findFirstPositionWhereHaplotypesDiffer(haplotypeBases, haplotypePDBases, nextHaplotypeBases, nextHaplotypePDBases); + int nextHapStartIndex = 0; //disable the optimization for now until its confirmed to be correct + final double result = subComputeReadLikelihoodGivenHaplotypeLog10(haplotypeBases, haplotypePDBases, readBases, readQuals, insertionGOP, deletionGOP, overallGCP, hapStartIndex, recacheReadValues, nextHapStartIndex); + + Utils.validate(result <= 0.0, () -> "PairHMM Log Probability cannot be greater than 0: " + String.format("haplotype: %s, read: %s, result: %f, PairHMM: %s", new String(haplotypeBases), new String(readBases), result, this.getClass().getSimpleName())); + Utils.validate(MathUtils.isValidLog10Probability(result), () -> "Invalid Log Probability: " + result); + + // Warning: This assumes no downstream modification of the haplotype bases (saves us from copying the array). It is okay for the haplotype caller. + previousHaplotypeBases = haplotypeBases; + + // For the next iteration, the hapStartIndex for the next haploytpe becomes the index for the current haplotype + // The array implementation has to look ahead to the next haplotype to store caching info. It cannot do this if nextHapStart is before hapStart + hapStartIndex = (nextHapStartIndex < hapStartIndex) ? 0: nextHapStartIndex; + + return result; + } + + /** + * To be implemented by subclasses to do calculation for #computeReadLikelihoodGivenHaplotypeLog10 + */ + protected abstract double subComputeReadLikelihoodGivenHaplotypeLog10( final byte[] haplotypeBases, + final byte[] haplotypePDBases, + final byte[] readBases, + final byte[] readQuals, + final byte[] insertionGOP, + final byte[] deletionGOP, + final byte[] overallGCP, + final int hapStartIndex, + final boolean recacheReadValues, + final int nextHapStartIndex); + + /** + * Compute the first position at which two haplotypes differ + * + * If the haplotypes are exact copies of each other, returns the min length of the two haplotypes. + * + * @param haplotype1 the first haplotype1 + * @param haplotype2 the second haplotype1 + * @throws IllegalArgumentException if haplotype1 or haplotype2 are null or zero length + * @return the index of the first position in haplotype1 and haplotype2 where the byte isn't the same + */ + public static int findFirstPositionWhereHaplotypesDiffer(final byte[] haplotype1, final byte[] pd1, final byte[] haplotype2, final byte[] pd2) throws IllegalArgumentException { + if ( haplotype1 == null || haplotype1.length == 0 ) throw new IllegalArgumentException("Haplotype1 is bad " + Arrays.toString(haplotype1)); + if ( haplotype2 == null || haplotype2.length == 0 ) throw new IllegalArgumentException("Haplotype2 is bad " + Arrays.toString(haplotype2)); + + for( int i = 0; i < haplotype1.length && i < haplotype2.length; i++ ) { + if( haplotype1[i] != haplotype2[i] || pd1[i] != pd2[i]) { + return i; + } + } + + return Math.min(haplotype1.length, haplotype2.length); + } + + /** + * Return the results of the computeLogLikelihoods function + */ + public double[] getLogLikelihoodArray() { + return mLogLikelihoodArray; + } + + /** + * Attach a debugOuputStream to this HMM instance + */ + public void setAndInitializeDebugOutputStream(final OutputStreamWriter writer) { + try { + debugOutputStream = writer; + debugOutputStream.write("# hap-bases\thap-pd-bases\tread-bases\tread-qual\tread-ins-qual\tread-del-qual\tgcp\texpected-result"); + } catch (IOException e) { + throw new GATKException("Error writing to specified HMM results output stream", e); + } + } + + /** + * Method to be invoked by implementing HMM engines to output the various hmm inputs/outputs with uniform formatting. + */ + protected void writeToResultsFileIfApplicable(byte[] readBases, byte[] readQuals, byte[] readInsQuals, byte[] readDelQuals, byte[] overallGCP, byte[] alleleBases, byte[] allelePDBases, double lk) { + + if (debugOutputStream!= null) { + try { + debugOutputStream.write("\n" + new String(alleleBases) + "\t" + Arrays.toString(allelePDBases) + "\t" + new String(readBases) + "\t" + SAMUtils.phredToFastq(readQuals) + "\t" + SAMUtils.phredToFastq(readInsQuals) + "\t" + SAMUtils.phredToFastq(readDelQuals) + "\t" + SAMUtils.phredToFastq(overallGCP) + "\t" + String.format("%e",lk)); + } catch (IOException e) { + throw new GATKException("Error writing to specified HMM results output stream", e); + } + } + } + + /** + * Called at the end of the program to close files, print profiling information etc + */ + @Override + public void close() { + if(doProfiling) { + logger.info("Total compute time in PairHMM computeLogLikelihoods() : " + (pairHMMComputeTime * 1e-9)); + } + if(debugOutputStream != null) { + try { + debugOutputStream.close(); + } catch (IOException e) { + throw new GATKException("Error closing the pairHMM debug output stream", e); + } + } + } +} diff --git a/src/main/java/org/broadinstitute/hellbender/utils/pileup/PileupBasedAlleles.java b/src/main/java/org/broadinstitute/hellbender/utils/pileup/PileupBasedAlleles.java index b18ffef18a6..a2eec754330 100644 --- a/src/main/java/org/broadinstitute/hellbender/utils/pileup/PileupBasedAlleles.java +++ b/src/main/java/org/broadinstitute/hellbender/utils/pileup/PileupBasedAlleles.java @@ -1,8 +1,7 @@ package org.broadinstitute.hellbender.utils.pileup; import com.google.common.annotations.VisibleForTesting; -import htsjdk.samtools.SAMFileHeader; -import htsjdk.samtools.SAMRecord; +import htsjdk.samtools.*; import htsjdk.samtools.util.SequenceUtil; import htsjdk.variant.variantcontext.Allele; import htsjdk.variant.variantcontext.VariantContext; @@ -10,8 +9,10 @@ import org.broadinstitute.hellbender.engine.AlignmentAndReferenceContext; import org.broadinstitute.hellbender.engine.AlignmentContext; import org.broadinstitute.hellbender.engine.ReferenceContext; +import org.broadinstitute.hellbender.exceptions.GATKException; import org.broadinstitute.hellbender.tools.walkers.haplotypecaller.PileupDetectionArgumentCollection; import org.broadinstitute.hellbender.utils.SimpleInterval; +import org.broadinstitute.hellbender.utils.Utils; import org.broadinstitute.hellbender.utils.read.GATKRead; import java.util.*; @@ -23,6 +24,19 @@ */ public final class PileupBasedAlleles { + final static String MISMATCH_BASES_PERCENTAGE_TAG = "MZ"; + public static final double MISMATCH_BASES_PERCENTAGE_ADJUSMTENT = 1000.0; + + // internal values to be used for tagging the VCF info fields appropriately + public static String PILEUP_ALLELE_SUPPORTING_READS = "PileupSupportingReads"; + public static String PILEUP_ALLELE_BAD_READS_TAG = "PileupSupportingBadReads"; + public static String PILEUP_ALLELE_ASSEMBLY_BAD_READS_TAG = "PileupAssemblyBadReads"; + public static String PILEUP_ALLELE_TOTAL_READS = "PileupAssemblyTotalReads"; + + private final static int COUNT_IDX = 0; + private final static int BAD_COUNT_IDX = 1; + private final static int ASSEMBLY_BAD_COUNT_IDX = 2; + /** * Accepts the raw per-base pileups stored from the active region detection code and parses them for potential variants * that are visible in the pileups but might be dropped from assembly for any number of reasons. The basic algorithm works @@ -38,78 +52,114 @@ public final class PileupBasedAlleles { * @param headerForReads Header for the reads (only necessary for SAM file conversion) * @return A list of variant context objects corresponding to potential variants that pass our heuristics. */ - public static ArrayList getPileupVariantContexts(final List alignmentAndReferenceContextList, final PileupDetectionArgumentCollection args, final SAMFileHeader headerForReads) { + public static List getPileupVariantContexts(final List alignmentAndReferenceContextList, final PileupDetectionArgumentCollection args, final SAMFileHeader headerForReads, final int minBaseQualityScore) { - final ArrayList pileupVariantList = new ArrayList<>(); + final List pileupVariantList = new ArrayList<>(); // Iterate over every base - for(AlignmentAndReferenceContext alignmentAndReferenceContext : alignmentAndReferenceContextList) { + for (int i = 0; i < alignmentAndReferenceContextList.size(); i++) { + AlignmentAndReferenceContext alignmentAndReferenceContext = alignmentAndReferenceContextList.get(i); + boolean onlyTrackDeletions = false; + //Skip all work on sites that aren't active according to our heuristic + if (args.activeRegionPhredThreshold > 0.0 && alignmentAndReferenceContext.getActivityScore() < args.activeRegionPhredThreshold ) { + //This solves a discordance with Illumina where they count deletions (and thus construct them and filter on the threshold) not at the anchor base but at the first + //deleted base on the reference. Consequently we must allow deletions to be detected one base upstream of adctive regions. + if (args.detectIndels && i+1 < alignmentAndReferenceContextList.size() && alignmentAndReferenceContextList.get(i+1).getActivityScore() > args.activeRegionPhredThreshold ) { + onlyTrackDeletions = true; + } else { + continue; + } + } + final AlignmentContext alignmentContext = alignmentAndReferenceContext.getAlignmentContext(); final ReferenceContext referenceContext = alignmentAndReferenceContext.getReferenceContext(); - final int numOfBases = alignmentContext.size(); + int numOfBases = alignmentContext.size(); final ReadPileup pileup = alignmentContext.getBasePileup(); final byte refBase = referenceContext.getBase(); - Map insertionCounts = new HashMap<>(); - - Map altCounts = new HashMap<>(); - - int totalAltReads = 0; - int totalAltBadReads = 0; + //Key for counts arrays [support, bad reads, assembly bad reads] + Map insertionCounts = new HashMap<>(); + Map deletionCounts = new HashMap<>(); + Map altCounts = new HashMap<>(); for (PileupElement element : pileup) { final byte eachBase = element.getBase(); + // Subtract out low quality bases to mimic the reading active region determination //TODO this might need to also ignore the qual basees + if (element.getQual() < minBaseQualityScore) { + numOfBases--; + } + // check to see that the base is not ref (and non-deletion) and increment the alt counts (and evaluate if the read is "bad") - if (refBase != eachBase && eachBase != 'D') { - incrementAltCount(eachBase, altCounts); - totalAltReads++; - // Handle the "badness" - if (evaluateBadRead(element.getRead(), referenceContext, args, headerForReads)) { - totalAltBadReads++; - } + if (refBase != eachBase && eachBase != 'D' && element.getQual() > args.qualityForSnpsInPileupDetection) { + incrementAltCount(eachBase, altCounts, + evaluateBadRead(element.getRead(), referenceContext, args, headerForReads), + evaluateBadReadForAssembly(element.getRead(), referenceContext, args, headerForReads)); } - // TODO currently this only handles Insertions. + //NOTE: we count indels if (args.detectIndels) { // now look for indels if (element.isBeforeInsertion()) { - incrementInsertionCount(element.getBasesOfImmediatelyFollowingInsertion(), insertionCounts); + incrementInsertionCount(element.getBasesOfImmediatelyFollowingInsertion(), insertionCounts, + evaluateBadRead(element.getRead(), referenceContext, args, headerForReads), + evaluateBadReadForAssembly(element.getRead(), referenceContext, args, headerForReads)); } + if (element.isBeforeDeletionStart()) { + incrementDeletionCount(element.getLengthOfImmediatelyFollowingIndel(), deletionCounts, + evaluateBadRead(element.getRead(), referenceContext, args, headerForReads), + evaluateBadReadForAssembly(element.getRead(), referenceContext, args, headerForReads)); - //TODO this is possibly double dipping if there are snps adjacent to indels? - totalAltReads++; - // Handle the "badness" - if (evaluateBadRead(element.getRead(), referenceContext, args, headerForReads)) { - totalAltBadReads++; } } - } // Evaluate the detected SNP alleles for this site - final List alleles = new ArrayList<>(); - alleles.add(Allele.create(referenceContext.getBase(), true)); - final Optional> maxAlt = altCounts.entrySet().stream().max(Comparator.comparingInt(Map.Entry::getValue)); - if (maxAlt.isPresent() - && passesFilters(args, false, numOfBases, totalAltBadReads, totalAltReads, maxAlt.get())) { - - alleles.add(Allele.create(maxAlt.get().getKey())); - final VariantContextBuilder pileupSNP = new VariantContextBuilder("pileup", alignmentContext.getContig(), alignmentContext.getStart(), alignmentContext.getEnd(), alleles); - pileupVariantList.add(pileupSNP.make()); + if (!onlyTrackDeletions) { + for (Map.Entry allele : altCounts.entrySet()) { + List alleles = new ArrayList<>(); + alleles.add(Allele.create(referenceContext.getBase(), true)); + alleles.add(Allele.create(allele.getKey())); + final VariantContextBuilder pileupSNP = new VariantContextBuilder("pileup", alignmentContext.getContig(), alignmentContext.getStart(), alignmentContext.getEnd(), alleles); + pileupVariantList.add(pileupSNP + .attribute(PILEUP_ALLELE_SUPPORTING_READS, allele.getValue()[COUNT_IDX]) + .attribute(PILEUP_ALLELE_BAD_READS_TAG, allele.getValue()[BAD_COUNT_IDX]) + .attribute(PILEUP_ALLELE_ASSEMBLY_BAD_READS_TAG, allele.getValue()[ASSEMBLY_BAD_COUNT_IDX]) + .attribute(PILEUP_ALLELE_TOTAL_READS, numOfBases).make()); + } } - // Evaluate the detected INDEL alleles for this site if (args.detectIndels) { - final List indelAlleles = new ArrayList<>(); - indelAlleles.add(Allele.create(referenceContext.getBase(), true)); - final Optional> maxIns = insertionCounts.entrySet().stream().max(Comparator.comparingInt(Map.Entry::getValue)); - if (maxIns.isPresent() - && passesFilters(args, true, numOfBases, totalAltBadReads, totalAltReads, maxIns.get())) { - - indelAlleles.add(Allele.create((char)referenceContext.getBase() + maxIns.get().getKey())); - final VariantContextBuilder pileupInsertion = new VariantContextBuilder("pileup", alignmentContext.getContig(), alignmentContext.getStart(), alignmentContext.getEnd(), indelAlleles); - pileupVariantList.add(pileupInsertion.make()); + // Evaluate the detected Insertions alleles for this site + if (!onlyTrackDeletions) { + for (Map.Entry allele : insertionCounts.entrySet()) { + List delAlleles = new ArrayList<>(); + delAlleles.add(Allele.create(referenceContext.getBase(), true)); + delAlleles.add(Allele.create((char) referenceContext.getBase() + allele.getKey())); + final VariantContextBuilder pileupInsertion = new VariantContextBuilder("pileup", alignmentContext.getContig(), alignmentContext.getStart(), alignmentContext.getEnd(), delAlleles); + pileupVariantList.add(pileupInsertion + .attribute(PILEUP_ALLELE_SUPPORTING_READS, allele.getValue()[COUNT_IDX]) + .attribute(PILEUP_ALLELE_BAD_READS_TAG, allele.getValue()[BAD_COUNT_IDX]) + .attribute(PILEUP_ALLELE_ASSEMBLY_BAD_READS_TAG, allele.getValue()[ASSEMBLY_BAD_COUNT_IDX]) + .attribute(PILEUP_ALLELE_TOTAL_READS, numOfBases).make()); + } + } + + // Evaluate the detected Deletions alleles for this site + for (Map.Entry allele : deletionCounts.entrySet()) { + List insAlleles = new ArrayList<>(); + insAlleles.add(Allele.create(referenceContext.getBase(), false)); + insAlleles.add(Allele.create(referenceContext.getBases( + new SimpleInterval(referenceContext.getContig(), + alignmentContext.getStart(), + alignmentContext.getEnd() + allele.getKey())), + true)); + final VariantContextBuilder pileupInsertion = new VariantContextBuilder("pileup", alignmentContext.getContig(), alignmentContext.getStart(), alignmentContext.getEnd() + allele.getKey(), insAlleles); + pileupVariantList.add(pileupInsertion + .attribute(PILEUP_ALLELE_SUPPORTING_READS, allele.getValue()[COUNT_IDX]) + .attribute(PILEUP_ALLELE_BAD_READS_TAG, allele.getValue()[BAD_COUNT_IDX]) + .attribute(PILEUP_ALLELE_ASSEMBLY_BAD_READS_TAG, allele.getValue()[ASSEMBLY_BAD_COUNT_IDX]) + .attribute(PILEUP_ALLELE_TOTAL_READS, numOfBases).make()); } } } @@ -123,10 +173,35 @@ && passesFilters(args, true, numOfBases, totalAltBadReads, totalAltReads, maxIns * - Does it have greater than pileupAbsoluteDepth number of reads supporting it? * - Are the reads supporting alts at the site greater than badReadThreshold percent "good"? //TODO evaluate if this is worth doing on a per-allele basis or otherwise */ - private static boolean passesFilters(final PileupDetectionArgumentCollection args, boolean indel, final int numOfBases, final int totalAltBadReads, final int totalAltReads, final Map.Entry maxAlt) { - return ((float) maxAlt.getValue() / (float) numOfBases) > (indel ? args.indelThreshold : args.snpThreshold) - && numOfBases >= args.pileupAbsoluteDepth - && ((args.badReadThreshold <= 0.0) || (float) totalAltBadReads / (float)totalAltReads <= args.badReadThreshold); + public static boolean passesFilters(final PileupDetectionArgumentCollection args, final VariantContext pileupVariant) { + //Validation that this VC is the correct object type + validatePileupVariant(pileupVariant); + + final int pileupSupport = pileupVariant.getAttributeAsInt(PILEUP_ALLELE_SUPPORTING_READS, 0); + final int totalDepth = pileupVariant.getAttributeAsInt(PILEUP_ALLELE_TOTAL_READS, 0); + return ((double) pileupSupport / (double) totalDepth) > (pileupVariant.isIndel() ? args.indelThreshold : args.snpThreshold) + && totalDepth >= args.pileupAbsoluteDepth + && ((args.badReadThreshold <= 0.0) || (double) pileupVariant.getAttributeAsInt(PILEUP_ALLELE_BAD_READS_TAG,0) / (double)pileupSupport <= args.badReadThreshold); + } + + // TODO this is the most sketchy one... does a variant that fails pileup calling with only one bad read as support count as garbage by this tool... + public static boolean shouldFilterAssemblyVariant(final PileupDetectionArgumentCollection args, final VariantContext pileupVariant) { + //Validation that this VC is the correct object type + validatePileupVariant(pileupVariant); + final int pileupSupport = pileupVariant.getAttributeAsInt(PILEUP_ALLELE_SUPPORTING_READS, 0); + final int assemblyBadReads = pileupVariant.getAttributeAsInt(PILEUP_ALLELE_ASSEMBLY_BAD_READS_TAG, 0); + return ((args.assemblyBadReadThreshold > 0.0) && (double) assemblyBadReads / (double) pileupSupport >= args.assemblyBadReadThreshold); + } + + private static void validatePileupVariant(final VariantContext pileupVariant) { + Utils.nonNull(pileupVariant); + if (pileupVariant.getAlleles().size() != 2 || + !pileupVariant.hasAttribute(PILEUP_ALLELE_ASSEMBLY_BAD_READS_TAG) || + !pileupVariant.hasAttribute(PILEUP_ALLELE_SUPPORTING_READS) || + !pileupVariant.hasAttribute(PILEUP_ALLELE_TOTAL_READS) || + !pileupVariant.hasAttribute(PILEUP_ALLELE_BAD_READS_TAG)) { + throw new GATKException.ShouldNeverReachHereException("The supplied Variant Context "+pileupVariant.toString()+" is not a PileupVariantContext"); + } } /** @@ -155,25 +230,17 @@ static boolean evaluateBadRead(final GATKRead read, final ReferenceContext refer return true; } - //TODO this conversion is really unnecessary. Perhaps we should expose a new SequenceUtil like NM tag calculation?... - SAMRecord samRecordForRead = read.convertToSAMRecord(headerForRead); - // Assert that the edit distance for the read is in line - if (args.badReadEditDistance > 0.0) { - final int nmScore; - if (! read.hasAttribute("NM")) { - nmScore = SequenceUtil.calculateSamNmTag(samRecordForRead, referenceContext.getBases(new SimpleInterval(read)), read.getStart() - 1); - } else { - nmScore = read.getAttributeAsInteger("NM"); - } - if (nmScore > (read.getLength() * args.badReadEditDistance)) { - return true; - } + final Integer mismatchPercentage = read.getAttributeAsInteger(MISMATCH_BASES_PERCENTAGE_TAG); + Utils.nonNull(mismatchPercentage); + if ((mismatchPercentage / MISMATCH_BASES_PERCENTAGE_ADJUSMTENT) > args.badReadEditDistance) { + return true; } //TODO add threshold descibed by illumina about insert size compared to the average if (args.templateLengthStd > 0 && args.templateLengthMean > 0) { + SAMRecord samRecordForRead = read.convertToSAMRecord(headerForRead); int templateLength = samRecordForRead.getInferredInsertSize(); // This is an illumina magic number... Its possible none of this is particularly important for Functional Equivalency. if (templateLength < args.templateLengthMean - 2.25 * args.templateLengthStd @@ -184,13 +251,48 @@ static boolean evaluateBadRead(final GATKRead read, final ReferenceContext refer return false; } - private static void incrementInsertionCount(String insertion, Map insertionCounts){ - insertionCounts.put(insertion, - insertionCounts.getOrDefault(insertion,0) + 1); + @VisibleForTesting + static boolean evaluateBadReadForAssembly(final GATKRead read, final ReferenceContext referenceContext, final PileupDetectionArgumentCollection args, final SAMFileHeader headerForRead) { + if (args.assemblyBadReadThreshold <= 0.0) { + return false; + } + // TODO other checks? + Utils.nonNull(read.getAttributeAsInteger(MISMATCH_BASES_PERCENTAGE_TAG)); + return (read.getAttributeAsInteger(MISMATCH_BASES_PERCENTAGE_TAG) / MISMATCH_BASES_PERCENTAGE_ADJUSMTENT) > args.assemblyBadReadEditDistance; } - private static void incrementAltCount(byte base, Map altCounts){ - altCounts.put(base, - altCounts.getOrDefault(base,0) + 1); + // Helper methods to manage the badness counting arrays + private static void incrementInsertionCount(String insertion, Map insertionCounts, boolean bad, boolean assemblybad){ + int[] values = insertionCounts.computeIfAbsent(insertion, (i) -> new int[3] ); + values[COUNT_IDX]+=1; values[BAD_COUNT_IDX]+=bad?1:0; values[ASSEMBLY_BAD_COUNT_IDX]+=assemblybad?1:0; + } + private static void incrementDeletionCount(Integer deletion, Map deletionCounts, boolean bad, boolean assemblybad){ + int[] values = deletionCounts.computeIfAbsent(deletion, (i) -> new int[3] ); + values[COUNT_IDX]+=1; values[BAD_COUNT_IDX]+=bad?1:0; values[ASSEMBLY_BAD_COUNT_IDX]+=assemblybad?1:0; + } + private static void incrementAltCount(byte base, Map altCounts, boolean bad, boolean assemblybad){ + int[] values = altCounts.computeIfAbsent(base, (i) -> new int[3] ); + values[COUNT_IDX]+=1; values[BAD_COUNT_IDX]+=bad?1:0; values[ASSEMBLY_BAD_COUNT_IDX]+=assemblybad?1:0; + } + + + public static void addMismatchPercentageToRead(final GATKRead read, final SAMFileHeader headerForRead, final ReferenceContext referenceContext) { + //TODO this conversion is really unnecessary. Perhaps we should expose a new SequenceUtil like NM tag calculation?... + if (read.hasAttribute(MISMATCH_BASES_PERCENTAGE_TAG)){ + return; + } + + SAMRecord samRecordForRead = read.convertToSAMRecord(headerForRead); + final int nmScore; + if (! read.hasAttribute("NM")) { + nmScore = SequenceUtil.calculateSamNmTag(samRecordForRead, referenceContext.getBases(new SimpleInterval(read)), read.getStart() - 1); + } else { + nmScore = read.getAttributeAsInteger("NM"); + } + // We adjust the NM score by any indels in the read + int adjustedNMScore = nmScore - read.getCigarElements().stream().filter(element -> element.getOperator().isIndel()).mapToInt(CigarElement::getLength).sum(); + + // NOTE: we store the percentage as an integer x1000 because that is what the read attributes support. 4 units of precision should be more than enough for this ratio in the first place whereas 3 is probably not (reads over 100 bases get binned). + read.setAttribute(MISMATCH_BASES_PERCENTAGE_TAG, (int) (MISMATCH_BASES_PERCENTAGE_ADJUSMTENT * adjustedNMScore / (read.getCigarElements().stream().filter(element -> element.getOperator().isAlignment()).mapToInt(CigarElement::getLength).sum() ))); } } diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerIntegrationTest.java index 0bf2fe27ba9..2d3eb1a94f5 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerIntegrationTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/HaplotypeCallerIntegrationTest.java @@ -1979,6 +1979,65 @@ public void testPileupCallingDRAGENModeConsistentWithPastResults(final String in } } + @Test(dataProvider="HaplotypeCallerTestInputs") + public void testPileupCallingDRAGEN378ModeConsistentWithPastResults(final String inputFileName, final String referenceFileName) throws Exception { + Utils.resetRandomGenerator(); + + final File output = createTempFile("testVCFModeIsConsistentWithPastResults", ".vcf"); + final File expected = new File(TEST_FILES_DIR, "expected.pileupCallerDRAGEN.378.gatk4.vcf"); + + final String outputPath = UPDATE_EXACT_MATCH_EXPECTED_OUTPUTS ? expected.getAbsolutePath() : output.getAbsolutePath(); + + final String[] args = { + "-I", inputFileName, + "-R", referenceFileName, + "-L", "20:10000000-10100000", + "-O", outputPath, + "--dragen-378-concordance-mode", + "--dragstr-params-path", TEST_FILES_DIR+"example.dragstr-params.txt", + + "--" + StandardArgumentDefinitions.ADD_OUTPUT_VCF_COMMANDLINE, "false", + }; + + runCommandLine(args); + + // Test for an exact match against past results + if ( ! UPDATE_EXACT_MATCH_EXPECTED_OUTPUTS ) { + IntegrationTestSpec.assertEqualTextFiles(output, expected); + } + } + + @Test(dataProvider="HaplotypeCallerTestInputs") + public void testPileupCallingDRAGEN378OptimizedModeConsistentWithPastResults(final String inputFileName, final String referenceFileName) throws Exception { + Utils.resetRandomGenerator(); + + final File output = createTempFile("testVCFModeIsConsistentWithPastResults", ".vcf"); + final File expected = new File(TEST_FILES_DIR, "expected.pileupCallerDRAGEN.378.gatk4.vcf"); + + final String outputPath = UPDATE_EXACT_MATCH_EXPECTED_OUTPUTS ? expected.getAbsolutePath() : output.getAbsolutePath(); + + final String[] args = { + "-I", inputFileName, + "-R", referenceFileName, + "-L", "20:10000000-10100000", + "-O", outputPath, + "--dragen-378-concordance-mode", + "--dragstr-params-path", TEST_FILES_DIR+"example.dragstr-params.txt", + "--" + StandardArgumentDefinitions.ADD_OUTPUT_VCF_COMMANDLINE, "false", + + // This optimization in PDHMM mode should have essentially no bearing on the output, this test deliberately + // uses the same expected output as the above test to enforce that over this short test range the optimization + // doesn't impact the results in any meaningful way. + "--" + PileupDetectionArgumentCollection.PDHMM_READ_OVERLAP_OPTIMIZATION + }; + + runCommandLine(args); + + // Test for an exact match against past results + if ( ! UPDATE_EXACT_MATCH_EXPECTED_OUTPUTS ) { + IntegrationTestSpec.assertEqualTextFiles(output, expected); + } + } @DataProvider(name="PairHMMResultsModes") public Object[][] PairHMMResultsModes() { @@ -2032,6 +2091,49 @@ public void testPairHMMResultsFile(final PairHMM.Implementation implementation, } } } + + @Test() + // Since the PDHMM isn't currently slot-in compared to the pairHMM modes this has to be computed seperately... + public void testPDPairHMMResultsFile() throws Exception { + Utils.resetRandomGenerator(); + + final File vcfOutput = createTempFile("hmmResultFileTest", ".vcf"); + final File hmmOutput = createTempFile("hmmResult", ".txt"); + final File expected = new File(largeFileTestDir, "expected.PDHMM.hmmresults.txt"); + + final String hmmOutputPath = UPDATE_EXACT_MATCH_EXPECTED_OUTPUTS ? expected.getAbsolutePath() : hmmOutput.getAbsolutePath(); + + final String[] args = { + "-I", NA12878_20_21_WGS_bam, + "-R", b37_reference_20_21, + "-L", "20:10009875", // site selected as one of the more complex in our standard test inputs (which means lots of PD events in the haplotypes) + "-ip", "300", + "-O", vcfOutput.getAbsolutePath(), + "--dragen-mode", + "--dragstr-params-path", TEST_FILES_DIR+"example.dragstr-params.txt", + + // Pileup Caller args + "--" + PileupDetectionArgumentCollection.PILEUP_DETECTION_LONG_NAME, + "--" + PileupDetectionArgumentCollection.PILEUP_DETECTION_ABSOLUTE_ALT_DEPTH, "0", + "--" + StandardArgumentDefinitions.ADD_OUTPUT_VCF_COMMANDLINE, "false", + + // Pileup caller and PDHMM arguments + "--" + PileupDetectionArgumentCollection.PILEUP_DETECTION_BAD_READ_RATIO_LONG_NAME, "0.40", + "--" + PileupDetectionArgumentCollection.PILEUP_DETECTION_ENABLE_INDELS, + "--" + PileupDetectionArgumentCollection.PILEUP_DETECTION_ACTIVE_REGION_PHRED_THRESHOLD_LONG_NAME, "3.0", + "--" + PileupDetectionArgumentCollection.PILEUP_DETECTION_FILTER_ASSEMBLY_HAPS_THRESHOLD, "0.4", + "--" + PileupDetectionArgumentCollection.GENERATE_PARTIALLY_DETERMINED_HAPLOTYPES_LONG_NAME, + + "--pdhmm-results-file", hmmOutputPath + }; + + runCommandLine(args); + + if ( ! UPDATE_EXACT_MATCH_EXPECTED_OUTPUTS ) { + IntegrationTestSpec.assertEqualTextFiles(hmmOutput, expected); + } + } + @Test public void testVcfFlowLikelihoodOptimizedCompConsistentWithPreviousResults() throws Exception { Utils.resetRandomGenerator(); diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngineUnitTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngineUnitTest.java new file mode 100644 index 00000000000..8fe8ee94efa --- /dev/null +++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/haplotypecaller/PartiallyDeterminedHaplotypeComputationEngineUnitTest.java @@ -0,0 +1,223 @@ +package org.broadinstitute.hellbender.tools.walkers.haplotypecaller; + +import htsjdk.samtools.TextCigarCodec; +import htsjdk.variant.variantcontext.Allele; +import htsjdk.variant.variantcontext.VariantContext; +import htsjdk.variant.variantcontext.VariantContextBuilder; +import org.broadinstitute.hellbender.GATKBaseTest; +import org.broadinstitute.hellbender.exceptions.GATKException; +import org.broadinstitute.hellbender.utils.SimpleInterval; +import org.broadinstitute.hellbender.utils.haplotype.EventMap; +import org.broadinstitute.hellbender.utils.haplotype.Haplotype; +import org.broadinstitute.hellbender.utils.haplotype.PartiallyDeterminedHaplotype; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.testng.Assert.*; + +public class PartiallyDeterminedHaplotypeComputationEngineUnitTest extends GATKBaseTest { + + VariantContext SNP_C_90 = new VariantContextBuilder("a","20",90, 90, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + VariantContext DEL_AAAAAAA_98 = new VariantContextBuilder("a","20",98, 104, Arrays.asList(Allele.create("AAAAAAA", true),Allele.ALT_A)).make(); + VariantContext SNP_C_100 = new VariantContextBuilder("a","20",100, 100, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + VariantContext SNP_G_101 = new VariantContextBuilder("a","20",101, 101, Arrays.asList(Allele.REF_A,Allele.ALT_G)).make(); + VariantContext SNP_G_102 = new VariantContextBuilder("a","20",102, 102, Arrays.asList(Allele.REF_A,Allele.ALT_G)).make(); + VariantContext SNP_C_104 = new VariantContextBuilder("a","20",104, 104, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + VariantContext SNP_C_105 = new VariantContextBuilder("a","20",105, 105, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + VariantContext SNP_G_105 = new VariantContextBuilder("a","20",105, 105, Arrays.asList(Allele.REF_A,Allele.ALT_G)).make(); + VariantContext SNP_C_106 = new VariantContextBuilder("a","20",106, 106, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + VariantContext SNP_T_106 = new VariantContextBuilder("a","20",106, 106, Arrays.asList(Allele.REF_A,Allele.ALT_T)).make(); + VariantContext SNP_C_109 = new VariantContextBuilder("a","20",109, 109, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + VariantContext SNP_C_107 = new VariantContextBuilder("a","20",107, 107, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + + VariantContext DEL_AA_105 = new VariantContextBuilder("a","20",105, 106, Arrays.asList(Allele.create("AA", true),Allele.ALT_A)).make(); + VariantContext DEL_AA_100 = new VariantContextBuilder("a","20",100, 101, Arrays.asList(Allele.create("AA", true),Allele.ALT_A)).make(); + VariantContext DEL_AAA_102 = new VariantContextBuilder("a","20",102, 104, Arrays.asList(Allele.create("AAA", true),Allele.ALT_A)).make(); + VariantContext DEL_AAAAAAA_102 = new VariantContextBuilder("a","20",102, 108, Arrays.asList(Allele.create("AAAAAAA", true),Allele.ALT_A)).make(); + + + VariantContext INS_TT_105 = new VariantContextBuilder("a","20",105, 105, Arrays.asList(Allele.REF_A, Allele.create("AT"))).make(); + VariantContext INS_TT_103 = new VariantContextBuilder("a","20",103, 103, Arrays.asList(Allele.REF_A, Allele.create("AT"))).make(); + VariantContext INS_TT_100 = new VariantContextBuilder("a","20",100, 100, Arrays.asList(Allele.REF_A, Allele.create("AT"))).make(); + VariantContext INS_GGG_106 = new VariantContextBuilder("a","20",106, 106, Arrays.asList(Allele.REF_A, Allele.create("AGG"))).make(); + + // TODO THESE ARE FOR INVALID TEST CASES + VariantContext SNP_C_99 = new VariantContextBuilder("a","20",99, 99, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + VariantContext SNP_C_120 = new VariantContextBuilder("a","20",120, 120, Arrays.asList(Allele.REF_A,Allele.ALT_C)).make(); + + + + @DataProvider + public Object[][] testConstructHaplotypeFromVariantsDataProvider() { + return new Object[][] { + { Collections.emptyList(), "AAAAAAAAAA", "10M", 0 }, + { Arrays.asList(SNP_C_105), "AAAAACAAAA", "5M1X4M", 0 }, + { Arrays.asList(SNP_C_100), "CAAAAAAAAA", "1X9M", 0 }, + { Arrays.asList(SNP_C_109), "AAAAAAAAAC", "9M1X", 0 }, + { Arrays.asList(SNP_C_105, SNP_C_106), "AAAAACCAAA", "5M2X3M", 0 }, + + { Arrays.asList(DEL_AA_105), "AAAAAAAAA", "6M1D3M", 0 }, + { Arrays.asList(DEL_AA_100), "AAAAAAAAA", "1M1D8M", 0 }, + { Arrays.asList(DEL_AA_105, SNP_C_109), "AAAAAAAAC", "6M1D2M1X", 0 }, + { Arrays.asList(DEL_AA_105, SNP_C_107, SNP_C_109), "AAAAAACAC", "6M1D1X1M1X", 0 }, + + { Arrays.asList(INS_TT_105), "AAAAAATAAAA", "6M1I4M", 0 }, + { Arrays.asList(INS_GGG_106), "AAAAAAAGGAAA", "7M2I3M", 0 }, + { Arrays.asList(DEL_AA_100, INS_GGG_106, SNP_C_109), "AAAAAAGGAAC", "1M1D5M2I2M1X", 0 }, + + //this tests that SNPS can be inserted immediately prior to (and following) indels + { Arrays.asList( SNP_C_105, DEL_AA_105 ), "AAAAACAAA", "5M1X1D3M", 1 }, + { Arrays.asList( SNP_C_100, DEL_AA_100 ), "CAAAAAAAA", "1X1D8M", 1 }, + { Arrays.asList( SNP_C_100, DEL_AA_100, SNP_G_102 ), "CGAAAAAAA", "1X1D1X7M", 1 }, + { Arrays.asList( SNP_C_105, INS_TT_105 ), "AAAAACTAAAA", "5M1X1I4M", 1 }, + { Arrays.asList( SNP_C_100, INS_TT_100, SNP_G_101 ), "CTGAAAAAAAA", "1X1I1X8M", 1 }, + { Arrays.asList( SNP_C_100, INS_TT_100, SNP_G_101, SNP_C_105, DEL_AA_105 ), "CTGAAACAAA", "1X1I1X3M1X1D3M", 2 }, + + //testing that the logic around anchor bases isn't resulting in variants being dropped accidntally + { Arrays.asList( SNP_C_104, DEL_AA_105 ), "AAAACAAAA", "4M1X1M1D3M", 0 }, + { Arrays.asList( SNP_C_104, INS_TT_105 ), "AAAACATAAAA", "4M1X1M1I4M", 0 }, + + }; + } + @Test(dataProvider = "testConstructHaplotypeFromVariantsDataProvider") + public void basicConstructHaplotypeFromVariants(List variants, String expectedBases, String expectedCigar, int numberOfCompounds) { + Haplotype ref = new Haplotype("AAAAAAAAAA".getBytes(), true, 500, TextCigarCodec.decode("10M")); + ref.setGenomeLocation(new SimpleInterval("20", 100, 110)); + + Haplotype result = PartiallyDeterminedHaplotypeComputationEngine.constructHaplotypeFromVariants(ref, variants, true); + Assert.assertEquals(result.getBases(), expectedBases.getBytes()); + Assert.assertEquals(result.getCigar(), TextCigarCodec.decode(expectedCigar)); + + // Assert that the resulting event map matches the input variants: + EventMap resultEMap = result.getEventMap(); + // NOTE, because of representation in VCF lines, the compound alleles get compressed into a single in the event map, here we assert that this is correct. + Assert.assertEquals(resultEMap.getNumberOfEvents(), variants.size() - numberOfCompounds); + } + + @Test(expectedExceptions = GATKException.class) + public void TestOutOfOrderInputs() { + Haplotype ref = new Haplotype("AAAAAAAAAA".getBytes(), true, 500, TextCigarCodec.decode("10M")); + ref.setGenomeLocation(new SimpleInterval("20", 100, 110)); + List variants = Arrays.asList(SNP_C_105, SNP_G_105); + + Haplotype result = PartiallyDeterminedHaplotypeComputationEngine.constructHaplotypeFromVariants(ref, variants, true); + } + + @Test(expectedExceptions = GATKException.class) + public void TestSNPsOverlapping() { + Haplotype ref = new Haplotype("AAAAAAAAAA".getBytes(), true, 500, TextCigarCodec.decode("10M")); + ref.setGenomeLocation(new SimpleInterval("20", 100, 110)); + List variants = Arrays.asList(SNP_C_109, DEL_AA_100); + + Haplotype result = PartiallyDeterminedHaplotypeComputationEngine.constructHaplotypeFromVariants(ref, variants, true); + } + + @Test(expectedExceptions = GATKException.class) + public void TestVariantNotOverlappingHap() { + Haplotype ref = new Haplotype("AAAAAAAAAA".getBytes(), true, 500, TextCigarCodec.decode("10M")); + ref.setGenomeLocation(new SimpleInterval("20", 100, 110)); + List variants = Arrays.asList(SNP_C_90); + + Haplotype result = PartiallyDeterminedHaplotypeComputationEngine.constructHaplotypeFromVariants(ref, variants, true); + } + + @Test(expectedExceptions = GATKException.class) + public void TestVariantIndelPartiallyOverlapping() { + Haplotype ref = new Haplotype("AAAAAAAAAA".getBytes(), true, 500, TextCigarCodec.decode("10M")); + ref.setGenomeLocation(new SimpleInterval("20", 100, 110)); + List variants = Arrays.asList(DEL_AAAAAAA_98); + + Haplotype result = PartiallyDeterminedHaplotypeComputationEngine.constructHaplotypeFromVariants(ref, variants, true); + } + + //This is a test asserting that a real edge case that was prone to cause failures in the PDHMM is handled properly when compound variants are taken into account. + //(62,Rlen=1,[C])->(82,Rlen=1,[C])->(84,Rlen=13,[C]) + @Test + public void testMessyAlignemntSite() { + Haplotype ref = new Haplotype("AAGAAAGATGGAGGCCCAGCCAGATCTGGACCCCACAGGCCGTCTCCCCACACAGCCATTCATGTGGTCTACTTCCAGCCATTCATGTGGTCTATTTCCAAGAAAATAGCCCATCCCCCCAAGATAACACCTTCTCAAAAACTTTACAGCTTTGTGTCTACACTGATATTTAGGTATTTTCTTTCTTTTTTTTTTATGATTAACACATCTAATTCAAGAATATCTTGGCAGGATATTCCCCGCTTAGGAAATG".getBytes(), true, 575, TextCigarCodec.decode("253M")); + ref.setGenomeLocation(new SimpleInterval("20", 24152646, 24152898)); + + VariantContext VC1 = new VariantContextBuilder("a", "20", 24152708, 24152708, Arrays.asList(Allele.REF_T, Allele.ALT_C)).make(); + VariantContext VC2 = new VariantContextBuilder("a", "20", 24152728, 24152728, Arrays.asList(Allele.REF_T, Allele.ALT_C)).make(); + VariantContext VC3 = new VariantContextBuilder("a", "20", 24152729, 24152741, Arrays.asList(Allele.create("CATGTGGTCTATT", true), Allele.ALT_C)).make(); + + List variants = Arrays.asList(VC1, VC2, VC3); + + Haplotype result = PartiallyDeterminedHaplotypeComputationEngine.constructHaplotypeFromVariants(ref, variants, true); + Assert.assertEquals(result.getCigar(), TextCigarCodec.decode("62M1X19M1X1M12D157M")); + + // Assert that the resulting event map matches the input variants: + EventMap resultEMap = result.getEventMap(); + Assert.assertEquals(resultEMap.getNumberOfEvents(), variants.size()); + for (VariantContext v : variants) { + VariantContext actualVC = resultEMap.get(v.getStart()); + Assert.assertNotNull(actualVC); + Assert.assertEquals(actualVC.getAlleles(), v.getAlleles()); + } + } + + + @DataProvider + public Object[][] testGeneratePDHaplotypeDataProvider() { + return new Object[][] { + {Arrays.asList(SNP_C_105, SNP_C_106), SNP_C_106, false, "AAAAAACAAA", new byte[]{0,0,0,0,0,17,0,0,0,0}, "6M1X3M"}, + {Arrays.asList(SNP_C_105, SNP_C_106), SNP_C_106, true , "AAAAAAAAAA", new byte[]{0,0,0,0,0,17,0,0,0,0}, "10M"}, + + {Arrays.asList(INS_TT_103, SNP_C_105, SNP_C_106), INS_TT_103, false, "AAAATAAAAAA", new byte[]{0,0,0,0,0,0,17,17,0,0,0}, "4M1I6M"}, + {Arrays.asList(INS_TT_103, SNP_C_105, SNP_C_106), INS_TT_103, true , "AAAAAAAAAA", new byte[]{0,0,0,0,0,17,17,0,0,0}, "10M"}, + {Arrays.asList(INS_TT_103, SNP_C_105, SNP_C_106), SNP_C_105, false, "AAAATACAAAA", new byte[]{0,0,0,0,6,0,0,17,0,0,0}, "4M1I1M1X4M"}, + {Arrays.asList(INS_TT_103, SNP_C_105, SNP_C_106), SNP_C_105, true , "AAAATAAAAAA", new byte[]{0,0,0,0,6,0,0,17,0,0,0}, "4M1I6M"}, + + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106), DEL_AAA_102, false, "AAAAAAAA" , new byte[]{0,0,0,17,17,0,0,0}, "3M2D5M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106), DEL_AAA_102, true , "AAAAAAAAAA", new byte[]{0,0,0,0,0,17,17,0,0,0}, "10M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106), SNP_C_105, false, "AAAAACAAAA", new byte[]{0,0,0,2,4,0,17,0,0,0}, "5M1X4M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106), SNP_C_105, true , "AAAAAAAAAA", new byte[]{0,0,0,2,4,0,17,0,0,0}, "10M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106), SNP_C_106, false, "AAAAAACAAA", new byte[]{0,0,0,2,4,17,0,0,0,0}, "6M1X3M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106), SNP_C_106, true , "AAAAAAAAAA", new byte[]{0,0,0,2,4,17,0,0,0,0}, "10M"}, + + // making sure we support "complex allels" from DRAGEN + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106, INS_GGG_106), SNP_C_105, false , "AAAAACAGGAAA", new byte[]{0,0,0,2,4,0,17,2,4,0,0,0}, "5M1X1M2I3M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106, SNP_T_106, INS_GGG_106), SNP_C_105, true , "AAAAAAAGGAAA", new byte[]{0,0,0,2,4,0,81,2,4,0,0,0}, "7M2I3M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106, INS_GGG_106), DEL_AAA_102, false , "AAAAAGGAAA", new byte[]{0,0,0,17,17,2,4,0,0,0}, "3M2D2M2I3M"}, + {Arrays.asList(DEL_AAA_102, SNP_C_105, SNP_C_106, SNP_T_106, INS_GGG_106), DEL_AAA_102, true , "AAAAAAAGGAAA", new byte[]{0,0,0,0,0,17,81,2,4,0,0,0}, "7M2I3M"}, + {Arrays.asList(SNP_G_101, SNP_C_105, DEL_AA_105), SNP_G_101, false , "AGAAAAAAAA", new byte[]{0,0,0,0,0,17,6,0,0,0}, "1M1X8M"}, + {Arrays.asList(SNP_G_101, SNP_C_105, DEL_AA_105), SNP_G_101, true , "AAAAAAAAAA", new byte[]{0,0,0,0,0,17,6,0,0,0}, "10M"}, + + }; + } + @Test(dataProvider = "testGeneratePDHaplotypeDataProvider") + public void testGeneratePDHaplotypeFromVariants(List variants, VariantContext targetVariant, boolean useRefBase, String expectedBases, byte[] expectedAltArray, String expectedCigar) { + Haplotype ref = new Haplotype("AAAAAAAAAA".getBytes(), true, 500, TextCigarCodec.decode("10M")); + ref.setGenomeLocation(new SimpleInterval("20", 100, 110)); + + PartiallyDeterminedHaplotype result = PartiallyDeterminedHaplotypeComputationEngine.createNewPDHaplotypeFromEvents(ref, targetVariant, useRefBase, variants); + Assert.assertEquals(new String(result.getBases()), expectedBases); + Assert.assertEquals(result.getAlternateBases(), expectedAltArray); + Assert.assertEquals(result.getCigar(), TextCigarCodec.decode(expectedCigar)); + Assert.assertEquals(result.getDeterminedPosition(), targetVariant.getStart()); + } + + // NOTE: This is an enfocement of a behavior that I consider to be a bug in DRAGEN. Specifically my assumption that we needn't ever concern + // ourselves with overlapping variants turns out to be false... As it turns out in DRAGEN, they are entirely accepting of construcitng a + // PD haplotype that is REF at bases that underly a spanning deletion... This means (for example) that if we have a 10 base undetermined + // deletion from 100-109 and we have a determined ref deletion at position 105-106, that we should STILL construct the halplotype with + // PD bases from 100-109 even though it means we are assigning that deletion at position 100 to be ref (essentially enforcing that we + // don't handle spanning deletions). Joint Deteciotion will likely override this behavior in the future. + @Test + public void testDeletionUnderlapingDeterminedBases() { + Haplotype ref = new Haplotype("AAAAAAAAAA".getBytes(), true, 500, TextCigarCodec.decode("10M")); + ref.setGenomeLocation(new SimpleInterval("20", 100, 110)); + + PartiallyDeterminedHaplotype result = PartiallyDeterminedHaplotypeComputationEngine.createNewPDHaplotypeFromEvents(ref, DEL_AA_105, true, Arrays.asList(DEL_AAAAAAA_102, DEL_AA_105)); + Assert.assertEquals(new String(result.getBases()), "AAAAAAAAAA"); + Assert.assertEquals(result.getAlternateBases(), new byte[]{0,0,0,2,0,0,0,0,4,0}); + Assert.assertEquals(result.getCigar(), TextCigarCodec.decode("10M")); + Assert.assertEquals(result.getDeterminedPosition(), DEL_AA_105.getStart()); + } +} \ No newline at end of file diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2IntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2IntegrationTest.java index e03ba0cbac4..d88ffc61553 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2IntegrationTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/mutect/Mutect2IntegrationTest.java @@ -20,6 +20,7 @@ import org.broadinstitute.hellbender.testutils.VariantContextTestUtils; import org.broadinstitute.hellbender.tools.walkers.annotator.AnnotationUtils; import org.broadinstitute.hellbender.tools.walkers.haplotypecaller.AssemblyBasedCallerArgumentCollection; +import org.broadinstitute.hellbender.tools.walkers.haplotypecaller.PileupDetectionArgumentCollection; import org.broadinstitute.hellbender.tools.walkers.haplotypecaller.ReadThreadingAssemblerArgumentCollection; import org.broadinstitute.hellbender.tools.walkers.haplotypecaller.ReferenceConfidenceMode; import org.broadinstitute.hellbender.tools.walkers.mutect.filtering.FilterMutectCalls; @@ -615,6 +616,40 @@ public void testMitochondria() { Assert.assertEquals(variants.get(0).getAttributeAsInt(GATKVCFConstants.ORIGINAL_CONTIG_MISMATCH_KEY, 0), 1741); } + // basic test on a small chunk of NA12878 mitochondria. This is intended to be a sanity check to ensure that the pileup-caller + // is A) Hooked up and functioning in Mutect and B) its arguments can be used to make reasonable calls when assembly doesn't detect variants + @Test + public void testPileupDetection() { + Utils.resetRandomGenerator(); + final File unfilteredVcf = createTempFile("unfiltered", ".vcf"); + + runMutect2(NA12878_MITO_BAM, unfilteredVcf, "chrM:1-1000", MITO_REF.getAbsolutePath(), Optional.empty(), + args -> args.add(M2ArgumentCollection.MITOCHONDRIA_MODE_LONG_NAME, true) + // Pileup-Detection arguments + .add(PileupDetectionArgumentCollection.PILEUP_DETECTION_LONG_NAME, true) + .add(PileupDetectionArgumentCollection.PILEUP_DETECTION_ENABLE_INDELS, true) + //.add(PileupDetectionArgumentCollection.PILEUP_DETECTION_ACTIVE_REGION_LOD_THRESHOLD_LONG_NAME, 0) // This is currently incompatible with Mutect 2 (isActive() doesn't store the original activity scores in M2Engine) + + // NOTE: These arguments are intended to force the assembly to fail at all sites in order to test what gets recovered by the pileup code + .add(ReadThreadingAssemblerArgumentCollection.KMER_SIZE_LONG_NAME, 1) + .add(ReadThreadingAssemblerArgumentCollection.DONT_INCREASE_KMER_SIZE_LONG_NAME, true) + ); + + final List variants = VariantContextTestUtils.streamVcf(unfilteredVcf).collect(Collectors.toList()); + final List variantKeys = variants.stream().map(VariantContextTestUtils::keyForVariant).collect(Collectors.toList()); + System.out.print(variantKeys); + + // NOTE: This list is un-principled, its simply asserting that we found SOMETHING with the pileupcaller we should because assembly is broken + // this is not set in stone, future changes to the pileupcaller/Mutect2 might cause this list to change + final List expectedKeys = Arrays.asList( + "chrM:152-152 T*, [C]", + "chrM:263-263 A*, [G]", + "chrM:302-302 A*, [AC]", //Pileup-calling doesn't detect overlapping indels as well as assembly + "chrM:310-310 T*, [C, TC]", + "chrM:750-750 A*, [G]"); + Assert.assertTrue(variantKeys.containsAll(expectedKeys)); + } + /** * Several difficult force calling sites including regression test for a thorny force calling bug involving * T -> A at chrM:8316. Previously this call was lost while trimming the assemblyResultSet because every haplotype diff --git a/src/test/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMMLikelihoodCalculationEngineUnitTest.java b/src/test/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMMLikelihoodCalculationEngineUnitTest.java new file mode 100644 index 00000000000..f91e797a964 --- /dev/null +++ b/src/test/java/org/broadinstitute/hellbender/utils/pairhmm/PDPairHMMLikelihoodCalculationEngineUnitTest.java @@ -0,0 +1,67 @@ +package org.broadinstitute.hellbender.utils.pairhmm; + +import htsjdk.samtools.SAMUtils; +import htsjdk.samtools.util.BufferedLineReader; +import org.apache.commons.lang.ArrayUtils; +import org.broadinstitute.gatk.nativebindings.pairhmm.PairHMMNativeArguments; +import org.broadinstitute.hellbender.GATKBaseTest; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; + +public class PDPairHMMLikelihoodCalculationEngineUnitTest extends GATKBaseTest { + + static final String DRAGEN_GATK_TEST_ASSERT_FILE = largeFileTestDir + "expected.PDHMM.hmmresults.txt"; + static final double DOUBLE_ASSERTION_DELTA = 0.0001; + + @DataProvider(name="PDPairHMMResultsModes") + public Object[][] PairHMMResultsModes() { + return new Object[][]{ + {PDPairHMM.Implementation.LOGLESS_CACHING}, + }; + } + + // This test is intended to make it simple to take the outputs of the PDHMM from one impelementation and test its outputs over another. + @Test(dataProvider = "PDPairHMMResultsModes") + public void testInputReconstitutionDRAGEN_GATK_TEST_FILE(PDPairHMM.Implementation implementation) { + final PDPairHMM pdPariHMM = implementation.makeNewHMM(new PairHMMNativeArguments()); + + try (final FileInputStream fis= new FileInputStream(DRAGEN_GATK_TEST_ASSERT_FILE); + final BufferedLineReader br = new BufferedLineReader(fis)) { + + br.lines().skip(1).forEach(line -> { + + final String[] split = line.split("\t"); + //debugOutputStream.write("\n" + new String(alleleBases) + "\t" + Arrays.toString(allelePDBases) + "\t" + new String(readBases) + "\t" + SAMUtils.phredToFastq(readQuals) + "\t" + SAMUtils.phredToFastq(readInsQuals) + "\t" + SAMUtils.phredToFastq(readDelQuals) + "\t" + SAMUtils.phredToFastq(overallGCP) + "\t" + String.format("%e",lk)); + byte[] alleleBases = split[0].getBytes(StandardCharsets.UTF_8); + byte[] allelePDBases = ArrayUtils.toPrimitive( + Arrays.stream(split[1].substring(1, split[1].length() - 1).split(",")) + .map(num -> Byte.parseByte(num.trim())).toArray(Byte[]::new)); + byte[] readBases = split[2].getBytes(StandardCharsets.UTF_8); + byte[] readQuals = SAMUtils.fastqToPhred(split[3]); + byte[] readInsQuals = SAMUtils.fastqToPhred(split[4]); + byte[] readDelQuals = SAMUtils.fastqToPhred(split[5]); + byte[] overallGCP = SAMUtils.fastqToPhred(split[6]); + double expected = Double.parseDouble(split[7]); + + // There will be Negative infinities in here in the case that we skipped likelihood computation for a variant + if (expected != Double.NEGATIVE_INFINITY) { + pdPariHMM.initialize(200, 500);// These are arbitrary initializations that should have no bearing on this operation + double actual = pdPariHMM.computeReadLikelihoodGivenHaplotypeLog10(alleleBases, allelePDBases, readBases, readQuals, readInsQuals, readDelQuals, overallGCP, false, null, null); + Assert.assertEquals(actual, expected, DOUBLE_ASSERTION_DELTA, String.format("Mismatching score actual: %e expected: %e computed on line %s", actual, expected, line)); + } + }); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/src/test/resources/large/expected.PDHMM.hmmresults.txt b/src/test/resources/large/expected.PDHMM.hmmresults.txt new file mode 100644 index 00000000000..846e1c4a03a --- /dev/null +++ b/src/test/resources/large/expected.PDHMM.hmmresults.txt @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c1c69923b5820679c9cc6f25a66ed75c3c561340228ea690eed46ea448c0689a +size 22726245 diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.378.gatk4.vcf b/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.378.gatk4.vcf new file mode 100644 index 00000000000..2d7bc678e8a --- /dev/null +++ b/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.378.gatk4.vcf @@ -0,0 +1,278 @@ +##fileformat=VCFv4.2 +##FILTER= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##FORMAT= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##INFO= +##contig= +##contig= +#CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA12878 +20 10000117 . C T 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.136;DP=66;ExcessHet=0.0000;FS=11.007;MLEAC=1;MLEAF=0.500;MQ=59.72;MQRankSum=0.913;QD=0.60;ReadPosRankSum=-0.223;SOR=1.538 GT:AD:DP:GP:GQ:PG:PL 0/1:36,28:64:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10000211 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.000;DP=56;ExcessHet=0.0000;FS=5.587;MLEAC=1;MLEAF=0.500;MQ=59.67;MQRankSum=1.037;QD=0.75;ReadPosRankSum=0.675;SOR=0.918 GT:AD:DP:GP:GQ:PG:PL 0/1:27,27:54:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10000439 . T G 277.22 . AC=2;AF=1.00;AN=2;DP=82;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.86;QD=3.47;SOR=1.236 GT:AD:DP:GP:GQ:PG:PL 1/1:0,80:80:277.22,236.99,0:99:0,34.77,37.78:315,240,0 +20 10000598 . T A 187.22 . AC=2;AF=1.00;AN=2;DP=51;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=55.45;QD=3.74;SOR=1.270 GT:AD:DP:GP:GQ:PG:PL 1/1:0,50:50:187.22,146.99,0:99:0,34.77,37.78:225,150,0 +20 10000694 . G A 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.599;DP=86;ExcessHet=0.0000;FS=1.822;MLEAC=1;MLEAF=0.500;MQ=48.63;MQRankSum=-5.114;QD=0.47;ReadPosRankSum=0.657;SOR=0.566 GT:AD:DP:GP:GQ:PG:PL 0/1:45,37:82:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10000758 . T A 323.22 . AC=2;AF=1.00;AN=2;DP=97;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=53.23;QD=3.40;SOR=0.802 GT:AD:DP:GP:GQ:PG:PL 1/1:0,95:95:323.22,282.99,0:99:0,34.77,37.78:361,286,0 +20 10001019 . T G 24.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.344;DP=72;ExcessHet=0.0000;FS=2.110;MLEAC=1;MLEAF=0.500;MQ=48.11;MQRankSum=-7.093;QD=0.37;ReadPosRankSum=-0.742;SOR=0.700 GT:AD:DP:GP:GQ:PG:PL 0/1:40,26:66:24.23,0,43.01:24:0,34.77,37.78:59,0,40 +20 10001298 . T A 256.22 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=54.22;QD=3.51;SOR=0.963 GT:AD:DP:GP:GQ:PG:PL 1/1:0,73:73:256.22,216.99,0:99:0,34.77,37.78:294,220,0 +20 10001436 . A AAGGCT 193.99 . AC=2;AF=1.00;AN=2;DP=60;DRAGstrInfo=1,3;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=40.93;QD=3.73;SOR=3.014 GT:AD:DP:GP:GQ:PG:PL 1/1:0,52:52:193.99,152.99,0:99:0,33,36.01:230,156,0 +20 10001474 . C T 256.22 . AC=2;AF=1.00;AN=2;DP=77;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=44.03;QD=3.51;SOR=1.516 GT:AD:DP:GP:GQ:PG:PL 1/1:0,73:73:256.22,215.99,0:99:0,34.77,37.78:294,219,0 +20 10001617 . C A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.143;DP=106;ExcessHet=0.0000;FS=13.163;MLEAC=1;MLEAF=0.500;MQ=59.03;MQRankSum=1.394;QD=0.39;ReadPosRankSum=-0.348;SOR=1.395 GT:AD:DP:GP:GQ:PG:PL 0/1:52,52:104:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10001628 . G A 322.22 . AC=2;AF=1.00;AN=2;DP=99;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.20;QD=3.39;SOR=1.053 GT:AD:DP:GP:GQ:PG:PL 1/1:0,95:95:322.22,281.99,0:99:0,34.77,37.78:360,285,0 +20 10001661 . T C 283.22 . AC=2;AF=1.00;AN=2;DP=85;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.41;QD=3.45;SOR=1.220 GT:AD:DP:GP:GQ:PG:PL 1/1:0,82:82:283.22,242.99,0:99:0,34.77,37.78:321,246,0 +20 10001670 . T G 284.22 . AC=2;AF=1.00;AN=2;DP=85;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=57.57;QD=3.47;SOR=1.022 GT:AD:DP:GP:GQ:PG:PL 1/1:0,82:82:284.22,243.99,0:99:0,34.77,37.78:322,247,0 +20 10002058 . T G 259.22 . AC=2;AF=1.00;AN=2;BaseQRankSum=1.913;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=57.54;MQRankSum=2.847;QD=3.37;ReadPosRankSum=0.563;SOR=0.753 GT:AD:DP:GP:GQ:PG:PL 1/1:1,76:77:259.22,218.99,0:99:0,34.77,37.78:297,222,0 +20 10002099 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.390;DP=69;ExcessHet=0.0000;FS=2.191;MLEAC=1;MLEAF=0.500;MQ=55.65;MQRankSum=-1.284;QD=0.60;ReadPosRankSum=0.147;SOR=0.428 GT:AD:DP:GP:GQ:PG:PL 0/1:27,40:67:40.23,0,38.01:36:0,34.77,37.78:75,0,35 +20 10002138 . C G 205.22 . AC=2;AF=1.00;AN=2;DP=61;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=55.42;QD=3.66;SOR=0.841 GT:AD:DP:GP:GQ:PG:PL 1/1:0,56:56:205.22,164.99,0:99:0,34.77,37.78:243,168,0 +20 10002142 . G C 202.22 . AC=2;AF=1.00;AN=2;DP=60;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=54.86;QD=3.68;SOR=0.729 GT:AD:DP:GP:GQ:PG:PL 1/1:0,55:55:202.22,161.99,0:99:0,34.77,37.78:240,165,0 +20 10002458 . G GT,GTTT 89 . AC=1,1;AF=0.500,0.500;AN=2;BaseQRankSum=0.762;DP=71;DRAGstrInfo=1,11;DRAGstrParams=24.5,10.0,8.0;ExcessHet=0.0000;FS=0.000;MLEAC=1,1;MLEAF=0.500,0.500;MQ=48.98;MQRankSum=0.963;QD=3.18;ReadPosRankSum=1.371;SOR=1.445 GT:AD:DP:GP:GQ:PG:PL 1/2:2,5,21:28:89,295,43.01,49,0,32.01:32:0,8,11.01,8,16,11.01:105,303,48,57,0,37 +20 10002470 . C T 227.22 . AC=2;AF=1.00;AN=2;DP=69;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=48.21;QD=3.39;SOR=0.784 GT:AD:DP:GP:GQ:PG:PL 1/1:0,67:67:227.22,186.99,0:99:0,34.77,37.78:265,190,0 +20 10002625 . G T 229.22 . AC=2;AF=1.00;AN=2;DP=65;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.07;QD=3.58;SOR=1.127 GT:AD:DP:GP:GQ:PG:PL 1/1:0,64:64:229.22,189.99,0:99:0,34.77,37.78:267,193,0 +20 10003021 . C T 223.22 . AC=2;AF=1.00;AN=2;DP=65;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.07;QD=3.60;SOR=1.057 GT:AD:DP:GP:GQ:PG:PL 1/1:0,62:62:223.22,183.99,0:99:0,34.77,37.78:261,187,0 +20 10003358 . A C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.004;DP=91;ExcessHet=0.0000;FS=0.844;MLEAC=1;MLEAF=0.500;MQ=59.80;MQRankSum=1.011;QD=0.45;ReadPosRankSum=-1.355;SOR=0.572 GT:AD:DP:GP:GQ:PG:PL 0/1:45,44:89:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10003651 . T C 316.22 . AC=2;AF=1.00;AN=2;DP=95;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.21;QD=3.40;SOR=1.511 GT:AD:DP:GP:GQ:PG:PL 1/1:0,93:93:316.22,275.99,0:99:0,34.77,37.78:354,279,0 +20 10003692 . A G 241.22 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.47;QD=3.55;SOR=1.352 GT:AD:DP:GP:GQ:PG:PL 1/1:0,68:68:241.22,201.99,0:99:0,34.77,37.78:279,205,0 +20 10003832 . G A 235.22 . AC=2;AF=1.00;AN=2;DP=68;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=57.22;QD=3.56;SOR=1.473 GT:AD:DP:GP:GQ:PG:PL 1/1:0,66:66:235.22,195.99,0:99:0,34.77,37.78:273,199,0 +20 10004094 . A C 194.22 . AC=2;AF=1.00;AN=2;DP=57;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.90;QD=3.66;SOR=1.524 GT:AD:DP:GP:GQ:PG:PL 1/1:0,53:53:194.22,153.99,0:99:0,34.77,37.78:232,157,0 +20 10004147 . A G 197.22 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.87;QD=3.72;SOR=1.179 GT:AD:DP:GP:GQ:PG:PL 1/1:0,53:53:197.22,155.99,0:99:0,34.77,37.78:235,159,0 +20 10004193 . G T 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.276;DP=79;ExcessHet=0.0000;FS=2.311;MLEAC=1;MLEAF=0.500;MQ=55.86;MQRankSum=3.395;QD=0.78;ReadPosRankSum=1.833;SOR=1.071 GT:AD:DP:GP:GQ:PG:PL 0/1:24,29:53:41.23,0,43.01:39:0,34.77,37.78:76,0,40 +20 10004351 . C G 247.22 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.05;QD=3.53;SOR=0.874 GT:AD:DP:GP:GQ:PG:PL 1/1:0,70:70:247.22,207.99,0:99:0,34.77,37.78:285,211,0 +20 10004389 . T G 223.22 . AC=2;AF=1.00;AN=2;DP=64;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.46;QD=3.60;SOR=1.143 GT:AD:DP:GP:GQ:PG:PL 1/1:0,62:62:223.22,183.99,0:99:0,34.77,37.78:261,187,0 +20 10004610 . A C 310.22 . AC=2;AF=1.00;AN=2;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.51;QD=3.41;SOR=0.715 GT:AD:DP:GP:GQ:PG:PL 1/1:0,91:91:310.22,269.99,0:99:0,34.77,37.78:348,273,0 +20 10004725 . A G 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.142;DP=67;ExcessHet=0.0000;FS=13.488;MLEAC=1;MLEAF=0.500;MQ=55.42;MQRankSum=3.059;QD=0.59;ReadPosRankSum=2.173;SOR=0.482 GT:AD:DP:GP:GQ:PG:PL 0/1:35,31:66:39.23,0,44.01:38:0,34.77,37.78:74,0,41 +20 10004769 . TAAAACTATGC T 38 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.735;DP=84;DRAGstrInfo=1,4;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=3.758;MLEAC=1;MLEAF=0.500;MQ=52.85;MQRankSum=-6.625;QD=0.59;ReadPosRankSum=2.134;SOR=1.306 GT:AD:DP:GP:GQ:PG:PL 0/1:37,27:64:38,0,43.01:37:0,33,36.01:71,0,40 +20 10004874 . A C 299.22 . AC=2;AF=1.00;AN=2;DP=88;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.34;QD=3.44;SOR=1.286 GT:AD:DP:GP:GQ:PG:PL 1/1:0,87:87:299.22,257.99,0:99:0,34.77,37.78:337,261,0 +20 10004887 . A G 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.356;DP=87;ExcessHet=0.0000;FS=1.793;MLEAC=1;MLEAF=0.500;MQ=59.47;MQRankSum=-0.067;QD=0.46;ReadPosRankSum=-1.114;SOR=0.984 GT:AD:DP:GP:GQ:PG:PL 0/1:45,40:85:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10005010 . C T 256.22 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=3.51;SOR=1.257 GT:AD:DP:GP:GQ:PG:PL 1/1:0,73:73:256.22,216.99,0:99:0,34.77,37.78:294,220,0 +20 10005427 . C T 202.22 . AC=2;AF=1.00;AN=2;DP=58;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.60;QD=3.68;SOR=0.729 GT:AD:DP:GP:GQ:PG:PL 1/1:0,55:55:202.22,161.99,0:99:0,34.77,37.78:240,165,0 +20 10005499 . A G 266.22 . AC=2;AF=1.00;AN=2;DP=78;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=3.50;SOR=1.121 GT:AD:DP:GP:GQ:PG:PL 1/1:0,76:76:266.22,225.99,0:99:0,34.77,37.78:304,229,0 +20 10005587 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.834;DP=75;ExcessHet=0.0000;FS=1.955;MLEAC=1;MLEAF=0.500;MQ=59.75;MQRankSum=-0.972;QD=0.56;ReadPosRankSum=0.248;SOR=0.848 GT:AD:DP:GP:GQ:PG:PL 0/1:36,36:72:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10005723 . A G 295.22 . AC=2;AF=1.00;AN=2;DP=89;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.79;QD=3.43;SOR=0.947 GT:AD:DP:GP:GQ:PG:PL 1/1:0,86:86:295.22,254.99,0:99:0,34.77,37.78:333,258,0 +20 10006291 . G A 27.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.311;DP=86;ExcessHet=0.0000;FS=0.853;MLEAC=1;MLEAF=0.500;MQ=59.30;MQRankSum=-1.081;QD=0.32;ReadPosRankSum=-1.447;SOR=0.659 GT:AD:DP:GP:GQ:PG:PL 0/1:53,31:84:27.23,0,43.01:27:0,34.77,37.78:62,0,40 +20 10006404 . A C 268.22 . AC=2;AF=1.00;AN=2;DP=84;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.23;QD=3.48;SOR=1.463 GT:AD:DP:GP:GQ:PG:PL 1/1:0,77:77:268.22,227.99,0:99:0,34.77,37.78:306,231,0 +20 10006682 . T A 259.22 . AC=2;AF=1.00;AN=2;DP=77;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.46;QD=3.50;SOR=1.209 GT:AD:DP:GP:GQ:PG:PL 1/1:0,74:74:259.22,218.99,0:99:0,34.77,37.78:297,222,0 +20 10006819 . AAAAC A 212.99 . AC=2;AF=1.00;AN=2;DP=80;DRAGstrInfo=4,7;DRAGstrParams=27.0,2.5,5.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.79;QD=3.67;SOR=0.762 GT:AD:DP:GP:GQ:PG:PL 1/1:0,58:58:212.99,171.99,0:99:0,5,8.01:221,175,0 +20 10007150 . G C 34.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.476;DP=68;ExcessHet=0.0000;FS=5.048;MLEAC=1;MLEAF=0.500;MQ=59.66;MQRankSum=0.000;QD=0.54;ReadPosRankSum=-0.077;SOR=0.746 GT:AD:DP:GP:GQ:PG:PL 0/1:38,25:63:34.23,0,43.01:34:0,34.77,37.78:69,0,40 +20 10007175 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.249;DP=66;ExcessHet=0.0000;FS=2.211;MLEAC=1;MLEAF=0.500;MQ=59.65;MQRankSum=1.319;QD=0.66;ReadPosRankSum=-1.213;SOR=0.434 GT:AD:DP:GP:GQ:PG:PL 0/1:23,38:61:40.23,0,35.01:34:0,34.77,37.78:75,0,32 +20 10007352 . C T 244.22 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=3.54;SOR=1.054 GT:AD:DP:GP:GQ:PG:PL 1/1:0,69:69:244.22,204.99,0:99:0,34.77,37.78:282,208,0 +20 10007531 . A G 253.22 . AC=2;AF=1.00;AN=2;DP=74;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.75;QD=3.52;SOR=1.577 GT:AD:DP:GP:GQ:PG:PL 1/1:0,72:72:253.22,213.99,0:99:0,34.77,37.78:291,217,0 +20 10007980 . A C 314.22 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.40;QD=3.42;SOR=1.038 GT:AD:DP:GP:GQ:PG:PL 1/1:0,92:92:314.22,272.99,0:99:0,34.77,37.78:352,276,0 +20 10008029 . T TA 200.99 . AC=2;AF=1.00;AN=2;BaseQRankSum=0.363;DP=98;DRAGstrInfo=1,9;DRAGstrParams=31.5,10.0,13.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.82;MQRankSum=0.645;QD=2.58;ReadPosRankSum=-1.378;SOR=0.796 GT:AD:DP:GP:GQ:PG:PL 1/1:3,75:78:200.99,158.99,0:99:0,13,16.01:217,162,0 +20 10008146 . TA T 248.99 . AC=2;AF=1.00;AN=2;DP=77;DRAGstrInfo=1,7;DRAGstrParams=41.5,10.0,20.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.56;QD=3.56;SOR=0.874 GT:AD:DP:GP:GQ:PG:PL 1/1:0,70:70:248.99,207.99,0:99:0,20,23.01:272,211,0 +20 10008221 . T C 278.22 . AC=2;AF=1.00;AN=2;DP=81;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.17;QD=3.48;SOR=0.850 GT:AD:DP:GP:GQ:PG:PL 1/1:0,80:80:278.22,236.99,0:99:0,34.77,37.78:316,240,0 +20 10008458 . T G 250.22 . AC=2;AF=1.00;AN=2;DP=72;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.39;QD=3.52;SOR=0.971 GT:AD:DP:GP:GQ:PG:PL 1/1:0,71:71:250.22,209.99,0:99:0,34.77,37.78:288,213,0 +20 10008742 . G T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.104;DP=63;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=37.99;MQRankSum=-1.341;QD=0.76;ReadPosRankSum=0.196;SOR=0.592 GT:AD:DP:GP:GQ:PG:PL 0/1:25,28:53:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10008758 . C CA 100.99 . AC=2;AF=1.00;AN=2;BaseQRankSum=0.095;DP=60;DRAGstrInfo=1,14;DRAGstrParams=22.8,10.0,6.0;ExcessHet=0.0000;FS=4.643;MLEAC=2;MLEAF=1.00;MQ=37.75;MQRankSum=-1.009;QD=2.46;ReadPosRankSum=-0.286;SOR=0.477 GT:AD:DP:GP:GQ:PG:PL 1/1:4,37:41:100.99,60.99,0:61:0,6,9.01:110,64,0 +20 10008921 . C CA 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.697;DP=66;DRAGstrInfo=1,13;DRAGstrParams=22.8,10.0,7.0;ExcessHet=0.0000;FS=2.864;MLEAC=1;MLEAF=0.500;MQ=54.46;MQRankSum=-1.827;QD=1.11;ReadPosRankSum=-0.411;SOR=0.895 GT:AD:DP:GP:GQ:PG:PL 0/1:18,19:37:41,0,43.01:39:0,7,10.01:48,0,40 +20 10008948 . TA T 173.99 . AC=2;AF=1.00;AN=2;DP=63;DRAGstrInfo=1,3;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.81;QD=3.87;SOR=1.714 GT:AD:DP:GP:GQ:PG:PL 1/1:0,45:45:173.99,131.99,0:99:0,33,36.01:210,135,0 +20 10008952 . CACACACACACA CCACACACACA,C 443 . AC=1,1;AF=0.500,0.500;AN=2;DP=70;DRAGstrInfo=2,23;DRAGstrParams=21.5,5.0,3.0;ExcessHet=0.0000;FS=0.000;MLEAC=1,1;MLEAF=0.500,0.500;MQ=50.75;QD=11.97;SOR=1.981 GT:AD:DP:GP:GQ:PG:PL 1/2:0,19,18:37:443,708,42.01,401,0,44.01:40:0,3,6.01,3,6,6.01:449,711,42,404,0,44 +20 10009227 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.220;DP=63;ExcessHet=0.0000;FS=9.110;MLEAC=1;MLEAF=0.500;MQ=57.21;MQRankSum=1.428;QD=0.65;ReadPosRankSum=-1.159;SOR=0.281 GT:AD:DP:GP:GQ:PG:PL 0/1:23,39:62:40.23,0,34.01:33:0,34.77,37.78:75,0,31 +20 10009246 . A G 268.22 . AC=2;AF=1.00;AN=2;DP=77;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.09;QD=3.48;SOR=0.887 GT:AD:DP:GP:GQ:PG:PL 1/1:0,77:77:268.22,227.99,0:99:0,34.77,37.78:306,231,0 +20 10009400 . T A 259.22 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=3.50;SOR=0.804 GT:AD:DP:GP:GQ:PG:PL 1/1:0,74:74:259.22,219.99,0:99:0,34.77,37.78:297,223,0 +20 10009512 . C G 268.22 . AC=2;AF=1.00;AN=2;DP=79;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.51;QD=3.48;SOR=1.223 GT:AD:DP:GP:GQ:PG:PL 1/1:0,77:77:268.22,227.99,0:99:0,34.77,37.78:306,231,0 +20 10009719 . A G 215.22 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.41;QD=3.59;SOR=0.986 GT:AD:DP:GP:GQ:PG:PL 1/1:0,60:60:215.22,174.99,0:99:0,34.77,37.78:253,178,0 +20 10009795 . A G 178.22 . AC=2;AF=1.00;AN=2;DP=57;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=57.10;QD=3.79;SOR=1.514 GT:AD:DP:GP:GQ:PG:PL 1/1:0,47:47:178.22,137.99,0:99:0,34.77,37.78:216,141,0 +20 10009844 . G A 43.22 . AC=2;AF=1.00;AN=2;BaseQRankSum=1.360;DP=62;ExcessHet=0.0000;FS=4.494;MLEAC=1;MLEAF=0.500;MQ=52.40;MQRankSum=3.040;QD=1.54;ReadPosRankSum=-2.702;SOR=0.172 GT:AD:DP:GP:GQ:PG:PL 1/1:5,23:28:43.22,2.99,0:3:0,34.77,37.78:81,6,0 +20 10009871 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.215;DP=68;ExcessHet=0.0000;FS=1.236;MLEAC=1;MLEAF=0.500;MQ=50.77;MQRankSum=1.639;QD=1.03;ReadPosRankSum=0.576;SOR=0.644 GT:AD:DP:GP:GQ:PG:PL 0/1:20,19:39:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10009875 . A AGGGAGG,G 241.23 . AC=1,1;AF=0.500,0.500;AN=2;DP=68;DRAGstrInfo=2,22;DRAGstrParams=21.5,5.0,3.0;ExcessHet=0.0000;FS=4.393;MLEAC=1,1;MLEAF=0.500,0.500;MQ=50.37;MQRankSum=0.891;QD=10.97;ReadPosRankSum=0.158;SOR=1.326 GT:AD:DP:GP:GQ:PG:PL 1/2:1,6,15:22:241.23,453.23,43.24,201,0,42.01:40:0,3,6.01,34.77,37.77,37.78:279,488,75,204,0,42 +20 10009879 . A G 182.22 . AC=2;AF=1.00;AN=2;BaseQRankSum=1.745;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.17;MQRankSum=-0.702;QD=3.25;ReadPosRankSum=0.155;SOR=0.490 GT:AD:DP:GP:GQ:PG:PL 1/1:1,55:56:182.22,140.99,0:99:0,34.77,37.78:220,144,0 +20 10009883 . A G 180.22 . AC=2;AF=1.00;AN=2;DP=68;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.56;QD=3.68;SOR=1.473 GT:AD:DP:GP:GQ:PG:PL 1/1:0,49:49:180.22,138.99,0:99:0,34.77,37.78:218,142,0 +20 10010393 . T G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.075;DP=81;ExcessHet=0.0000;FS=13.526;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=-1.302;QD=0.50;ReadPosRankSum=-1.820;SOR=0.595 GT:AD:DP:GP:GQ:PG:PL 0/1:37,43:80:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10010536 . G GA 281.99 . AC=2;AF=1.00;AN=2;DP=91;DRAGstrInfo=1,6;DRAGstrParams=46.5,10.0,24.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=61.76;QD=3.48;SOR=0.876 GT:AD:DP:GP:GQ:PG:PL 1/1:0,81:81:281.99,239.99,0:99:0,24,27.01:309,243,0 +20 10010766 . T G 235.22 . AC=2;AF=1.00;AN=2;DP=70;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=3.56;SOR=0.818 GT:AD:DP:GP:GQ:PG:PL 1/1:0,66:66:235.22,195.99,0:99:0,34.77,37.78:273,199,0 +20 10010832 . T C 262.22 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.50;QD=3.50;SOR=1.091 GT:AD:DP:GP:GQ:PG:PL 1/1:0,75:75:262.22,222.99,0:99:0,34.77,37.78:300,226,0 +20 10011075 . C T 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.385;DP=86;ExcessHet=0.0000;FS=0.818;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.46;ReadPosRankSum=-1.083;SOR=0.853 GT:AD:DP:GP:GQ:PG:PL 0/1:45,40:85:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10011309 . T C 268.22 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=3.48;SOR=1.223 GT:AD:DP:GP:GQ:PG:PL 1/1:0,77:77:268.22,227.99,0:99:0,34.77,37.78:306,231,0 +20 10011517 . GA G 36 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.924;DP=100;DRAGstrInfo=1,14;DRAGstrParams=22.8,10.0,6.0;ExcessHet=0.0000;FS=2.130;MLEAC=1;MLEAF=0.500;MQ=59.91;MQRankSum=2.041;QD=0.47;ReadPosRankSum=0.603;SOR=0.412 GT:AD:DP:GP:GQ:PG:PL 0/1:46,30:76:36,0,44.01:35:0,6,9.01:42,0,41 +20 10011666 . C T 256.22 . AC=2;AF=1.00;AN=2;DP=74;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.06;QD=3.51;SOR=1.103 GT:AD:DP:GP:GQ:PG:PL 1/1:0,73:73:256.22,216.99,0:99:0,34.77,37.78:294,220,0 +20 10011939 . C T 226.22 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=55.79;QD=3.59;SOR=1.270 GT:AD:DP:GP:GQ:PG:PL 1/1:0,63:63:226.22,186.99,0:99:0,34.77,37.78:264,190,0 +20 10012021 . CA C 239.99 . AC=2;AF=1.00;AN=2;DP=76;DRAGstrInfo=1,8;DRAGstrParams=35.5,10.0,15.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=55.65;QD=3.58;SOR=1.146 GT:AD:DP:GP:GQ:PG:PL 1/1:0,67:67:239.99,198.99,0:99:0,15,18.01:258,202,0 +20 10012362 . G T 115.22 . AC=2;AF=1.00;AN=2;DP=28;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=50.41;QD=4.43;SOR=3.611 GT:AD:DP:GP:GQ:PG:PL 1/1:0,26:26:115.22,74.99,0:75:0,34.77,37.78:153,78,0 +20 10012384 . T C 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.508;DP=20;ExcessHet=0.0000;FS=11.326;MLEAC=1;MLEAF=0.500;MQ=50.84;MQRankSum=-0.708;QD=1.96;ReadPosRankSum=1.255;SOR=0.021 GT:AD:DP:GP:GQ:PG:PL 0/1:11,9:20:39.23,0,34.01:33:0,34.77,37.78:74,0,31 +20 10012387 . T C 89.22 . AC=2;AF=1.00;AN=2;DP=19;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=50.31;QD=4.96;SOR=2.833 GT:AD:DP:GP:GQ:PG:PL 1/1:0,18:18:89.22,48.99,0:49:0,34.77,37.78:127,52,0 +20 10012479 . A G 99.22 . AC=2;AF=1.00;AN=2;DP=27;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=47.40;QD=4.72;SOR=0.784 GT:AD:DP:GP:GQ:PG:PL 1/1:0,21:21:99.22,58.99,0:59:0,34.77,37.78:137,62,0 +20 10012498 . C G 85.22 . AC=2;AF=1.00;AN=2;DP=27;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=43.08;QD=5.33;SOR=1.244 GT:AD:DP:GP:GQ:PG:PL 1/1:0,16:16:85.22,44.99,0:45:0,34.77,37.78:123,48,0 +20 10012518 . T C 84.22 . AC=2;AF=1.00;AN=2;DP=27;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=41.72;QD=5.26;SOR=1.244 GT:AD:DP:GP:GQ:PG:PL 1/1:0,16:16:84.22,43.99,0:44:0,34.77,37.78:122,47,0 +20 10012521 . C T 36.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.751;DP=26;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=39.53;MQRankSum=-0.392;QD=2.01;ReadPosRankSum=1.972;SOR=0.446 GT:AD:DP:GP:GQ:PG:PL 0/1:12,6:18:36.23,0,43.01:35:0,34.77,37.78:71,0,40 +20 10012570 . G GCA 87.99 . AC=2;AF=1.00;AN=2;DP=21;DRAGstrInfo=1,6;DRAGstrParams=46.5,10.0,24.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=31.73;QD=5.18;SOR=3.383 GT:AD:DP:GP:GQ:PG:PL 1/1:0,17:17:87.99,47.99,0:48:0,24,27.01:115,51,0 +20 10012572 . GT G 87.99 . AC=2;AF=1.00;AN=2;DP=22;DRAGstrInfo=1,1;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=32.85;QD=5.18;SOR=3.383 GT:AD:DP:GP:GQ:PG:PL 1/1:0,17:17:87.99,47.99,0:48:0,33,36.01:124,51,0 +20 10012631 . C CG 40 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.897;DP=26;DRAGstrInfo=1,1;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=8.909;MLEAC=1;MLEAF=0.500;MQ=43.83;MQRankSum=-1.843;QD=1.54;ReadPosRankSum=-2.212;SOR=0.046 GT:AD:DP:GP:GQ:PG:PL 0/1:9,17:26:40,0,27.01:27:0,33,36.01:73,0,24 +20 10012636 . G C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.559;DP=27;ExcessHet=0.0000;FS=8.909;MLEAC=1;MLEAF=0.500;MQ=44.53;MQRankSum=-1.524;QD=1.55;ReadPosRankSum=-1.899;SOR=0.046 GT:AD:DP:GP:GQ:PG:PL 0/1:9,17:26:40.23,0,27.01:27:0,34.77,37.78:75,0,24 +20 10012714 . G C 145.22 . AC=2;AF=1.00;AN=2;DP=40;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.86;QD=4.03;SOR=2.712 GT:AD:DP:GP:GQ:PG:PL 1/1:0,36:36:145.22,104.99,0:99:0,34.77,37.78:183,108,0 +20 10012751 . T C 129.22 . AC=2;AF=1.00;AN=2;DP=42;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=49.40;QD=4.17;SOR=0.892 GT:AD:DP:GP:GQ:PG:PL 1/1:0,31:31:129.22,88.99,0:89:0,34.77,37.78:167,92,0 +20 10013119 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.541;DP=63;ExcessHet=0.0000;FS=3.570;MLEAC=1;MLEAF=0.500;MQ=50.94;MQRankSum=-1.246;QD=0.67;ReadPosRankSum=0.355;SOR=0.362 GT:AD:DP:GP:GQ:PG:PL 0/1:29,31:60:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10013574 . G A 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.309;DP=73;ExcessHet=0.0000;FS=4.921;MLEAC=1;MLEAF=0.500;MQ=57.84;MQRankSum=-0.578;QD=0.55;ReadPosRankSum=0.905;SOR=1.329 GT:AD:DP:GP:GQ:PG:PL 0/1:38,33:71:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10014990 . C CAT 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.957;DP=91;DRAGstrInfo=2,5;DRAGstrParams=33.3,5.0,18.0;ExcessHet=0.0000;FS=2.050;MLEAC=1;MLEAF=0.500;MQ=60.54;MQRankSum=2.773;QD=0.53;ReadPosRankSum=-0.305;SOR=0.455 GT:AD:DP:GP:GQ:PG:PL 0/1:38,40:78:41,0,43.01:39:0,18,21.01:59,0,40 +20 10015679 . C T 23.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.258;DP=13;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=2.11;ReadPosRankSum=0.880;SOR=0.859 GT:AD:DP:GP:GQ:PG:PL 0/1:5,6:11:23.23,0,43.01:23:0,34.77,37.78:58,0,40 +20 10015761 . T C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.982;DP=22;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.95;MQRankSum=1.294;QD=1.83;ReadPosRankSum=1.805;SOR=0.352 GT:AD:DP:GP:GQ:PG:PL 0/1:9,13:22:40.23,0,39.01:37:0,34.77,37.78:75,0,36 +20 10018158 . G C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.213;DP=91;ExcessHet=0.0000;FS=0.808;MLEAC=1;MLEAF=0.500;MQ=59.80;MQRankSum=1.118;QD=0.46;ReadPosRankSum=1.179;SOR=0.834 GT:AD:DP:GP:GQ:PG:PL 0/1:40,48:88:40.23,0,41.01:38:0,34.77,37.78:75,0,38 +20 10018555 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.755;DP=85;ExcessHet=0.0000;FS=4.291;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.50;ReadPosRankSum=0.604;SOR=0.599 GT:AD:DP:GP:GQ:PG:PL 0/1:36,45:81:40.23,0,41.01:38:0,34.77,37.78:75,0,38 +20 10019093 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.659;DP=70;ExcessHet=0.0000;FS=0.909;MLEAC=1;MLEAF=0.500;MQ=59.34;MQRankSum=1.486;QD=0.57;ReadPosRankSum=-0.329;SOR=0.711 GT:AD:DP:GP:GQ:PG:PL 0/1:34,36:70:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10020229 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.961;DP=85;ExcessHet=0.0000;FS=0.827;MLEAC=1;MLEAF=0.500;MQ=59.24;MQRankSum=0.711;QD=0.48;ReadPosRankSum=-0.520;SOR=0.570 GT:AD:DP:GP:GQ:PG:PL 0/1:39,45:84:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10023689 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.195;DP=83;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.50;MQRankSum=1.843;QD=0.49;ReadPosRankSum=0.923;SOR=0.671 GT:AD:DP:GP:GQ:PG:PL 0/1:31,51:82:40.23,0,32.01:31:0,34.77,37.78:75,0,29 +20 10024107 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.770;DP=87;ExcessHet=0.0000;FS=0.817;MLEAC=1;MLEAF=0.500;MQ=59.42;MQRankSum=-1.546;QD=0.47;ReadPosRankSum=0.148;SOR=0.823 GT:AD:DP:GP:GQ:PG:PL 0/1:38,48:86:40.23,0,40.01:37:0,34.77,37.78:75,0,37 +20 10024300 . CT C,CTTT 103 . AC=1,1;AF=0.500,0.500;AN=2;BaseQRankSum=1.827;DP=74;DRAGstrInfo=1,23;DRAGstrParams=21.8,10.0,3.0;ExcessHet=0.0000;FS=0.000;MLEAC=1,1;MLEAF=0.500,0.500;MQ=47.95;MQRankSum=-0.736;QD=3.68;ReadPosRankSum=-1.117;SOR=0.437 GT:AD:DP:GP:GQ:PG:PL 1/2:3,14,11:28:103,81,43.01,71,0,43.01:40:0,3,6.01,3,6,6.01:109,84,43,74,0,43 +20 10026357 . T C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.700;DP=65;ExcessHet=0.0000;FS=8.911;MLEAC=1;MLEAF=0.500;MQ=58.48;MQRankSum=-0.148;QD=0.64;ReadPosRankSum=-0.076;SOR=0.722 GT:AD:DP:GP:GQ:PG:PL 0/1:28,35:63:40.23,0,41.01:38:0,34.77,37.78:75,0,38 +20 10026794 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.828;DP=58;ExcessHet=0.0000;FS=2.399;MLEAC=1;MLEAF=0.500;MQ=59.60;MQRankSum=-0.719;QD=0.77;ReadPosRankSum=-0.533;SOR=0.428 GT:AD:DP:GP:GQ:PG:PL 0/1:19,33:52:40.23,0,35.01:34:0,34.77,37.78:75,0,32 +20 10027234 . A ATTAG 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.446;DP=76;DRAGstrInfo=1,2;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=3.189;MLEAC=1;MLEAF=0.500;MQ=56.68;MQRankSum=-1.290;QD=0.58;ReadPosRankSum=-0.507;SOR=0.906 GT:AD:DP:GP:GQ:PG:PL 0/1:34,37:71:41,0,43.01:39:0,33,36.01:74,0,40 +20 10027868 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-5.793;DP=90;ExcessHet=0.0000;FS=6.868;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=0.032;QD=0.45;ReadPosRankSum=1.872;SOR=0.881 GT:AD:DP:GP:GQ:PG:PL 0/1:44,45:89:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10027872 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-5.491;DP=86;ExcessHet=0.0000;FS=8.870;MLEAC=1;MLEAF=0.500;MQ=59.46;MQRankSum=0.101;QD=0.47;ReadPosRankSum=1.053;SOR=0.826 GT:AD:DP:GP:GQ:PG:PL 0/1:40,45:85:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10028867 . A ATG 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.437;DP=93;DRAGstrInfo=2,10;DRAGstrParams=21.5,5.0,5.0;ExcessHet=0.0000;FS=6.134;MLEAC=1;MLEAF=0.500;MQ=60.39;MQRankSum=3.105;QD=0.56;ReadPosRankSum=0.548;SOR=0.289 GT:AD:DP:GP:GQ:PG:PL 0/1:34,39:73:41,0,43.01:39:0,5,8.01:46,0,40 +20 10030188 . T A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.711;DP=82;ExcessHet=0.0000;FS=9.186;MLEAC=1;MLEAF=0.500;MQ=59.72;MQRankSum=-1.013;QD=0.50;ReadPosRankSum=-0.553;SOR=1.105 GT:AD:DP:GP:GQ:PG:PL 0/1:42,39:81:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10031254 . A AT 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.102;DP=92;DRAGstrInfo=1,1;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=7.357;MLEAC=1;MLEAF=0.500;MQ=59.92;MQRankSum=0.017;QD=0.48;ReadPosRankSum=0.642;SOR=0.243 GT:AD:DP:GP:GQ:PG:PL 0/1:39,47:86:41,0,41.01:38:0,33,36.01:74,0,38 +20 10031342 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.833;DP=95;ExcessHet=0.0000;FS=1.714;MLEAC=1;MLEAF=0.500;MQ=59.76;MQRankSum=-0.866;QD=0.43;ReadPosRankSum=-0.012;SOR=0.955 GT:AD:DP:GP:GQ:PG:PL 0/1:41,52:93:40.23,0,40.01:37:0,34.77,37.78:75,0,37 +20 10031798 . G A 350.22 . AC=2;AF=1.00;AN=2;DP=106;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.61;QD=3.37;SOR=0.900 GT:AD:DP:GP:GQ:PG:PL 1/1:0,104:104:350.22,309.99,0:99:0,34.77,37.78:388,313,0 +20 10031827 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.552;DP=112;ExcessHet=0.0000;FS=4.729;MLEAC=1;MLEAF=0.500;MQ=59.83;MQRankSum=-0.945;QD=0.37;ReadPosRankSum=-1.396;SOR=0.382 GT:AD:DP:GP:GQ:PG:PL 0/1:52,56:108:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10032094 . G A 37.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.488;DP=85;ExcessHet=0.0000;FS=6.039;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.45;ReadPosRankSum=-0.579;SOR=0.260 GT:AD:DP:GP:GQ:PG:PL 0/1:47,36:83:37.23,0,43.01:36:0,34.77,37.78:72,0,40 +20 10032413 . T G 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-6.142;DP=66;ExcessHet=0.0000;FS=10.444;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=-0.065;QD=0.59;ReadPosRankSum=-1.003;SOR=1.293 GT:AD:DP:GP:GQ:PG:PL 0/1:35,31:66:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10032882 . A T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.697;DP=76;ExcessHet=0.0000;FS=4.673;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-1.014;QD=0.54;ReadPosRankSum=0.626;SOR=0.338 GT:AD:DP:GP:GQ:PG:PL 0/1:39,36:75:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10032972 . C CAT 40 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.354;DP=67;DRAGstrInfo=1,1;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=5.062;MLEAC=1;MLEAF=0.500;MQ=59.31;MQRankSum=-1.017;QD=0.63;ReadPosRankSum=-0.723;SOR=1.300 GT:AD:DP:GP:GQ:PG:PL 0/1:33,30:63:40,0,43.01:38:0,33,36.01:73,0,40 +20 10034306 . T C 33.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.975;DP=82;ExcessHet=0.0000;FS=0.872;MLEAC=1;MLEAF=0.500;MQ=58.87;MQRankSum=-0.432;QD=0.43;ReadPosRankSum=0.442;SOR=0.681 GT:AD:DP:GP:GQ:PG:PL 0/1:46,31:77:33.23,0,43.01:33:0,34.77,37.78:68,0,40 +20 10036930 . CGATAGCCCTAGCCCTAGATA C 39 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.720;DP=98;DRAGstrInfo=1,1;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=11.152;MLEAC=1;MLEAF=0.500;MQ=54.18;MQRankSum=-4.048;QD=0.57;ReadPosRankSum=0.460;SOR=0.269 GT:AD:DP:GP:GQ:PG:PL 0/1:39,29:68:39,0,43.01:38:0,33,36.01:72,0,40 +20 10037037 . C T 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.504;DP=97;ExcessHet=0.0000;FS=1.943;MLEAC=1;MLEAF=0.500;MQ=59.59;MQRankSum=-1.193;QD=0.51;ReadPosRankSum=-1.609;SOR=0.495 GT:AD:DP:GP:GQ:PG:PL 0/1:39,42:81:41.23,0,44.01:39:0,34.77,37.78:76,0,41 +20 10037110 . T TGATA 171.99 . AC=2;AF=1.00;AN=2;BaseQRankSum=1.975;DP=93;DRAGstrInfo=4,3;DRAGstrParams=32.0,2.5,17.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=53.08;MQRankSum=-0.183;QD=3.02;ReadPosRankSum=1.809;SOR=0.539 GT:AD:DP:GP:GQ:PG:PL 1/1:6,51:57:171.99,130.99,0:99:0,17,20.01:192,134,0 +20 10037144 . T TGATAGATA 90.99 . AC=2;AF=1.00;AN=2;DP=85;DRAGstrInfo=4,10;DRAGstrParams=26.0,2.5,3.0;ExcessHet=0.0000;FS=6.576;MLEAC=2;MLEAF=1.00;MQ=52.03;MQRankSum=-2.273;QD=3.64;ReadPosRankSum=2.817;SOR=0.378 GT:AD:DP:GP:GQ:PG:PL 1/1:3,22:25:90.99,49.99,0:50:0,3,6.01:97,53,0 +20 10037709 . A T 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.367;DP=86;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.73;MQRankSum=0.934;QD=0.54;ReadPosRankSum=0.040;SOR=0.608 GT:AD:DP:GP:GQ:PG:PL 0/1:39,32:71:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10039371 . T G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.381;DP=76;ExcessHet=0.0000;FS=7.728;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-0.884;QD=0.54;ReadPosRankSum=0.373;SOR=1.092 GT:AD:DP:GP:GQ:PG:PL 0/1:34,41:75:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10040772 . C CT 246.99 . AC=2;AF=1.00;AN=2;DP=82;DRAGstrInfo=1,8;DRAGstrParams=35.5,10.0,15.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.30;QD=3.53;SOR=0.811 GT:AD:DP:GP:GQ:PG:PL 1/1:0,70:70:246.99,205.99,0:99:0,15,18.01:265,209,0 +20 10040812 . AT A 242.99 . AC=2;AF=1.00;AN=2;DP=85;DRAGstrInfo=1,9;DRAGstrParams=31.5,10.0,13.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.06;QD=3.57;SOR=0.752 GT:AD:DP:GP:GQ:PG:PL 1/1:0,68:68:242.99,200.99,0:99:0,13,16.01:259,204,0 +20 10040821 . T A 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.357;DP=84;ExcessHet=0.0000;FS=0.879;MLEAC=1;MLEAF=0.500;MQ=50.94;MQRankSum=0.054;QD=0.55;ReadPosRankSum=-2.138;SOR=0.532 GT:AD:DP:GP:GQ:PG:PL 0/1:34,41:75:41.23,0,43.01:39:0,34.77,37.78:76,0,40 +20 10041304 . C T 247.22 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.02;QD=3.53;SOR=0.750 GT:AD:DP:GP:GQ:PG:PL 1/1:0,70:70:247.22,206.99,0:99:0,34.77,37.78:285,210,0 +20 10041701 . A ATATG 82.99 . AC=2;AF=1.00;AN=2;BaseQRankSum=-0.118;DP=83;DRAGstrInfo=2,13;DRAGstrParams=21.5,5.0,4.0;ExcessHet=0.0000;FS=1.394;MLEAC=2;MLEAF=1.00;MQ=57.92;MQRankSum=1.164;QD=1.34;ReadPosRankSum=0.380;SOR=0.474 GT:AD:DP:GP:GQ:PG:PL 1/1:10,52:62:82.99,40.99,0:41:0,4,7.01:90,44,0 +20 10042319 . C T 235.22 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.08;QD=3.56;SOR=1.033 GT:AD:DP:GP:GQ:PG:PL 1/1:0,66:66:235.22,195.99,0:99:0,34.77,37.78:273,199,0 +20 10042761 . A G 309.22 . AC=2;AF=1.00;AN=2;DP=92;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=3.40;SOR=1.389 GT:AD:DP:GP:GQ:PG:PL 1/1:0,91:91:309.22,268.99,0:99:0,34.77,37.78:347,272,0 +20 10042829 . A G 274.22 . AC=2;AF=1.00;AN=2;DP=83;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.78;QD=3.47;SOR=0.881 GT:AD:DP:GP:GQ:PG:PL 1/1:0,79:79:274.22,234.99,0:99:0,34.77,37.78:312,238,0 +20 10043002 . A T 37.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.986;DP=88;ExcessHet=0.0000;FS=2.877;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.43;ReadPosRankSum=-0.035;SOR=0.434 GT:AD:DP:GP:GQ:PG:PL 0/1:48,38:86:37.23,0,43.01:36:0,34.77,37.78:72,0,40 +20 10044849 . A G 216.22 . AC=2;AF=1.00;AN=2;DP=60;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.62;QD=3.60;SOR=1.255 GT:AD:DP:GP:GQ:PG:PL 1/1:0,60:60:216.22,176.99,0:99:0,34.77,37.78:254,180,0 +20 10045078 . G T 281.22 . AC=2;AF=1.00;AN=2;DP=84;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.78;QD=3.47;SOR=0.876 GT:AD:DP:GP:GQ:PG:PL 1/1:0,81:81:281.22,240.99,0:99:0,34.77,37.78:319,244,0 +20 10045642 . G C 283.22 . AC=2;AF=1.00;AN=2;DP=83;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.50;QD=3.45;SOR=0.846 GT:AD:DP:GP:GQ:PG:PL 1/1:0,82:82:283.22,242.99,0:99:0,34.77,37.78:321,246,0 +20 10046178 . AAGAAAGAAAG A 189.99 . AC=2;AF=1.00;AN=2;DP=64;DRAGstrInfo=4,3;DRAGstrParams=32.0,2.5,17.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=48.63;QD=3.80;SOR=0.859 GT:AD:DP:GP:GQ:PG:PL 1/1:0,50:50:189.99,148.99,0:99:0,17,20.01:210,152,0 +20 10046537 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.013;DP=58;ExcessHet=0.0000;FS=3.753;MLEAC=1;MLEAF=0.500;MQ=54.51;MQRankSum=0.230;QD=0.69;ReadPosRankSum=0.903;SOR=1.332 GT:AD:DP:GP:GQ:PG:PL 0/1:28,30:58:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10050828 . T C 36.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.855;DP=90;ExcessHet=0.0000;FS=1.755;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=1.256;QD=0.41;ReadPosRankSum=-0.029;SOR=0.488 GT:AD:DP:GP:GQ:PG:PL 0/1:50,38:88:36.23,0,43.01:35:0,34.77,37.78:71,0,40 +20 10051448 . T C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.289;DP=75;ExcessHet=0.0000;FS=5.233;MLEAC=1;MLEAF=0.500;MQ=59.44;MQRankSum=-1.424;QD=0.57;ReadPosRankSum=-0.875;SOR=0.284 GT:AD:DP:GP:GQ:PG:PL 0/1:36,35:71:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10052688 . C A 35.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.180;DP=83;ExcessHet=0.0000;FS=3.135;MLEAC=1;MLEAF=0.500;MQ=59.78;MQRankSum=0.870;QD=0.46;ReadPosRankSum=1.443;SOR=0.379 GT:AD:DP:GP:GQ:PG:PL 0/1:45,32:77:35.23,0,43.01:35:0,34.77,37.78:70,0,40 +20 10058022 . T C 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.501;DP=74;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.48;MQRankSum=0.277;QD=0.56;ReadPosRankSum=0.088;SOR=0.723 GT:AD:DP:GP:GQ:PG:PL 0/1:37,33:70:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10062935 . C CA 30 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.304;DP=93;DRAGstrInfo=1,20;DRAGstrParams=21.8,10.0,3.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=53.98;MQRankSum=-1.502;QD=1.20;ReadPosRankSum=-0.306;SOR=0.743 GT:AD:DP:GP:GQ:PG:PL 0/1:15,10:25:30,0,36.01:29:0,3,6.01:33,0,33 +20 10067049 . TAAAAAAAA TA,T 62 . AC=1,1;AF=0.500,0.500;AN=2;BaseQRankSum=0.682;DP=75;DRAGstrInfo=1,25;DRAGstrParams=21.8,10.0,3.0;ExcessHet=0.0000;FS=0.000;MLEAC=1,0;MLEAF=0.500,0.00;MQ=54.10;MQRankSum=0.725;QD=2.70;ReadPosRankSum=-0.202;SOR=0.527 GT:AD:DP:GP:GQ:PG:PL 1/2:3,9,11:23:62,22,1.01,33,0,43.01:1:0,3,6.01,3,6,6.01:68,25,1,36,0,43 +20 10067090 . C A 200.22 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=54.74;QD=3.64;SOR=0.729 GT:AD:DP:GP:GQ:PG:PL 1/1:0,55:55:200.22,160.99,0:99:0,34.77,37.78:238,164,0 +20 10067264 . G A 262.22 . AC=2;AF=1.00;AN=2;DP=77;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.10;QD=3.50;SOR=0.774 GT:AD:DP:GP:GQ:PG:PL 1/1:0,75:75:262.22,221.99,0:99:0,34.77,37.78:300,225,0 +20 10067722 . A C 199.22 . AC=2;AF=1.00;AN=2;DP=55;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=3.69;SOR=0.846 GT:AD:DP:GP:GQ:PG:PL 1/1:0,54:54:199.22,159.99,0:99:0,34.77,37.78:237,163,0 +20 10068158 . GTGTATATATATA G 0 . AC=0;AF=0.00;AN=2;BaseQRankSum=-1.960;DP=33;DRAGstrInfo=1,1;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=2.616;MLEAC=1;MLEAF=0.500;MQ=56.41;MQRankSum=-0.718;ReadPosRankSum=2.362;SOR=0.169 GT:AD:DP:GP:GQ:PG:PL 0/0:8,4:12:0,2,32.01:2:0,33,36.01:31,0,27 +20 10068981 . G A 223.22 . AC=2;AF=1.00;AN=2;DP=65;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.57;QD=3.60;SOR=0.899 GT:AD:DP:GP:GQ:PG:PL 1/1:0,62:62:223.22,183.99,0:99:0,34.77,37.78:261,187,0 +20 10070602 . T C 256.22 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.45;QD=3.51;SOR=0.720 GT:AD:DP:GP:GQ:PG:PL 1/1:0,73:73:256.22,215.99,0:99:0,34.77,37.78:294,219,0 +20 10070936 . T A 287.22 . AC=2;AF=1.00;AN=2;DP=84;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.52;QD=3.46;SOR=0.928 GT:AD:DP:GP:GQ:PG:PL 1/1:0,83:83:287.22,245.99,0:99:0,34.77,37.78:325,249,0 +20 10070938 . G GA 278.99 . AC=2;AF=1.00;AN=2;DP=85;DRAGstrInfo=1,1;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.80;QD=3.49;SOR=0.850 GT:AD:DP:GP:GQ:PG:PL 1/1:0,80:80:278.99,237.99,0:99:0,33,36.01:315,241,0 +20 10071135 . C T 278.22 . AC=2;AF=1.00;AN=2;DP=85;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.18;QD=3.48;SOR=1.031 GT:AD:DP:GP:GQ:PG:PL 1/1:0,80:80:278.22,237.99,0:99:0,34.77,37.78:316,241,0 +20 10071187 . G A 283.22 . AC=2;AF=1.00;AN=2;DP=90;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.74;QD=3.45;SOR=1.367 GT:AD:DP:GP:GQ:PG:PL 1/1:0,82:82:283.22,242.99,0:99:0,34.77,37.78:321,246,0 +20 10071890 . T C 208.22 . AC=2;AF=1.00;AN=2;DP=58;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=3.65;SOR=0.728 GT:AD:DP:GP:GQ:PG:PL 1/1:0,57:57:208.22,167.99,0:99:0,34.77,37.78:246,171,0 +20 10072505 . A G 227.22 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=3.55;SOR=0.822 GT:AD:DP:GP:GQ:PG:PL 1/1:0,64:64:227.22,187.99,0:99:0,34.77,37.78:265,191,0 +20 10074187 . A G 275.22 . AC=2;AF=1.00;AN=2;DP=81;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.14;QD=3.48;SOR=0.881 GT:AD:DP:GP:GQ:PG:PL 1/1:0,79:79:275.22,234.99,0:99:0,34.77,37.78:313,238,0 +20 10074240 . T C 292.22 . AC=2;AF=1.00;AN=2;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.54;QD=3.44;SOR=0.922 GT:AD:DP:GP:GQ:PG:PL 1/1:0,85:85:292.22,251.99,0:99:0,34.77,37.78:330,255,0 +20 10074716 . G A 234.22 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=3.55;SOR=1.284 GT:AD:DP:GP:GQ:PG:PL 1/1:0,66:66:234.22,194.99,0:99:0,34.77,37.78:272,198,0 +20 10074806 . G A 253.22 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.25;QD=3.52;SOR=0.869 GT:AD:DP:GP:GQ:PG:PL 1/1:0,72:72:253.22,212.99,0:99:0,34.77,37.78:291,216,0 +20 10075043 . T C 220.22 . AC=2;AF=1.00;AN=2;DP=64;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.64;QD=3.61;SOR=1.107 GT:AD:DP:GP:GQ:PG:PL 1/1:0,61:61:220.22,180.99,0:99:0,34.77,37.78:258,184,0 +20 10075168 . C T 301.22 . AC=2;AF=1.00;AN=2;DP=90;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.11;QD=3.42;SOR=0.997 GT:AD:DP:GP:GQ:PG:PL 1/1:0,88:88:301.22,260.99,0:99:0,34.77,37.78:339,264,0 +20 10075508 . GA G 245.99 . AC=2;AF=1.00;AN=2;DP=86;DRAGstrInfo=1,11;DRAGstrParams=24.5,10.0,8.0;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.91;QD=3.42;SOR=1.148 GT:AD:DP:GP:GQ:PG:PL 1/1:0,72:72:245.99,204.99,0:99:0,8,11.01:257,208,0 +20 10076250 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.491;DP=83;ExcessHet=0.0000;FS=5.855;MLEAC=1;MLEAF=0.500;MQ=59.42;MQRankSum=-1.441;QD=0.50;ReadPosRankSum=0.356;SOR=0.374 GT:AD:DP:GP:GQ:PG:PL 0/1:41,39:80:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10076339 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.069;DP=72;ExcessHet=0.0000;FS=1.992;MLEAC=1;MLEAF=0.500;MQ=59.68;MQRankSum=-0.866;QD=0.56;ReadPosRankSum=1.015;SOR=0.446 GT:AD:DP:GP:GQ:PG:PL 0/1:32,40:72:40.23,0,41.01:38:0,34.77,37.78:75,0,38 +20 10076399 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.274;DP=97;ExcessHet=0.0000;FS=2.671;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.42;ReadPosRankSum=-0.936;SOR=0.920 GT:AD:DP:GP:GQ:PG:PL 0/1:45,50:95:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10076989 . CA C 40 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.093;DP=85;DRAGstrInfo=1,18;DRAGstrParams=21.8,10.0,4.0;ExcessHet=0.0000;FS=1.808;MLEAC=1;MLEAF=0.500;MQ=57.12;MQRankSum=0.000;QD=1.18;ReadPosRankSum=-0.871;SOR=0.560 GT:AD:DP:GP:GQ:PG:PL 0/1:16,18:34:40,0,43.01:38:0,4,7.01:44,0,40 +20 10077752 . T C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-6.503;DP=80;ExcessHet=0.0000;FS=4.458;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.51;ReadPosRankSum=-0.352;SOR=1.251 GT:AD:DP:GP:GQ:PG:PL 0/1:34,45:79:40.23,0,40.01:37:0,34.77,37.78:75,0,37 +20 10081750 . C A 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.670;DP=90;ExcessHet=0.0000;FS=0.824;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.47;ReadPosRankSum=-0.406;SOR=0.664 GT:AD:DP:GP:GQ:PG:PL 0/1:44,39:83:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10081800 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.241;DP=69;ExcessHet=0.0000;FS=11.086;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.59;ReadPosRankSum=-2.622;SOR=0.143 GT:AD:DP:GP:GQ:PG:PL 0/1:35,33:68:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10082892 . C T 169.22 . AC=2;AF=1.00;AN=2;DP=47;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.51;QD=3.85;SOR=0.883 GT:AD:DP:GP:GQ:PG:PL 1/1:0,44:44:169.22,128.99,0:99:0,34.77,37.78:207,132,0 +20 10085211 . A T 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.501;DP=78;ExcessHet=0.0000;FS=0.870;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-1.028;QD=0.52;ReadPosRankSum=-1.405;SOR=0.723 GT:AD:DP:GP:GQ:PG:PL 0/1:40,36:76:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10086110 . G A 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.545;DP=84;ExcessHet=0.0000;FS=1.816;MLEAC=1;MLEAF=0.500;MQ=59.17;MQRankSum=-0.657;QD=0.48;ReadPosRankSum=0.237;SOR=0.555 GT:AD:DP:GP:GQ:PG:PL 0/1:43,39:82:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10086283 . G T 30.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.379;DP=85;ExcessHet=0.0000;FS=1.827;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.36;ReadPosRankSum=2.030;SOR=0.481 GT:AD:DP:GP:GQ:PG:PL 0/1:52,33:85:30.23,0,43.01:30:0,34.77,37.78:65,0,40 +20 10086619 . T A 28.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.341;DP=74;ExcessHet=0.0000;FS=2.056;MLEAC=1;MLEAF=0.500;MQ=59.31;MQRankSum=-0.371;QD=0.39;ReadPosRankSum=-0.798;SOR=0.976 GT:AD:DP:GP:GQ:PG:PL 0/1:46,26:72:28.23,0,43.01:28:0,34.77,37.78:63,0,40 +20 10086853 . G A 37.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.915;DP=77;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.16;MQRankSum=-0.177;QD=0.51;ReadPosRankSum=-0.100;SOR=0.767 GT:AD:DP:GP:GQ:PG:PL 0/1:41,32:73:37.23,0,43.01:36:0,34.77,37.78:72,0,40 +20 10086954 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.606;DP=71;ExcessHet=0.0000;FS=4.812;MLEAC=1;MLEAF=0.500;MQ=59.68;MQRankSum=0.000;QD=0.59;ReadPosRankSum=-0.534;SOR=1.185 GT:AD:DP:GP:GQ:PG:PL 0/1:34,34:68:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10087230 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.407;DP=100;ExcessHet=0.0000;FS=3.860;MLEAC=1;MLEAF=0.500;MQ=58.93;MQRankSum=1.707;QD=0.42;ReadPosRankSum=0.307;SOR=0.960 GT:AD:DP:GP:GQ:PG:PL 0/1:42,54:96:40.23,0,40.01:37:0,34.77,37.78:75,0,37 +20 10087394 . T G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.340;DP=85;ExcessHet=0.0000;FS=4.225;MLEAC=1;MLEAF=0.500;MQ=59.73;MQRankSum=1.207;QD=0.48;ReadPosRankSum=0.885;SOR=0.436 GT:AD:DP:GP:GQ:PG:PL 0/1:35,49:84:40.23,0,38.01:36:0,34.77,37.78:75,0,35 +20 10087754 . T G 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.054;DP=89;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.76;MQRankSum=2.140;QD=0.52;ReadPosRankSum=-0.478;SOR=0.631 GT:AD:DP:GP:GQ:PG:PL 0/1:37,43:80:41.23,0,43.01:39:0,34.77,37.78:76,0,40 +20 10087804 . C T 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.940;DP=109;ExcessHet=0.0000;FS=3.847;MLEAC=1;MLEAF=0.500;MQ=60.13;MQRankSum=2.618;QD=0.41;ReadPosRankSum=0.341;SOR=0.369 GT:AD:DP:GP:GQ:PG:PL 0/1:50,50:100:41.23,0,44.01:39:0,34.77,37.78:76,0,41 +20 10087820 . C CAG 31 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.814;DP=109;DRAGstrInfo=2,10;DRAGstrParams=21.5,5.0,5.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=60.06;MQRankSum=0.342;QD=0.54;ReadPosRankSum=0.054;SOR=0.854 GT:AD:DP:GP:GQ:PG:PL 0/1:39,18:57:31,0,44.01:31:0,5,8.01:36,0,41 +20 10088063 . C T 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.516;DP=101;ExcessHet=0.0000;FS=2.698;MLEAC=1;MLEAF=0.500;MQ=59.21;MQRankSum=0.910;QD=0.42;ReadPosRankSum=0.121;SOR=1.005 GT:AD:DP:GP:GQ:PG:PL 0/1:50,44:94:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10088699 . C T 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.852;DP=69;ExcessHet=0.0000;FS=19.564;MLEAC=1;MLEAF=0.500;MQ=55.76;MQRankSum=-3.518;QD=0.60;ReadPosRankSum=-1.788;SOR=2.091 GT:AD:DP:GP:GQ:PG:PL 0/1:36,28:64:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10088730 . G A 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.123;DP=66;ExcessHet=0.0000;FS=18.070;MLEAC=1;MLEAF=0.500;MQ=52.18;MQRankSum=-5.029;QD=0.73;ReadPosRankSum=0.738;SOR=1.798 GT:AD:DP:GP:GQ:PG:PL 0/1:29,25:54:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10088736 . A C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.073;DP=67;ExcessHet=0.0000;FS=11.873;MLEAC=1;MLEAF=0.500;MQ=52.30;MQRankSum=-5.315;QD=0.71;ReadPosRankSum=0.871;SOR=1.045 GT:AD:DP:GP:GQ:PG:PL 0/1:28,29:57:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10088747 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.997;DP=63;ExcessHet=0.0000;FS=9.762;MLEAC=1;MLEAF=0.500;MQ=51.67;MQRankSum=-5.045;QD=0.72;ReadPosRankSum=0.379;SOR=1.263 GT:AD:DP:GP:GQ:PG:PL 0/1:25,31:56:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10088799 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.595;DP=57;ExcessHet=0.0000;FS=10.098;MLEAC=1;MLEAF=0.500;MQ=52.07;MQRankSum=-2.089;QD=0.75;ReadPosRankSum=1.217;SOR=0.987 GT:AD:DP:GP:GQ:PG:PL 0/1:23,31:54:40.23,0,40.01:37:0,34.77,37.78:75,0,37 +20 10088895 . C T 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.462;DP=55;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=56.66;MQRankSum=0.577;QD=0.93;ReadPosRankSum=1.301;SOR=0.653 GT:AD:DP:GP:GQ:PG:PL 0/1:23,18:41:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10088968 . C CAAA 40 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.177;DP=83;DRAGstrInfo=1,11;DRAGstrParams=24.5,10.0,8.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=51.07;MQRankSum=-5.280;QD=0.63;ReadPosRankSum=1.308;SOR=0.627 GT:AD:DP:GP:GQ:PG:PL 0/1:30,33:63:40,0,43.01:38:0,8,11.01:48,0,40 +20 10088980 . T C 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.020;DP=82;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=50.62;MQRankSum=-5.456;QD=0.54;ReadPosRankSum=1.712;SOR=0.749 GT:AD:DP:GP:GQ:PG:PL 0/1:38,35:73:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10088985 . T C 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.702;DP=87;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=50.82;MQRankSum=-5.481;QD=0.48;ReadPosRankSum=1.792;SOR=0.650 GT:AD:DP:GP:GQ:PG:PL 0/1:43,36:79:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10089441 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.885;DP=77;ExcessHet=0.0000;FS=6.071;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-0.948;QD=0.53;ReadPosRankSum=-0.156;SOR=1.363 GT:AD:DP:GP:GQ:PG:PL 0/1:37,39:76:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10089525 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.659;DP=83;ExcessHet=0.0000;FS=5.560;MLEAC=1;MLEAF=0.500;MQ=59.22;MQRankSum=0.715;QD=0.49;ReadPosRankSum=0.921;SOR=0.675 GT:AD:DP:GP:GQ:PG:PL 0/1:38,44:82:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10090289 . CA C 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.548;DP=94;DRAGstrInfo=1,16;DRAGstrParams=21.8,10.0,5.0;ExcessHet=0.0000;FS=1.271;MLEAC=1;MLEAF=0.500;MQ=59.66;MQRankSum=1.588;QD=0.95;ReadPosRankSum=1.074;SOR=0.990 GT:AD:DP:GP:GQ:PG:PL 0/1:16,27:43:41,0,41.01:38:0,5,8.01:46,0,38 +20 10090764 . A G 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.561;DP=69;ExcessHet=0.0000;FS=4.873;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.60;ReadPosRankSum=1.073;SOR=0.315 GT:AD:DP:GP:GQ:PG:PL 0/1:35,30:65:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10090970 . T C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.297;DP=72;ExcessHet=0.0000;FS=0.898;MLEAC=1;MLEAF=0.500;MQ=59.48;MQRankSum=1.486;QD=0.57;ReadPosRankSum=-0.129;SOR=0.576 GT:AD:DP:GP:GQ:PG:PL 0/1:34,36:70:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10091214 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.248;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.75;MQRankSum=-0.932;QD=0.55;ReadPosRankSum=-0.431;SOR=0.596 GT:AD:DP:GP:GQ:PG:PL 0/1:35,38:73:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10092415 . A G 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-6.731;DP=102;ExcessHet=0.0000;FS=0.741;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.40;ReadPosRankSum=0.082;SOR=0.665 GT:AD:DP:GP:GQ:PG:PL 0/1:52,49:101:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10093568 . GT G 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.085;DP=68;DRAGstrInfo=1,13;DRAGstrParams=22.8,10.0,7.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.56;MQRankSum=1.073;QD=0.91;ReadPosRankSum=0.792;SOR=0.693 GT:AD:DP:GP:GQ:PG:PL 0/1:23,22:45:41,0,44.01:39:0,7,10.01:48,0,41 +20 10093923 . T A 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.667;DP=69;ExcessHet=0.0000;FS=0.924;MLEAC=1;MLEAF=0.500;MQ=59.21;MQRankSum=0.358;QD=0.59;ReadPosRankSum=-1.583;SOR=0.772 GT:AD:DP:GP:GQ:PG:PL 0/1:35,32:67:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10094251 . T A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.251;DP=66;ExcessHet=0.0000;FS=11.483;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=0.65;ReadPosRankSum=1.806;SOR=1.211 GT:AD:DP:GP:GQ:PG:PL 0/1:26,36:62:40.23,0,39.01:37:0,34.77,37.78:75,0,36 +20 10094582 . A G 37.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.388;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.41;MQRankSum=1.270;QD=0.54;ReadPosRankSum=-0.018;SOR=0.772 GT:AD:DP:GP:GQ:PG:PL 0/1:39,30:69:37.23,0,43.01:36:0,34.77,37.78:72,0,40 +20 10094774 . C T 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.705;DP=79;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.42;MQRankSum=0.975;QD=0.52;ReadPosRankSum=0.245;SOR=0.628 GT:AD:DP:GP:GQ:PG:PL 0/1:40,36:76:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10095432 . GTGATGATGA G 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.798;DP=81;DRAGstrInfo=3,15;DRAGstrParams=22.8,3.3,2.0;ExcessHet=0.0000;FS=2.369;MLEAC=1;MLEAF=0.500;MQ=54.28;MQRankSum=-4.548;QD=0.80;ReadPosRankSum=0.801;SOR=0.404 GT:AD:DP:GP:GQ:PG:PL 0/1:27,24:51:41,0,43.01:39:0,2,5.01:43,0,40 +20 10095741 . A G 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.346;DP=73;ExcessHet=0.0000;FS=4.611;MLEAC=1;MLEAF=0.500;MQ=57.10;MQRankSum=-2.354;QD=0.55;ReadPosRankSum=-0.547;SOR=0.550 GT:AD:DP:GP:GQ:PG:PL 0/1:37,34:71:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10096293 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.770;DP=79;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.64;MQRankSum=1.366;QD=0.53;ReadPosRankSum=-1.263;SOR=0.693 GT:AD:DP:GP:GQ:PG:PL 0/1:38,38:76:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10096596 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.728;DP=89;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.80;MQRankSum=0.612;QD=0.46;ReadPosRankSum=-0.170;SOR=0.640 GT:AD:DP:GP:GQ:PG:PL 0/1:40,47:87:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10096768 . A C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.764;DP=94;ExcessHet=0.0000;FS=3.983;MLEAC=1;MLEAF=0.500;MQ=59.26;MQRankSum=-1.609;QD=0.44;ReadPosRankSum=0.613;SOR=0.445 GT:AD:DP:GP:GQ:PG:PL 0/1:42,49:91:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10096899 . G T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.755;DP=80;ExcessHet=0.0000;FS=9.606;MLEAC=1;MLEAF=0.500;MQ=59.53;MQRankSum=-1.387;QD=0.51;ReadPosRankSum=0.422;SOR=1.707 GT:AD:DP:GP:GQ:PG:PL 0/1:39,40:79:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10096905 . TA T 40 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.897;DP=85;DRAGstrInfo=1,2;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=11.448;MLEAC=1;MLEAF=0.500;MQ=59.29;MQRankSum=-1.656;QD=0.49;ReadPosRankSum=0.269;SOR=1.760 GT:AD:DP:GP:GQ:PG:PL 0/1:39,43:82:40,0,43.01:38:0,33,36.01:73,0,40 +20 10096933 . G C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.914;DP=90;ExcessHet=0.0000;FS=23.320;MLEAC=1;MLEAF=0.500;MQ=59.33;MQRankSum=-1.802;QD=0.47;ReadPosRankSum=0.383;SOR=1.534 GT:AD:DP:GP:GQ:PG:PL 0/1:44,41:85:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10096958 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.839;DP=92;ExcessHet=0.0000;FS=16.778;MLEAC=1;MLEAF=0.500;MQ=59.34;MQRankSum=-1.701;QD=0.44;ReadPosRankSum=-1.606;SOR=1.387 GT:AD:DP:GP:GQ:PG:PL 0/1:45,47:92:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10097075 . T G 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.641;DP=98;ExcessHet=0.0000;FS=5.232;MLEAC=1;MLEAF=0.500;MQ=57.94;MQRankSum=-1.604;QD=0.44;ReadPosRankSum=0.254;SOR=0.566 GT:AD:DP:GP:GQ:PG:PL 0/1:44,49:93:41.23,0,44.01:39:0,34.77,37.78:76,0,41 +20 10097101 . C CTTT 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.105;DP=83;DRAGstrInfo=1,10;DRAGstrParams=27.5,10.0,10.0;ExcessHet=0.0000;FS=8.900;MLEAC=1;MLEAF=0.500;MQ=57.52;MQRankSum=-2.020;QD=0.59;ReadPosRankSum=3.262;SOR=0.607 GT:AD:DP:GP:GQ:PG:PL 0/1:34,35:69:41,0,44.01:39:0,10,13.01:51,0,41 +20 10097436 . CTTTTCTTTCTTTCTTTCTTTCTTTCTTTCTTTCTTT C 25 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.450;DP=93;DRAGstrInfo=1,4;DRAGstrParams=47.5,10.0,33.0;ExcessHet=0.0000;FS=0.836;MLEAC=1;MLEAF=0.500;MQ=54.19;MQRankSum=-6.610;QD=0.27;ReadPosRankSum=-1.770;SOR=0.821 GT:AD:DP:GP:GQ:PG:PL 0/1:58,33:91:25,0,44.01:25:0,33,36.01:58,0,41 +20 10097437 . TTTTC T 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.584;DP=70;DRAGstrInfo=4,13;DRAGstrParams=24.0,2.5,2.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.81;MQRankSum=4.211;QD=0.91;ReadPosRankSum=1.593;SOR=0.749 GT:AD:DP:GP:GQ:PG:PL 0/1:22,23:45:41,0,44.01:39:0,2,5.01:43,0,41 +20 10097626 . C A 37.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.085;DP=52;ExcessHet=0.0000;FS=2.701;MLEAC=1;MLEAF=0.500;MQ=57.92;MQRankSum=-1.331;QD=0.78;ReadPosRankSum=1.015;SOR=0.324 GT:AD:DP:GP:GQ:PG:PL 0/1:28,20:48:37.23,0,43.01:36:0,34.77,37.78:72,0,40 +20 10097789 . T C 36.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.396;DP=63;ExcessHet=0.0000;FS=5.430;MLEAC=1;MLEAF=0.500;MQ=57.62;MQRankSum=-2.744;QD=0.62;ReadPosRankSum=0.269;SOR=0.863 GT:AD:DP:GP:GQ:PG:PL 0/1:34,24:58:36.23,0,43.01:35:0,34.77,37.78:71,0,40 +20 10097928 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.420;DP=40;ExcessHet=0.0000;FS=2.862;MLEAC=1;MLEAF=0.500;MQ=58.25;MQRankSum=-1.611;QD=1.09;ReadPosRankSum=-0.214;SOR=1.063 GT:AD:DP:GP:GQ:PG:PL 0/1:17,20:37:40.23,0,42.01:38:0,34.77,37.78:75,0,39 +20 10098110 . G C 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.510;DP=36;ExcessHet=0.0000;FS=6.658;MLEAC=1;MLEAF=0.500;MQ=58.71;MQRankSum=-1.477;QD=1.12;ReadPosRankSum=-0.730;SOR=0.069 GT:AD:DP:GP:GQ:PG:PL 0/1:19,17:36:40.23,0,37.01:35:0,34.77,37.78:75,0,34 +20 10098135 . C A 35.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.155;DP=38;ExcessHet=0.0000;FS=4.337;MLEAC=1;MLEAF=0.500;MQ=59.64;MQRankSum=1.546;QD=0.93;ReadPosRankSum=-0.591;SOR=0.075 GT:AD:DP:GP:GQ:PG:PL 0/1:24,14:38:35.23,0,40.01:34:0,34.77,37.78:70,0,37 +20 10098219 . TATATATA T 40 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.739;DP=21;DRAGstrInfo=2,4;DRAGstrParams=40.3,5.0,22.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.94;MQRankSum=-0.205;QD=1.90;ReadPosRankSum=0.356;SOR=0.465 GT:AD:DP:GP:GQ:PG:PL 0/1:12,9:21:40,0,43.01:38:0,22,25.01:62,0,40 +20 10098237 . A T 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.252;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=52.81;MQRankSum=-1.935;QD=3.44;ReadPosRankSum=1.254;SOR=0.693 GT:AD:DP:GP:GQ:PG:PL 0/1:6,6:12:41.23,0,43.01:39:0,34.77,37.78:76,0,40 +20 10098265 . T C 29.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.834;DP=6;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=41.96;MQRankSum=-1.834;QD=4.87;ReadPosRankSum=0.842;SOR=1.329 GT:AD:DP:GP:GQ:PG:PL 0/1:2,4:6:29.23,0,42.01:29:0,34.77,37.78:64,0,39 +20 10098344 . A G 33.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.674;DP=4;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=50.60;MQRankSum=-1.383;QD=8.31;ReadPosRankSum=0.000;SOR=0.693 GT:AD:DP:GP:GQ:PG:PL 0/1:2,2:4:33.23,0,43.01:33:0,34.77,37.78:68,0,40 +20 10098360 . A ATATATAATATATATATTAAATATATATAATATGTATAATTTATATGTAATATATAATATATATATTA 33 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.674;DP=3;DRAGstrInfo=2,4;DRAGstrParams=40.3,5.0,22.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=47.05;MQRankSum=-0.674;QD=11.00;ReadPosRankSum=0.674;SOR=0.693 GT:AD:DP:GP:GQ:PG:PL 0/1:1,2:3:33,0,39.01:32:0,22,25.01:55,0,36 +20 10098786 . C T 12.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.431;DP=10;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.21;MQRankSum=-2.200;QD=1.36;ReadPosRankSum=-1.383;SOR=0.132 GT:AD:DP:GP:GQ:PG:PL 0/1:7,2:9:12.23,0,43.01:12:0,34.77,37.78:47,0,40 +20 10098885 . C CA 39 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.186;DP=34;DRAGstrInfo=1,5;DRAGstrParams=47.5,10.0,27.0;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=50.06;MQRankSum=-4.449;QD=1.26;ReadPosRankSum=-0.954;SOR=0.518 GT:AD:DP:GP:GQ:PG:PL 0/1:17,14:31:39,0,43.01:38:0,27,30.01:66,0,40 +20 10098945 . T C 37.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.225;DP=25;ExcessHet=0.0000;FS=4.075;MLEAC=1;MLEAF=0.500;MQ=50.95;MQRankSum=-2.636;QD=1.62;ReadPosRankSum=1.200;SOR=2.494 GT:AD:DP:GP:GQ:PG:PL 0/1:9,14:23:37.23,0,40.01:35:0,34.77,37.78:72,0,37 +20 10098987 . C T 34.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.922;DP=26;ExcessHet=0.0000;FS=7.368;MLEAC=1;MLEAF=0.500;MQ=50.42;MQRankSum=-2.877;QD=1.37;ReadPosRankSum=0.384;SOR=3.056 GT:AD:DP:GP:GQ:PG:PL 0/1:11,14:25:34.23,0,42.01:34:0,34.77,37.78:69,0,39 +20 10099029 . T C 35.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.809;DP=36;ExcessHet=0.0000;FS=2.032;MLEAC=1;MLEAF=0.500;MQ=52.65;MQRankSum=-3.641;QD=1.26;ReadPosRankSum=-1.224;SOR=1.329 GT:AD:DP:GP:GQ:PG:PL 0/1:18,10:28:35.23,0,43.01:35:0,34.77,37.78:70,0,40 +20 10099034 . C A 35.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.757;DP=34;ExcessHet=0.0000;FS=4.265;MLEAC=1;MLEAF=0.500;MQ=53.05;MQRankSum=-3.641;QD=1.26;ReadPosRankSum=-1.850;SOR=1.721 GT:AD:DP:GP:GQ:PG:PL 0/1:18,10:28:35.23,0,43.01:35:0,34.77,37.78:70,0,40 +20 10099044 . A C 37.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.148;DP=31;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=52.38;MQRankSum=-4.418;QD=1.55;ReadPosRankSum=-2.207;SOR=0.515 GT:AD:DP:GP:GQ:PG:PL 0/1:15,9:24:37.23,0,43.01:36:0,34.77,37.78:72,0,40 +20 10099046 . T C 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.264;DP=32;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=51.38;MQRankSum=-4.449;QD=1.53;ReadPosRankSum=-2.553;SOR=0.616 GT:AD:DP:GP:GQ:PG:PL 0/1:15,10:25:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10099055 . T C 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.051;DP=37;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=50.33;MQRankSum=-4.519;QD=1.40;ReadPosRankSum=-2.951;SOR=0.839 GT:AD:DP:GP:GQ:PG:PL 0/1:15,13:28:39.23,0,43.01:38:0,34.77,37.78:74,0,40 +20 10099079 . C T 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.791;DP=41;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=50.34;MQRankSum=-4.452;QD=1.09;ReadPosRankSum=-0.383;SOR=0.883 GT:AD:DP:GP:GQ:PG:PL 0/1:20,15:35:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10099111 . T TTTTGTTTG 41 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.506;DP=58;DRAGstrInfo=4,4;DRAGstrParams=28.0,2.5,13.0;ExcessHet=0.0000;FS=2.790;MLEAC=1;MLEAF=0.500;MQ=52.40;MQRankSum=-2.602;QD=0.95;ReadPosRankSum=-0.629;SOR=1.302 GT:AD:DP:GP:GQ:PG:PL 0/1:18,25:43:41,0,41.01:38:0,13,16.01:54,0,38 +20 10099140 . G T 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.267;DP=69;ExcessHet=0.0000;FS=2.116;MLEAC=1;MLEAF=0.500;MQ=54.63;MQRankSum=-2.506;QD=0.63;ReadPosRankSum=0.460;SOR=0.990 GT:AD:DP:GP:GQ:PG:PL 0/1:31,34:65:41.23,0,43.01:39:0,34.77,37.78:76,0,40 +20 10099190 . G T 41.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.034;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=56.35;MQRankSum=-1.711;QD=0.63;ReadPosRankSum=-1.260;SOR=0.776 GT:AD:DP:GP:GQ:PG:PL 0/1:33,32:65:41.23,0,43.01:39:0,34.77,37.78:76,0,40 +20 10099220 . A G 38.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.664;DP=50;ExcessHet=0.0000;FS=1.137;MLEAC=1;MLEAF=0.500;MQ=55.95;MQRankSum=-2.596;QD=0.85;ReadPosRankSum=0.629;SOR=0.519 GT:AD:DP:GP:GQ:PG:PL 0/1:25,20:45:38.23,0,43.01:37:0,34.77,37.78:73,0,40 +20 10099250 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.170;DP=44;ExcessHet=0.0000;FS=7.195;MLEAC=1;MLEAF=0.500;MQ=54.98;MQRankSum=-2.272;QD=1.09;ReadPosRankSum=0.583;SOR=0.162 GT:AD:DP:GP:GQ:PG:PL 0/1:16,21:37:40.23,0,41.01:38:0,34.77,37.78:75,0,38 +20 10099535 . G A 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.034;DP=68;ExcessHet=0.0000;FS=2.172;MLEAC=1;MLEAF=0.500;MQ=59.04;MQRankSum=-1.418;QD=0.62;ReadPosRankSum=-0.777;SOR=0.408 GT:AD:DP:GP:GQ:PG:PL 0/1:26,39:65:40.23,0,37.01:35:0,34.77,37.78:75,0,34 +20 10099565 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.595;DP=69;ExcessHet=0.0000;FS=8.736;MLEAC=1;MLEAF=0.500;MQ=59.39;MQRankSum=-1.266;QD=0.58;ReadPosRankSum=1.225;SOR=0.191 GT:AD:DP:GP:GQ:PG:PL 0/1:31,38:69:40.23,0,41.01:38:0,34.77,37.78:75,0,38 +20 10099755 . C T 40.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.550;DP=65;ExcessHet=0.0000;FS=2.074;MLEAC=1;MLEAF=0.500;MQ=59.36;MQRankSum=-0.022;QD=0.62;ReadPosRankSum=-0.230;SOR=0.446 GT:AD:DP:GP:GQ:PG:PL 0/1:33,32:65:40.23,0,43.01:38:0,34.77,37.78:75,0,40 +20 10099832 . A G 39.23 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.563;DP=73;ExcessHet=0.0000;FS=4.632;MLEAC=1;MLEAF=0.500;MQ=58.97;MQRankSum=0.869;QD=0.54;ReadPosRankSum=-1.023;SOR=0.871 GT:AD:DP:GP:GQ:PG:PL 0/1:39,33:72:39.23,0,43.01:38:0,34.77,37.78:74,0,40 diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.378.gatk4.vcf.idx b/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.378.gatk4.vcf.idx new file mode 100644 index 0000000000000000000000000000000000000000..faaa8db8f33f5465dd7a04f43478d68d10e33f15 GIT binary patch literal 2923 zcmeHJ%}T^D5RM35d;!6;cx%!&Y1+k0X{#=1g|)kQE8TAPN9%S;vf>`RdG_K<=+TGp zC43USIo+}%zJZW|VTNHc^JVxZB@crr=qHcVm=ZQ zPYQj5l`OFqN@FQhy_BU;xRw(AJ2Io)(L$)~kgmi>iWJ;vQTr zM%DtFE*H@{8u!AJB(+@bTTL%&-IZhX{t3`PUJgI-V*|C39niQNWgUkg&m|6H;Isi7 zQQvj~KVaxM3A27L$xe8FFZV8sGpCJs@-h{y}pIkT1}; u-L-41nZue0h7V>Rnh6*l7#!2fs$p34^J-cxJ$Ut7ERz ##contig= #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT NA12878 +20 10000117 . C T 926.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.136;DP=66;ExcessHet=0.0000;FS=11.007;MLEAC=1;MLEAF=0.500;MQ=59.72;MQRankSum=0.913;QD=14.48;ReadPosRankSum=-0.223;SOR=1.538 GT:AD:DP:GQ:PL 0/1:36,28:64:99:934,0,1248 +20 10000211 . C T 962.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.867;DP=54;ExcessHet=0.0000;FS=5.587;MLEAC=1;MLEAF=0.500;MQ=59.65;MQRankSum=1.057;QD=18.16;ReadPosRankSum=0.703;SOR=0.944 GT:AD:DP:GQ:PL 0/1:26,27:53:99:970,0,906 20 10000439 . T G 2819.06 . AC=2;AF=1.00;AN=2;DP=82;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.86;QD=25.36;SOR=1.236 GT:AD:DP:GQ:PL 1/1:0,80:80:99:2833,240,0 20 10001019 . T G 671.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.541;DP=75;ExcessHet=0.0000;FS=3.406;MLEAC=1;MLEAF=0.500;MQ=47.62;MQRankSum=-7.498;QD=10.33;ReadPosRankSum=-0.925;SOR=0.665 GT:AD:DP:GQ:PL 0/1:39,26:65:99:679,0,1426 20 10001436 . A AAGGCT 2325.03 . AC=2;AF=1.00;AN=2;DP=58;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=41.22;QD=28.73;SOR=3.014 GT:AD:DP:GQ:PL 1/1:0,52:52:99:2339,156,0 20 10001474 . C T 2655.06 . AC=2;AF=1.00;AN=2;DP=77;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=44.87;QD=30.97;SOR=1.516 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2669,219,0 20 10002138 . C G 2026.06 . AC=2;AF=1.00;AN=2;DP=56;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=57.01;QD=27.24;SOR=0.770 GT:AD:DP:GQ:PL 1/1:0,52:52:99:2040,156,0 20 10002142 . G C 1976.06 . AC=2;AF=1.00;AN=2;DP=55;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.45;QD=28.20;SOR=0.813 GT:AD:DP:GQ:PL 1/1:0,51:51:99:1990,153,0 -20 10002470 . C T 1588.06 . AC=2;AF=1.00;AN=2;DP=54;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.22;QD=32.41;SOR=0.733 GT:AD:DP:GQ:PL 1/1:0,49:49:99:1602,147,0 -20 10002478 . A T 215.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.664;DP=58;ExcessHet=0.0000;FS=35.852;MLEAC=1;MLEAF=0.500;MQ=52.80;MQRankSum=-2.518;QD=4.07;ReadPosRankSum=2.003;SOR=4.287 GT:AD:DP:GQ:PL 0/1:36,17:53:99:223,0,943 20 10003358 . A C 1475.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.004;DP=91;ExcessHet=0.0000;FS=0.844;MLEAC=1;MLEAF=0.500;MQ=59.80;MQRankSum=1.011;QD=16.58;ReadPosRankSum=-1.355;SOR=0.572 GT:AD:DP:GQ:PL 0/1:45,44:89:99:1483,0,1477 20 10003832 . G A 2720.06 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.82;QD=25.00;SOR=1.473 GT:AD:DP:GQ:PL 1/1:0,66:66:99:2734,199,0 20 10004147 . A G 1855.06 . AC=2;AF=1.00;AN=2;DP=54;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=55.65;QD=29.56;SOR=1.244 GT:AD:DP:GQ:PL 1/1:0,52:52:99:1869,156,0 20 10004193 . G T 968.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.276;DP=56;ExcessHet=0.0000;FS=2.311;MLEAC=1;MLEAF=0.500;MQ=59.17;MQRankSum=3.395;QD=18.28;ReadPosRankSum=1.833;SOR=1.071 GT:AD:DP:GQ:PL 0/1:24,29:53:99:976,0,780 20 10004351 . C G 2770.06 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.05;QD=30.62;SOR=0.874 GT:AD:DP:GQ:PL 1/1:0,70:70:99:2784,211,0 20 10004389 . T G 2509.06 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.62;QD=28.17;SOR=1.143 GT:AD:DP:GQ:PL 1/1:0,62:62:99:2523,187,0 -20 10004887 . A G 151.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.700;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=15.16;ReadPosRankSum=0.160;SOR=1.508 GT:AD:DP:GQ:PL 0/1:5,5:10:99:159,0,155 -20 10005010 . C T 2949.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=26.80;SOR=1.226 GT:AD:DP:GQ:PL 1/1:0,72:72:99:2963,217,0 -20 10005427 . C T 2229.06 . AC=2;AF=1.00;AN=2;DP=60;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.62;QD=26.00;SOR=0.729 GT:AD:DP:GQ:PL 1/1:0,55:55:99:2243,165,0 -20 10005499 . A G 3068.06 . AC=2;AF=1.00;AN=2;DP=78;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=30.02;SOR=1.121 GT:AD:DP:GQ:PL 1/1:0,76:76:99:3082,229,0 +20 10004769 . TAAAACTATGC T 1011.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.599;DP=80;ExcessHet=0.0000;FS=3.758;MLEAC=1;MLEAF=0.500;MQ=52.80;MQRankSum=-6.625;QD=15.81;ReadPosRankSum=1.879;SOR=1.306 GT:AD:DP:GQ:PL 0/1:37,27:64:99:1019,0,1471 +20 10004874 . A C 3447.06 . AC=2;AF=1.00;AN=2;DP=90;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.35;QD=26.80;SOR=1.286 GT:AD:DP:GQ:PL 1/1:0,87:87:99:3461,261,0 +20 10004887 . A G 1344.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.356;DP=90;ExcessHet=0.0000;FS=1.793;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=-0.067;QD=15.82;ReadPosRankSum=-1.114;SOR=0.984 GT:AD:DP:GQ:PL 0/1:45,40:85:99:1352,0,1542 +20 10005010 . C T 2949.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=26.00;SOR=1.226 GT:AD:DP:GQ:PL 1/1:0,72:72:99:2963,217,0 +20 10005427 . C T 2229.06 . AC=2;AF=1.00;AN=2;DP=60;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.62;QD=30.02;SOR=0.729 GT:AD:DP:GQ:PL 1/1:0,55:55:99:2243,165,0 +20 10005499 . A G 3068.06 . AC=2;AF=1.00;AN=2;DP=78;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=31.98;SOR=1.121 GT:AD:DP:GQ:PL 1/1:0,76:76:99:3082,229,0 +20 10006819 . AAAAC A 2554.03 . AC=2;AF=1.00;AN=2;DP=81;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=61.06;QD=27.51;SOR=0.762 GT:AD:DP:GQ:PL 1/1:0,58:58:99:2568,176,0 20 10007150 . G C 691.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.476;DP=64;ExcessHet=0.0000;FS=5.048;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=10.98;ReadPosRankSum=-0.077;SOR=0.746 GT:AD:DP:GQ:PL 0/1:38,25:63:99:699,0,1321 20 10007175 . C T 1371.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.249;DP=63;ExcessHet=0.0000;FS=2.211;MLEAC=1;MLEAF=0.500;MQ=59.63;MQRankSum=1.319;QD=22.49;ReadPosRankSum=-1.213;SOR=0.434 GT:AD:DP:GQ:PL 0/1:23,38:61:99:1379,0,712 -20 10007352 . C T 2779.06 . AC=2;AF=1.00;AN=2;DP=70;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.67;QD=31.98;SOR=1.054 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2793,208,0 -20 10007980 . A C 3571.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.69;QD=27.51;SOR=1.014 GT:AD:DP:GQ:PL 1/1:0,91:91:99:3585,273,0 -20 10008458 . T G 2669.06 . AC=2;AF=1.00;AN=2;DP=72;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.76;QD=29.11;SOR=0.980 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2683,207,0 -20 10009400 . T A 3013.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=28.08;SOR=0.804 GT:AD:DP:GQ:PL 1/1:0,74:74:99:3027,223,0 -20 10009512 . C G 3054.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.53;QD=23.23;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:3068,231,0 +20 10007352 . C T 2779.06 . AC=2;AF=1.00;AN=2;DP=70;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.67;QD=29.11;SOR=1.054 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2793,208,0 +20 10007980 . A C 3571.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.69;QD=28.08;SOR=1.014 GT:AD:DP:GQ:PL 1/1:0,91:91:99:3585,273,0 +20 10008146 . TA T 2165.03 . AC=2;AF=1.00;AN=2;DP=77;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.56;QD=30.93;SOR=0.874 GT:AD:DP:GQ:PL 1/1:0,70:70:99:2179,211,0 +20 10008458 . T G 2669.06 . AC=2;AF=1.00;AN=2;DP=72;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.76;QD=23.23;SOR=0.980 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2683,207,0 +20 10008921 . C CA 283.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.610;DP=60;ExcessHet=0.0000;FS=1.311;MLEAC=1;MLEAF=0.500;MQ=56.00;MQRankSum=-1.306;QD=8.10;ReadPosRankSum=-0.017;SOR=0.644 GT:AD:DP:GQ:PL 0/1:18,17:35:99:291,0,366 +20 10008948 . TA T 663.02 . AC=2;AF=1.00;AN=2;BaseQRankSum=0.090;DP=55;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.58;MQRankSum=0.565;QD=23.68;ReadPosRankSum=0.403;SOR=0.527 GT:AD:DP:GQ:PL 1/1:2,26:28:29:677,29,0 +20 10008952 . CACACACACACA CCACACACACA,C 766.97 . AC=1,1;AF=0.500,0.500;AN=2;BaseQRankSum=-0.634;DP=58;ExcessHet=0.0000;FS=0.000;MLEAC=1,1;MLEAF=0.500,0.500;MQ=51.40;MQRankSum=0.426;QD=25.57;ReadPosRankSum=0.125;SOR=0.473 GT:AD:DP:GQ:PL 1/2:2,12,16:30:99:802,564,583,218,0,925 +20 10009400 . T A 3013.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.03;SOR=0.804 GT:AD:DP:GQ:PL 1/1:0,74:74:99:3027,223,0 +20 10009512 . C G 3054.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.53;QD=30.67;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:3068,231,0 20 10009871 . A G 41.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.394;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=57.39;MQRankSum=0.696;QD=2.97;ReadPosRankSum=-2.638;SOR=0.368 GT:AD:DP:GQ:PL 0/1:11,3:14:49:49,0,128 20 10009875 . A G 52.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.856;DP=20;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=56.45;MQRankSum=0.820;QD=3.29;ReadPosRankSum=-2.619;SOR=0.260 GT:AD:DP:GQ:PL 0/1:13,3:16:50:60,0,50 20 10010393 . T G 1485.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.351;DP=79;ExcessHet=0.0000;FS=11.600;MLEAC=1;MLEAF=0.500;MQ=59.42;MQRankSum=-1.284;QD=18.81;ReadPosRankSum=-1.738;SOR=0.606 GT:AD:DP:GQ:PL 0/1:36,43:79:99:1493,0,1230 20 10010536 . G GA 2455.03 . AC=2;AF=1.00;AN=2;DP=92;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=61.74;QD=30.69;SOR=0.850 GT:AD:DP:GQ:PL 1/1:0,80:80:99:2469,240,0 -20 10010766 . T G 2426.06 . AC=2;AF=1.00;AN=2;DP=69;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.03;SOR=0.818 GT:AD:DP:GQ:PL 1/1:0,66:66:99:2440,199,0 +20 10010766 . T G 2426.06 . AC=2;AF=1.00;AN=2;DP=69;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=26.61;SOR=0.818 GT:AD:DP:GQ:PL 1/1:0,66:66:99:2440,199,0 20 10011075 . C T 1346.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.364;DP=86;ExcessHet=0.0000;FS=1.800;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.22;ReadPosRankSum=-1.036;SOR=0.968 GT:AD:DP:GQ:PL 0/1:44,39:83:99:1354,0,1333 -20 10011309 . T C 2707.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=30.67;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:2721,231,0 -20 10011666 . C T 2976.06 . AC=2;AF=1.00;AN=2;DP=74;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.06;QD=26.61;SOR=1.103 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2990,220,0 -20 10012362 . G T 850.06 . AC=2;AF=1.00;AN=2;DP=25;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=54.31;QD=29.20;SOR=4.003 GT:AD:DP:GQ:PL 1/1:0,23:23:69:864,69,0 +20 10011309 . T C 2707.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.20;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:2721,231,0 +20 10011517 . GA G 519.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.298;DP=98;ExcessHet=0.0000;FS=6.289;MLEAC=1;MLEAF=0.500;MQ=59.91;MQRankSum=2.190;QD=6.84;ReadPosRankSum=1.026;SOR=0.263 GT:AD:DP:GQ:PL 0/1:46,30:76:99:527,0,876 +20 10011666 . C T 2976.06 . AC=2;AF=1.00;AN=2;DP=74;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.06;QD=28.55;SOR=1.103 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2990,220,0 +20 10012362 . G T 850.06 . AC=2;AF=1.00;AN=2;DP=25;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=54.31;QD=34.42;SOR=4.003 GT:AD:DP:GQ:PL 1/1:0,23:23:69:864,69,0 20 10012384 . T C 250.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.773;DP=18;ExcessHet=0.0000;FS=7.375;MLEAC=1;MLEAF=0.500;MQ=53.38;MQRankSum=-0.811;QD=13.92;ReadPosRankSum=0.800;SOR=0.044 GT:AD:DP:GQ:PL 0/1:10,8:18:99:258,0,355 20 10012387 . T C 399.06 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=53.38;QD=24.94;SOR=3.258 GT:AD:DP:GQ:PL 1/1:0,16:16:46:413,46,0 -20 10012479 . A G 507.06 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.29;QD=29.83;SOR=0.804 GT:AD:DP:GQ:PL 1/1:0,17:17:50:521,50,0 -20 10012498 . C G 406.06 . AC=2;AF=1.00;AN=2;DP=11;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=42.15;QD=28.55;SOR=1.270 GT:AD:DP:GQ:PL 1/1:0,11:11:33:420,33,0 -20 10012518 . T C 407.06 . AC=2;AF=1.00;AN=2;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=43.58;QD=34.42;SOR=0.859 GT:AD:DP:GQ:PL 1/1:0,11:11:33:421,33,0 -20 10012521 . C T 92.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.335;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=40.86;MQRankSum=-0.376;QD=7.72;ReadPosRankSum=2.093;SOR=0.693 GT:AD:DP:GQ:PL 0/1:8,4:12:99:100,0,223 -20 10012570 . G GCA 434.02 . AC=2;AF=1.00;AN=2;DP=10;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=40.42;QD=28.53;SOR=3.258 GT:AD:DP:GQ:PL 1/1:0,10:10:30:448,30,0 -20 10012573 . T G 195.05 . AC=2;AF=1.00;AN=2;DP=11;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=41.49;QD=17.73;SOR=3.442 GT:AD:DP:GQ:PL 1/1:0,11:11:26:209,26,0 -20 10012631 . C CG 514.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.659;DP=21;ExcessHet=0.0000;FS=8.822;MLEAC=1;MLEAF=0.500;MQ=48.34;MQRankSum=-1.670;QD=24.50;ReadPosRankSum=-1.777;SOR=0.048 GT:AD:DP:GQ:PL 0/1:8,13:21:99:522,0,237 -20 10012636 . G C 397.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.575;DP=22;ExcessHet=0.0000;FS=5.959;MLEAC=1;MLEAF=0.500;MQ=48.93;MQRankSum=-1.513;QD=18.07;ReadPosRankSum=-1.777;SOR=0.058 GT:AD:DP:GQ:PL 0/1:8,14:22:99:405,0,294 +20 10012570 . G GCA 275.98 . AC=2;AF=1.00;AN=2;DP=8;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=42.80;QD=28.53;SOR=4.174 GT:AD:DP:GQ:PL 1/1:0,7:7:21:290,21,0 +20 10012572 . GT G 191.93 . AC=2;AF=1.00;AN=2;DP=9;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=43.79;QD=31.99;SOR=3.912 GT:AD:DP:GQ:PL 1/1:0,6:6:18:206,18,0 +20 10012631 . C CG 407.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.030;DP=21;ExcessHet=0.0000;FS=8.822;MLEAC=1;MLEAF=0.500;MQ=48.34;MQRankSum=-1.670;QD=19.41;ReadPosRankSum=-1.777;SOR=0.048 GT:AD:DP:GQ:PL 0/1:8,13:21:99:415,0,237 +20 10012636 . G C 397.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.711;DP=22;ExcessHet=0.0000;FS=5.959;MLEAC=1;MLEAF=0.500;MQ=48.93;MQRankSum=-1.513;QD=18.07;ReadPosRankSum=-1.777;SOR=0.058 GT:AD:DP:GQ:PL 0/1:8,14:22:99:405,0,175 20 10012714 . G C 1315.06 . AC=2;AF=1.00;AN=2;DP=36;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.52;QD=27.23;SOR=2.964 GT:AD:DP:GQ:PL 1/1:0,35:35:99:1329,105,0 20 10013119 . C T 1032.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.724;DP=61;ExcessHet=0.0000;FS=2.248;MLEAC=1;MLEAF=0.500;MQ=51.43;MQRankSum=-1.089;QD=17.50;ReadPosRankSum=0.159;SOR=0.405 GT:AD:DP:GQ:PL 0/1:29,30:59:99:1040,0,936 +20 10013574 . G A 1071.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.469;DP=73;ExcessHet=0.0000;FS=7.109;MLEAC=1;MLEAF=0.500;MQ=58.17;MQRankSum=-0.271;QD=15.53;ReadPosRankSum=0.706;SOR=1.675 GT:AD:DP:GQ:PL 0/1:38,31:69:99:1079,0,1301 +20 10014990 . C CAT 1267.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.930;DP=89;ExcessHet=0.0000;FS=2.076;MLEAC=1;MLEAF=0.500;MQ=60.88;MQRankSum=3.260;QD=16.46;ReadPosRankSum=-0.311;SOR=0.429 GT:AD:DP:GQ:PL 0/1:38,39:77:99:1275,0,1247 20 10015679 . C T 161.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.200;DP=10;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.16;ReadPosRankSum=0.497;SOR=0.693 GT:AD:DP:GQ:PL 0/1:5,5:10:99:169,0,166 20 10015761 . T C 365.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.982;DP=23;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.99;MQRankSum=1.294;QD=16.62;ReadPosRankSum=1.805;SOR=0.352 GT:AD:DP:GQ:PL 0/1:9,13:22:99:373,0,284 20 10018158 . G C 1660.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.213;DP=94;ExcessHet=0.0000;FS=0.808;MLEAC=1;MLEAF=0.500;MQ=59.80;MQRankSum=1.118;QD=18.87;ReadPosRankSum=1.179;SOR=0.834 GT:AD:DP:GQ:PL 0/1:40,48:88:99:1668,0,1165 @@ -77,43 +83,52 @@ 20 10020229 . G A 1559.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.792;DP=84;ExcessHet=0.0000;FS=0.833;MLEAC=1;MLEAF=0.500;MQ=59.50;MQRankSum=0.104;QD=19.02;ReadPosRankSum=-0.549;SOR=0.573 GT:AD:DP:GQ:PL 0/1:38,44:82:99:1567,0,1130 20 10023689 . G A 1873.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.144;DP=82;ExcessHet=0.0000;FS=0.877;MLEAC=1;MLEAF=0.500;MQ=59.77;MQRankSum=1.352;QD=23.42;ReadPosRankSum=1.162;SOR=0.549 GT:AD:DP:GQ:PL 0/1:29,51:80:99:1881,0,946 20 10024107 . C T 1715.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.770;DP=89;ExcessHet=0.0000;FS=0.817;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=-1.546;QD=19.95;ReadPosRankSum=0.148;SOR=0.823 GT:AD:DP:GQ:PL 0/1:38,48:86:99:1723,0,1086 -20 10024288 . C T 70.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.728;DP=67;ExcessHet=0.0000;FS=38.617;MLEAC=1;MLEAF=0.500;MQ=52.85;MQRankSum=-5.589;QD=1.10;ReadPosRankSum=2.599;SOR=5.132 GT:AD:DP:GQ:PL 0/1:52,12:64:78:78,0,1623 -20 10024294 . C T 189.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.772;DP=67;ExcessHet=0.0000;FS=64.013;MLEAC=1;MLEAF=0.500;MQ=51.67;MQRankSum=-4.001;QD=3.01;ReadPosRankSum=2.236;SOR=5.667 GT:AD:DP:GQ:PL 0/1:47,16:63:99:197,0,1450 20 10026794 . C T 1105.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.828;DP=56;ExcessHet=0.0000;FS=2.399;MLEAC=1;MLEAF=0.500;MQ=59.59;MQRankSum=-0.719;QD=21.26;ReadPosRankSum=-0.533;SOR=0.428 GT:AD:DP:GQ:PL 0/1:19,33:52:99:1113,0,529 +20 10027234 . A ATTAG 1350.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.406;DP=75;ExcessHet=0.0000;FS=3.248;MLEAC=1;MLEAF=0.500;MQ=57.44;MQRankSum=-0.845;QD=19.57;ReadPosRankSum=-0.510;SOR=0.926 GT:AD:DP:GQ:PL 0/1:34,35:69:99:1358,0,1320 20 10027868 . A G 1324.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-5.793;DP=91;ExcessHet=0.0000;FS=6.868;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=0.032;QD=14.88;ReadPosRankSum=1.872;SOR=0.881 GT:AD:DP:GQ:PL 0/1:44,45:89:99:1332,0,1512 20 10027872 . A G 1539.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-5.491;DP=88;ExcessHet=0.0000;FS=8.870;MLEAC=1;MLEAF=0.500;MQ=59.48;MQRankSum=0.101;QD=18.11;ReadPosRankSum=1.053;SOR=0.826 GT:AD:DP:GQ:PL 0/1:40,45:85:99:1547,0,1439 +20 10028867 . A ATG 1137.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.874;DP=93;ExcessHet=0.0000;FS=4.652;MLEAC=1;MLEAF=0.500;MQ=60.68;MQRankSum=2.711;QD=16.02;ReadPosRankSum=0.630;SOR=0.336 GT:AD:DP:GQ:PL 0/1:32,39:71:99:1145,0,915 20 10030188 . T A 1393.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.711;DP=82;ExcessHet=0.0000;FS=9.186;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=-1.013;QD=17.21;ReadPosRankSum=-0.553;SOR=1.105 GT:AD:DP:GQ:PL 0/1:42,39:81:99:1401,0,1524 20 10031342 . G A 1855.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.833;DP=93;ExcessHet=0.0000;FS=1.714;MLEAC=1;MLEAF=0.500;MQ=59.75;MQRankSum=-0.866;QD=19.95;ReadPosRankSum=-0.012;SOR=0.955 GT:AD:DP:GQ:PL 0/1:41,52:93:99:1863,0,1375 -20 10031798 . G A 4311.06 . AC=2;AF=1.00;AN=2;DP=107;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.61;QD=29.52;SOR=0.900 GT:AD:DP:GQ:PL 1/1:0,104:104:99:4325,313,0 20 10032094 . G A 1241.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.488;DP=86;ExcessHet=0.0000;FS=6.039;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=14.96;ReadPosRankSum=-0.579;SOR=0.260 GT:AD:DP:GQ:PL 0/1:47,36:83:99:1249,0,1497 20 10032882 . A T 1223.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.697;DP=76;ExcessHet=0.0000;FS=4.673;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-1.014;QD=16.32;ReadPosRankSum=0.626;SOR=0.338 GT:AD:DP:GQ:PL 0/1:39,36:75:99:1231,0,1406 +20 10032972 . C CAT 1152.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.354;DP=67;ExcessHet=0.0000;FS=5.062;MLEAC=1;MLEAF=0.500;MQ=59.66;MQRankSum=-1.017;QD=18.30;ReadPosRankSum=-0.723;SOR=1.300 GT:AD:DP:GQ:PL 0/1:33,30:63:99:1160,0,1295 20 10034306 . T C 803.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.661;DP=80;ExcessHet=0.0000;FS=0.890;MLEAC=1;MLEAF=0.500;MQ=59.48;MQRankSum=1.150;QD=10.72;ReadPosRankSum=0.539;SOR=0.685 GT:AD:DP:GQ:PL 0/1:46,29:75:99:811,0,1593 +20 10036930 . CGATAGCCCTAGCCCTAGATA C 1069.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.720;DP=96;ExcessHet=0.0000;FS=13.351;MLEAC=1;MLEAF=0.500;MQ=54.33;MQRankSum=-3.973;QD=16.21;ReadPosRankSum=0.460;SOR=0.256 GT:AD:DP:GQ:PL 0/1:37,29:66:99:1077,0,1441 +20 10037037 . C T 1453.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.504;DP=88;ExcessHet=0.0000;FS=1.943;MLEAC=1;MLEAF=0.500;MQ=60.08;MQRankSum=-1.193;QD=17.95;ReadPosRankSum=-1.609;SOR=0.495 GT:AD:DP:GQ:PL 0/1:39,42:81:99:1461,0,1127 +20 10037110 . T TGATA 1196.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.089;DP=83;ExcessHet=0.0000;FS=16.682;MLEAC=1;MLEAF=0.500;MQ=55.24;MQRankSum=5.270;QD=24.42;ReadPosRankSum=4.165;SOR=1.122 GT:AD:DP:GQ:PL 0/1:13,36:49:99:1204,0,402 +20 10037144 . T TGATAGATA 667.01 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.744;DP=80;ExcessHet=0.0000;FS=13.898;MLEAC=1;MLEAF=0.500;MQ=53.44;MQRankSum=-5.852;QD=8.55;ReadPosRankSum=2.953;SOR=1.320 GT:AD:DP:GQ:PL 0/1:39,39:78:99:1428,0,1388 20 10037709 . A T 1024.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.367;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.68;MQRankSum=0.934;QD=14.43;ReadPosRankSum=0.040;SOR=0.608 GT:AD:DP:GQ:PL 0/1:39,32:71:99:1032,0,1354 20 10039371 . T G 1345.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.260;DP=76;ExcessHet=0.0000;FS=6.144;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=18.18;ReadPosRankSum=0.391;SOR=1.031 GT:AD:DP:GQ:PL 0/1:34,40:74:99:1353,0,1194 -20 10042761 . A G 3536.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.47;SOR=1.364 GT:AD:DP:GQ:PL 1/1:0,90:90:99:3550,269,0 +20 10040772 . C CT 1467.03 . AC=2;AF=1.00;AN=2;DP=64;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.07;QD=28.77;SOR=0.813 GT:AD:DP:GQ:PL 1/1:0,51:51:99:1481,153,0 +20 10042761 . A G 3536.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.52;SOR=1.364 GT:AD:DP:GQ:PL 1/1:0,90:90:99:3550,269,0 20 10043002 . A T 1308.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.986;DP=89;ExcessHet=0.0000;FS=2.877;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=15.22;ReadPosRankSum=-0.035;SOR=0.434 GT:AD:DP:GQ:PL 0/1:48,38:86:99:1316,0,1658 -20 10044849 . A G 2106.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.61;QD=32.91;SOR=1.316 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2120,177,0 +20 10044849 . A G 2106.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.61;QD=33.47;SOR=1.316 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2120,177,0 +20 10046537 . A G 840.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.909;DP=57;ExcessHet=0.0000;FS=3.724;MLEAC=1;MLEAF=0.500;MQ=54.50;MQRankSum=0.395;QD=14.75;ReadPosRankSum=0.727;SOR=1.262 GT:AD:DP:GQ:PL 0/1:28,29:57:99:848,0,902 20 10050828 . T C 1248.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.704;DP=91;ExcessHet=0.0000;FS=2.887;MLEAC=1;MLEAF=0.500;MQ=59.54;MQRankSum=0.892;QD=14.52;ReadPosRankSum=-0.140;SOR=0.521 GT:AD:DP:GQ:PL 0/1:49,37:86:99:1256,0,1768 20 10052688 . C A 1083.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.180;DP=83;ExcessHet=0.0000;FS=3.135;MLEAC=1;MLEAF=0.500;MQ=59.78;MQRankSum=0.870;QD=14.07;ReadPosRankSum=1.443;SOR=0.379 GT:AD:DP:GQ:PL 0/1:45,32:77:99:1091,0,1645 -20 10067264 . G A 2937.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=31.31;SOR=0.776 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2951,219,0 -20 10067722 . A C 2161.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=31.45;SOR=0.846 GT:AD:DP:GQ:PL 1/1:0,54:54:99:2175,163,0 -20 10068981 . G A 2444.06 . AC=2;AF=1.00;AN=2;DP=63;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.27;SOR=0.950 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2458,178,0 -20 10070602 . T C 2706.06 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.78;QD=31.26;SOR=0.749 GT:AD:DP:GQ:PL 1/1:0,72:72:99:2720,216,0 -20 10071135 . C T 3272.06 . AC=2;AF=1.00;AN=2;DP=88;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.21;QD=27.76;SOR=1.003 GT:AD:DP:GQ:PL 1/1:0,79:79:99:3286,238,0 -20 10071187 . G A 3425.06 . AC=2;AF=1.00;AN=2;DP=85;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.73;QD=29.09;SOR=1.367 GT:AD:DP:GQ:PL 1/1:0,82:82:99:3439,246,0 +20 10058022 . T C 996.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.346;DP=72;ExcessHet=0.0000;FS=0.920;MLEAC=1;MLEAF=0.500;MQ=59.16;MQRankSum=0.466;QD=14.66;ReadPosRankSum=0.018;SOR=0.849 GT:AD:DP:GQ:PL 0/1:36,32:68:99:1004,0,1261 +20 10067049 . TAAAAAAA T 461.20 . AC=2;AF=1.00;AN=2;BaseQRankSum=-0.254;DP=61;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.70;MQRankSum=-0.200;QD=30.75;ReadPosRankSum=-1.490;SOR=1.179 GT:AD:DP:GQ:PL 1/1:2,13:15:8:474,8,0 +20 10067264 . G A 2937.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=32.91;SOR=0.776 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2951,219,0 +20 10067722 . A C 2161.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=31.31;SOR=0.846 GT:AD:DP:GQ:PL 1/1:0,54:54:99:2175,163,0 +20 10068172 . G A 532.04 . AC=2;AF=1.00;AN=2;BaseQRankSum=1.453;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.04;MQRankSum=-0.309;QD=31.30;ReadPosRankSum=-0.436;SOR=0.481 GT:AD:DP:GQ:PL 1/1:1,16:17:25:546,25,0 +20 10068981 . G A 2444.06 . AC=2;AF=1.00;AN=2;DP=63;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=31.45;SOR=0.950 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2458,178,0 +20 10071135 . C T 3272.06 . AC=2;AF=1.00;AN=2;DP=88;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.21;QD=33.27;SOR=1.003 GT:AD:DP:GQ:PL 1/1:0,79:79:99:3286,238,0 +20 10071187 . G A 3425.06 . AC=2;AF=1.00;AN=2;DP=85;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.73;QD=31.26;SOR=1.367 GT:AD:DP:GQ:PL 1/1:0,82:82:99:3439,246,0 20 10072505 . A G 2114.06 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.03;SOR=0.822 GT:AD:DP:GQ:PL 1/1:0,64:64:99:2128,191,0 -20 10074187 . A G 3005.06 . AC=2;AF=1.00;AN=2;DP=78;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.41;QD=26.08;SOR=0.859 GT:AD:DP:GQ:PL 1/1:0,76:76:99:3019,229,0 -20 10074716 . G A 2444.06 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=33.85;SOR=1.249 GT:AD:DP:GQ:PL 1/1:0,65:65:99:2458,195,0 -20 10074806 . G A 2832.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.38;QD=27.08;SOR=0.840 GT:AD:DP:GQ:PL 1/1:0,71:71:99:2846,213,0 -20 10075043 . T C 2420.06 . AC=2;AF=1.00;AN=2;DP=64;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.64;QD=25.42;SOR=1.107 GT:AD:DP:GQ:PL 1/1:0,61:61:99:2434,184,0 -20 10075168 . C T 3627.06 . AC=2;AF=1.00;AN=2;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=27.65;SOR=0.997 GT:AD:DP:GQ:PL 1/1:0,88:88:99:3641,264,0 +20 10074716 . G A 2415.06 . AC=2;AF=1.00;AN=2;DP=70;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.67;QD=27.76;SOR=1.214 GT:AD:DP:GQ:PL 1/1:0,64:64:99:2429,192,0 +20 10074806 . G A 2832.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.38;QD=29.09;SOR=0.840 GT:AD:DP:GQ:PL 1/1:0,71:71:99:2846,213,0 +20 10075043 . T C 2420.06 . AC=2;AF=1.00;AN=2;DP=64;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.64;QD=26.08;SOR=1.107 GT:AD:DP:GQ:PL 1/1:0,61:61:99:2434,184,0 +20 10075168 . C T 3627.06 . AC=2;AF=1.00;AN=2;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=33.85;SOR=0.997 GT:AD:DP:GQ:PL 1/1:0,88:88:99:3641,264,0 +20 10075508 . GA G 1952.03 . AC=2;AF=1.00;AN=2;DP=81;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=61.11;QD=27.89;SOR=1.085 GT:AD:DP:GQ:PL 1/1:0,70:70:99:1966,210,0 20 10076250 . A G 1128.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.386;DP=82;ExcessHet=0.0000;FS=7.546;MLEAC=1;MLEAF=0.500;MQ=59.41;MQRankSum=-1.423;QD=14.29;ReadPosRankSum=0.270;SOR=0.344 GT:AD:DP:GQ:PL 0/1:40,39:79:99:1136,0,1339 20 10076339 . A G 1330.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.069;DP=76;ExcessHet=0.0000;FS=1.992;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-0.866;QD=18.48;ReadPosRankSum=1.015;SOR=0.446 GT:AD:DP:GQ:PL 0/1:32,40:72:99:1338,0,1035 20 10076399 . G A 1828.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.154;DP=95;ExcessHet=0.0000;FS=1.680;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=19.45;ReadPosRankSum=-1.058;SOR=0.952 GT:AD:DP:GQ:PL 0/1:44,50:94:99:1836,0,1544 +20 10076989 . CA C 202.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.145;DP=77;ExcessHet=0.0000;FS=7.323;MLEAC=1;MLEAF=0.500;MQ=58.49;MQRankSum=1.233;QD=5.19;ReadPosRankSum=-0.643;SOR=0.579 GT:AD:DP:GQ:PL 0/1:23,16:39:99:210,0,342 20 10077752 . T C 1366.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-6.503;DP=83;ExcessHet=0.0000;FS=4.458;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=17.30;ReadPosRankSum=-0.352;SOR=1.251 GT:AD:DP:GQ:PL 0/1:34,45:79:99:1374,0,1187 20 10081750 . C A 1374.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.670;DP=92;ExcessHet=0.0000;FS=0.824;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.56;ReadPosRankSum=-0.406;SOR=0.664 GT:AD:DP:GQ:PL 0/1:44,39:83:99:1382,0,1525 20 10081800 . C T 1130.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.241;DP=69;ExcessHet=0.0000;FS=11.086;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.63;ReadPosRankSum=-2.622;SOR=0.143 GT:AD:DP:GQ:PL 0/1:35,33:68:99:1138,0,1222 -20 10082892 . C T 1673.06 . AC=2;AF=1.00;AN=2;DP=44;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.48;QD=29.48;SOR=0.836 GT:AD:DP:GQ:PL 1/1:0,43:43:99:1687,129,0 +20 10082892 . C T 1673.06 . AC=2;AF=1.00;AN=2;DP=44;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.48;QD=27.08;SOR=0.836 GT:AD:DP:GQ:PL 1/1:0,43:43:99:1687,129,0 20 10085211 . A T 1231.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.501;DP=81;ExcessHet=0.0000;FS=0.870;MLEAC=1;MLEAF=0.500;MQ=59.72;MQRankSum=-1.028;QD=16.21;ReadPosRankSum=-1.405;SOR=0.723 GT:AD:DP:GQ:PL 0/1:40,36:76:99:1239,0,1443 20 10086110 . G A 1295.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.343;DP=83;ExcessHet=0.0000;FS=1.810;MLEAC=1;MLEAF=0.500;MQ=59.16;MQRankSum=-0.680;QD=16.00;ReadPosRankSum=0.170;SOR=0.495 GT:AD:DP:GQ:PL 0/1:43,38:81:99:1303,0,1506 20 10086283 . G T 1046.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.304;DP=86;ExcessHet=0.0000;FS=0.855;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=12.46;ReadPosRankSum=1.889;SOR=0.529 GT:AD:DP:GQ:PL 0/1:52,32:84:99:1054,0,1771 @@ -122,27 +137,51 @@ 20 10086954 . G A 1116.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.606;DP=70;ExcessHet=0.0000;FS=4.812;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.42;ReadPosRankSum=-0.534;SOR=1.185 GT:AD:DP:GQ:PL 0/1:34,34:68:99:1124,0,1051 20 10087394 . T G 1709.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.340;DP=85;ExcessHet=0.0000;FS=4.225;MLEAC=1;MLEAF=0.500;MQ=59.46;MQRankSum=1.207;QD=20.35;ReadPosRankSum=0.885;SOR=0.436 GT:AD:DP:GQ:PL 0/1:35,49:84:99:1717,0,1186 20 10087754 . T G 1403.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.239;DP=87;ExcessHet=0.0000;FS=0.851;MLEAC=1;MLEAF=0.500;MQ=60.60;MQRankSum=2.166;QD=17.77;ReadPosRankSum=-0.378;SOR=0.596 GT:AD:DP:GQ:PL 0/1:37,42:79:99:1411,0,1236 -20 10088730 . G A 637.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.224;DP=57;ExcessHet=0.0000;FS=15.383;MLEAC=1;MLEAF=0.500;MQ=52.92;MQRankSum=-4.839;QD=12.26;ReadPosRankSum=0.581;SOR=1.592 GT:AD:DP:GQ:PL 0/1:29,23:52:99:645,0,965 -20 10088736 . A C 774.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.282;DP=60;ExcessHet=0.0000;FS=9.673;MLEAC=1;MLEAF=0.500;MQ=52.86;MQRankSum=-5.169;QD=14.08;ReadPosRankSum=0.573;SOR=0.851 GT:AD:DP:GQ:PL 0/1:28,27:55:99:782,0,854 +20 10088699 . C T 797.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.803;DP=67;ExcessHet=0.0000;FS=16.952;MLEAC=1;MLEAF=0.500;MQ=56.90;MQRankSum=-3.140;QD=12.87;ReadPosRankSum=-1.456;SOR=1.914 GT:AD:DP:GQ:PL 0/1:36,26:62:99:805,0,1088 +20 10088730 . G A 961.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.224;DP=57;ExcessHet=0.0000;FS=9.673;MLEAC=1;MLEAF=0.500;MQ=52.92;MQRankSum=-5.143;QD=17.48;ReadPosRankSum=0.581;SOR=1.025 GT:AD:DP:GQ:PL 0/1:29,26:55:99:969,0,956 +20 10088736 . A C 884.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.282;DP=60;ExcessHet=0.0000;FS=9.673;MLEAC=1;MLEAF=0.500;MQ=52.86;MQRankSum=-5.169;QD=16.08;ReadPosRankSum=0.573;SOR=0.851 GT:AD:DP:GQ:PL 0/1:28,27:55:99:892,0,854 20 10088747 . A G 798.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.877;DP=56;ExcessHet=0.0000;FS=7.653;MLEAC=1;MLEAF=0.500;MQ=52.20;MQRankSum=-4.907;QD=14.79;ReadPosRankSum=0.009;SOR=1.092 GT:AD:DP:GQ:PL 0/1:25,29:54:99:806,0,854 20 10088895 . C T 556.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.330;DP=43;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=57.80;MQRankSum=0.260;QD=13.92;ReadPosRankSum=1.238;SOR=0.727 GT:AD:DP:GQ:PL 0/1:22,18:40:99:564,0,651 -20 10088980 . T C 357.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.826;DP=60;ExcessHet=0.0000;FS=4.045;MLEAC=1;MLEAF=0.500;MQ=55.36;MQRankSum=-3.210;QD=6.62;ReadPosRankSum=0.950;SOR=1.295 GT:AD:DP:GQ:PL 0/1:37,17:54:99:365,0,1159 -20 10088985 . T C 456.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.437;DP=63;ExcessHet=0.0000;FS=2.347;MLEAC=1;MLEAF=0.500;MQ=55.03;MQRankSum=-3.151;QD=7.61;ReadPosRankSum=0.799;SOR=1.056 GT:AD:DP:GQ:PL 0/1:42,18:60:99:464,0,1357 +20 10088968 . C CAAA 211.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.220;DP=54;ExcessHet=0.0000;FS=9.387;MLEAC=1;MLEAF=0.500;MQ=57.02;MQRankSum=-3.733;QD=5.43;ReadPosRankSum=0.617;SOR=2.819 GT:AD:DP:GQ:PL 0/1:30,9:39:99:219,0,1177 20 10089441 . A G 1200.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.885;DP=79;ExcessHet=0.0000;FS=6.071;MLEAC=1;MLEAF=0.500;MQ=59.71;MQRankSum=-0.948;QD=15.80;ReadPosRankSum=-0.156;SOR=1.363 GT:AD:DP:GQ:PL 0/1:37,39:76:99:1208,0,1313 20 10089525 . C T 1569.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.859;DP=83;ExcessHet=0.0000;FS=4.260;MLEAC=1;MLEAF=0.500;MQ=59.50;MQRankSum=1.531;QD=19.38;ReadPosRankSum=0.862;SOR=0.617 GT:AD:DP:GQ:PL 0/1:38,43:81:99:1577,0,1088 +20 10090289 . CA C 414.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.431;DP=84;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.97;MQRankSum=1.393;QD=10.91;ReadPosRankSum=0.048;SOR=0.859 GT:AD:DP:GQ:PL 0/1:14,24:38:99:422,0,231 20 10090764 . A G 861.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.659;DP=67;ExcessHet=0.0000;FS=4.975;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=13.68;ReadPosRankSum=1.207;SOR=0.310 GT:AD:DP:GQ:PL 0/1:34,29:63:99:869,0,1207 +20 10090970 . T C 1278.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.484;DP=70;ExcessHet=0.0000;FS=0.927;MLEAC=1;MLEAF=0.500;MQ=59.47;MQRankSum=1.509;QD=18.53;ReadPosRankSum=-0.072;SOR=0.518 GT:AD:DP:GQ:PL 0/1:33,36:69:99:1286,0,1092 20 10092415 . A G 1656.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-6.731;DP=103;ExcessHet=0.0000;FS=0.741;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.40;ReadPosRankSum=0.082;SOR=0.665 GT:AD:DP:GQ:PL 0/1:52,49:101:99:1664,0,1901 -20 10092927 . G T 127.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.507;DP=83;ExcessHet=0.0000;FS=60.191;MLEAC=1;MLEAF=0.500;MQ=59.16;MQRankSum=-3.009;QD=1.77;ReadPosRankSum=-0.220;SOR=5.279 GT:AD:DP:GQ:PL 0/1:59,13:72:99:135,0,1864 20 10093923 . T A 1096.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.667;DP=73;ExcessHet=0.0000;FS=0.924;MLEAC=1;MLEAF=0.500;MQ=59.25;MQRankSum=0.358;QD=16.37;ReadPosRankSum=-1.583;SOR=0.772 GT:AD:DP:GQ:PL 0/1:35,32:67:99:1104,0,1257 20 10094251 . T A 1291.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.251;DP=67;ExcessHet=0.0000;FS=11.483;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=20.83;ReadPosRankSum=1.806;SOR=1.211 GT:AD:DP:GQ:PL 0/1:26,36:62:99:1299,0,781 +20 10094582 . A G 944.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.388;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=1.270;QD=13.69;ReadPosRankSum=-0.018;SOR=0.772 GT:AD:DP:GQ:PL 0/1:39,30:69:99:952,0,1350 +20 10094774 . C T 1057.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.784;DP=81;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=0.962;QD=14.10;ReadPosRankSum=0.197;SOR=0.690 GT:AD:DP:GQ:PL 0/1:40,35:75:99:1065,0,1282 +20 10095432 . GTGATGATGA G 868.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.063;DP=79;ExcessHet=0.0000;FS=1.102;MLEAC=1;MLEAF=0.500;MQ=54.53;MQRankSum=-4.431;QD=17.37;ReadPosRankSum=0.396;SOR=0.460 GT:AD:DP:GQ:PL 0/1:27,23:50:99:876,0,1000 20 10095741 . A G 1096.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.534;DP=72;ExcessHet=0.0000;FS=4.721;MLEAC=1;MLEAF=0.500;MQ=57.39;MQRankSum=-2.313;QD=15.67;ReadPosRankSum=-0.500;SOR=0.515 GT:AD:DP:GQ:PL 0/1:36,34:70:99:1104,0,1233 +20 10096293 . C T 1376.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.664;DP=79;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.64;MQRankSum=1.397;QD=18.36;ReadPosRankSum=-1.135;SOR=0.638 GT:AD:DP:GQ:PL 0/1:37,38:75:99:1384,0,1258 +20 10096596 . C T 1583.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.728;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.82;MQRankSum=0.612;QD=18.20;ReadPosRankSum=-0.170;SOR=0.640 GT:AD:DP:GQ:PL 0/1:40,47:87:99:1591,0,1273 20 10096768 . A C 1703.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.764;DP=96;ExcessHet=0.0000;FS=3.983;MLEAC=1;MLEAF=0.500;MQ=59.28;MQRankSum=-1.609;QD=18.72;ReadPosRankSum=0.613;SOR=0.445 GT:AD:DP:GQ:PL 0/1:42,49:91:99:1711,0,1452 -20 10096958 . G A 566.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.277;DP=64;ExcessHet=0.0000;FS=7.479;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=8.99;ReadPosRankSum=-2.151;SOR=0.784 GT:AD:DP:GQ:PL 0/1:44,19:63:99:574,0,1571 -20 10097075 . T G 1440.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.398;DP=95;ExcessHet=0.0000;FS=6.783;MLEAC=1;MLEAF=0.500;MQ=58.12;MQRankSum=-1.398;QD=15.83;ReadPosRankSum=0.242;SOR=0.694 GT:AD:DP:GQ:PL 0/1:44,47:91:99:1448,0,1485 +20 10096899 . G T 1405.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.755;DP=84;ExcessHet=0.0000;FS=9.606;MLEAC=1;MLEAF=0.500;MQ=59.28;MQRankSum=-1.387;QD=17.79;ReadPosRankSum=0.422;SOR=1.707 GT:AD:DP:GQ:PL 0/1:39,40:79:99:1413,0,1365 +20 10096905 . TA T 1522.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.897;DP=86;ExcessHet=0.0000;FS=11.448;MLEAC=1;MLEAF=0.500;MQ=59.30;MQRankSum=-1.656;QD=18.57;ReadPosRankSum=0.269;SOR=1.760 GT:AD:DP:GQ:PL 0/1:39,43:82:99:1530,0,1212 +20 10096933 . G C 1336.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.914;DP=89;ExcessHet=0.0000;FS=23.320;MLEAC=1;MLEAF=0.500;MQ=59.32;MQRankSum=-1.802;QD=15.73;ReadPosRankSum=0.383;SOR=1.534 GT:AD:DP:GQ:PL 0/1:44,41:85:99:1344,0,1514 +20 10096958 . G A 1628.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.697;DP=93;ExcessHet=0.0000;FS=19.237;MLEAC=1;MLEAF=0.500;MQ=59.35;MQRankSum=-1.682;QD=17.90;ReadPosRankSum=-1.593;SOR=1.375 GT:AD:DP:GQ:PL 0/1:44,47:91:99:1636,0,1487 +20 10097075 . T G 1466.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.533;DP=96;ExcessHet=0.0000;FS=6.613;MLEAC=1;MLEAF=0.500;MQ=58.14;MQRankSum=-1.389;QD=15.94;ReadPosRankSum=0.235;SOR=0.628 GT:AD:DP:GQ:PL 0/1:44,48:92:99:1474,0,1482 +20 10097101 . C CTTT 1132.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.907;DP=80;ExcessHet=0.0000;FS=4.931;MLEAC=1;MLEAF=0.500;MQ=58.24;MQRankSum=-0.684;QD=17.16;ReadPosRankSum=1.777;SOR=0.385 GT:AD:DP:GQ:PL 0/1:33,33:66:99:1140,0,1220 +20 10097437 . TTTTC CTTTC,T 1114.06 . AC=1,1;AF=0.500,0.500;AN=2;BaseQRankSum=-0.660;DP=60;ExcessHet=0.0000;FS=0.000;MLEAC=1,1;MLEAF=0.500,0.500;MQ=58.33;MQRankSum=3.089;QD=30.95;ReadPosRankSum=-0.138;SOR=0.859 GT:AD:DP:GQ:PL 1/2:2,11,23:36:99:1131,862,1679,307,0,383 20 10097789 . T C 709.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.157;DP=60;ExcessHet=0.0000;FS=5.374;MLEAC=1;MLEAF=0.500;MQ=58.05;MQRankSum=-2.805;QD=12.45;ReadPosRankSum=0.220;SOR=0.756 GT:AD:DP:GQ:PL 0/1:34,23:57:99:717,0,1190 20 10097928 . G A 591.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.203;DP=37;ExcessHet=0.0000;FS=1.315;MLEAC=1;MLEAF=0.500;MQ=58.11;MQRankSum=-1.654;QD=16.43;ReadPosRankSum=-0.079;SOR=0.951 GT:AD:DP:GQ:PL 0/1:17,19:36:99:599,0,586 20 10098110 . G C 573.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.510;DP=36;ExcessHet=0.0000;FS=6.658;MLEAC=1;MLEAF=0.500;MQ=58.71;MQRankSum=-1.477;QD=15.93;ReadPosRankSum=-0.730;SOR=0.069 GT:AD:DP:GQ:PL 0/1:19,17:36:99:581,0,631 +20 10098135 . C A 436.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.155;DP=39;ExcessHet=0.0000;FS=4.337;MLEAC=1;MLEAF=0.500;MQ=59.65;MQRankSum=1.546;QD=11.49;ReadPosRankSum=-0.591;SOR=0.075 GT:AD:DP:GQ:PL 0/1:24,14:38:99:444,0,874 +20 10098219 . TATATATA T 325.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.147;DP=21;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.94;MQRankSum=-0.205;QD=15.50;ReadPosRankSum=0.427;SOR=0.465 GT:AD:DP:GQ:PL 0/1:12,9:21:99:333,0,461 +20 10098237 . A T 254.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.006;DP=14;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=53.89;MQRankSum=-1.742;QD=19.59;ReadPosRankSum=1.118;SOR=0.836 GT:AD:DP:GQ:PL 0/1:6,7:13:99:262,0,208 +20 10098265 . T C 109.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.834;DP=6;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=41.96;MQRankSum=-1.834;QD=18.27;ReadPosRankSum=0.842;SOR=1.329 GT:AD:DP:GQ:PL 0/1:2,4:6:49:117,0,49 +20 10098344 . A G 62.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.674;DP=5;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=47.08;MQRankSum=-1.383;QD=15.66;ReadPosRankSum=0.000;SOR=0.693 GT:AD:DP:GQ:PL 0/1:2,2:4:67:70,0,67 20 10098786 . C T 32.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.431;DP=9;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=54.65;MQRankSum=-2.200;QD=3.63;ReadPosRankSum=-1.383;SOR=0.132 GT:AD:DP:GQ:PL 0/1:7,2:9:40:40,0,217 +20 10098885 . C CA 463.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.165;DP=33;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=49.73;MQRankSum=-4.449;QD=14.95;ReadPosRankSum=-0.954;SOR=0.518 GT:AD:DP:GQ:PL 0/1:17,14:31:99:471,0,572 +20 10099044 . A C 115.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.165;DP=24;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=54.53;MQRankSum=-3.771;QD=5.78;ReadPosRankSum=-1.601;SOR=0.465 GT:AD:DP:GQ:PL 0/1:15,5:20:99:123,0,493 +20 10099046 . T C 177.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.002;DP=21;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=52.78;MQRankSum=-3.858;QD=8.46;ReadPosRankSum=-2.053;SOR=0.616 GT:AD:DP:GQ:PL 0/1:15,6:21:99:185,0,552 +20 10099055 . T C 156.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.462;DP=26;ExcessHet=0.0000;FS=2.016;MLEAC=1;MLEAF=0.500;MQ=50.95;MQRankSum=-3.426;QD=6.53;ReadPosRankSum=-1.973;SOR=1.284 GT:AD:DP:GQ:PL 0/1:17,7:24:99:164,0,578 +20 10099079 . C T 241.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.367;DP=33;ExcessHet=0.0000;FS=1.397;MLEAC=1;MLEAF=0.500;MQ=50.89;MQRankSum=-4.614;QD=7.55;ReadPosRankSum=-1.267;SOR=1.051 GT:AD:DP:GQ:PL 0/1:19,13:32:99:249,0,528 +20 10099111 . T TTTTGTTTG 954.60 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.832;DP=55;ExcessHet=0.0000;FS=4.525;MLEAC=1;MLEAF=0.500;MQ=53.38;MQRankSum=-2.973;QD=22.73;ReadPosRankSum=-0.526;SOR=1.445 GT:AD:DP:GQ:PL 0/1:17,25:42:99:962,0,568 +20 10099140 . G T 995.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.167;DP=68;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.01;MQRankSum=-2.069;QD=15.32;ReadPosRankSum=1.073;SOR=0.776 GT:AD:DP:GQ:PL 0/1:33,32:65:99:1003,0,1014 +20 10099190 . G T 1055.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.034;DP=65;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=57.56;MQRankSum=-1.711;QD=16.24;ReadPosRankSum=-1.260;SOR=0.776 GT:AD:DP:GQ:PL 0/1:33,32:65:99:1063,0,1154 20 10099220 . A G 598.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.664;DP=47;ExcessHet=0.0000;FS=1.137;MLEAC=1;MLEAF=0.500;MQ=57.74;MQRankSum=-2.596;QD=13.30;ReadPosRankSum=0.629;SOR=0.519 GT:AD:DP:GQ:PL 0/1:25,20:45:99:606,0,873 20 10099535 . G A 1356.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.034;DP=68;ExcessHet=0.0000;FS=2.172;MLEAC=1;MLEAF=0.500;MQ=59.04;MQRankSum=-1.418;QD=20.87;ReadPosRankSum=-0.777;SOR=0.408 GT:AD:DP:GQ:PL 0/1:26,39:65:99:1364,0,686 20 10099565 . C T 1367.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.595;DP=70;ExcessHet=0.0000;FS=8.736;MLEAC=1;MLEAF=0.500;MQ=59.40;MQRankSum=-1.266;QD=19.82;ReadPosRankSum=1.225;SOR=0.191 GT:AD:DP:GQ:PL 0/1:31,38:69:99:1375,0,994 diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.gatk4.vcf b/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.gatk4.vcf index 337246864fb..83681307ab8 100644 --- a/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.gatk4.vcf +++ b/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.gatk4.vcf @@ -30,45 +30,39 @@ 20 10001474 . C T 2625.06 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=45.04;QD=28.73;SOR=1.483 GT:AD:DP:GQ:PL 1/1:0,72:72:99:2639,216,0 20 10002138 . C G 2026.06 . AC=2;AF=1.00;AN=2;DP=56;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=57.01;QD=30.97;SOR=0.770 GT:AD:DP:GQ:PL 1/1:0,52:52:99:2040,156,0 20 10002142 . G C 1976.06 . AC=2;AF=1.00;AN=2;DP=55;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.45;QD=27.24;SOR=0.813 GT:AD:DP:GQ:PL 1/1:0,51:51:99:1990,153,0 -20 10002470 . C T 1588.06 . AC=2;AF=1.00;AN=2;DP=54;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.22;QD=32.41;SOR=0.733 GT:AD:DP:GQ:PL 1/1:0,49:49:99:1602,147,0 -20 10002478 . A T 215.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.664;DP=58;ExcessHet=0.0000;FS=35.852;MLEAC=1;MLEAF=0.500;MQ=52.80;MQRankSum=-2.518;QD=4.07;ReadPosRankSum=2.003;SOR=4.287 GT:AD:DP:GQ:PL 0/1:36,17:53:99:223,0,943 20 10003358 . A C 1475.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.004;DP=91;ExcessHet=0.0000;FS=0.844;MLEAC=1;MLEAF=0.500;MQ=59.80;MQRankSum=1.011;QD=16.58;ReadPosRankSum=-1.355;SOR=0.572 GT:AD:DP:GQ:PL 0/1:45,44:89:99:1483,0,1477 20 10003832 . G A 2720.06 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.82;QD=28.20;SOR=1.473 GT:AD:DP:GQ:PL 1/1:0,66:66:99:2734,199,0 -20 10004147 . A G 1819.06 . AC=2;AF=1.00;AN=2;DP=53;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=55.56;QD=25.00;SOR=1.201 GT:AD:DP:GQ:PL 1/1:0,51:51:99:1833,153,0 -20 10004193 . G T 937.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.392;DP=54;ExcessHet=0.0000;FS=2.369;MLEAC=1;MLEAF=0.500;MQ=59.14;MQRankSum=3.385;QD=18.39;ReadPosRankSum=1.724;SOR=0.941 GT:AD:DP:GQ:PL 0/1:23,28:51:99:945,0,776 +20 10004147 . A G 1855.06 . AC=2;AF=1.00;AN=2;DP=54;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=55.65;QD=25.00;SOR=1.244 GT:AD:DP:GQ:PL 1/1:0,52:52:99:1869,156,0 +20 10004193 . G T 968.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.276;DP=56;ExcessHet=0.0000;FS=2.311;MLEAC=1;MLEAF=0.500;MQ=59.17;MQRankSum=3.395;QD=18.28;ReadPosRankSum=1.833;SOR=1.071 GT:AD:DP:GQ:PL 0/1:24,29:53:99:976,0,780 20 10004351 . C G 2770.06 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.05;QD=29.56;SOR=0.874 GT:AD:DP:GQ:PL 1/1:0,70:70:99:2784,211,0 20 10004389 . T G 2509.06 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.62;QD=30.62;SOR=1.143 GT:AD:DP:GQ:PL 1/1:0,62:62:99:2523,187,0 -20 10004887 . A G 151.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.700;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=15.16;ReadPosRankSum=0.160;SOR=1.508 GT:AD:DP:GQ:PL 0/1:5,5:10:99:159,0,155 -20 10005010 . C T 2949.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=28.17;SOR=1.226 GT:AD:DP:GQ:PL 1/1:0,72:72:99:2963,217,0 -20 10005427 . C T 2229.06 . AC=2;AF=1.00;AN=2;DP=60;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.62;QD=26.80;SOR=0.729 GT:AD:DP:GQ:PL 1/1:0,55:55:99:2243,165,0 -20 10005499 . A G 3068.06 . AC=2;AF=1.00;AN=2;DP=78;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=26.00;SOR=1.121 GT:AD:DP:GQ:PL 1/1:0,76:76:99:3082,229,0 +20 10004874 . A C 3447.06 . AC=2;AF=1.00;AN=2;DP=90;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.35;QD=28.17;SOR=1.286 GT:AD:DP:GQ:PL 1/1:0,87:87:99:3461,261,0 +20 10004887 . A G 1344.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.356;DP=90;ExcessHet=0.0000;FS=1.793;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=-0.067;QD=15.82;ReadPosRankSum=-1.114;SOR=0.984 GT:AD:DP:GQ:PL 0/1:45,40:85:99:1352,0,1542 +20 10005010 . C T 2949.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=26.80;SOR=1.226 GT:AD:DP:GQ:PL 1/1:0,72:72:99:2963,217,0 +20 10005427 . C T 2229.06 . AC=2;AF=1.00;AN=2;DP=60;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.62;QD=26.00;SOR=0.729 GT:AD:DP:GQ:PL 1/1:0,55:55:99:2243,165,0 +20 10005499 . A G 3068.06 . AC=2;AF=1.00;AN=2;DP=78;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=30.02;SOR=1.121 GT:AD:DP:GQ:PL 1/1:0,76:76:99:3082,229,0 20 10007150 . G C 691.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.476;DP=64;ExcessHet=0.0000;FS=5.048;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=10.98;ReadPosRankSum=-0.077;SOR=0.746 GT:AD:DP:GQ:PL 0/1:38,25:63:99:699,0,1321 20 10007175 . C T 1371.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.249;DP=63;ExcessHet=0.0000;FS=2.211;MLEAC=1;MLEAF=0.500;MQ=59.63;MQRankSum=1.319;QD=22.49;ReadPosRankSum=-1.213;SOR=0.434 GT:AD:DP:GQ:PL 0/1:23,38:61:99:1379,0,712 -20 10007352 . C T 2779.06 . AC=2;AF=1.00;AN=2;DP=70;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.67;QD=30.02;SOR=1.054 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2793,208,0 -20 10007980 . A C 3571.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.69;QD=31.98;SOR=1.014 GT:AD:DP:GQ:PL 1/1:0,91:91:99:3585,273,0 -20 10008458 . T G 2669.06 . AC=2;AF=1.00;AN=2;DP=72;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.76;QD=27.51;SOR=0.980 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2683,207,0 +20 10007352 . C T 2779.06 . AC=2;AF=1.00;AN=2;DP=70;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.67;QD=31.98;SOR=1.054 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2793,208,0 +20 10007980 . A C 3571.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.69;QD=27.51;SOR=1.014 GT:AD:DP:GQ:PL 1/1:0,91:91:99:3585,273,0 +20 10008458 . T G 2669.06 . AC=2;AF=1.00;AN=2;DP=72;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.76;QD=29.11;SOR=0.980 GT:AD:DP:GQ:PL 1/1:0,69:69:99:2683,207,0 20 10008951 . A C 1524.06 . AC=2;AF=1.00;AN=2;BaseQRankSum=0.599;DP=53;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=50.72;MQRankSum=1.910;QD=30.48;ReadPosRankSum=0.694;SOR=0.892 GT:AD:DP:GQ:PL 1/1:1,49:50:99:1538,118,0 -20 10009400 . T A 3013.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.11;SOR=0.804 GT:AD:DP:GQ:PL 1/1:0,74:74:99:3027,223,0 -20 10009512 . C G 3054.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.53;QD=28.08;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:3068,231,0 -20 10009871 . A G 98.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.472;DP=23;ExcessHet=0.0000;FS=5.161;MLEAC=1;MLEAF=0.500;MQ=56.86;MQRankSum=0.955;QD=5.19;ReadPosRankSum=-1.294;SOR=0.685 GT:AD:DP:GQ:PL 0/1:14,5:19:99:106,0,224 -20 10009875 . A G 92.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.191;DP=25;ExcessHet=0.0000;FS=5.379;MLEAC=1;MLEAF=0.500;MQ=56.14;MQRankSum=0.921;QD=4.63;ReadPosRankSum=-1.234;SOR=0.669 GT:AD:DP:GQ:PL 0/1:15,5:20:99:100,0,122 -20 10009886 . A G 48.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.204;DP=23;ExcessHet=0.0000;FS=3.136;MLEAC=1;MLEAF=0.500;MQ=55.79;MQRankSum=-0.792;QD=6.95;ReadPosRankSum=0.000;SOR=0.916 GT:AD:DP:GQ:PL 0/1:4,3:7:56:56,0,136 +20 10009400 . T A 3013.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=28.08;SOR=0.804 GT:AD:DP:GQ:PL 1/1:0,74:74:99:3027,223,0 +20 10009512 . C G 3054.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.53;QD=23.23;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:3068,231,0 +20 10009871 . A G 41.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.394;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=57.39;MQRankSum=0.696;QD=2.97;ReadPosRankSum=-2.638;SOR=0.368 GT:AD:DP:GQ:PL 0/1:11,3:14:49:49,0,128 +20 10009875 . A G 52.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.856;DP=20;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=56.45;MQRankSum=0.820;QD=3.29;ReadPosRankSum=-2.619;SOR=0.260 GT:AD:DP:GQ:PL 0/1:13,3:16:50:60,0,50 20 10010393 . T G 1485.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.351;DP=79;ExcessHet=0.0000;FS=11.600;MLEAC=1;MLEAF=0.500;MQ=59.42;MQRankSum=-1.284;QD=18.81;ReadPosRankSum=-1.738;SOR=0.606 GT:AD:DP:GQ:PL 0/1:36,43:79:99:1493,0,1230 -20 10010766 . T G 2426.06 . AC=2;AF=1.00;AN=2;DP=69;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=23.23;SOR=0.818 GT:AD:DP:GQ:PL 1/1:0,66:66:99:2440,199,0 +20 10010766 . T G 2426.06 . AC=2;AF=1.00;AN=2;DP=69;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.03;SOR=0.818 GT:AD:DP:GQ:PL 1/1:0,66:66:99:2440,199,0 20 10011075 . C T 1346.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.364;DP=86;ExcessHet=0.0000;FS=1.800;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.22;ReadPosRankSum=-1.036;SOR=0.968 GT:AD:DP:GQ:PL 0/1:44,39:83:99:1354,0,1333 -20 10011309 . T C 2707.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.03;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:2721,231,0 -20 10011666 . C T 2976.06 . AC=2;AF=1.00;AN=2;DP=74;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.06;QD=30.67;SOR=1.103 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2990,220,0 -20 10012362 . G T 850.06 . AC=2;AF=1.00;AN=2;DP=25;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=54.31;QD=26.61;SOR=4.003 GT:AD:DP:GQ:PL 1/1:0,23:23:69:864,69,0 +20 10011309 . T C 2707.06 . AC=2;AF=1.00;AN=2;DP=80;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=30.67;SOR=1.223 GT:AD:DP:GQ:PL 1/1:0,77:77:99:2721,231,0 +20 10011666 . C T 2976.06 . AC=2;AF=1.00;AN=2;DP=74;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.06;QD=26.61;SOR=1.103 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2990,220,0 +20 10012362 . G T 850.06 . AC=2;AF=1.00;AN=2;DP=25;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=54.31;QD=29.20;SOR=4.003 GT:AD:DP:GQ:PL 1/1:0,23:23:69:864,69,0 20 10012384 . T C 250.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.773;DP=18;ExcessHet=0.0000;FS=7.375;MLEAC=1;MLEAF=0.500;MQ=53.38;MQRankSum=-0.811;QD=13.92;ReadPosRankSum=0.800;SOR=0.044 GT:AD:DP:GQ:PL 0/1:10,8:18:99:258,0,355 20 10012387 . T C 399.06 . AC=2;AF=1.00;AN=2;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=53.38;QD=24.94;SOR=3.258 GT:AD:DP:GQ:PL 1/1:0,16:16:46:413,46,0 -20 10012479 . A G 541.06 . AC=2;AF=1.00;AN=2;DP=19;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=51.79;QD=30.06;SOR=0.914 GT:AD:DP:GQ:PL 1/1:0,18:18:53:555,53,0 -20 10012498 . C G 430.06 . AC=2;AF=1.00;AN=2;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=43.92;QD=29.20;SOR=1.022 GT:AD:DP:GQ:PL 1/1:0,12:12:36:444,36,0 -20 10012518 . T C 407.06 . AC=2;AF=1.00;AN=2;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=43.58;QD=28.55;SOR=0.859 GT:AD:DP:GQ:PL 1/1:0,11:11:33:421,33,0 -20 10012521 . C T 92.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.335;DP=12;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=40.86;MQRankSum=-0.376;QD=7.72;ReadPosRankSum=2.093;SOR=0.693 GT:AD:DP:GQ:PL 0/1:8,4:12:99:100,0,223 -20 10012571 . G A 317.04 . AC=2;AF=1.00;AN=2;DP=8;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=42.80;QD=34.42;SOR=2.833 GT:AD:DP:GQ:PL 1/1:0,8:8:24:331,24,0 -20 10012573 . T G 296.05 . AC=2;AF=1.00;AN=2;DP=9;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=43.79;QD=32.89;SOR=3.056 GT:AD:DP:GQ:PL 1/1:0,9:9:27:310,27,0 +20 10012571 . G A 134.96 . AC=2;AF=1.00;AN=2;DP=5;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=43.29;QD=26.99;SOR=3.611 GT:AD:DP:GQ:PL 1/1:0,5:5:15:149,15,0 +20 10012573 . T G 143.96 . AC=2;AF=1.00;AN=2;DP=6;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=44.67;QD=28.79;SOR=3.611 GT:AD:DP:GQ:PL 1/1:0,5:5:15:158,15,0 20 10012636 . G C 110.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.281;DP=13;ExcessHet=0.0000;FS=8.921;MLEAC=1;MLEAF=0.500;MQ=50.79;MQRankSum=-1.691;QD=8.51;ReadPosRankSum=-0.144;SOR=0.022 GT:AD:DP:GQ:PL 0/1:8,5:13:99:118,0,202 -20 10012714 . G C 1315.06 . AC=2;AF=1.00;AN=2;DP=36;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.52;QD=28.53;SOR=2.964 GT:AD:DP:GQ:PL 1/1:0,35:35:99:1329,105,0 +20 10012714 . G C 1315.06 . AC=2;AF=1.00;AN=2;DP=36;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=52.52;QD=28.55;SOR=2.964 GT:AD:DP:GQ:PL 1/1:0,35:35:99:1329,105,0 20 10013119 . C T 1032.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.724;DP=61;ExcessHet=0.0000;FS=2.248;MLEAC=1;MLEAF=0.500;MQ=51.43;MQRankSum=-1.089;QD=17.50;ReadPosRankSum=0.159;SOR=0.405 GT:AD:DP:GQ:PL 0/1:29,30:59:99:1040,0,936 20 10013574 . G A 1071.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.469;DP=73;ExcessHet=0.0000;FS=7.109;MLEAC=1;MLEAF=0.500;MQ=58.17;MQRankSum=-0.271;QD=15.53;ReadPosRankSum=0.706;SOR=1.675 GT:AD:DP:GQ:PL 0/1:38,31:69:99:1079,0,1301 20 10015679 . C T 161.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.200;DP=10;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.16;ReadPosRankSum=0.497;SOR=0.693 GT:AD:DP:GQ:PL 0/1:5,5:10:99:169,0,166 @@ -79,48 +73,42 @@ 20 10020229 . G A 1559.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.792;DP=84;ExcessHet=0.0000;FS=0.833;MLEAC=1;MLEAF=0.500;MQ=59.50;MQRankSum=0.104;QD=19.02;ReadPosRankSum=-0.549;SOR=0.573 GT:AD:DP:GQ:PL 0/1:38,44:82:99:1567,0,1130 20 10023689 . G A 1873.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.144;DP=82;ExcessHet=0.0000;FS=0.877;MLEAC=1;MLEAF=0.500;MQ=59.77;MQRankSum=1.352;QD=23.42;ReadPosRankSum=1.162;SOR=0.549 GT:AD:DP:GQ:PL 0/1:29,51:80:99:1881,0,946 20 10024107 . C T 1715.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.770;DP=89;ExcessHet=0.0000;FS=0.817;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=-1.546;QD=19.95;ReadPosRankSum=0.148;SOR=0.823 GT:AD:DP:GQ:PL 0/1:38,48:86:99:1723,0,1086 -20 10024288 . C T 70.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.728;DP=67;ExcessHet=0.0000;FS=38.617;MLEAC=1;MLEAF=0.500;MQ=52.85;MQRankSum=-5.589;QD=1.10;ReadPosRankSum=2.599;SOR=5.132 GT:AD:DP:GQ:PL 0/1:52,12:64:78:78,0,1623 -20 10024294 . C T 189.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.772;DP=67;ExcessHet=0.0000;FS=64.013;MLEAC=1;MLEAF=0.500;MQ=51.67;MQRankSum=-4.001;QD=3.01;ReadPosRankSum=2.236;SOR=5.667 GT:AD:DP:GQ:PL 0/1:47,16:63:99:197,0,1450 20 10026794 . C T 1105.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.828;DP=56;ExcessHet=0.0000;FS=2.399;MLEAC=1;MLEAF=0.500;MQ=59.59;MQRankSum=-0.719;QD=21.26;ReadPosRankSum=-0.533;SOR=0.428 GT:AD:DP:GQ:PL 0/1:19,33:52:99:1113,0,529 20 10027868 . A G 1324.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-5.793;DP=91;ExcessHet=0.0000;FS=6.868;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=0.032;QD=14.88;ReadPosRankSum=1.872;SOR=0.881 GT:AD:DP:GQ:PL 0/1:44,45:89:99:1332,0,1512 20 10027872 . A G 1539.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-5.491;DP=88;ExcessHet=0.0000;FS=8.870;MLEAC=1;MLEAF=0.500;MQ=59.48;MQRankSum=0.101;QD=18.11;ReadPosRankSum=1.053;SOR=0.826 GT:AD:DP:GQ:PL 0/1:40,45:85:99:1547,0,1439 20 10030188 . T A 1393.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.711;DP=82;ExcessHet=0.0000;FS=9.186;MLEAC=1;MLEAF=0.500;MQ=59.49;MQRankSum=-1.013;QD=17.21;ReadPosRankSum=-0.553;SOR=1.105 GT:AD:DP:GQ:PL 0/1:42,39:81:99:1401,0,1524 20 10031342 . G A 1855.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.833;DP=93;ExcessHet=0.0000;FS=1.714;MLEAC=1;MLEAF=0.500;MQ=59.75;MQRankSum=-0.866;QD=19.95;ReadPosRankSum=-0.012;SOR=0.955 GT:AD:DP:GQ:PL 0/1:41,52:93:99:1863,0,1375 -20 10031798 . G A 4311.06 . AC=2;AF=1.00;AN=2;DP=107;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.61;QD=27.23;SOR=0.900 GT:AD:DP:GQ:PL 1/1:0,104:104:99:4325,313,0 20 10032094 . G A 1241.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.488;DP=86;ExcessHet=0.0000;FS=6.039;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=14.96;ReadPosRankSum=-0.579;SOR=0.260 GT:AD:DP:GQ:PL 0/1:47,36:83:99:1249,0,1497 20 10032882 . A T 1223.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.697;DP=76;ExcessHet=0.0000;FS=4.673;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-1.014;QD=16.32;ReadPosRankSum=0.626;SOR=0.338 GT:AD:DP:GQ:PL 0/1:39,36:75:99:1231,0,1406 20 10034306 . T C 803.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.661;DP=80;ExcessHet=0.0000;FS=0.890;MLEAC=1;MLEAF=0.500;MQ=59.48;MQRankSum=1.150;QD=10.72;ReadPosRankSum=0.539;SOR=0.685 GT:AD:DP:GQ:PL 0/1:46,29:75:99:811,0,1593 -20 10037037 . C T 1460.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.541;DP=87;ExcessHet=0.0000;FS=0.916;MLEAC=1;MLEAF=0.500;MQ=60.08;MQRankSum=-1.210;QD=18.26;ReadPosRankSum=-1.577;SOR=0.523 GT:AD:DP:GQ:PL 0/1:38,42:80:99:1468,0,1085 +20 10037037 . C T 1457.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.504;DP=88;ExcessHet=0.0000;FS=1.943;MLEAC=1;MLEAF=0.500;MQ=60.08;MQRankSum=-1.193;QD=18.00;ReadPosRankSum=-1.609;SOR=0.495 GT:AD:DP:GQ:PL 0/1:39,42:81:99:1465,0,1124 20 10037709 . A T 1024.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.367;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.68;MQRankSum=0.934;QD=14.43;ReadPosRankSum=0.040;SOR=0.608 GT:AD:DP:GQ:PL 0/1:39,32:71:99:1032,0,1354 20 10039371 . T G 1345.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.260;DP=76;ExcessHet=0.0000;FS=6.144;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=18.18;ReadPosRankSum=0.391;SOR=1.031 GT:AD:DP:GQ:PL 0/1:34,40:74:99:1353,0,1194 -20 10042761 . A G 3536.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.52;SOR=1.364 GT:AD:DP:GQ:PL 1/1:0,90:90:99:3550,269,0 +20 10042761 . A G 3536.06 . AC=2;AF=1.00;AN=2;DP=93;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=34.42;SOR=1.364 GT:AD:DP:GQ:PL 1/1:0,90:90:99:3550,269,0 20 10043002 . A T 1308.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=3.986;DP=89;ExcessHet=0.0000;FS=2.877;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=15.22;ReadPosRankSum=-0.035;SOR=0.434 GT:AD:DP:GQ:PL 0/1:48,38:86:99:1316,0,1658 -20 10044849 . A G 2106.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.61;QD=33.47;SOR=1.316 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2120,177,0 +20 10044849 . A G 2106.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.61;QD=28.53;SOR=1.316 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2120,177,0 20 10046537 . A G 840.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.909;DP=57;ExcessHet=0.0000;FS=3.724;MLEAC=1;MLEAF=0.500;MQ=54.50;MQRankSum=0.395;QD=14.75;ReadPosRankSum=0.727;SOR=1.262 GT:AD:DP:GQ:PL 0/1:28,29:57:99:848,0,902 20 10050828 . T C 1248.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.704;DP=91;ExcessHet=0.0000;FS=2.887;MLEAC=1;MLEAF=0.500;MQ=59.54;MQRankSum=0.892;QD=14.52;ReadPosRankSum=-0.140;SOR=0.521 GT:AD:DP:GQ:PL 0/1:49,37:86:99:1256,0,1768 20 10052688 . C A 1083.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.180;DP=83;ExcessHet=0.0000;FS=3.135;MLEAC=1;MLEAF=0.500;MQ=59.78;MQRankSum=0.870;QD=14.07;ReadPosRankSum=1.443;SOR=0.379 GT:AD:DP:GQ:PL 0/1:45,32:77:99:1091,0,1645 20 10058022 . T C 996.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.346;DP=72;ExcessHet=0.0000;FS=0.920;MLEAC=1;MLEAF=0.500;MQ=59.16;MQRankSum=0.466;QD=14.66;ReadPosRankSum=0.018;SOR=0.849 GT:AD:DP:GQ:PL 0/1:36,32:68:99:1004,0,1261 -20 10067264 . G A 2937.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=32.91;SOR=0.776 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2951,219,0 -20 10067722 . A C 2161.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=31.31;SOR=0.846 GT:AD:DP:GQ:PL 1/1:0,54:54:99:2175,163,0 -20 10068172 . G A 480.06 . AC=2;AF=1.00;AN=2;DP=15;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.45;QD=31.45;SOR=0.836 GT:AD:DP:GQ:PL 1/1:0,13:13:39:494,39,0 -20 10068981 . G A 2444.06 . AC=2;AF=1.00;AN=2;DP=63;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.27;SOR=0.950 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2458,178,0 -20 10070602 . T C 2706.06 . AC=2;AF=1.00;AN=2;DP=76;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=58.78;QD=31.26;SOR=0.749 GT:AD:DP:GQ:PL 1/1:0,72:72:99:2720,216,0 -20 10071135 . C T 3272.06 . AC=2;AF=1.00;AN=2;DP=88;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.21;QD=27.76;SOR=1.003 GT:AD:DP:GQ:PL 1/1:0,79:79:99:3286,238,0 -20 10071187 . G A 3425.06 . AC=2;AF=1.00;AN=2;DP=85;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.73;QD=29.09;SOR=1.367 GT:AD:DP:GQ:PL 1/1:0,82:82:99:3439,246,0 +20 10067264 . G A 2937.06 . AC=2;AF=1.00;AN=2;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=27.23;SOR=0.776 GT:AD:DP:GQ:PL 1/1:0,73:73:99:2951,219,0 +20 10067722 . A C 2161.06 . AC=2;AF=1.00;AN=2;DP=59;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=29.52;SOR=0.846 GT:AD:DP:GQ:PL 1/1:0,54:54:99:2175,163,0 +20 10068172 . G A 532.04 . AC=2;AF=1.00;AN=2;BaseQRankSum=1.453;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=56.04;MQRankSum=-0.309;QD=31.30;ReadPosRankSum=-0.436;SOR=0.481 GT:AD:DP:GQ:PL 1/1:1,16:17:25:546,25,0 +20 10068981 . G A 2444.06 . AC=2;AF=1.00;AN=2;DP=63;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.47;SOR=0.950 GT:AD:DP:GQ:PL 1/1:0,59:59:99:2458,178,0 +20 10071135 . C T 3272.06 . AC=2;AF=1.00;AN=2;DP=88;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.21;QD=32.91;SOR=1.003 GT:AD:DP:GQ:PL 1/1:0,79:79:99:3286,238,0 +20 10071187 . G A 3425.06 . AC=2;AF=1.00;AN=2;DP=85;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.73;QD=31.31;SOR=1.367 GT:AD:DP:GQ:PL 1/1:0,82:82:99:3439,246,0 20 10072505 . A G 2114.06 . AC=2;AF=1.00;AN=2;DP=67;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=60.00;QD=33.03;SOR=0.822 GT:AD:DP:GQ:PL 1/1:0,64:64:99:2128,191,0 -20 10074187 . A G 3005.06 . AC=2;AF=1.00;AN=2;DP=78;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.41;QD=26.08;SOR=0.859 GT:AD:DP:GQ:PL 1/1:0,76:76:99:3019,229,0 -20 10074716 . G A 2444.06 . AC=2;AF=1.00;AN=2;DP=71;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.68;QD=33.85;SOR=1.249 GT:AD:DP:GQ:PL 1/1:0,65:65:99:2458,195,0 -20 10074806 . G A 2832.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.38;QD=27.08;SOR=0.840 GT:AD:DP:GQ:PL 1/1:0,71:71:99:2846,213,0 -20 10075043 . T C 2420.06 . AC=2;AF=1.00;AN=2;DP=64;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.64;QD=25.42;SOR=1.107 GT:AD:DP:GQ:PL 1/1:0,61:61:99:2434,184,0 -20 10075168 . C T 3627.06 . AC=2;AF=1.00;AN=2;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=27.65;SOR=0.997 GT:AD:DP:GQ:PL 1/1:0,88:88:99:3641,264,0 +20 10074716 . G A 2415.06 . AC=2;AF=1.00;AN=2;DP=70;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.67;QD=31.45;SOR=1.214 GT:AD:DP:GQ:PL 1/1:0,64:64:99:2429,192,0 +20 10074806 . G A 2832.06 . AC=2;AF=1.00;AN=2;DP=75;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.38;QD=33.27;SOR=0.840 GT:AD:DP:GQ:PL 1/1:0,71:71:99:2846,213,0 +20 10075043 . T C 2420.06 . AC=2;AF=1.00;AN=2;DP=64;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.64;QD=31.26;SOR=1.107 GT:AD:DP:GQ:PL 1/1:0,61:61:99:2434,184,0 +20 10075168 . C T 3627.06 . AC=2;AF=1.00;AN=2;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.37;QD=27.76;SOR=0.997 GT:AD:DP:GQ:PL 1/1:0,88:88:99:3641,264,0 20 10076250 . A G 1128.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.386;DP=82;ExcessHet=0.0000;FS=7.546;MLEAC=1;MLEAF=0.500;MQ=59.41;MQRankSum=-1.423;QD=14.29;ReadPosRankSum=0.270;SOR=0.344 GT:AD:DP:GQ:PL 0/1:40,39:79:99:1136,0,1339 20 10076339 . A G 1330.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.069;DP=76;ExcessHet=0.0000;FS=1.992;MLEAC=1;MLEAF=0.500;MQ=59.70;MQRankSum=-0.866;QD=18.48;ReadPosRankSum=1.015;SOR=0.446 GT:AD:DP:GQ:PL 0/1:32,40:72:99:1338,0,1035 20 10076399 . G A 1828.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.154;DP=95;ExcessHet=0.0000;FS=1.680;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=19.45;ReadPosRankSum=-1.058;SOR=0.952 GT:AD:DP:GQ:PL 0/1:44,50:94:99:1836,0,1544 20 10077752 . T C 1366.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-6.503;DP=83;ExcessHet=0.0000;FS=4.458;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=17.30;ReadPosRankSum=-0.352;SOR=1.251 GT:AD:DP:GQ:PL 0/1:34,45:79:99:1374,0,1187 -20 10079476 . T G 35.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.780;DP=57;ExcessHet=0.0000;FS=58.877;MLEAC=1;MLEAF=0.500;MQ=58.86;MQRankSum=-0.779;QD=0.77;ReadPosRankSum=1.477;SOR=5.130 GT:AD:DP:GQ:PL 0/1:34,12:46:43:43,0,1163 20 10081750 . C A 1374.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.670;DP=92;ExcessHet=0.0000;FS=0.824;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.56;ReadPosRankSum=-0.406;SOR=0.664 GT:AD:DP:GQ:PL 0/1:44,39:83:99:1382,0,1525 20 10081800 . C T 1130.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.241;DP=69;ExcessHet=0.0000;FS=11.086;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.63;ReadPosRankSum=-2.622;SOR=0.143 GT:AD:DP:GQ:PL 0/1:35,33:68:99:1138,0,1222 -20 10082892 . C T 1673.06 . AC=2;AF=1.00;AN=2;DP=44;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.48;QD=29.48;SOR=0.836 GT:AD:DP:GQ:PL 1/1:0,43:43:99:1687,129,0 +20 10082892 . C T 1673.06 . AC=2;AF=1.00;AN=2;DP=44;ExcessHet=0.0000;FS=0.000;MLEAC=2;MLEAF=1.00;MQ=59.48;QD=29.09;SOR=0.836 GT:AD:DP:GQ:PL 1/1:0,43:43:99:1687,129,0 20 10085211 . A T 1231.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.501;DP=81;ExcessHet=0.0000;FS=0.870;MLEAC=1;MLEAF=0.500;MQ=59.72;MQRankSum=-1.028;QD=16.21;ReadPosRankSum=-1.405;SOR=0.723 GT:AD:DP:GQ:PL 0/1:40,36:76:99:1239,0,1443 20 10086110 . G A 1295.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.343;DP=83;ExcessHet=0.0000;FS=1.810;MLEAC=1;MLEAF=0.500;MQ=59.16;MQRankSum=-0.680;QD=16.00;ReadPosRankSum=0.170;SOR=0.495 GT:AD:DP:GQ:PL 0/1:43,38:81:99:1303,0,1506 20 10086283 . G T 1046.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.304;DP=86;ExcessHet=0.0000;FS=0.855;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=12.46;ReadPosRankSum=1.889;SOR=0.529 GT:AD:DP:GQ:PL 0/1:52,32:84:99:1054,0,1771 @@ -133,28 +121,36 @@ 20 10088730 . G A 961.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.224;DP=57;ExcessHet=0.0000;FS=9.673;MLEAC=1;MLEAF=0.500;MQ=52.92;MQRankSum=-5.143;QD=17.48;ReadPosRankSum=0.581;SOR=1.025 GT:AD:DP:GQ:PL 0/1:29,26:55:99:969,0,956 20 10088736 . A C 884.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.282;DP=60;ExcessHet=0.0000;FS=9.673;MLEAC=1;MLEAF=0.500;MQ=52.86;MQRankSum=-5.169;QD=16.08;ReadPosRankSum=0.573;SOR=0.851 GT:AD:DP:GQ:PL 0/1:28,27:55:99:892,0,854 20 10088747 . A G 798.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-3.877;DP=56;ExcessHet=0.0000;FS=7.653;MLEAC=1;MLEAF=0.500;MQ=52.20;MQRankSum=-4.907;QD=14.79;ReadPosRankSum=0.009;SOR=1.092 GT:AD:DP:GQ:PL 0/1:25,29:54:99:806,0,854 -20 10088895 . C T 556.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.330;DP=43;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=57.80;MQRankSum=0.260;QD=13.92;ReadPosRankSum=1.238;SOR=0.727 GT:AD:DP:GQ:PL 0/1:22,18:40:99:564,0,651 -20 10088980 . T C 357.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.826;DP=60;ExcessHet=0.0000;FS=4.045;MLEAC=1;MLEAF=0.500;MQ=55.36;MQRankSum=-3.210;QD=6.62;ReadPosRankSum=0.950;SOR=1.295 GT:AD:DP:GQ:PL 0/1:37,17:54:99:365,0,1159 -20 10088985 . T C 456.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.437;DP=63;ExcessHet=0.0000;FS=2.347;MLEAC=1;MLEAF=0.500;MQ=55.03;MQRankSum=-3.151;QD=7.61;ReadPosRankSum=0.799;SOR=1.056 GT:AD:DP:GQ:PL 0/1:42,18:60:99:464,0,1357 +20 10088895 . C T 524.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.730;DP=43;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=57.40;MQRankSum=0.507;QD=13.12;ReadPosRankSum=1.109;SOR=0.567 GT:AD:DP:GQ:PL 0/1:23,17:40:99:532,0,676 20 10089441 . A G 1200.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-4.885;DP=79;ExcessHet=0.0000;FS=6.071;MLEAC=1;MLEAF=0.500;MQ=59.71;MQRankSum=-0.948;QD=15.80;ReadPosRankSum=-0.156;SOR=1.363 GT:AD:DP:GQ:PL 0/1:37,39:76:99:1208,0,1313 20 10089525 . C T 1569.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.859;DP=83;ExcessHet=0.0000;FS=4.260;MLEAC=1;MLEAF=0.500;MQ=59.50;MQRankSum=1.531;QD=19.38;ReadPosRankSum=0.862;SOR=0.617 GT:AD:DP:GQ:PL 0/1:38,43:81:99:1577,0,1088 20 10090764 . A G 861.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.659;DP=67;ExcessHet=0.0000;FS=4.975;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=13.68;ReadPosRankSum=1.207;SOR=0.310 GT:AD:DP:GQ:PL 0/1:34,29:63:99:869,0,1207 20 10090970 . T C 1278.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.484;DP=70;ExcessHet=0.0000;FS=0.927;MLEAC=1;MLEAF=0.500;MQ=59.47;MQRankSum=1.509;QD=18.53;ReadPosRankSum=-0.072;SOR=0.518 GT:AD:DP:GQ:PL 0/1:33,36:69:99:1286,0,1092 20 10092415 . A G 1656.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-6.731;DP=103;ExcessHet=0.0000;FS=0.741;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=16.40;ReadPosRankSum=0.082;SOR=0.665 GT:AD:DP:GQ:PL 0/1:52,49:101:99:1664,0,1901 -20 10092927 . G T 127.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.507;DP=83;ExcessHet=0.0000;FS=60.191;MLEAC=1;MLEAF=0.500;MQ=59.16;MQRankSum=-3.009;QD=1.77;ReadPosRankSum=-0.220;SOR=5.279 GT:AD:DP:GQ:PL 0/1:59,13:72:99:135,0,1864 20 10093923 . T A 1096.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.667;DP=73;ExcessHet=0.0000;FS=0.924;MLEAC=1;MLEAF=0.500;MQ=59.25;MQRankSum=0.358;QD=16.37;ReadPosRankSum=-1.583;SOR=0.772 GT:AD:DP:GQ:PL 0/1:35,32:67:99:1104,0,1257 20 10094251 . T A 1291.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.251;DP=67;ExcessHet=0.0000;FS=11.483;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=20.83;ReadPosRankSum=1.806;SOR=1.211 GT:AD:DP:GQ:PL 0/1:26,36:62:99:1299,0,781 +20 10094582 . A G 944.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.388;DP=73;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=1.270;QD=13.69;ReadPosRankSum=-0.018;SOR=0.772 GT:AD:DP:GQ:PL 0/1:39,30:69:99:952,0,1350 +20 10094774 . C T 1057.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.784;DP=81;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=59.43;MQRankSum=0.962;QD=14.10;ReadPosRankSum=0.197;SOR=0.690 GT:AD:DP:GQ:PL 0/1:40,35:75:99:1065,0,1282 20 10095741 . A G 1096.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.534;DP=72;ExcessHet=0.0000;FS=4.721;MLEAC=1;MLEAF=0.500;MQ=57.39;MQRankSum=-2.313;QD=15.67;ReadPosRankSum=-0.500;SOR=0.515 GT:AD:DP:GQ:PL 0/1:36,34:70:99:1104,0,1233 20 10096293 . C T 1376.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.664;DP=79;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.64;MQRankSum=1.397;QD=18.36;ReadPosRankSum=-1.135;SOR=0.638 GT:AD:DP:GQ:PL 0/1:37,38:75:99:1384,0,1258 20 10096596 . C T 1583.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.728;DP=91;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=58.82;MQRankSum=0.612;QD=18.20;ReadPosRankSum=-0.170;SOR=0.640 GT:AD:DP:GQ:PL 0/1:40,47:87:99:1591,0,1273 20 10096768 . A C 1703.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.764;DP=96;ExcessHet=0.0000;FS=3.983;MLEAC=1;MLEAF=0.500;MQ=59.28;MQRankSum=-1.609;QD=18.72;ReadPosRankSum=0.613;SOR=0.445 GT:AD:DP:GQ:PL 0/1:42,49:91:99:1711,0,1452 -20 10096958 . G A 566.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=1.277;DP=64;ExcessHet=0.0000;FS=7.479;MLEAC=1;MLEAF=0.500;MQ=60.00;MQRankSum=0.000;QD=8.99;ReadPosRankSum=-2.151;SOR=0.784 GT:AD:DP:GQ:PL 0/1:44,19:63:99:574,0,1571 +20 10096899 . G T 1101.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.758;DP=76;ExcessHet=0.0000;FS=12.891;MLEAC=1;MLEAF=0.500;MQ=59.20;MQRankSum=-1.552;QD=15.52;ReadPosRankSum=0.538;SOR=2.079 GT:AD:DP:GQ:PL 0/1:39,32:71:99:1109,0,1390 +20 10096933 . G C 1336.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.914;DP=89;ExcessHet=0.0000;FS=23.320;MLEAC=1;MLEAF=0.500;MQ=59.32;MQRankSum=-1.802;QD=15.73;ReadPosRankSum=0.383;SOR=1.534 GT:AD:DP:GQ:PL 0/1:44,41:85:99:1344,0,1514 +20 10096958 . G A 1628.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.697;DP=93;ExcessHet=0.0000;FS=19.237;MLEAC=1;MLEAF=0.500;MQ=59.35;MQRankSum=-1.682;QD=17.90;ReadPosRankSum=-1.593;SOR=1.375 GT:AD:DP:GQ:PL 0/1:44,47:91:99:1636,0,1487 20 10097075 . T G 1440.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-2.398;DP=95;ExcessHet=0.0000;FS=6.783;MLEAC=1;MLEAF=0.500;MQ=58.12;MQRankSum=-1.398;QD=15.83;ReadPosRankSum=0.242;SOR=0.694 GT:AD:DP:GQ:PL 0/1:44,47:91:99:1448,0,1485 20 10097437 . T C 457.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.666;DP=65;ExcessHet=0.0000;FS=3.846;MLEAC=1;MLEAF=0.500;MQ=56.58;MQRankSum=-4.652;QD=7.04;ReadPosRankSum=-4.566;SOR=0.325 GT:AD:DP:GQ:PL 0/1:45,20:65:99:465,0,1547 20 10097789 . T C 709.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.157;DP=60;ExcessHet=0.0000;FS=5.374;MLEAC=1;MLEAF=0.500;MQ=58.05;MQRankSum=-2.805;QD=12.45;ReadPosRankSum=0.220;SOR=0.756 GT:AD:DP:GQ:PL 0/1:34,23:57:99:717,0,1190 20 10097928 . G A 591.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.203;DP=37;ExcessHet=0.0000;FS=1.315;MLEAC=1;MLEAF=0.500;MQ=58.11;MQRankSum=-1.654;QD=16.43;ReadPosRankSum=-0.079;SOR=0.951 GT:AD:DP:GQ:PL 0/1:17,19:36:99:599,0,586 -20 10098110 . G C 493.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.074;DP=34;ExcessHet=0.0000;FS=7.278;MLEAC=1;MLEAF=0.500;MQ=58.63;MQRankSum=-1.574;QD=14.52;ReadPosRankSum=-0.833;SOR=0.053 GT:AD:DP:GQ:PL 0/1:19,15:34:99:501,0,637 +20 10098110 . G C 573.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=2.510;DP=36;ExcessHet=0.0000;FS=6.658;MLEAC=1;MLEAF=0.500;MQ=58.71;MQRankSum=-1.477;QD=15.93;ReadPosRankSum=-0.730;SOR=0.069 GT:AD:DP:GQ:PL 0/1:19,17:36:99:581,0,631 +20 10098135 . C A 436.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.155;DP=39;ExcessHet=0.0000;FS=4.337;MLEAC=1;MLEAF=0.500;MQ=59.65;MQRankSum=1.546;QD=11.49;ReadPosRankSum=-0.591;SOR=0.075 GT:AD:DP:GQ:PL 0/1:24,14:38:99:444,0,874 20 10098786 . C T 32.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.431;DP=9;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=54.65;MQRankSum=-2.200;QD=3.63;ReadPosRankSum=-1.383;SOR=0.132 GT:AD:DP:GQ:PL 0/1:7,2:9:40:40,0,217 +20 10099044 . A C 49.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.201;DP=22;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=56.15;MQRankSum=-3.419;QD=2.76;ReadPosRankSum=-1.481;SOR=0.193 GT:AD:DP:GQ:PL 0/1:15,3:18:57:57,0,499 +20 10099046 . T C 73.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.822;DP=18;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.26;MQRankSum=-3.419;QD=4.09;ReadPosRankSum=-1.364;SOR=0.193 GT:AD:DP:GQ:PL 0/1:15,3:18:81:81,0,561 +20 10099055 . T C 50.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.460;DP=19;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=55.52;MQRankSum=-3.419;QD=2.81;ReadPosRankSum=-0.830;SOR=0.330 GT:AD:DP:GQ:PL 0/1:15,3:18:58:58,0,557 +20 10099079 . C T 40.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=0.694;DP=23;ExcessHet=0.0000;FS=2.192;MLEAC=1;MLEAF=0.500;MQ=56.33;MQRankSum=-3.254;QD=1.77;ReadPosRankSum=-0.568;SOR=1.460 GT:AD:DP:GQ:PL 0/1:19,4:23:48:48,0,551 +20 10099140 . G T 583.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.176;DP=49;ExcessHet=0.0000;FS=6.794;MLEAC=1;MLEAF=0.500;MQ=60.07;MQRankSum=1.344;QD=12.42;ReadPosRankSum=-0.466;SOR=1.944 GT:AD:DP:GQ:PL 0/1:28,19:47:99:591,0,932 +20 10099190 . G T 1055.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-0.034;DP=65;ExcessHet=0.0000;FS=0.000;MLEAC=1;MLEAF=0.500;MQ=57.56;MQRankSum=-1.711;QD=16.24;ReadPosRankSum=-1.260;SOR=0.776 GT:AD:DP:GQ:PL 0/1:33,32:65:99:1063,0,1154 20 10099220 . A G 598.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=-1.664;DP=47;ExcessHet=0.0000;FS=1.137;MLEAC=1;MLEAF=0.500;MQ=57.74;MQRankSum=-2.596;QD=13.30;ReadPosRankSum=0.629;SOR=0.519 GT:AD:DP:GQ:PL 0/1:25,20:45:99:606,0,873 20 10099535 . G A 1356.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=5.034;DP=68;ExcessHet=0.0000;FS=2.172;MLEAC=1;MLEAF=0.500;MQ=59.04;MQRankSum=-1.418;QD=20.87;ReadPosRankSum=-0.777;SOR=0.408 GT:AD:DP:GQ:PL 0/1:26,39:65:99:1364,0,686 20 10099565 . C T 1367.64 . AC=1;AF=0.500;AN=2;BaseQRankSum=4.595;DP=70;ExcessHet=0.0000;FS=8.736;MLEAC=1;MLEAF=0.500;MQ=59.40;MQRankSum=-1.266;QD=19.82;ReadPosRankSum=1.225;SOR=0.191 GT:AD:DP:GQ:PL 0/1:31,38:69:99:1375,0,994 diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.gatk4.vcf.idx b/src/test/resources/org/broadinstitute/hellbender/tools/haplotypecaller/expected.pileupCallerDRAGEN.gatk4.vcf.idx index b82a7046a7304fd255d50d41c5d8aa9873dc7d3e..3d8e4b970205cc4e70cf7f49aefa2078f60f9d1a 100644 GIT binary patch delta 72 zcmX@jbDC$uJl@|W3}6t@c}u@#;_7ZGLk32mfRO~ HxG;?XrScCx delta 72 zcmX@jbDC$uJl>OK3}Dcp#C5%X;_7ZGQwBz$fRO=CVH0Urj`g`&fw!k=N{q_9~|Nm z@8TN9V6JCiU~Fh;Y+`O`RzjE6ZV=Q46AB!)o5epf(fkA4UZb1eY4xhV7i delta 141 zcmaDMwpVPz0$$JU3}8?Yb^l4-#I?>$dIpmj86`Xn^b8n$T^;@6-CP|*LW5l6!yJP= z9sQhL89*{HL1+I^zYqo^Lkk8*peaTM3=Fjl3^qVEhzkO@HrFzq=2Up*1K|c|L+GD% I5E^DX0RE63Qvd(}