From ea1b699778873b3dd838ec185c918f393f2dffc7 Mon Sep 17 00:00:00 2001 From: Mark DePristo Date: Wed, 13 Jun 2012 10:17:10 -0400 Subject: [PATCH] Cleanup the interface for BCF2FieldEncoder -- Now uses a much clearer approach. Update all user classes to new interface --- .../sting/utils/codecs/bcf2/BCF2Encoder.java | 2 + .../writer/BCF2FieldEncoder.java | 328 +++++++++++------- .../writer/BCF2FieldWriter.java | 133 ++++--- .../writer/BCF2FieldWriterManager.java | 19 +- .../writer/IntGenotypeFieldAccessors.java | 5 +- 5 files changed, 288 insertions(+), 199 deletions(-) diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/bcf2/BCF2Encoder.java b/public/java/src/org/broadinstitute/sting/utils/codecs/bcf2/BCF2Encoder.java index 52953a927..255e3c0ce 100644 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/bcf2/BCF2Encoder.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/bcf2/BCF2Encoder.java @@ -24,6 +24,7 @@ package org.broadinstitute.sting.utils.codecs.bcf2; +import com.google.java.contract.Requires; import org.broadinstitute.sting.utils.exceptions.ReviewedStingException; import java.io.ByteArrayOutputStream; @@ -181,6 +182,7 @@ public final class BCF2Encoder { // // -------------------------------------------------------------------------------- + @Requires({"s != null", "sizeToWrite >= 0"}) public void encodeString(final String s, final int sizeToWrite) throws IOException { final byte[] bytes = s.getBytes(); for ( int i = 0; i < sizeToWrite; i++ ) diff --git a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldEncoder.java b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldEncoder.java index 74aff2d20..6a9136f67 100644 --- a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldEncoder.java +++ b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldEncoder.java @@ -57,7 +57,13 @@ public abstract class BCF2FieldEncoder { final int dictionaryOffset; final BCF2Type dictionaryOffsetType; - public BCF2FieldEncoder(final VCFCompoundHeaderLine headerLine, final BCF2Encoder encoder, final Map dict, final BCF2Type fixedType) { + // ---------------------------------------------------------------------- + // + // Constructor + // + // ---------------------------------------------------------------------- + + public BCF2FieldEncoder(final VCFCompoundHeaderLine headerLine, final Map dict, final BCF2Type fixedType) { this.headerLine = headerLine; this.fixedType = fixedType; @@ -67,147 +73,218 @@ public abstract class BCF2FieldEncoder { dictionaryOffsetType = BCF2Utils.determineIntegerType(offset); } - public VCFHeaderLineCount getCountType() { - return headerLine.getCountType(); - } - - public VCFCompoundHeaderLine getHeaderLine() { - return headerLine; - } - - public boolean hasFixedCount() { return getCountType() == VCFHeaderLineCount.INTEGER; } - public boolean hasUnboundedCount() { return getCountType() == VCFHeaderLineCount.UNBOUNDED; } - public boolean hasContextDeterminedCount() { return ! hasFixedCount() && ! hasUnboundedCount(); } - + // ---------------------------------------------------------------------- // - // TODO -- this class should own two clean methods - // - // Tell us whether the type and size are static, determined by from the VC itself, - // or from the actual encoded values. If the last case, provide a function that tell us - // the encoding type and size of the underlying data, given a single value. + // Basic accessors // + // ---------------------------------------------------------------------- - // TODO -- cleanup logic of counts - // todo -- differentiate between the VCF header declared size and the encoded size - // TODO -- for example, getUnboundedCount should be getCountFromSizeOfValue() - // - // GenotypeEncoders need to inspect the size properties of the underlying encoder - // and determine how (and whether) they need to iterate once through the data to - // determine max size (for padding) - // + public final String getField() { return headerLine.getID(); } - @Requires("hasFixedCount()") - public int getFixedCount() { - return headerLine.getCount(); + /** + * Write the field key (dictionary offset and type) into the BCF2Encoder stream + * + * @param encoder where we write our dictionary offset + * @throws IOException + */ + public final void writeFieldKey(final BCF2Encoder encoder) throws IOException { + encoder.encodeTyped(dictionaryOffset, dictionaryOffsetType); } - public int getUnboundedCount(final Object value) { - return value instanceof List ? ((List) value).size() : 1; - } - - public int getContextDeterminedCount(final VariantContext vc) { - return headerLine.getCount(vc.getNAlleles() - 1); - } - - public int getBCFFieldCount(final VariantContext vc, final Object value) { - if ( hasFixedCount() ) - return getFixedCount(); - else if ( hasUnboundedCount() ) - return getUnboundedCount(value); - else - return getContextDeterminedCount(vc); - } - - public String getField() { return headerLine.getID(); } - - public int getDictionaryOffset() { return dictionaryOffset; } - public BCF2Type getDictionaryOffsetType() { return dictionaryOffsetType; } - - public boolean isFixedTyped() { return ! isDynamicallyTyped(); } - public boolean isDynamicallyTyped() { return fixedType == null; } - public BCF2Type getType(final Object value) { return isDynamicallyTyped() ? getDynamicType(value) : getFixedType(); } - public BCF2Type getFixedType() { - if ( fixedType != null ) - return fixedType; - else - throw new ReviewedStingException("Not a fixed type encoder: " + getField()); - } - public BCF2Type getDynamicType(final Object value) { throw new ReviewedStingException("Function getDynamicType() not implemented"); } - @Override public String toString() { return "BCF2FieldEncoder for " + getField() + " with count " + getCountType() + " encoded with " + getClass().getSimpleName(); } - public void encodeValue(final BCF2Encoder encoder, final Object value, final BCF2Type type) throws IOException { + // ---------------------------------------------------------------------- + // + // methods to determine the number of encoded elements + // + // ---------------------------------------------------------------------- + + protected final VCFHeaderLineCount getCountType() { + return headerLine.getCountType(); + } + + @Ensures("result != (hasValueDeterminedNumElements() || hasContextDeterminedNumElements())") + public boolean hasConstantNumElements() { + return getCountType() == VCFHeaderLineCount.INTEGER; + } + + @Ensures("result != (hasConstantNumElements() || hasContextDeterminedNumElements())") + public boolean hasValueDeterminedNumElements() { + return getCountType() == VCFHeaderLineCount.UNBOUNDED; + } + + @Ensures("result != (hasValueDeterminedNumElements() || hasConstantNumElements())") + public boolean hasContextDeterminedNumElements() { + return ! hasConstantNumElements() && ! hasValueDeterminedNumElements(); + } + + @Requires("hasConstantNumElements()") + @Ensures("result >= 0") + public int numElements() { + return headerLine.getCount(); + } + + @Requires("hasValueDeterminedNumElements()") + @Ensures("result >= 0") + public int numElements(final Object value) { + return numElementsFromValue(value); + //return value instanceof List ? ((List) value).size() : 1; + } + + @Requires("hasContextDeterminedNumElements()") + @Ensures("result >= 0") + public int numElements(final VariantContext vc) { + return headerLine.getCount(vc.getNAlleles() - 1); + } + + @Ensures("result >= 0") + public final int numElements(final VariantContext vc, final Object value) { + if ( hasConstantNumElements() ) return numElements(); + else if ( hasContextDeterminedNumElements() ) return numElements(vc); + else return numElements(value); + } + + /** + * Given a value, return the number of elements we will encode for it. + * + * Assumes the value is encoded as a List + * + * @param value + * @return + */ + @Requires("hasValueDeterminedNumElements()") + @Ensures("result >= 0") + protected int numElementsFromValue(final Object value) { + if ( value == null ) return 0; + else if ( value instanceof List ) return ((List) value).size(); + else return 1; + } + + // ---------------------------------------------------------------------- + // + // methods to determine the BCF2 type of the encoded values + // + // ---------------------------------------------------------------------- + + @Ensures("result || isDynamicallyTyped()") + public final boolean isStaticallyTyped() { return ! isDynamicallyTyped(); } + + @Ensures("result || isStaticallyTyped()") + public final boolean isDynamicallyTyped() { return fixedType == null; } + + public final BCF2Type getType(final Object value) { + return isDynamicallyTyped() ? getDynamicType(value) : getStaticType(); + } + + @Requires("isStaticallyTyped()") + @Ensures("result != null") + public final BCF2Type getStaticType() { + return fixedType; + } + + @Requires("isDynamicallyTyped()") + @Ensures("result != null") + public BCF2Type getDynamicType(final Object value) { + throw new ReviewedStingException("BUG: cannot get dynamic type for statically typed BCF2 field"); + } + + // ---------------------------------------------------------------------- + // + // methods to encode values, including the key abstract method + // + // ---------------------------------------------------------------------- + + @Requires({"encoder != null", "isDynamicallyTyped() || type == getStaticType()"}) + public void encodeOneValue(final BCF2Encoder encoder, final Object value, final BCF2Type type) throws IOException { encodeValue(encoder, value, type, 0); } + @Requires({"encoder != null", "isDynamicallyTyped() || type == getStaticType()", "minValues >= 0"}) public abstract void encodeValue(final BCF2Encoder encoder, final Object value, final BCF2Type type, final int minValues) throws IOException; - - /** - * Helper function that takes an object and returns a list representation - * of it: - * - * o == null => [] - * o is a list => o - * else => [o] - * - * @param o - * @return - */ - private final static List toList(final Class c, final Object o) { - if ( o == null ) return Collections.emptyList(); - else if ( o instanceof List ) return (List)o; - else return Collections.singletonList((T)o); - } + // ---------------------------------------------------------------------- + // + // Subclass to encode Strings + // + // ---------------------------------------------------------------------- public static class StringOrCharacter extends BCF2FieldEncoder { - public StringOrCharacter(final VCFCompoundHeaderLine headerLine, final BCF2Encoder encoder, final Map dict ) { - super(headerLine, encoder, dict, BCF2Type.CHAR); + public StringOrCharacter(final VCFCompoundHeaderLine headerLine, final Map dict ) { + super(headerLine, dict, BCF2Type.CHAR); } @Override public void encodeValue(final BCF2Encoder encoder, final Object value, final BCF2Type type, final int minValues) throws IOException { - if ( value != null ) { - final String s = encodeString(value); - encoder.encodeString(s, Math.max(s.length(), minValues)); - } + final String s = javaStringToBCF2String(value); + encoder.encodeString(s, Math.max(s.length(), minValues)); } - @Override - public int getBCFFieldCount(final VariantContext vc, final Object value) { - return value == null ? 0 : encodeString(value).length(); + // + // Regardless of what the header says, BCF2 strings and characters are always encoded + // as arrays of CHAR type, which has a variable number of elements depending on the + // exact string being encoded + // + @Override public boolean hasConstantNumElements() { return false; } + @Override public boolean hasContextDeterminedNumElements() { return false; } + @Override public boolean hasValueDeterminedNumElements() { return true; } + @Override protected int numElementsFromValue(final Object value) { + return value == null ? 0 : javaStringToBCF2String(value).length(); } - private String encodeString(final Object value) { - return value instanceof List ? BCF2Utils.collapseStringList((List)value) : (String)value; + /** + * Recode the incoming object to a String, compacting it into a + * BCF2 string if the value is a list. + * + * @param value a String or List to encode, or null + * @return a non-null string to encode + */ + @Ensures("result != null") + private String javaStringToBCF2String(final Object value) { + return value == null + ? "" + : (value instanceof List + ? BCF2Utils.collapseStringList((List)value) + : (String)value); } } + // ---------------------------------------------------------------------- + // + // Subclass to encode FLAG + // + // ---------------------------------------------------------------------- + public static class Flag extends BCF2FieldEncoder { - public Flag(final VCFCompoundHeaderLine headerLine, final BCF2Encoder encoder, final Map dict ) { - super(headerLine, encoder, dict, BCF2Type.INT8); + public Flag(final VCFCompoundHeaderLine headerLine, final Map dict ) { + super(headerLine, dict, BCF2Type.INT8); if ( ! headerLine.isFixedCount() || headerLine.getCount() != 0 ) throw new ReviewedStingException("Flag encoder only suppports atomic flags!"); } @Override - public int getFixedCount() { + public int numElements() { return 1; // the header says 0 but we will write 1 value } @Override @Requires("minValues <= 1") public void encodeValue(final BCF2Encoder encoder, final Object value, final BCF2Type type, final int minValues) throws IOException { - encoder.encodePrimitive(1, getFixedType()); + encoder.encodePrimitive(1, getStaticType()); } } + // ---------------------------------------------------------------------- + // + // Subclass to encode FLOAT + // + // ---------------------------------------------------------------------- + public static class Float extends BCF2FieldEncoder { - public Float(final VCFCompoundHeaderLine headerLine, final BCF2Encoder encoder, final Map dict ) { - super(headerLine, encoder, dict, BCF2Type.FLOAT); + public Float(final VCFCompoundHeaderLine headerLine, final Map dict ) { + super(headerLine, dict, BCF2Type.FLOAT); } @Override @@ -222,13 +299,19 @@ public abstract class BCF2FieldEncoder { } } + // ---------------------------------------------------------------------- + // + // Subclass to encode int[] + // + // ---------------------------------------------------------------------- + public static class IntArray extends BCF2FieldEncoder { - public IntArray(final VCFCompoundHeaderLine headerLine, final BCF2Encoder encoder, final Map dict ) { - super(headerLine, encoder, dict, null); + public IntArray(final VCFCompoundHeaderLine headerLine, final Map dict ) { + super(headerLine, dict, null); } @Override - public int getUnboundedCount(final Object value) { + protected int numElementsFromValue(final Object value) { return value == null ? 0 : ((int[])value).length; } @@ -250,9 +333,15 @@ public abstract class BCF2FieldEncoder { } } - public static class IntList extends BCF2FieldEncoder { - public IntList(final VCFCompoundHeaderLine headerLine, final BCF2Encoder encoder, final Map dict ) { - super(headerLine, encoder, dict, null); + // ---------------------------------------------------------------------- + // + // Subclass to encode List + // + // ---------------------------------------------------------------------- + + public static class GenericInts extends BCF2FieldEncoder { + public GenericInts(final VCFCompoundHeaderLine headerLine, final Map dict ) { + super(headerLine, dict, null); } @Override @@ -271,20 +360,27 @@ public abstract class BCF2FieldEncoder { } } - public static class AtomicInt extends BCF2FieldEncoder { - public AtomicInt(final VCFCompoundHeaderLine headerLine, final BCF2Encoder encoder, final Map dict ) { - super(headerLine, encoder, dict, null); - } - @Override - public BCF2Type getDynamicType(final Object value) { - return value == null ? BCF2Type.INT8 : BCF2Utils.determineIntegerType((Integer)value); - } + // ---------------------------------------------------------------------- + // + // Helper methods + // + // ---------------------------------------------------------------------- - @Override - @Requires("minValues <= 1") // 0 is ok as this means no values need to be encoded - public void encodeValue(final BCF2Encoder encoder, final Object value, final BCF2Type type, final int minValues) throws IOException { - encoder.encodeRawInt(value == null ? type.getMissingBytes() : (Integer)value, type); - } + /** + * Helper function that takes an object and returns a list representation + * of it: + * + * o == null => [] + * o is a list => o + * else => [o] + * + * @param o + * @return + */ + private final static List toList(final Class c, final Object o) { + if ( o == null ) return Collections.emptyList(); + else if ( o instanceof List ) return (List)o; + else return Collections.singletonList((T)o); } } diff --git a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriter.java b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriter.java index d796e09c0..4a2077138 100644 --- a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriter.java +++ b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriter.java @@ -24,6 +24,7 @@ package org.broadinstitute.sting.utils.variantcontext.writer; +import com.google.java.contract.Requires; import org.broadinstitute.sting.utils.codecs.bcf2.BCF2Encoder; import org.broadinstitute.sting.utils.codecs.bcf2.BCF2Type; import org.broadinstitute.sting.utils.codecs.bcf2.BCF2Utils; @@ -40,31 +41,10 @@ import java.util.List; import java.util.Map; /** - * [Short one sentence description of this walker] - *

- *

- * [Functionality of this walker] - *

- *

- *

Input

- *

- * [Input description] - *

- *

- *

Output

- *

- * [Output description] - *

- *

- *

Examples

- *
- *    java
- *      -jar GenomeAnalysisTK.jar
- *      -T $WalkerName
- *  
* - * @author Your Name - * @since Date created + * + * @author Mark DePristo + * @since 6/12 */ public abstract class BCF2FieldWriter { private final VCFHeader header; @@ -82,7 +62,7 @@ public abstract class BCF2FieldWriter { protected String getField() { return getFieldEncoder().getField(); } public void start(final BCF2Encoder encoder, final VariantContext vc) throws IOException { - encoder.encodeTyped(fieldEncoder.getDictionaryOffset(), fieldEncoder.getDictionaryOffsetType()); + fieldEncoder.writeFieldKey(encoder); } public void done(final BCF2Encoder encoder, final VariantContext vc) throws IOException { } // TODO -- overload done so that we null out values and test for correctness @@ -119,9 +99,9 @@ public abstract class BCF2FieldWriter { // the value is missing, just write in null encoder.encodeType(0, type); } else { - final int valueCount = getFieldEncoder().getBCFFieldCount(vc, rawValue); + final int valueCount = getFieldEncoder().numElements(vc, rawValue); encoder.encodeType(valueCount, type); - getFieldEncoder().encodeValue(encoder, rawValue, type); + getFieldEncoder().encodeOneValue(encoder, rawValue, type); } } } @@ -139,8 +119,8 @@ public abstract class BCF2FieldWriter { protected GenotypesWriter(final VCFHeader header, final BCF2FieldEncoder fieldEncoder) { super(header, fieldEncoder); - if ( fieldEncoder.hasFixedCount() ) { - nValuesPerGenotype = getFieldEncoder().getFixedCount(); + if ( fieldEncoder.hasConstantNumElements() ) { + nValuesPerGenotype = getFieldEncoder().numElements(); } } @@ -150,10 +130,10 @@ public abstract class BCF2FieldWriter { super.start(encoder, vc); // only update if we need to - if ( ! getFieldEncoder().hasFixedCount() ) { - if ( getFieldEncoder().hasContextDeterminedCount() ) + if ( ! getFieldEncoder().hasConstantNumElements() ) { + if ( getFieldEncoder().hasContextDeterminedNumElements() ) // we are cheap -- just depends on genotype of allele counts - nValuesPerGenotype = getFieldEncoder().getContextDeterminedCount(vc); + nValuesPerGenotype = getFieldEncoder().numElements(vc); else // we have to go fishing through the values themselves (expensive) nValuesPerGenotype = computeMaxSizeOfGenotypeFieldFromValues(vc); @@ -167,27 +147,25 @@ public abstract class BCF2FieldWriter { getFieldEncoder().encodeValue(encoder, fieldValue, encodingType, nValuesPerGenotype); } - public Object getGenotypeValue(final Genotype g) { - return g.getAttribute(getField()); + protected int numElements(final VariantContext vc, final Genotype g) { + return getFieldEncoder().numElements(vc, g.getAttribute(getField())); } private final int computeMaxSizeOfGenotypeFieldFromValues(final VariantContext vc) { int size = -1; for ( final Genotype g : vc.getGenotypes() ) { - final Object o = getGenotypeValue(g); - size = Math.max(size, getFieldEncoder().getBCFFieldCount(vc, o)); + size = Math.max(size, numElements(vc, g)); } return size; } } - public static class FixedTypeGenotypesWriter extends GenotypesWriter { - public FixedTypeGenotypesWriter(final VCFHeader header, final BCF2FieldEncoder fieldEncoder) { + public static class StaticallyTypeGenotypesWriter extends GenotypesWriter { + public StaticallyTypeGenotypesWriter(final VCFHeader header, final BCF2FieldEncoder fieldEncoder) { super(header, fieldEncoder); - - encodingType = getFieldEncoder().getFixedType(); + encodingType = getFieldEncoder().getStaticType(); } } @@ -211,12 +189,6 @@ public abstract class BCF2FieldWriter { } } - // TODO TODO TODO TODO TODO - // TODO - // TODO THIS ROUTINE NEEDS TO BE OPTIMIZED. IT ACCOUNTS FOR A SIGNIFICANT AMOUNT OF THE - // TODO RUNTIME FOR WRITING OUT BCF FILES WITH MANY GENOTYPES - // TODO - // TODO TODO TODO TODO TODO public static class IGFGenotypesWriter extends GenotypesWriter { final IntGenotypeFieldAccessors.Accessor ige; @@ -248,19 +220,14 @@ public abstract class BCF2FieldWriter { } @Override - public Object getGenotypeValue(final Genotype g) { - return ige.getValues(g); + protected int numElements(final VariantContext vc, final Genotype g) { + return ige.getSize(g); } } - // TODO TODO TODO TODO TODO - // TODO - // TODO we should really have a fast path for encoding diploid genotypes where - // TODO we don't pay the overhead of creating the allele maps - // TODO - // TODO TODO TODO TODO TODO public static class GTWriter extends GenotypesWriter { - Map alleleMap = null; + final Map alleleMapForTriPlus = new HashMap(5); + Allele ref, alt1; public GTWriter(final VCFHeader header, final BCF2FieldEncoder fieldEncoder) { super(header, fieldEncoder); @@ -274,20 +241,20 @@ public abstract class BCF2FieldWriter { + vc.getNAlleles() + " at " + vc.getChr() + ":" + vc.getStart()); encodingType = BCF2Type.INT8; - alleleMap = buildAlleleMap(vc); + buildAlleleMap(vc); nValuesPerGenotype = vc.getMaxPloidy(); - super.start(encoder, vc); //To change body of overridden methods use File | Settings | File Templates. + + super.start(encoder, vc); } @Override public void addGenotype(final BCF2Encoder encoder, final VariantContext vc, final Genotype g) throws IOException { - final List alleles = g.getAlleles(); - final int samplePloidy = alleles.size(); + final int samplePloidy = g.getPloidy(); for ( int i = 0; i < nValuesPerGenotype; i++ ) { if ( i < samplePloidy ) { // we encode the actual allele - final Allele a = alleles.get(i); - final int offset = alleleMap.get(a); + final Allele a = g.getAllele(i); + final int offset = getAlleleOffset(a); final int encoded = ((offset+1) << 1) | (g.isPhased() ? 0x01 : 0x00); encoder.encodePrimitive(encoded, encodingType); } else { @@ -297,16 +264,44 @@ public abstract class BCF2FieldWriter { } } - private final static Map buildAlleleMap(final VariantContext vc) { - final Map alleleMap = new HashMap(vc.getAlleles().size()+1); - alleleMap.put(Allele.NO_CALL, -1); // convenience for lookup - - final List alleles = vc.getAlleles(); - for ( int i = 0; i < alleles.size(); i++ ) { - alleleMap.put(alleles.get(i), i); + /** + * Fast path code to determine the offset. + * + * Inline tests for == against ref (most common, first test) + * == alt1 (second most common, second test) + * == NO_CALL (third) + * and finally in the map from allele => offset for all alt 2+ alleles + * + * @param a the allele whose offset we wish to determine + * @return the offset (from 0) of the allele in the list of variant context alleles (-1 means NO_CALL) + */ + @Requires("a != null") + private final int getAlleleOffset(final Allele a) { + if ( a == ref ) return 0; + else if ( a == alt1 ) return 1; + else if ( a == Allele.NO_CALL ) return -1; + else { + final Integer o = alleleMapForTriPlus.get(a); + if ( o == null ) throw new ReviewedStingException("BUG: Couldn't find allele offset for allele " + a); + return o; } + } - return alleleMap; + private final void buildAlleleMap(final VariantContext vc) { + // these are fast path options to determine the offsets for + final int nAlleles = vc.getNAlleles(); + ref = vc.getReference(); + alt1 = nAlleles > 1 ? vc.getAlternateAllele(0) : null; + + if ( nAlleles > 2 ) { + // for multi-allelics we need to clear the map, and add additional looks + alleleMapForTriPlus.clear(); + alleleMapForTriPlus.put(Allele.NO_CALL, -1); // convenience for lookup + final List alleles = vc.getAlleles(); + for ( int i = 2; i < alleles.size(); i++ ) { + alleleMapForTriPlus.put(alleles.get(i), i); + } + } } } } diff --git a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriterManager.java b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriterManager.java index 4b527fdca..7ce4f64e4 100644 --- a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriterManager.java +++ b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/BCF2FieldWriterManager.java @@ -84,7 +84,7 @@ public class BCF2FieldWriterManager { } private final void log(final String field, final BCF2FieldWriter writer) { - logger.info("Using writer " + writer); + logger.info(writer); } // ----------------------------------------------------------------- @@ -109,23 +109,20 @@ public class BCF2FieldWriterManager { if ( createGenotypesEncoders && intGenotypeFieldAccessors.getAccessor(line.getID()) != null ) { if ( line.getType() != VCFHeaderLineType.Integer ) logger.warn("Warning: field " + line.getID() + " expected to encode an integer but saw " + line.getType() + " for record " + line); - return new BCF2FieldEncoder.IntArray(line, encoder, dict); + return new BCF2FieldEncoder.IntArray(line, dict); } else if ( createGenotypesEncoders && line.getID().equals(VCFConstants.GENOTYPE_KEY) ) { - return new BCF2FieldEncoder.IntList(line, encoder, dict); + return new BCF2FieldEncoder.GenericInts(line, dict); } else { switch ( line.getType() ) { case Character: case String: - return new BCF2FieldEncoder.StringOrCharacter(line, encoder, dict); + return new BCF2FieldEncoder.StringOrCharacter(line, dict); case Flag: - return new BCF2FieldEncoder.Flag(line, encoder, dict); + return new BCF2FieldEncoder.Flag(line, dict); case Float: - return new BCF2FieldEncoder.Float(line, encoder, dict); + return new BCF2FieldEncoder.Float(line, dict); case Integer: - if ( line.getCountType() == VCFHeaderLineCount.INTEGER && line.getCount() == 1 ) - return new BCF2FieldEncoder.AtomicInt(line, encoder, dict); - else - return new BCF2FieldEncoder.IntList(line, encoder, dict); + return new BCF2FieldEncoder.GenericInts(line, dict); default: throw new ReviewedStingException("Unexpected type for field " + line.getID()); } @@ -153,7 +150,7 @@ public class BCF2FieldWriterManager { } else if ( line.getType() == VCFHeaderLineType.Integer ) { return new BCF2FieldWriter.IntegerTypeGenotypesWriter(header, fieldEncoder); } else { - return new BCF2FieldWriter.FixedTypeGenotypesWriter(header, fieldEncoder); + return new BCF2FieldWriter.StaticallyTypeGenotypesWriter(header, fieldEncoder); } } diff --git a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/IntGenotypeFieldAccessors.java b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/IntGenotypeFieldAccessors.java index a37378ffa..e02526e1e 100644 --- a/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/IntGenotypeFieldAccessors.java +++ b/public/java/src/org/broadinstitute/sting/utils/variantcontext/writer/IntGenotypeFieldAccessors.java @@ -39,8 +39,7 @@ import java.util.HashMap; */ class IntGenotypeFieldAccessors { // initialized once per writer to allow parallel writers to work - private final HashMap intGenotypeFieldEncoders = - new HashMap(); + private final HashMap intGenotypeFieldEncoders = new HashMap(); public IntGenotypeFieldAccessors() { intGenotypeFieldEncoders.put(VCFConstants.DEPTH_KEY, new IntGenotypeFieldAccessors.DPAccessor()); @@ -61,7 +60,7 @@ class IntGenotypeFieldAccessors { public static abstract class Accessor { public abstract int[] getValues(final Genotype g); - public int getSize(final Genotype g) { + public final int getSize(final Genotype g) { final int[] v = getValues(g); return v == null ? 0 : v.length; }