Multiple bugfixes
-- VariantFiltration now properly sets passFilters in VC -- BCF2 writer now properly decodes lazy BCF genotype data that it uses. Improper use generated a horrible subtle bug but the good news is that the extra checks I put in (unnecessarily a few days ago) caught the bug! Signed-off-by: Mark DePristo <depristo@broadinstitute.org>
This commit is contained in:
parent
3066894215
commit
19a257a5c1
|
|
@ -333,7 +333,11 @@ public class VariantFiltration extends RodWalker<Integer, Integer> {
|
||||||
filters.add(exp.name);
|
filters.add(exp.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
builder.filters(filters);
|
|
||||||
|
if ( filters.isEmpty() )
|
||||||
|
builder.passFilters();
|
||||||
|
else
|
||||||
|
builder.filters(filters);
|
||||||
|
|
||||||
writer.add(builder.make());
|
writer.add(builder.make());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -245,9 +245,11 @@ class BCF2Writer extends IndexingVariantContextWriter {
|
||||||
|
|
||||||
private BCF2Codec.LazyData getLazyData(final VariantContext vc) {
|
private BCF2Codec.LazyData getLazyData(final VariantContext vc) {
|
||||||
if ( vc.getGenotypes().isLazyWithData() ) {
|
if ( vc.getGenotypes().isLazyWithData() ) {
|
||||||
LazyGenotypesContext lgc = (LazyGenotypesContext)vc.getGenotypes();
|
LazyGenotypesContext lgc = (LazyGenotypesContext)vc.getGenotypes();
|
||||||
if ( lgc.getUnparsedGenotypeData() instanceof BCF2Codec.LazyData )
|
if ( WRITE_UNDECODED_GENOTYPE_BLOCK && lgc.getUnparsedGenotypeData() instanceof BCF2Codec.LazyData )
|
||||||
return (BCF2Codec.LazyData)lgc.getUnparsedGenotypeData();
|
return (BCF2Codec.LazyData)lgc.getUnparsedGenotypeData();
|
||||||
|
else
|
||||||
|
lgc.decode(); // WARNING -- required to avoid keeping around bad lazy data for too long
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -286,6 +288,8 @@ class BCF2Writer extends IndexingVariantContextWriter {
|
||||||
private void buildFilter( VariantContext vc ) throws IOException {
|
private void buildFilter( VariantContext vc ) throws IOException {
|
||||||
if ( vc.isFiltered() ) {
|
if ( vc.isFiltered() ) {
|
||||||
encodeStringsByRef(vc.getFilters());
|
encodeStringsByRef(vc.getFilters());
|
||||||
|
} else if ( vc.filtersWereApplied() ) {
|
||||||
|
encodeStringsByRef(Collections.singleton(VCFConstants.PASSES_FILTERS_v4));
|
||||||
} else {
|
} else {
|
||||||
encoder.encodeTypedMissing(BCF2Type.INT8);
|
encoder.encodeTypedMissing(BCF2Type.INT8);
|
||||||
}
|
}
|
||||||
|
|
@ -303,27 +307,27 @@ class BCF2Writer extends IndexingVariantContextWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] buildSamplesData(final VariantContext vc) throws IOException {
|
private byte[] buildSamplesData(final VariantContext vc) throws IOException {
|
||||||
final BCF2Codec.LazyData lazyData = getLazyData(vc);
|
final BCF2Codec.LazyData lazyData = getLazyData(vc); // has critical side effects
|
||||||
if ( WRITE_UNDECODED_GENOTYPE_BLOCK && lazyData != null ) {
|
if ( lazyData != null ) {
|
||||||
// we never decoded any data from this BCF file, so just pass it back
|
// we never decoded any data from this BCF file, so just pass it back
|
||||||
return lazyData.bytes;
|
return lazyData.bytes;
|
||||||
} else {
|
|
||||||
// we have to do work to convert the VC into a BCF2 byte stream
|
|
||||||
final List<String> genotypeFields = VCFWriter.calcVCFGenotypeKeys(vc, header);
|
|
||||||
for ( final String field : genotypeFields ) {
|
|
||||||
final BCF2FieldWriter.GenotypesWriter writer = fieldManager.getGenotypeFieldWriter(field);
|
|
||||||
if ( writer == null ) errorUnexpectedFieldToWrite(vc, field, "FORMAT");
|
|
||||||
|
|
||||||
writer.start(encoder, vc);
|
|
||||||
for ( final String name : sampleNames ) {
|
|
||||||
Genotype g = vc.getGenotype(name);
|
|
||||||
if ( g == null ) VCFWriter.missingSampleError(vc, header);
|
|
||||||
writer.addGenotype(encoder, vc, g);
|
|
||||||
}
|
|
||||||
writer.done(encoder, vc);
|
|
||||||
}
|
|
||||||
return encoder.getRecordBytes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// we have to do work to convert the VC into a BCF2 byte stream
|
||||||
|
final List<String> genotypeFields = VCFWriter.calcVCFGenotypeKeys(vc, header);
|
||||||
|
for ( final String field : genotypeFields ) {
|
||||||
|
final BCF2FieldWriter.GenotypesWriter writer = fieldManager.getGenotypeFieldWriter(field);
|
||||||
|
if ( writer == null ) errorUnexpectedFieldToWrite(vc, field, "FORMAT");
|
||||||
|
|
||||||
|
writer.start(encoder, vc);
|
||||||
|
for ( final String name : sampleNames ) {
|
||||||
|
Genotype g = vc.getGenotype(name);
|
||||||
|
if ( g == null ) VCFWriter.missingSampleError(vc, header);
|
||||||
|
writer.addGenotype(encoder, vc, g);
|
||||||
|
}
|
||||||
|
writer.done(encoder, vc);
|
||||||
|
}
|
||||||
|
return encoder.getRecordBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -740,6 +740,8 @@ public class VariantContextTestProvider {
|
||||||
Assert.assertEquals(actual.getAlleles(), expected.getAlleles(), "alleles");
|
Assert.assertEquals(actual.getAlleles(), expected.getAlleles(), "alleles");
|
||||||
|
|
||||||
assertAttributesEquals(actual.getAttributes(), expected.getAttributes());
|
assertAttributesEquals(actual.getAttributes(), expected.getAttributes());
|
||||||
|
Assert.assertEquals(actual.filtersWereApplied(), expected.filtersWereApplied(), "filtersWereApplied");
|
||||||
|
Assert.assertEquals(actual.isFiltered(), expected.isFiltered(), "isFiltered");
|
||||||
BaseTest.assertEqualsSet(actual.getFilters(), expected.getFilters(), "filters");
|
BaseTest.assertEqualsSet(actual.getFilters(), expected.getFilters(), "filters");
|
||||||
BaseTest.assertEqualsDoubleSmart(actual.getPhredScaledQual(), expected.getPhredScaledQual());
|
BaseTest.assertEqualsDoubleSmart(actual.getPhredScaledQual(), expected.getPhredScaledQual());
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue