Repository navigation
htsjdk 6.0.0 Release Notes
Major release. It includes every change in 5.0.2. Before upgrading, read Upgrading from 5.x; to explain differences from files 5.x wrote, see Output that differs from 5.x.
Headlines
java.nio.file.Paththroughout the public API. Every reader, writer, index and reference works with any NIO file system provider (S3, GCS, HDFS, jimfs), andStringandURIarguments are resolved by their scheme.- Current VCF and BCF. VCF 3.2 to 4.5 are read and 4.0 to 4.5 written, with VCF 4.4 and 4.5's additions. BCF 2.1 and 2.2 are read, raw or BGZF, and BCF is written as bcftools writes it, BGZF BCF 2.2 with a CSI index.
- CSI indexes, and CRAM's own CRAI. BAM, bgzipped VCF and other tabix files, and BCF can be indexed with CSI, for references longer than 512 Mbp. CRAM is indexed with a
.craiand queried from it directly. - Bgzipped SAM is an indexed format, written, indexed and queried like BAM.
- Faster than 5.0.2. Converting BAM to CRAM takes 29% less time, reading VCF 9–11% less, and writing bgzipped VCF 12% less. The CRAM 3.1 profiles choose codecs as htslib does.
Upgrading from 5.x
These changes can break code that compiles or runs against 5.x.
Paths and files
-
java.io.FileAPIs are replaced byjava.nio.file.Path(224 methods and constructors). Pass aPath, or aStringorURI, whichIOUtil.getPathresolves by scheme; bridge aFilewithfile.toPath()or the null-safeIOUtil.toPath(file).SamReader r = SamReaderFactory.makeDefault().open(Path.of("/data/x.bam")); SAMFileWriter w = new SAMFileWriterFactory().makeBAMWriter(header, true, Path.of("/data/out.bam")); SamReader s3 = SamReaderFactory.makeDefault().open(URI.create("s3://bucket/x.bam")); // with an S3 provider on the class path
-
A few
FileAPIs remain: temporary files (IOUtil.newTempFile,getDefaultTmpDir,createTempDir), the bridgesIOUtil.toPathandfilesToPaths, and sixteen deprecated overloads, each with aPathtwin, inCRAMFileReader,MetricsFile,BlockCompressedInputStreamandCRAIIndex. -
Defaults.REFERENCE_FASTAis aPath. -
ReferenceSequenceFile.close()no longer declaresIOException(#1179): delete catch blocks that only it needed, andthrows IOExceptionfrom implementations ofclose(). -
Removed:
NotPrimarySkippingIterator, deprecated since 2.13.0 (useSecondaryAlignmentSkippingIterator), andTestUtil.BASE_URL_FOR_HTTP_TESTS.
SAM, BAM and CRAM
- A CRAM writer refuses codecs its CRAM version lacks, where 5.x wrote a file labelled 3.0 full of 3.1 codecs. A default strategy asked for CRAM 3.0 takes the new
NORMAL_3_0profile's codecs; SMALL, ARCHIVE and codecs set by hand are refused for 3.0.setCramVersionaccepts only 3.0 and 3.1. SAMFileWriterFactorywritesx.sam.gzas bgzipped SAM, where it wrote BAM, and recognises names in any case:x.SAMandx.CRAMare SAM and CRAM, not BAM, andx.BAM's index isx.bai.- Header text is UTF-8, and read names and tags pass through byte for byte, in SAM, BAM and CRAM alike (#1108, #1202, #1940). UTF-8 is what the SAM specification allows in
DS,CLand@COvalues; read names andZandAtags are passed through unchanged, as htslib passes them, rather than checked against the specification's ASCII-only rule, which htsjdk doesn't enforce elsewhere in the header either. Writing a tab, line break or NUL a field can't hold, or a char above 0xFF in a read name or tag, throwsIllegalArgumentException. A header line that isn't valid UTF-8, as 5.x could write, is read as Latin-1 and written back as UTF-8, and a non-ASCII read name in a CRAM from 5.x reads back as its UTF-8 bytes. - Records the specification allows on unmapped and unpaired reads are accepted (#1584): RNAME
*with a MAPQ or CIGAR, and MAPQ 255 on an unmapped read. Pair and mate flags on an unpaired read, and other MAPQs on an unmapped read, are warnings, among them the newINVALID_UNPAIRED_FLAG_MATE_UNMAPPEDandINVALID_UNMAPPED_MAPPING_QUALITY; STRICT still rejects them. SAMSequenceRecordaccepts names outside the SAM RNAME pattern (#1295), except an empty name,*,=, and names with spaces or control characters. In a SAM or BAM header such a name is the newINVALID_SEQUENCE_NAMEerror. Check names withvalidateSequenceNameorisValidSequenceName.- A read group's
DTis kept as written (#561), not rewritten in the JVM's time zone, which changesSAMUtils.calculateReadGroupRecordChecksumfor such headers. An unparseableDTis a warning, andgetRunDate()returns null for it.
VCF and BCF
- BCF is written as BGZF BCF 2.2 with a
.csiindex.VariantContextWriterBuilder.setBCFVersion(BCFVersion.BCF_2_1)writes raw BCF 2.1 with a Tribble.idx, as 5.x did; only raw BCF accepts a customIndexCreator. - Writing records out of order with on-the-fly indexing throws (#787).
INDEX_ON_THE_FLYis a default option, so this applies to any VCF or BCF written to a file with a reference dictionary: sort the records, or unset the option. - VCF and BCF are recognised by one rule (#664):
.vcf,.gvcfand.bcf, and.vcfor.gvcffollowed by.gz,.gzip,.bgzor.bgzf, in any case.VariantContextWriterBuilderthrows forx.gz,x.txt.gzandx.bcf.gz, which 5.x wrote as BGZF VCF; callsetOutputFileTypeaftersetOutputPathto write any format under any name. - Header and sample collections are unmodifiable:
VCFHeader's accessors, andgetSampleNames()andgetSampleNamesOrderedByName()onVariantContextandGenotypesContext; copy before changing.getSampleNamesInOrder()andgetSampleNameToOffset()returnListandMap, notArrayListandHashMap. - A header keeps the first INFO, FORMAT, FILTER or structured line per ID (#250, #929), as bcftools does, and numbers its contig lines itself (#1573).
- A standard INFO or FORMAT line declared with another type is kept as declared (
GQasFloat, for example), soVCFUtils.smartMergeHeadersrefuses a key declared with two types; fix such a header first, for example withVCFStandardHeaderLines.getInfoLine("DB"). The standardPQline isInteger(#751). - A header keeps the version it declares through copies and merges, and null if it declares none. Writers write the version given to
setVCFVersion, else the header's (at least 4.2), and refuse a header line that needs a later one.VCFHeader.validateVersionTransitionis gone. - A record's end is worked out as htslib works it out, from REF,
END,SVLEN(for<DEL>,<DUP>,<CNV>and<INV>) andLEN, sogetEnd()changes for symbolic alleles with anSVLENand noEND. - A genotype keeps each allele's phase (
0/1|2, and VCF 4.4's leading|0/1). Writing a phase the output version can't express throws;VCFEncoder.writeGtFieldhas an overload that allows it. BCF2Type's integer ranges leave the sentinel values unused, as htslib does: −127..−121 are written as INT16, the seven values aboveInteger.MIN_VALUEare refused, and an INT8 −127, INT16 −32767 or INT32 −2147483647 in a BCF from an earlier htsjdk reads as the end of its vector.- VCF, GFF3 and Tribble text are read and written as UTF-8, not Latin-1 or the platform default: a byte in a Latin-1 file that isn't valid UTF-8 reads as U+FFFD and is lost on rewrite.
- The
samjdk.optimistic_vcf_4_4property andDefaults.OPTIMISTIC_VCF_4_4andOPTIMISTIC_VCF_4_4_PROPERTYare removed.VCF3Codecno longer takes part in codec discovery. StructuralVariantTypegainsMIXED, whichVariantContext.getStructuralVariantType()returns when the alleles have more than one major type or disagree withSVTYPE.VCFCompoundHeaderLine.equalscomparesSourceandVersion. Header attribute values are escaped when written, so a caller that escaped quotes itself must stop.- For
AbstractVCFCodecsubclasses:parseFilterstakes the line number, the scratch fields (parts,genotypeParts,alleleMap,lineNo,filterHash) are gone, andstringCacheis private (usegetCachedString).
Indexes
-
An indexed CRAM is written with a
.crai, not a.cram.bai.SamFiles.findIndexfinds either;SAMFileWriterFactory.setCreateBaiIndexForCram(true)writes a BAI for one more release. -
A reader's index is no longer a
DiskBasedBAMFileIndex,CSIIndexorAbstractBAMFileIndex, so casts to them fail. AskSamReader.Indexing.getHtsIndexinstead:getHtsIndex(BrowseableBAMIndex.class)for bins,getHtsIndex(BAMIndex.class)for per-reference counts,getHtsIndex(CRAIQueryIndex.class)for CRAM containers.getIndex()is deprecated. A CRAI keeps no counts, sogetUnplacedRecordCount()is empty for a CRAM with unplaced reads.// 5.x: ((AbstractBAMFileIndex) reader.indexing().getIndex()).getNoCoordinateCount() OptionalLong unplaced = reader.indexing().getHtsIndex().getUnplacedRecordCount();
-
The deprecated BAM index classes still work when constructed directly, but a query that finds nothing returns an empty span, not
null, their memory-mapping arguments do nothing, andAbstractBAMFileIndex's protected methods for reading the file are gone.BAMIndexMergerrejects a CSI. -
TabixIndexis built on the newBinningIndex:TabixIndex(TabixFormat, List<String>, BinningIndex)andgetBinningIndex()replace theBinningIndexContent[]constructor andgetIndices(), and the internal index types ofTabixReaderandTabixUtilsare gone. -
A
.csibeside a tabix-indexed file is preferred to a.tbi, as htslib prefers it. -
A Tribble index can't be built over BGZF BCF (#945), where 5.x built one that found nothing;
BCF2Codecrefuses a compressed stream. Index BGZF BCF with CSI. -
AbstractFeatureReader.getFeatureReader(resource, codec, Index)refuses aTabixIndexorBCFCsiIndex, whose BGZF offsets it would misread; give it the index's path instead. -
Tribble iterators close when read to their end, and closing a reader closes any still open (#494). A query whose start is after its end returns nothing from a Tribble
.idx(#204).
Other
DiskBackedQueueandSamRecordTrackingBufferareAutoCloseable, and no longer delete their spill files when garbage-collected: close or clear them.- Runtime dependencies are updated: commons-compress 1.28.0, which brings in commons-codec, xz 1.12, snappy-java 1.1.10.8, org.json 20260522, and commons-logging 1.4.0 for JEXL.
- VCF objects stored with Java serialization by 5.x, such as a
VCFHeader, its header lines or genotypes, can't be deserialized by 6.0 (InvalidClassException), since their classes changed. This concerns serialized Java objects only; VCF and BCF files written by 5.x read as before. - Some public classes inside the CRAM and BCF codecs changed signatures:
TrialCompressor's constructor,CompressionUtils.encodePack, and the constructors ofBCF2FieldEncoder's subclasses.
Output that differs from 5.x
What htsjdk writes, for anyone comparing output with files 5.x wrote (expected test outputs, for example). Each is a fix or a change described elsewhere in this section.
- VCF header: only the first line per ID is kept; a standard line declared with another type stays as declared;
##contiglines carrymd5,URLandspeciesfrom a sequence dictionary (#730);##fileformatis the header's version (at least 4.2), where a copy of a 4.3 header used to be written as 4.2; INFO and FORMAT lines keep every attribute, and quoted values are escaped as the specification requires; repeated unstructured lines, and structured lines with distinct IDs, are kept (#500, #277). - VCF records: negative doubles are written like positive ones (
-5.00, not-5.000e+00); a missing GT is written as., where 5.x threw, and a sample with every value missing as., not an empty column; String values are percent-encoded from VCF 4.3;0/1|2is written as it is, not as0|1|2. - BCF: BGZF BCF 2.2 with a
.csi;IDX=on FILTER, INFO, FORMAT and contig lines; vectors sized from their values and padded with END_OF_VECTOR; flags, GT width, phase bits andrlenas htslib writes them. - CRAM: a
.crai, not a.cram.bai;M5added to@SQlines without one (#506); the file id is the file name, so the same records give identical files wherever they are written (#1068); empty blocks written RAW (#1633); reads without bases, unsignedBarrays and pairs with linked template lengths stored as htslib stores them; different codec choices (see Performance). - SAM and BAM: header text is UTF-8;
@RG DTis as written; a CIGAR too long for BAM goes inCG:B:I, notCG:B:i(#1560); a U in SEQ is read and written as T (#1728);x.sam.gzis bgzipped SAM. - Indexes: BAI, TBI and CSI have htslib's content and equal samtools' and tabix's once read (a CSI for bgzipped SAM also carries a tabix header); a TBI carries record counts as tabix's does (#1586); a CRAM's BAI has real offsets in its metadata (#401).
- Elsewhere:
FastaReferenceWriter's.faigives a sequence shorter than one line its own line widths, as samtools does; the.md5beside a gzipped file is of the compressed file (#758);BasicFastqWriterends lines with\non every platform (#1105); warnings go throughLog(#1261).
New features
VCF and BCF versions
| Read | Written | |
|---|---|---|
| VCF | 3.2 to 4.5, by default | 4.0 to 4.5: the version given to setVCFVersion, else the header's, at least 4.2 |
| BCF | 2.1 and 2.2, raw or BGZF | BGZF BCF 2.2 by default; raw BCF 2.1 with setBCFVersion(BCFVersion.BCF_2_1) |
VCF 4.4 and 4.5 bring the Number codes P, LA, LR, LG and M; a phase for each allele, including a leading |0/1 (Genotype.isAllelePhased); reserved keys, as constants in the new VCFConstants.INFO and VCFConstants.FORMAT, and as lines in VCFStandardHeaderLines where a key's definition doesn't vary by version; symbolic and breakend alleles, parsed into StructuralVariantAllele and Breakend; and record ends from SVLEN and LEN. String values are percent-encoded from VCF 4.3, and text is UTF-8.
BCF is read as htslib reads it, from its dictionaries (sparse IDX values included) to its end-of-vector markers, and decodes to the values the VCF reader gives (#946). BCF2Writer is public. The VCF and BCF codecs are thread-safe once their header is read (#1026).
Indexing
| Format | Index written | Indexes read |
|---|---|---|
| BAM | BAI by default, or CSI | BAI, CSI |
| CRAM | CRAI | CRAI, BAI |
| Bgzipped SAM | CSI by default, or BAI | BAI and CSI from samtools index; TBI and CSI from tabix |
| Bgzipped VCF, BED, GFF | TBI by default, or CSI | TBI, CSI |
| BCF | CSI for BGZF BCF; Tribble .idx for raw BCF 2.1 |
CSI, .idx |
- Choose the index with
SAMFileWriterFactory.setBamIndexTypeorsetSamIndexType(BAI,CSI, orAUTO, a CSI only when a sequence is too long for a BAI) andVariantContextWriterBuilder.setTabixIndexType(TBIorCSI). - Index an existing file with
BAMIndexer.createIndex(reader, output, log, indexType)for BAM and bgzipped SAM, andIndexFactory.createIndex(path, codec, type, dictionary)for bgzipped text (IndexType.TABIXorCSI) and BGZF BCF (CSI, for a BCF whose contigs are in the header's order). - References longer than 512 Mbp need CSI, or CRAI for CRAM.
- Indexes match htslib's: equal to samtools' and tabix's once read, with the record counts
bcftools index -nreads, whichTabixIndex.getRecordCountgives too (#1586).
Every index answers queries through one format-neutral interface, htsjdk.index.HtsQueryIndex, which SamReader.Indexing.getHtsIndex() returns; getHtsIndex(Class) reaches what one format alone has. A CRAM is queried from its CRAI directly (#851), so a CRAM on a reference longer than 512 Mbp is queryable (#1747) and opening one is about 70% faster. BGZF BCF is queried through its CSI by the new BCFFileReader, which VCFFileReader uses.
BAI and CSI indexes are read a reference at a time when a query first needs them, and kept while memory allows: 1,000 queries on one chromosome of a whole-genome BAI take 2 ms rather than 64, and through a CSI 11 ms rather than 932. SamReaderFactory.indexLoading chooses LAZY, EAGER or AUTO, the default, which reads an index whole when it is given as a stream, is on another file system, or is under a megabyte. BAI, TBI and CSI share one sparse implementation, htsjdk.index.BinningIndex, so an index over 50,000 small contigs takes 10 MB rather than 951 MB, and queries through a tabix index are faster (VCFFileReader.query −20%).
Bgzipped SAM
x.sam.gz (or .gzip, .bgz or .bgzf) is now an indexed format, like BAM:
SAMFileWriterFactorywrites it, and indexes it while writing: a CSI by default (x.sam.gz.csi, as samtools writes), or a BAI withsetSamIndexType.- A file opened from a
Pathis queried like a BAM, through the BAI or CSI ofsamtools indexor the TBI or CSI oftabix -p sam. - An existing file is indexed with
BAMIndexer.createIndex, from a reader opened withINCLUDE_SOURCE_IN_RECORDS.
Other new features
SAMRecordQueryNameNaturalComparatorsorts read names in samtools' natural order (SS:queryname:natural).- The
NORMAL_3_0CRAM profile writes CRAM 3.0 with rANS 4x8 and GZIP, which htsjdk before 4.3.0 and other readers without CRAM 3.1 support read. CRAMContainerStreamWriter.finish(writeEOFContainer, closeStream)lets a caller keep its stream open (#1092).- INFO and FORMAT header lines keep every attribute, in any order, through
getGenericFieldValueandgetGenericFields;smartMergeHeaderskeeps the line with the laterVersionwhen two inputs define a field alike for the sameSource. VariantFileTypetells VCF from BCF by name or by content;VariantContext.getIDs();VCFHeader.getOtherHeaderLines(String).IOUtil.openGzipOrBgzfStreamreads BGZF, and gzip of any number of members, from any stream.htsjdk.samtools.util.UnsynchronizedByteArrayOutputStream, aByteArrayOutputStreamwithout locking.- The jar names its automatic module
htsjdk(#1724), so a modular application canrequires htsjdk;; it is not yet an explicit module, so jlink can't use it.
Deprecations
VCFConstants' top-level INFO and FORMAT key names (GENOTYPE_KEY,DEPTH_KEYand the rest), in favour ofVCFConstants.INFOandVCFConstants.FORMAT; each one's Javadoc names its replacement. They remain compile-time constants, so only builds that treat deprecation warnings as errors notice.- For removal in 7.0.0:
SamReader.Indexing.getIndex();SAMFileWriterFactory.setCreateBaiIndexForCram;DiskBasedBAMFileIndex,CSIIndex,AbstractBAMFileIndex,BinningIndexBuilder,BinningIndexContent,LinearIndex,BinWithOffset, andBAMIndexMerger.mergeBinsandmergeLinearIndexes; andSamIndexes.openIndexFileAsBaiOrNull,openIndexUrlAsBaiOrNull,asBaiStreamOrNullandasBaiSeekableStreamOrNull(#1425). SamReaderFactory.Option.CACHE_FILE_BASED_INDEXESandDONT_MEMORY_MAP_INDEX, which have no effect.- The sixteen
Fileoverloads that remain (see Paths and files). AsciiLineReaderandAsciiLineReaderIterator, in favour ofUtf8LineReaderandUtf8LineReaderIterator.VCF3Codec;VCFFileReader.isBCF,AbstractVCFCodec.canDecodeFileandBCF2Codec.tryReadBCFVersion, in favour ofVariantFileType;BCF2Codec.ALLOWED_MINOR_VERSION,ALLOWED_BCF_VERSION,validateVersionCompatibilityanderror(String).VariantContextUtils.getMetaDataForField, in favour ofVCFHeader.getInfoHeaderLineandgetFormatHeaderLine.
Performance
Against 5.0.2, each run in a fresh JVM, with BGZF level 1 and the NORMAL CRAM profile, on chromosome 3 of a 1000 Genomes WGS BAM (1.37 million reads), a 1,000-sample VCF and a one-million-record gVCF:
| Change | |
|---|---|
| BAM to CRAM | −29% |
| CRAM to BAM | −7% |
| Reading VCF | −9% to −11% |
| VCF to bgzipped VCF | −12% |
| VCF to BCF 2.1 | −17% |
| Reading BAM, BAM to BAM, BCF to VCF | unchanged |
- The CRAM 3.1 profiles try the codecs htslib's do, and choose among them as htslib does. NORMAL's files are 0.7–1.1% larger than samtools'; SMALL's and ARCHIVE's are 2–9% smaller than before but take longer to write. A CRAM 3.1 writer no longer holds 6 MB of rANS tables for every distinct tag.
- SAM text is parsed about 2.2 times as fast; writing it is about 4.5% slower for reads with long Z tags such as OQ, for the checks that keep its text valid.
- BCF writing takes genotypes by position and encodes without a lock per byte; decoding skips padding. BAM bases are packed through a lookup table. Index queries: see Indexing.
SamLocusIteratorandEdgeReadIteratorno longer slow down as reads get longer (#1490).
Bug fixes
Fixes that change output are listed under Output that differs from 5.x.
SAM, BAM and CRAM
- A mapped read without bases (SEQ
*) keeps its CIGAR, NM and MD through a CRAM htsjdk writes; 5.x read it back as0M. - htsjdk 4.x can read the CRAMs htsjdk writes again, so far as it reads their CRAM version: 5.0.0 wrote empty GZIP blocks that 4.x rejects (#1633).
- A CRAM labelled 3.0 no longer contains CRAM 3.1 codecs: the
FASTprofile compressed tags with rANS Nx16. - CRAM template lengths of mates stored together are derived as htslib derives them (#1189).
- Unsigned
Barrays keep their type through CRAM (#499), and bytes 0x80–0xFF in CRAM read names and tags are kept. - The NM worked out for a CRAM record counts every inserted base (#1187); a read running past the end of its reference keeps its bases, NM and MD.
- Reading CRAM matches samtools in MD past the end of the reference, the internal
cFtag, and the PNEXT of an unpaired read. - The CRAM writer keeps an unpaired read's 0x2, 0x8, 0x20, 0x40 and 0x80 flags and its PNEXT, and an
RGtag with no@RGline. Such unpaired reads now fail STRICT validation when read from CRAM, as they do from SAM and BAM. - The CRAM writer handles an empty quality array as missing qualities, and a slice whose placed reads are all unmapped (#714).
- A CRAM with an EOF container partway through is read to its end (#1271).
- CRAM quality scores with a HUFFMAN encoding can be read (#518).
- CRAM iterators over a seekable stream no longer cut each other short (#563).
- A CRAM opened by
Pathis read through a buffer; unbuffered, it was very slow on NFS (#1756). ReferenceSourceno longer returns another contig's bases when one source serves CRAMs whose@SQlines are in different orders.CRAMFileReaderconstructors without a validation stringency useSILENT.- The beta API's CRAM 3.0 encoder writes CRAM 3.0, and its 2.1 encoder throws.
- Multi-interval queries return every record when a file's references are not in dictionary order (#1271).
queryUnmapped()on a CSI-indexed BAM no longer seeks to the wrong place.- A BAM writer that can't build or write its index fails the write, and refuses later writes.
- Reading a BAI or TBI whose metadata bin has the wrong number of chunks suggests a CSI index, since the reference is probably longer than 2^29 (#823, #643).
- A sort-order check no longer fails because the caller changed a record it was given (#760).
SamReaderFactory.makeDefault()uses the default inflater factory in force when it is called (#1666, #831).- A plain SAM file can be iterated again after its first iterator is closed (#681).
- A reader whose header can't be read no longer leaks its file handle (#494).
SAMFileWriterFactory's copies keep the deflater factory and the flag format.SAMRecord.isUnsignedArrayAttributeno longer throwsNullPointerException.SAMUtils.getNumOverlappingAlignedBasesToClipandclipOverlappingAlignedBasesclip part of a partly overlapping=orXelement, as they doM(5.x clipped150=to150Swhere50=100Swas right), and no longer clip mates on different references.- A
SAMFileWritergiven records out of order names the record before the offending one, rather than the offending one twice. - Bgzipped SAM is read with the
InflaterFactoryset onSamReaderFactory, rather than always the default. - A CRAM reader on a stream that can't seek throws a clear
IllegalStateExceptionfor a query or index call, rather thanNullPointerException(#426). - A failed CRAM reference lookup names the sequence and the
.fai,.gziand.dictfiles a CRAM's reference needs (#998, #1732). - Dates with a space or a lower-case
torzare parsed (#1217).
VCF and BCF
- The BCF writer keeps an interior missing value in a vector, sizes each FORMAT vector from its values, sizes strings by their UTF-8 length, writes String INFO values whatever their comma count (#1063), accepts a
Flagline with a non-zeroNumber, and masks n_sample to 24 bits. - A missing value inside a BCF vector no longer shifts the values after it.
- INFO values are typed by their INFO line and FORMAT values by their FORMAT line, where an INFO field sharing an ID with a FORMAT field took the FORMAT line's type.
getAttributeAsInt,getAttributeAsDouble,getAttributeAsBoolean,getAttributeAsIntListandgetAttributeAsDoubleListreturn the default for a missing value read from VCF (#1228, #1073).- Spaces in INFO values are accepted (#1667).
- A malformed genotype is reported as a
TribbleExceptionnaming the sample and key. VCFFileReaderopens VCF 3.2 and 3.3, and reads a 3.x record withFILTER=PASSas passing.smartMergeHeaderspromotesIntegerandFloattoFloatin either order, and keeps every contig when the inputs' dictionaries differ (#1574).Genotype.sameGenotypeignoring phase tells polyploid genotypes apart by allele counts.getStructuralVariantType()returnsDELfor anSVTYPEofDEL:ME.VariantContext.hasID()is false for a deserialized record without an ID.- An empty VCF is reported as empty (#973).
toString()no longer decodes lazily decoded genotypes (#1011).- Closing a VCF or BCF writer, or a
BlockCompressedOutputStream, twice does nothing (#469). - VCF and BCF are read and written without commons-jexl on the class path.
VCFFileReaderopens a path in a zip or jar file system.VariantContextWriterBuilderkeeps anIndexCreatorthe caller supplied for block-compressed VCF.
Indexes and tabix
- A tabix index with a sequence that has no records is written correctly.
TabixReaderreturns a last line without a newline, strips a CR before the newline, accepts contig names containing:or-(#1017), rejects a plain-gzip file, and names the index files it looked for.- A Tribble index with a byte of 0x80 or above in a name is read (#1614).
FASTA and references
FastaSequenceIndexCreatorindexes a FASTA with blank lines (#1748) or a last line without a newline.- A FASTA whose first lines are
;comments can be read and indexed. - A sequence longer than 2^30 bases read without a dictionary no longer fails (#1380).
- A gzipped (not bgzipped) FASTA with a
.faiis read sequentially rather than rejected (#1143). - Opening an indexed FASTA checks that it matches its
.fai. - Indexed lookups from several threads return the right bases (#1749), and bgzipped lookups no longer re-inflate a block each time (#1131).
- A bgzipped FASTA from
FastaReferenceWritercan be opened as indexed, andGZIIndex.buildIndexhandles more than 2 GiB of data. - Closing a
FastaReferenceWritergiven no sequences writes an empty FASTA (#1498).
Input, output and utilities
- Gzipped and bgzipped input from pipes, sockets and URLs is no longer silently truncated (#1691).
- A BGZF file made by joining others is read to its end.
IOUtil.isGZIPInputStreamchecks only the gzip header.- FTP works with strict servers, on any port, and fails cleanly for a missing file (#470, #797, #463, #464, #618, #623). A reader picks the format of a file over FTP by its name, so a CRAM or SAM over FTP no longer opens as BAM, and a BAM whose name doesn't end in
.bamis no longer opened as one. SeekableMemoryStream.read(buffer, offset, 0)returns 0, andSeekablePathStream.read()no longer returns 0 for an empty channel read (#1399).IOUtil.deletePathsgiven a singlePathdeletes only that path.IOUtil.assertFileIsWritableandassertDirectoryIsWritableaccept outputs on NFS servers whose access checks disagree with their ACLs (#1671).ProcessExecutor.executeAndReturnInterleavedOutputno longer deadlocks on large output.SortingCollectionbuffers its temporary files on large heaps (#1741), andSortingLongCollectionclamps its buffer as documented.TagFilteraccepts a list of any type (#1082).Histogram.getMin,getMaxandgetModethrowIllegalStateExceptionon an empty histogram (#1657).- A malformed BED or GFF3 line is reported with its file, column and text (#709).
- The published POM lists the Apache 2.0 and LGPL licences as well as MIT (#1710).
Full Changelog: 5.0.2...6.0.0