From 53a7d5cbae245296e2c112b8a1a441255823b27c Mon Sep 17 00:00:00 2001 From: Eric Banks Date: Thu, 20 Feb 2014 00:53:13 -0500 Subject: [PATCH] Fixing a bug in the GVCF writer. The writer was never resetting the pointer to the end of the last non-ref VariantContext that it saw. This was fine except when it jumped to a new contig - and a lower position on that contig - where it thought that it was still part of that previous non-ref VariantContext so wouldn't emit a reference block. Therefore, ref blocks were missing from the beginnings of all chromosomes (except chr1). Added unit test to cover this case. --- .../sting/utils/gvcf/GVCFWriter.java | 15 +++++++-- .../sting/utils/gvcf/GVCFWriterUnitTest.java | 31 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/protected/gatk-protected/src/main/java/org/broadinstitute/sting/utils/gvcf/GVCFWriter.java b/protected/gatk-protected/src/main/java/org/broadinstitute/sting/utils/gvcf/GVCFWriter.java index aa269779b..71d61c920 100644 --- a/protected/gatk-protected/src/main/java/org/broadinstitute/sting/utils/gvcf/GVCFWriter.java +++ b/protected/gatk-protected/src/main/java/org/broadinstitute/sting/utils/gvcf/GVCFWriter.java @@ -84,6 +84,7 @@ public class GVCFWriter implements VariantContextWriter { /** fields updated on the fly during GVCFWriter operation */ int nextAvailableStart = -1; + String contigOfNextAvailableStart = null; private String sampleName = null; private HomRefBlock currentBlock = null; @@ -187,10 +188,17 @@ public class GVCFWriter implements VariantContextWriter { * @return a VariantContext to be emitted, or null if non is appropriate */ protected VariantContext addHomRefSite(final VariantContext vc, final Genotype g) { - if ( nextAvailableStart != -1 && vc.getStart() <= nextAvailableStart ) { + if ( nextAvailableStart != -1 ) { // don't create blocks while the hom-ref site falls before nextAvailableStart (for deletions) - return null; - } else if ( currentBlock == null ) { + if ( vc.getStart() <= nextAvailableStart && vc.getChr().equals(contigOfNextAvailableStart) ) { + return null; + } + // otherwise, reset to non-relevant + nextAvailableStart = -1; + contigOfNextAvailableStart = null; + } + + if ( currentBlock == null ) { currentBlock = createNewBlock(vc, g); return null; } else if ( currentBlock.withinBounds(g.getGQ()) ) { @@ -302,6 +310,7 @@ public class GVCFWriter implements VariantContextWriter { // g is variant, so flush the bands and emit vc emitCurrentBlock(); nextAvailableStart = vc.getEnd(); + contigOfNextAvailableStart = vc.getChr(); underlyingWriter.add(vc); } } diff --git a/protected/gatk-protected/src/test/java/org/broadinstitute/sting/utils/gvcf/GVCFWriterUnitTest.java b/protected/gatk-protected/src/test/java/org/broadinstitute/sting/utils/gvcf/GVCFWriterUnitTest.java index 77a9714fe..cda022ab8 100644 --- a/protected/gatk-protected/src/test/java/org/broadinstitute/sting/utils/gvcf/GVCFWriterUnitTest.java +++ b/protected/gatk-protected/src/test/java/org/broadinstitute/sting/utils/gvcf/GVCFWriterUnitTest.java @@ -202,6 +202,37 @@ public class GVCFWriterUnitTest extends BaseTest { assertGoodVC(mockWriter.emitted.get(1), "21", 3, 3, false); } + @Test + public void testCrossingContigBoundaryToLowerPositionsRef() { + final GVCFWriter writer = new GVCFWriter(mockWriter, standardPartition); + + writer.add(makeHomRef("20", 30, 30)); + writer.add(makeHomRef("20", 31, 30)); + Assert.assertEquals(mockWriter.emitted.size(), 0); + writer.add(makeHomRef("21", 10, 30)); + Assert.assertEquals(mockWriter.emitted.size(), 1); + assertGoodVC(mockWriter.emitted.get(0), "20", 30, 31, false); + writer.add(makeNonRef("21", 11, 30)); + Assert.assertEquals(mockWriter.emitted.size(), 3); + assertGoodVC(mockWriter.emitted.get(1), "21", 10, 10, false); + assertGoodVC(mockWriter.emitted.get(2), "21", 11, 11, true); + } + + @Test + public void testCrossingContigBoundaryFromNonRefToLowerPositionsRef() { + final GVCFWriter writer = new GVCFWriter(mockWriter, standardPartition); + + writer.add(makeNonRef("20", 20, 30)); + Assert.assertEquals(mockWriter.emitted.size(), 1); + writer.add(makeHomRef("21", 10, 30)); + Assert.assertEquals(mockWriter.emitted.size(), 1); + assertGoodVC(mockWriter.emitted.get(0), "20", 20, 20, true); + writer.add(makeNonRef("21", 11, 30)); + Assert.assertEquals(mockWriter.emitted.size(), 3); + assertGoodVC(mockWriter.emitted.get(1), "21", 10, 10, false); + assertGoodVC(mockWriter.emitted.get(2), "21", 11, 11, true); + } + @Test public void testCrossingContigBoundaryNonRef() { final GVCFWriter writer = new GVCFWriter(mockWriter, standardPartition);