From 16f635595e405500bb1b63d32d5ffe9e54139560 Mon Sep 17 00:00:00 2001 From: Chris Whelan Date: Thu, 19 Sep 2019 11:07:43 -0400 Subject: [PATCH] Make VCFHeader not throw exception if contig header lines lack length field --- .../java/htsjdk/variant/vcf/VCFContigHeaderLine.java | 7 ++++++- src/main/java/htsjdk/variant/vcf/VCFHeader.java | 6 ++++-- .../java/htsjdk/variant/vcf/VCFHeaderUnitTest.java | 12 ++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/main/java/htsjdk/variant/vcf/VCFContigHeaderLine.java b/src/main/java/htsjdk/variant/vcf/VCFContigHeaderLine.java index 2cbc40ea28..730cb32dde 100644 --- a/src/main/java/htsjdk/variant/vcf/VCFContigHeaderLine.java +++ b/src/main/java/htsjdk/variant/vcf/VCFContigHeaderLine.java @@ -76,9 +76,14 @@ public Integer getContigIndex() { return contigIndex; } + /** + * Get the SAMSequenceRecord that corresponds to this VCF header line. + * @return The SAMSequenceRecord containing the ID, length, assembly, and index of this contig. Returns null if the + * contig header line does not have a length. + */ public SAMSequenceRecord getSAMSequenceRecord() { final String lengthString = this.getGenericFieldValue("length"); - if (lengthString == null) throw new TribbleException("Contig " + this.getID() + " does not have a length field."); + if (lengthString == null) return null; final SAMSequenceRecord record = new SAMSequenceRecord(this.getID(), Integer.parseInt(lengthString)); record.setAssembly(this.getGenericFieldValue("assembly")); record.setSequenceIndex(this.contigIndex); diff --git a/src/main/java/htsjdk/variant/vcf/VCFHeader.java b/src/main/java/htsjdk/variant/vcf/VCFHeader.java index c023e5bbf2..266b23a5c5 100644 --- a/src/main/java/htsjdk/variant/vcf/VCFHeader.java +++ b/src/main/java/htsjdk/variant/vcf/VCFHeader.java @@ -261,7 +261,7 @@ public List getContigLines() { /** * Returns the contigs in this VCF file as a SAMSequenceDictionary. Returns null if contigs lines are - * not present in the header. Throws SAMException if one or more contig lines do not have length + * not present in the header. Returns null if one or more contig lines do not have length * information. */ public SAMSequenceDictionary getSequenceDictionary() { @@ -270,7 +270,9 @@ public SAMSequenceDictionary getSequenceDictionary() { final List sequenceRecords = new ArrayList(contigHeaderLines.size()); for (final VCFContigHeaderLine contigHeaderLine : contigHeaderLines) { - sequenceRecords.add(contigHeaderLine.getSAMSequenceRecord()); + final SAMSequenceRecord samSequenceRecord = contigHeaderLine.getSAMSequenceRecord(); + if (samSequenceRecord == null) return null; + sequenceRecords.add(samSequenceRecord); } return new SAMSequenceDictionary(sequenceRecords); diff --git a/src/test/java/htsjdk/variant/vcf/VCFHeaderUnitTest.java b/src/test/java/htsjdk/variant/vcf/VCFHeaderUnitTest.java index 5bb42a3205..5b96f6c23f 100644 --- a/src/test/java/htsjdk/variant/vcf/VCFHeaderUnitTest.java +++ b/src/test/java/htsjdk/variant/vcf/VCFHeaderUnitTest.java @@ -239,6 +239,18 @@ public void testVCFHeaderAddContigLine() { } @Test + public void testVCFHeaderContigLineMissingLength() { + final VCFHeader header = getHiSeqVCFHeader(); + final VCFContigHeaderLine contigLine = new VCFContigHeaderLine( + "", VCFHeaderVersion.VCF4_0, VCFHeader.CONTIG_KEY, 0); + header.addMetaDataLine(contigLine); + Assert.assertTrue(header.getContigLines().contains(contigLine), "Test contig line not found in contig header lines"); + Assert.assertTrue(header.getMetaDataInInputOrder().contains(contigLine), "Test contig line not found in set of all header lines"); + + Assert.assertNull(header.getSequenceDictionary()); + } + + @Test public void testVCFHeaderHonorContigLineOrder() throws IOException { try (final VCFFileReader vcfReader = new VCFFileReader(new File(variantTestDataRoot + "dbsnp_135.b37.1000.vcf"), false)) { // start with a header with a bunch of contig lines