public final Object decodeTypedValue(final byte typeDescriptor) throws IOException { final int size = decodeNumberOfElements(typeDescriptor); return decodeTypedValue(typeDescriptor, size); }
public final Object decodeTypedValue() throws IOException { final byte typeDescriptor = readTypeDescriptor(); return decodeTypedValue(typeDescriptor); }
/** * Reads the next record from input stream and prepare this decoder to decode values from it * * @param stream * @return */ public void readNextBlock(final int blockSizeInBytes, final InputStream stream) { if ( blockSizeInBytes < 0 ) throw new TribbleException("Invalid block size " + blockSizeInBytes); setRecordBytes(readRecordBytes(blockSizeInBytes, stream)); }
hd.decoder.setRecordBytes((byte[])data); final String field = hd.getFieldDict().get( (Integer)hd.decoder.decodeTypedValue()); final byte type = hd.decoder.readTypeDescriptor(); final int numElems = hd.decoder.decodeNumberOfElements(type);
final BCF2Decoder decoder = new BCF2Decoder(((BCF2Codec.LazyData)data).bytes); final int offset = (Integer) decoder.decodeTypedValue(); final String field = codec.getDictionaryString(offset); final byte typeDescriptor = decoder.readTypeDescriptor(); final int numElements = decoder.decodeNumberOfElements(typeDescriptor); final BCF2GenotypeFieldDecoders.Decoder fieldDecoder = codec.getGenotypeFieldDecoder(field); try {
@Override public void decode(final List<Allele> siteAlleles, final String field, final BCF2Decoder decoder, final byte typeDescriptor, final int numElements, final GenotypeBuilder[] gbs) throws IOException { for ( final GenotypeBuilder gb : gbs ) { Object value = decoder.decodeTypedValue(typeDescriptor, numElements); assert value == null || value instanceof String; gb.filter((String)value); } } }
@Test(dataProvider = "IntArrays") public void testIntArrays(final List<Integer> ints) throws IOException { final BCF2Encoder encoder = new BCF2Encoder(); encoder.encodeTyped(ints, BCF2Type.INT16); final BCF2Decoder decoder = new BCF2Decoder(encoder.getRecordBytes()); final byte typeDescriptor = decoder.readTypeDescriptor(); // read the int[] with the low-level version final int size = decoder.decodeNumberOfElements(typeDescriptor); final int[] decoded = decoder.decodeIntArray(typeDescriptor, size); if ( isMissing(ints) ) { // we expect that the result is null in this case Assert.assertNull(decoded, "Encoded all missing values -- expected null"); } else { // we expect at least some values to come back Assert.assertTrue(decoded.length > 0, "Must have at least 1 element for non-null encoded data"); // check corresponding values for ( int i = 0; i < ints.size(); i++ ) { final Integer expected = ints.get(i); if ( expected == null ) { Assert.assertTrue(decoded.length <= i, "we expect decoded to be truncated for missing values"); } else { Assert.assertTrue(decoded.length > i, "we expected at least " + i + " values in decoded array"); Assert.assertEquals(decoded[i], (int)expected); } } } }
public void testReadAndSkipWithMultipleBlocks(final List<BCF2TypedValue> block1, final List<BCF2TypedValue> block2) throws IOException { final byte[] record1 = encodeRecord(block1); final byte[] record2 = encodeRecord(block2); // each record is individually good decodeRecord(block1, record1); decodeRecord(block2, record2); BCF2Decoder decoder = new BCF2Decoder(); // test setting decoder.setRecordBytes(record1); decodeRecord(block1, decoder); decoder.setRecordBytes(record2); decodeRecord(block2, decoder); // test combining the streams final byte[] combined = combineRecords(record1, record2); final List<BCF2TypedValue> combinedObjects = new ArrayList<BCF2TypedValue>(block1); combinedObjects.addAll(block2); // the combined bytes is the same as the combined objects InputStream stream = new ByteArrayInputStream(combined); decoder.readNextBlock(record1.length, stream); decodeRecord(block1, decoder); decoder.readNextBlock(record2.length, stream); decodeRecord(block2, decoder); // skipping the first block allows us to read the second block directly stream = new ByteArrayInputStream(combined); decoder.skipNextBlock(record1.length, stream); decoder.readNextBlock(record2.length, stream); decodeRecord(block2, decoder); }
public void testBCF2BasicTypesWithEncodeMe(final List<BCF2TypedValue> toEncode, final EncodeMe func) throws IOException { for ( final BCF2TypedValue tv : toEncode ) { BCF2Encoder encoder = new BCF2Encoder(); func.encode(encoder, tv); BCF2Decoder decoder = new BCF2Decoder(encoder.getRecordBytes()); final Object decoded = decoder.decodeTypedValue(); Assert.assertNotNull(decoded); Assert.assertFalse(decoded instanceof List); myAssertEquals(tv, decoded); } }
public final int decodeNumberOfElements(final byte typeDescriptor) throws IOException { if ( BCF2Utils.sizeIsOverflow(typeDescriptor) ) // -1 ensures we explode immediately with a bad size if the result is missing return decodeInt(readTypeDescriptor(), -1); else // the size is inline, so just decode it return BCF2Utils.decodeSize(typeDescriptor); }
@Override public void decode(final List<Allele> siteAlleles, final String field, final BCF2Decoder decoder, final byte typeDescriptor, final int numElements, final GenotypeBuilder[] gbs) throws IOException { for ( final GenotypeBuilder gb : gbs ) { gb.PL(decoder.decodeIntArray(typeDescriptor, numElements)); } } }
@Override public void decode(final List<Allele> siteAlleles, final String field, final BCF2Decoder decoder, final byte typeDescriptor, final int numElements, final GenotypeBuilder[] gbs) throws IOException { for ( final GenotypeBuilder gb : gbs ) { // the -1 is for missing gb.GQ(decoder.decodeInt(typeDescriptor, -1)); } } }
@Override public VariantContext decode( final PositionalBufferedStream inputStream ) { try { recordNo++; final VariantContextBuilder builder = new VariantContextBuilder(); final int sitesBlockSize = decoder.readBlockSize(inputStream); final int genotypeBlockSize = decoder.readBlockSize(inputStream); decoder.readNextBlock(sitesBlockSize, inputStream); decodeSiteLoc(builder); final SitesInfoForDecoding info = decodeSitesExtendedInfo(builder); decoder.readNextBlock(genotypeBlockSize, inputStream); createLazyGenotypesDecoder(info, builder); return builder.fullyDecoded(true).make(); } catch ( IOException e ) { throw new TribbleException("Failed to read BCF file", e); } }
/** * Create a new decoder ready to read BCF2 data from the byte[] recordBytes, for testing purposes * * @param recordBytes */ protected BCF2Decoder(final byte[] recordBytes) { setRecordBytes(recordBytes); }
public final Object decodeSingleValue(final BCF2Type type) throws IOException { // TODO -- decodeTypedValue should integrate this routine final int value = decodeInt(type); if ( value == type.getMissingBytes() ) return null; else { switch (type) { case INT8: case INT16: case INT32: return value; case FLOAT: return rawFloatToFloat(value); case CHAR: return value & 0xFF; // TODO -- I cannot imagine why we'd get here, as string needs to be special cased default: throw new TribbleException("BCF2 codec doesn't know how to decode type " + type ); } } }
public final Object decodeTypedValue(final byte typeDescriptor, final int size) throws IOException { if ( size == 0 ) { // missing value => null in java return null; } else { final BCF2Type type = BCF2Utils.decodeType(typeDescriptor); if ( type == BCF2Type.CHAR ) { // special case string decoding for efficiency return decodeLiteralString(size); } else if ( size == 1 ) { return decodeSingleValue(type); } else { final ArrayList<Object> ints = new ArrayList<Object>(size); for ( int i = 0; i < size; i++ ) { final Object val = decodeSingleValue(type); if ( val == null ) continue; // auto-pruning. We remove trailing nulls ints.add(val); } return ints.isEmpty() ? null : ints; // return null when all of the values are null } } }
/** * Decode the sites level data from this classes decoder * * @param builder * @return */ private final SitesInfoForDecoding decodeSitesExtendedInfo(final VariantContextBuilder builder) throws IOException { final Object qual = decoder.decodeSingleValue(BCF2Type.FLOAT); if ( qual != null ) { builder.log10PError(((Double)qual) / -10.0); } final int nAlleleInfo = decoder.decodeInt(BCF2Type.INT32); final int nFormatSamples = decoder.decodeInt(BCF2Type.INT32); final int nAlleles = nAlleleInfo >> 16; final int nInfo = nAlleleInfo & 0x0000FFFF; final int nFormatFields = nFormatSamples >> 24; final int nSamples = nFormatSamples & 0x00FFFFF; if ( header.getNGenotypeSamples() != nSamples ) error("Reading BCF2 files with different numbers of samples per record " + "is not currently supported. Saw " + header.getNGenotypeSamples() + " samples in header but have a record with " + nSamples + " samples"); decodeID(builder); final List<Allele> alleles = decodeAlleles(builder, pos, nAlleles); decodeFilter(builder); decodeInfo(builder, nInfo); final SitesInfoForDecoding info = new SitesInfoForDecoding(nFormatFields, nSamples, alleles); if ( ! info.isValid() ) error("Sites info is malformed: " + info); return info; }
private final void decodeRecord(final List<BCF2TypedValue> toEncode, final BCF2Decoder decoder) throws IOException { for ( final BCF2TypedValue tv : toEncode ) { Assert.assertFalse(decoder.blockIsFullyDecoded()); final Object decoded = decoder.decodeTypedValue(); myAssertEquals(tv, decoded); } Assert.assertTrue(decoder.blockIsFullyDecoded()); }
private final void decodeRecord(final List<BCF2TypedValue> toEncode, final byte[] record) throws IOException { decodeRecord(toEncode, new BCF2Decoder(record)); }
hd.decoder.setRecordBytes((byte[])data); final String field = hd.getFieldDict().get( (Integer)hd.decoder.decodeTypedValue()); final byte type = hd.decoder.readTypeDescriptor(); final int numElems = hd.decoder.decodeNumberOfElements(type);