diff --git a/src/main/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparator.java b/src/main/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparator.java index 494f9a42857..6c8da6b3765 100644 --- a/src/main/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparator.java +++ b/src/main/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparator.java @@ -5,8 +5,10 @@ import org.apache.commons.collections4.CollectionUtils; import org.broadinstitute.barclay.argparser.*; import org.broadinstitute.hellbender.engine.*; +import org.broadinstitute.hellbender.exceptions.GATKException; import org.broadinstitute.hellbender.exceptions.UserException; import org.broadinstitute.hellbender.tools.walkers.annotator.*; +import org.broadinstitute.hellbender.tools.walkers.annotator.allelespecific.AS_QualByDepth; import org.broadinstitute.hellbender.tools.walkers.annotator.allelespecific.AS_StandardAnnotation; import org.broadinstitute.hellbender.tools.walkers.genotyper.AlleleSubsettingUtils; import org.broadinstitute.hellbender.tools.walkers.genotyper.GenotypeAssignmentMethod; @@ -136,6 +138,12 @@ public class VCFComparator extends MultiVariantWalkerGroupedByOverlap { @Argument(fullName = "ignore-dbsnp-ids", optional = true) private boolean ignoreDbsnp = false; + @Argument(fullName = "ignore-gq0", optional = true) + private boolean ignoreGq0 = false; + + @Argument(fullName = "ignore-multi-allelics", optional = true, doc="Ignore sites where the AC length in the actual matches the actual number of alleles, but doesn't match the expected VC.") + private boolean ignoreSomeMultiAllelics = false; + @Advanced @Argument(fullName=ReblockGVCF.ANNOTATIONS_TO_KEEP_LONG_NAME, doc="Annotations that are not recognized by GATK that should be checked, otherwise they are removed if ignore-non-ref-data is set.", optional = true) private List annotationsToKeep = new ArrayList<>(); @@ -188,10 +196,18 @@ public void apply(final List variantContexts, final ReferenceCon final VariantContext vc = variantContexts.get(0); //TODO: if there's a variant that overlaps the requested interval the start may not be in the requested intervals if (!muteDiffs) { - throwOrWarn(new UserException("Unmatched variant in " + vc.getSource() + " at position " + vc.getContig() + ":" + vc.getStart())); + if (!ignoreGq0 && vc.getGenotypes().stream().anyMatch(g -> g.hasGQ() && g.getGQ() == 0)) { + throwOrWarn(new UserException("Unmatched variant in " + vc.getSource() + " at position " + vc.getContig() + ":" + vc.getStart())); + } else { + return; + } //low coverage sites will have QUAL for singleton hom-vars boosted because of GQ0 hom-refs } else if (hasGoodEvidence(vc)) { - throwOrWarn(new UserException("Unmatched variant in " + vc.getSource() + " at position " + vc.getContig() + ":" + vc.getStart())); + if (!ignoreGq0 && vc.getGenotypes().stream().anyMatch(g -> g.hasGQ() && g.getGQ() == 0)) { + throwOrWarn(new UserException("Unmatched variant in " + vc.getSource() + " at position " + vc.getContig() + ":" + vc.getStart())); + } else { + return; + } } } @@ -211,7 +227,7 @@ public void apply(final List variantContexts, final ReferenceCon // if there's only one match, then it's the expected matching itself, so actual is missing the same vc start // if it's a high quality site, throw an error/warning otherwise it's low quality so skip it if (isHighQuality(vc) && hasGoodEvidence(vc) - && !vc.getGenotype(0).getAlleles().contains(Allele.SPAN_DEL)){ + && vc.getGenotypes().stream().noneMatch(g -> g.getAlleles().contains(Allele.SPAN_DEL))){ throwOrWarn(new UserException("Apparent unmatched high quality variant in " + vc.getSource() + " at " + vc.getContig() + ":" + vc.getStart())); } else { return; @@ -235,10 +251,13 @@ public void apply(final List variantContexts, final ReferenceCon final VariantContext expectedTrimmed = trimAlleles(vc, overlappingDels); final VariantContext actualTrimmed = trimAlleles(match, overlappingDels); + final boolean vcShouldBeSkippedDueToNoCalls = variantContexts.stream().anyMatch(v -> v.getGenotypes().stream().anyMatch(g -> g.isNoCall() || (g.hasGQ() && g.getGQ() == 0))); //do single-sample GVCF checks, including deletion trimming and dropping if (isSingleSample) { try { - validateSingleSampleDeletions(vc, match, expectedTrimmed, actualTrimmed, overlappingDels); + if (!(ignoreGq0 && vcShouldBeSkippedDueToNoCalls)) { + validateSingleSampleDeletions(vc, match, expectedTrimmed, actualTrimmed, overlappingDels, vcShouldBeSkippedDueToNoCalls); + } } catch (UserException e) { throwOrWarn(e); } @@ -250,7 +269,7 @@ public void apply(final List variantContexts, final ReferenceCon //more rigorous checks on annotations and genotypes try { - checkVariantContextsAreMatching(actualTrimmed, expectedTrimmed, overlappingDels); + checkVariantContextsAreMatching(actualTrimmed, expectedTrimmed, overlappingDels, vcShouldBeSkippedDueToNoCalls); } catch (UserException e) { final boolean hasLowQualityGenotype = expectedTrimmed.getGenotypes().stream().anyMatch(g -> g.getGQ() < 20); if (!muteDiffs || !(alleleNumberIsDifferent || inbreedingCoeffIsDifferent || hasLowQualityGenotype)) { @@ -270,7 +289,7 @@ public void apply(final List variantContexts, final ReferenceCon private void validateSingleSampleDeletions(final VariantContext vc, final VariantContext match, final VariantContext expectedTrimmed, final VariantContext actualTrimmed, - final List overlappingDels) { + final List overlappingDels, final boolean nearbyGq0) { final Genotype expectedGenotype = expectedTrimmed.getGenotype(0); final List expectedGenotypeAlleles = expectedGenotype.getAlleles(); final Genotype actualGenotype = actualTrimmed.getGenotype(0); @@ -299,12 +318,12 @@ private void validateSingleSampleDeletions(final VariantContext vc, final Varian //could be dropped hom ref if (overlappingDels.stream().anyMatch(v -> v.getGenotype(0).isHomRef())) { try { - checkAttributes(vc.getAttributes(), match.getAttributes(), vc.getAlleles(), match.getAlleles(), vc.getPhredScaledQual()); + checkAttributes(vc.getAttributes(), match.getAttributes(), vc.getAlleles(), match.getAlleles(), vc.getPhredScaledQual(), getDpForQual(vc), getAsAdSum(vc)); } catch (UserException e) { throw wrapWithPosition(vc.getContig(), vc.getStart(), new UserException("INFO attributes do not match at " + vc.getContig() + ":" + vc.getStart())); } try { - checkGenotypes(expectedGenotype, actualGenotype); + checkGenotypes(expectedGenotype, actualGenotype, nearbyGq0); } catch (final UserException e) { throw wrapWithPosition(vc.getContig(), vc.getStart(), e); } @@ -330,6 +349,15 @@ private void validateSingleSampleDeletions(final VariantContext vc, final Varian } } + private static int getAsAdSum(VariantContext vc) { + List AS_ADs = AS_QualByDepth.getAlleleDepths(vc.getGenotypes()); + return AS_ADs == null ? 0 : AS_ADs.stream().mapToInt(Integer::intValue).sum(); + } + + private static int getDpForQual(VariantContext vc) { + return QualByDepth.getDepth(vc.getGenotypes(), null); + } + private boolean hasGoodEvidence(final VariantContext vc) { return (vc.getPhredScaledQual() > goodQualThreshold) && (vc.getAttributeAsInt(VCFConstants.DEPTH_KEY,0)/(double)vc.getAttributeAsInt(VCFConstants.ALLELE_NUMBER_KEY,0)) > 5 @@ -337,7 +365,7 @@ private boolean hasGoodEvidence(final VariantContext vc) { } private void checkVariantContextsAreMatching(final VariantContext actual, final VariantContext expected, - final List overlappingDels) { + final List overlappingDels, boolean nearbyGq0) { if (!actual.getContig().equals(expected.getContig())) { throw wrapWithPosition(expected.getContig(), expected.getStart(), new UserException("contigs differ for VCs")); } @@ -349,16 +377,21 @@ private void checkVariantContextsAreMatching(final VariantContext actual, final //don't check end in case we're being lenient about alleles //check alleles - if (actualHasNewAlleles(expected, actual)) { - try { - checkAlleles(actual, expected, overlappingDels); - } catch (final UserException e) { - throw wrapWithPosition(expected.getContig(), expected.getStart(), e); + if (!(ignoreGq0 && nearbyGq0)) { + if (actualHasNewAlleles(expected, actual)) { + try { + checkAlleles(actual, expected, overlappingDels); + } catch (final UserException e) { + throw wrapWithPosition(expected.getContig(), expected.getStart(), e); + } } } if (!ignoreDbsnp && !actual.getID().equals(expected.getID())) { //more alleles might mean more dbSNP matches - throw wrapWithPosition(expected.getContig(), expected.getStart(), new UserException("dbsnp IDs differ for VCs")); + //alleles are checked elsewhere, so if that check was ignored the dbsnp ID check should be ignored too + if (actual.getAlleles().size() == expected.getAlleles().size()) { + throw wrapWithPosition(expected.getContig(), expected.getStart(), new UserException("dbsnp IDs differ for VCs")); + } } if (ignoreAnnotations) { @@ -366,16 +399,21 @@ private void checkVariantContextsAreMatching(final VariantContext actual, final } if (!ignoreQuals) { - final double diff = Math.abs(actual.getPhredScaledQual() - expected.getPhredScaledQual()); - if (diff > qualTolerance) { - throw wrapWithPosition(expected.getContig(), expected.getStart(), new UserException("qual scores differ by " + diff + ", which is more than " + qualTolerance)); + if (!(ignoreGq0 && nearbyGq0)) { + final double diff = Math.abs(actual.getPhredScaledQual() - expected.getPhredScaledQual()); + if (diff > qualTolerance) { + throw wrapWithPosition(expected.getContig(), expected.getStart(), new UserException("qual scores differ by " + diff + ", which is more than " + qualTolerance)); + } } } - try { - checkAttributes(actual.getAttributes(), expected.getAttributes(), actual.getAlternateAlleles(), expected.getAlternateAlleles(), expected.getPhredScaledQual()); - } catch (final UserException e) { - throw wrapWithPosition(expected.getContig() ,expected.getStart() , e); + if (!(ignoreGq0 && nearbyGq0)) { + try { + checkAttributes(actual.getAttributes(), expected.getAttributes(), actual.getAlternateAlleles(), expected.getAlternateAlleles(), expected.getPhredScaledQual(), + getDpForQual(expected), getAsAdSum(expected)); + } catch (final UserException e) { + throw wrapWithPosition(expected.getContig(), expected.getStart(), e); + } } if (!alleleNumberIsDifferent) { @@ -391,7 +429,7 @@ private void checkVariantContextsAreMatching(final VariantContext actual, final for (int i = 0; i < actual.getGenotypes().size(); i++) { try { - checkGenotypes(actual.getGenotype(0), expected.getGenotype(0)); + checkGenotypes(actual.getGenotype(0), expected.getGenotype(0), nearbyGq0); } catch (final UserException e) { throw wrapWithPosition(expected.getContig(), expected.getStart(), e); } @@ -453,18 +491,33 @@ private UserException wrapWithPosition(final String contig, final int start, fin @SuppressWarnings("unchecked") private void checkAttributes(final Map actual, final Map expected, final List actualAlts, final List expectedAlts, - final double expectedQual) { + final double expectedQual, final int expectedDP, final int expectedAS_AD) { final Set expectedKeys = new LinkedHashSet<>(expected.keySet()); //do a precheck on AN because then we can't expect the rest of the annotations to match alleleNumberIsDifferent = actual.containsKey(VCFConstants.ALLELE_NUMBER_KEY) && !isAttributeValueEqual(VCFConstants.ALLELE_NUMBER_KEY, actual.get(VCFConstants.ALLELE_NUMBER_KEY), expected.get(VCFConstants.ALLELE_NUMBER_KEY)); + if (ignoreSomeMultiAllelics && actual.containsKey(VCFConstants.ALLELE_COUNT_KEY)) { + final Object actualAcValue = actual.get(VCFConstants.ALLELE_COUNT_KEY); + final Object expectedAcValue = expected.get(VCFConstants.ALLELE_COUNT_KEY); + final List actualAC = actualAcValue instanceof List ? (List) actualAcValue : Collections.singletonList(actualAcValue); + final List expectedAC = expectedAcValue instanceof List ? (List) expected.get(VCFConstants.ALLELE_COUNT_KEY) : Collections.singletonList(expectedAcValue); + if (actualAC.size() != expectedAC.size() && actualAC.size() == actualAlts.size()) { + //skip this site because it's a multiallelic site and the allele count size is now fixed (the correct size in actual rather than expected) + return; + } + } + if (actual.containsKey(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY)) { try { - inbreedingCoeffIsDifferent = !isAttributeEqualDoubleSmart(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY, - Double.parseDouble(actual.get(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY).toString()), - Double.parseDouble(expected.get(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY).toString()), 0.001); + if (expected.containsKey(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY)) { + inbreedingCoeffIsDifferent = !isAttributeEqualDoubleSmart(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY, + Double.parseDouble(actual.get(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY).toString()), + Double.parseDouble(expected.get(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY).toString()), 0.001); + } else { + throw makeVariantExceptionFromDifference(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY, actual.get(GATKVCFConstants.INBREEDING_COEFFICIENT_KEY).toString(), "missing"); + } } catch (UserException e) { inbreedingCoeffIsDifferent = true; throw e; @@ -497,7 +550,7 @@ private void checkAttributes(final Map actual, final Map expectedList, actualList; - if (key.contains("AS_") || key.equals(GATKVCFConstants.AS_SB_TABLE_KEY)) { + if (key.contains("AS_") && key.contains("RAW") || key.equals(GATKVCFConstants.AS_SB_TABLE_KEY)) { expectedList = AnnotationUtils.decodeAnyASListWithRawDelim(expectedValue.toString()); actualList = AnnotationUtils.decodeAnyASListWithRawDelim(actualValue.toString()); } else { @@ -515,7 +568,14 @@ private void checkAttributes(final Map actual, final Map= actualList.size() || i >= expectedList.size()) { //TODO: the toStrings here don't do a great job @@ -530,7 +590,7 @@ private void checkAttributes(final Map actual, final Map actual, final Map actual, final Map actual, final Map dpChange) { @@ -872,19 +947,20 @@ private boolean isACEqualEnough(final String key, final List a return true; } - private boolean qualByDepthWillHaveJitter(final double expectedQual, final int expectedDepth) { + private boolean qualByDepthWillHaveJitter(final double expectedQual, final int expectedDepth, final int expectedAS_AD) { final double qdEstimate = expectedQual / (double) expectedDepth; - if (QualByDepth.fixTooHighQD(qdEstimate) != qdEstimate || qdEstimate > 34.9) { //I don't know why we get different values at 34.9 -- there must be rounding somewhere? + if (QualByDepth.fixTooHighQD(qdEstimate) != qdEstimate || qdEstimate > 34.9 || //I don't know why we get different values at 34.9 -- there must be rounding somewhere? + expectedAS_AD == 0) { //if alelle specific AD is 0 (which happens in dragen) then we'll have jitter since Infinity is larger than the cutoff return true; } return false; } - private boolean qualByDepthDifferenceIsAcceptable(final double actual, final double expected, final double expectedQual, final int expectedDP) { + private boolean qualByDepthDifferenceIsAcceptable(final double actual, final double expected, final double expectedQual, final int expectedDP, final int expectedAS_AD) { final double diff = Math.abs(expected - actual); final double relativeDiff = diff / (expected); return expected > 25.0 || relativeDiff < 0.01 || diff < 0.5 ////25 is in the "jitter" zone - || qualByDepthWillHaveJitter(expectedQual, expectedDP); + || qualByDepthWillHaveJitter(expectedQual, expectedDP, expectedAS_AD); } public Object onTraversalSuccess() { diff --git a/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparatorIntegrationTest.java b/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparatorIntegrationTest.java index e60bf275a8d..5fa5d1a7391 100644 --- a/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparatorIntegrationTest.java +++ b/src/test/java/org/broadinstitute/hellbender/tools/walkers/variantutils/VCFComparatorIntegrationTest.java @@ -20,21 +20,21 @@ public class VCFComparatorIntegrationTest extends CommandLineProgramTest { @DataProvider(name = "getTestVcfs") public Object[][] getTestVcfs() { - return new Object[][] { - { " -L chr1:186475", "expected_warning_as_vqslod.txt" }, - { " -L chr1:186475 --ignore-attribute AS_VQSLOD", "empty_file.txt" }, - { " -L chr1:187471 --ignore-attribute AS_VQSLOD", "expected_warning_filter.txt" }, - { " -L chr1:186475-945669 " + DEFAULT_WARP_SETTINGS, "empty_file.txt" }, - { " -L chr1:945670 " + DEFAULT_WARP_SETTINGS, "qual_diff_warning.txt"}, // different QUAL values - { " -L chr1:945670 --qual-change-allowed 0.1 --ignore-attribute AS_VQSLOD", "empty_file.txt"}, - { " -L chr1:186475 --mute-acceptable-diffs", "empty_file.txt" } // low quality site is muted even though the AS_VQSLOD is different + return new Object[][]{ + {" -L chr1:186475", "expected_warning_as_vqslod.txt"}, + {" -L chr1:186475 --ignore-attribute AS_VQSLOD", "empty_file.txt"}, + {" -L chr1:187471 --ignore-attribute AS_VQSLOD", "expected_warning_filter.txt"}, + {" -L chr1:186475-945669 " + DEFAULT_WARP_SETTINGS, "empty_file.txt"}, + {" -L chr1:945670 " + DEFAULT_WARP_SETTINGS, "qual_diff_warning.txt"}, // different QUAL values + {" -L chr1:945670 --qual-change-allowed 0.1 --ignore-attribute AS_VQSLOD", "empty_file.txt"}, + {" -L chr1:186475 --mute-acceptable-diffs", "empty_file.txt"} // low quality site is muted even though the AS_VQSLOD is different }; } @Test(dataProvider = "getTestVcfs") public void testAnnotationDifferences(String args, String expectedWarnings) throws IOException { final IntegrationTestSpec testSpec = new IntegrationTestSpec( - " -R " + hg38Reference + + " -R " + hg38Reference + " -V:actual " + TEST_DATA_DIRECTORY + "actual.vcf" + " -V:expected " + TEST_DATA_DIRECTORY + "expected.vcf" + " --output-warnings %s" + @@ -66,13 +66,16 @@ public void testExpectedFailure() { @DataProvider(name = "getTestGvcfs") public Object[][] getTestGvcfs() { - return new Object[][] { - { " -L chr1:864084-864610", "empty_file.txt" }, //matching ref blocks - { " -L chr1:54682-347969", "ref_block_warning.txt"}, // non-matching ref block - { " -L chr1:792417", "tree_score_warning.txt"}, // variant site - { " -L chr1:792417 --ignore-non-ref-data --" + + return new Object[][]{ + {" -L chr1:864084-864610", "empty_file.txt"}, //matching ref blocks + {" -L chr1:54682-347969", "ref_block_warning.txt"}, // non-matching ref block + {" -L chr1:792417", "tree_score_warning.txt"}, // variant site + {" -L chr1:792417 --ignore-non-ref-data --" + ReblockGVCF.ANNOTATIONS_TO_KEEP_LONG_NAME + " TREE_SCORE", "tree_score_warning.txt"}, // when non-ref data is dropped non-GATK annotations can be dropped - { " -L chr1:792417 --ignore-attribute TREE_SCORE", "empty_file.txt"} + {" -L chr1:792417 --ignore-attribute TREE_SCORE --ignore-non-ref-data", "empty_file.txt"}, // check that RAW_MQandDP matches with and without --ignore-non-ref-data + {" -L chr1:792417 --ignore-attribute TREE_SCORE", "empty_file.txt"}, + {" -L chr1:950542", "depth_warning.txt"}, + {" -L chr1:950542 --ignore-gq0", "empty_file.txt"} }; } diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf index 6c6c67d48fb..48de930e2d9 100644 --- a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf +++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf @@ -3507,3 +3507,4 @@ chr1 922687 . C . . END=922690 GT:DP:GQ 0/0:7:20 chr1 922691 . C . . END=922701 GT:DP:GQ 0/0:7:0 chr1 922702 . C . . END=922711 GT:DP:GQ 0/0:7:20 chr1 922712 . T . . END=950541 GT:DP:GQ 0/0:4:0 +chr1 950542 . G . . END=950543 GT:DP:GQ 0/0:4:0 diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf.idx b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf.idx index ea94cd86b68..702552e2339 100644 Binary files a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf.idx and b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/actual.NA12878.rb.g.vcf.idx differ diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf index 790563325a7..24510b3aca4 100644 --- a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf +++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf @@ -3506,3 +3506,4 @@ chr1 922687 . C . . END=922690 GT:DP:GQ 0/0:7:20 chr1 922691 . C . . END=922701 GT:DP:GQ 0/0:7:0 chr1 922702 . C . . END=922711 GT:DP:GQ 0/0:7:20 chr1 922712 . T . . END=950541 GT:DP:GQ 0/0:4:0 +chr1 950542 . G . . END=950543 GT:DP:GQ 0/0:5:0 \ No newline at end of file diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf.idx b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf.idx index cf9d16e7f1d..21a6a369338 100644 Binary files a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf.idx and b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected.NA12878.rb.g.vcf.idx differ diff --git a/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected/depth_warning.txt b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected/depth_warning.txt new file mode 100644 index 00000000000..0f04aab9483 --- /dev/null +++ b/src/test/resources/org/broadinstitute/hellbender/tools/walkers/VCFComparator/expected/depth_warning.txt @@ -0,0 +1 @@ +At position chr1:950542 Genotypes have different DP value: actual has 4 expected has 5 \ No newline at end of file