From 2324c5a74f03d8dcfa8235db47bfa0e1edf33afa Mon Sep 17 00:00:00 2001 From: Eric Banks Date: Mon, 19 Mar 2012 21:29:24 -0400 Subject: [PATCH] Simplified the interface for simple VCF header lines by making the VCFSimpleHeaderLine not abstract anymore - now any arbitrary header line with an ID (e.g. the contig and ALT lines) can be part of this class without having to define new classes. Also, renamed the 'named' header line to 'id' since that's more accurate. --- .../gatk/refdata/RefMetaDataTracker.java | 2 +- .../gatk/refdata/tracks/FeatureManager.java | 2 +- .../walkers/annotator/VariantAnnotator.java | 2 +- .../walkers/diffengine/VCFDiffableReader.java | 4 +- .../walkers/variantutils/VariantsToVCF.java | 4 +- .../utils/codecs/vcf/AbstractVCFCodec.java | 24 +++--- .../utils/codecs/vcf/VCFAltHeaderLine.java | 28 ------- .../codecs/vcf/VCFCompoundHeaderLine.java | 4 +- .../sting/utils/codecs/vcf/VCFConstants.java | 7 ++ .../utils/codecs/vcf/VCFFilterHeaderLine.java | 4 +- .../sting/utils/codecs/vcf/VCFHeader.java | 5 +- .../codecs/vcf/VCFHeaderLineTranslator.java | 12 ++- ...edHeaderLine.java => VCFIDHeaderLine.java} | 6 +- .../utils/codecs/vcf/VCFSimpleHeaderLine.java | 75 ++++++++++++------- .../sting/utils/codecs/vcf/VCFUtils.java | 10 +-- 15 files changed, 102 insertions(+), 87 deletions(-) delete mode 100644 public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFAltHeaderLine.java rename public/java/src/org/broadinstitute/sting/utils/codecs/vcf/{VCFNamedHeaderLine.java => VCFIDHeaderLine.java} (91%) diff --git a/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java b/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java index 286e22369..0e13e4ad9 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java +++ b/public/java/src/org/broadinstitute/sting/gatk/refdata/RefMetaDataTracker.java @@ -418,7 +418,7 @@ public class RefMetaDataTracker { * with the current site as a RODRecordList List object. If no data track with specified name is available, * returns defaultValue wrapped as RODRecordList object. NOTE: if defaultValue is null, it will be wrapped up * with track name set to 'name' and location set to null; otherwise the wrapper object will have name and - * location set to defaultValue.getName() and defaultValue.getLocation(), respectively (use caution, + * location set to defaultValue.getID() and defaultValue.getLocation(), respectively (use caution, * defaultValue.getLocation() may be not equal to what RODRecordList's location would be expected to be otherwise: * for instance, on locus traversal, location is usually expected to be a single base we are currently looking at, * regardless of the presence of "extended" RODs overlapping with that location). diff --git a/public/java/src/org/broadinstitute/sting/gatk/refdata/tracks/FeatureManager.java b/public/java/src/org/broadinstitute/sting/gatk/refdata/tracks/FeatureManager.java index fcd85fd1d..55dd50334 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/refdata/tracks/FeatureManager.java +++ b/public/java/src/org/broadinstitute/sting/gatk/refdata/tracks/FeatureManager.java @@ -132,7 +132,7 @@ public class FeatureManager { } /** - * Return the FeatureDescriptor with getName().equals(name) + * Return the FeatureDescriptor with getID().equals(name) * * @param name * @return A FeatureDescriptor or null if none is found diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java index 5312c4136..66c142582 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/annotator/VariantAnnotator.java @@ -240,7 +240,7 @@ public class VariantAnnotator extends RodWalker implements Ann for ( VCFHeaderLine line : VCFUtils.getHeaderFields(getToolkit(), Arrays.asList(expression.binding.getName())) ) { if ( line instanceof VCFInfoHeaderLine ) { VCFInfoHeaderLine infoline = (VCFInfoHeaderLine)line; - if ( infoline.getName().equals(expression.fieldName) ) { + if ( infoline.getID().equals(expression.fieldName) ) { targetHeaderLine = infoline; break; } diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java index 3c0da8e9d..c9a6cb8f2 100644 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/diffengine/VCFDiffableReader.java @@ -68,8 +68,8 @@ public class VCFDiffableReader implements DiffableReader { VCFHeader header = (VCFHeader)vcfCodec.readHeader(lineReader); for ( VCFHeaderLine headerLine : header.getMetaData() ) { String key = headerLine.getKey(); - if ( headerLine instanceof VCFNamedHeaderLine ) - key += "_" + ((VCFNamedHeaderLine) headerLine).getName(); + if ( headerLine instanceof VCFIDHeaderLine) + key += "_" + ((VCFIDHeaderLine) headerLine).getID(); if ( root.hasElement(key) ) logger.warn("Skipping duplicate header line: file=" + file + " line=" + headerLine.toString()); else diff --git a/public/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToVCF.java b/public/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToVCF.java index f5928b723..05865b587 100755 --- a/public/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToVCF.java +++ b/public/java/src/org/broadinstitute/sting/gatk/walkers/variantutils/VariantsToVCF.java @@ -216,12 +216,12 @@ public class VariantsToVCF extends RodWalker { Set hInfo = new HashSet(); hInfo.addAll(VCFUtils.getHeaderFields(getToolkit(), Arrays.asList(variants.getName()))); //hInfo.add(new VCFHeaderLine("source", "VariantsToVCF")); - //hInfo.add(new VCFHeaderLine("reference", getToolkit().getArguments().referenceFile.getName())); + //hInfo.add(new VCFHeaderLine("reference", getToolkit().getArguments().referenceFile.getID())); allowedGenotypeFormatStrings.add(VCFConstants.GENOTYPE_KEY); for ( VCFHeaderLine field : hInfo ) { if ( field instanceof VCFFormatHeaderLine) { - allowedGenotypeFormatStrings.add(((VCFFormatHeaderLine)field).getName()); + allowedGenotypeFormatStrings.add(((VCFFormatHeaderLine)field).getID()); } } diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java index 3c2ed18e4..273d5a377 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/AbstractVCFCodec.java @@ -154,18 +154,24 @@ public abstract class AbstractVCFCodec implements FeatureCodec, NameAwareCodec { throw new UserException.MalformedVCFHeader("The FORMAT field was provided but there is no genotype/sample data"); } else { - if ( str.startsWith("##INFO=") ) { - VCFInfoHeaderLine info = new VCFInfoHeaderLine(str.substring(7),version); + if ( str.startsWith(VCFConstants.INFO_HEADER_START) ) { + final VCFInfoHeaderLine info = new VCFInfoHeaderLine(str.substring(7),version); metaData.add(info); - infoFields.put(info.getName(), info.getType()); - } else if ( str.startsWith("##FILTER=") ) { - VCFFilterHeaderLine filter = new VCFFilterHeaderLine(str.substring(9),version); + infoFields.put(info.getID(), info.getType()); + } else if ( str.startsWith(VCFConstants.FILTER_HEADER_START) ) { + final VCFFilterHeaderLine filter = new VCFFilterHeaderLine(str.substring(9), version); metaData.add(filter); - filterFields.add(filter.getName()); - } else if ( str.startsWith("##FORMAT=") ) { - VCFFormatHeaderLine format = new VCFFormatHeaderLine(str.substring(9),version); + filterFields.add(filter.getID()); + } else if ( str.startsWith(VCFConstants.FORMAT_HEADER_START) ) { + final VCFFormatHeaderLine format = new VCFFormatHeaderLine(str.substring(9), version); metaData.add(format); - formatFields.put(format.getName(), format.getType()); + formatFields.put(format.getID(), format.getType()); + } else if ( str.startsWith(VCFConstants.CONTIG_HEADER_START) ) { + final VCFSimpleHeaderLine contig = new VCFSimpleHeaderLine(str.substring(9), version, VCFSimpleHeaderLine.SupportedHeaderLineType.GENERIC, null); + metaData.add(contig); + } else if ( str.startsWith(VCFConstants.ALT_HEADER_START) ) { + final VCFSimpleHeaderLine alt = new VCFSimpleHeaderLine(str.substring(6), version, VCFSimpleHeaderLine.SupportedHeaderLineType.GENERIC, Arrays.asList("ID", "Description")); + metaData.add(alt); } else { int equals = str.indexOf("="); if ( equals != -1 ) diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFAltHeaderLine.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFAltHeaderLine.java deleted file mode 100644 index a9de949d8..000000000 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFAltHeaderLine.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.broadinstitute.sting.utils.codecs.vcf; - -/** - * @author ebanks - * A class representing a key=value entry for ALT fields in the VCF header - */ -public class VCFAltHeaderLine extends VCFSimpleHeaderLine { - - /** - * create a VCF filter header line - * - * @param name the name for this header line - * @param description the description for this header line - */ - public VCFAltHeaderLine(String name, String description) { - super(name, description, SupportedHeaderLineType.ALT); - } - - /** - * create a VCF info header line - * - * @param line the header line - * @param version the vcf header version - */ - protected VCFAltHeaderLine(String line, VCFHeaderVersion version) { - super(line, version, SupportedHeaderLineType.ALT); - } -} \ No newline at end of file diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFCompoundHeaderLine.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFCompoundHeaderLine.java index 97166833b..d2bd507b5 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFCompoundHeaderLine.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFCompoundHeaderLine.java @@ -34,7 +34,7 @@ import java.util.Map; /** * a base class for compound header lines, which include info lines and format lines (so far) */ -public abstract class VCFCompoundHeaderLine extends VCFHeaderLine implements VCFNamedHeaderLine { +public abstract class VCFCompoundHeaderLine extends VCFHeaderLine implements VCFIDHeaderLine { public enum SupportedHeaderLineType { INFO(true), FORMAT(false); @@ -52,7 +52,7 @@ public abstract class VCFCompoundHeaderLine extends VCFHeaderLine implements VCF private VCFHeaderLineType type; // access methods - public String getName() { return name; } + public String getID() { return name; } public String getDescription() { return description; } public VCFHeaderLineType getType() { return type; } public VCFHeaderLineCount getCountType() { return countType; } diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFConstants.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFConstants.java index 8e9d989cc..b23371cc9 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFConstants.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFConstants.java @@ -80,6 +80,13 @@ public final class VCFConstants { public static final String PHASED_SWITCH_PROB_v3 = "\\"; public static final String PHASING_TOKENS = "/|\\"; + // header lines + public static final String FILTER_HEADER_START = "##FILTER"; + public static final String FORMAT_HEADER_START = "##FORMAT"; + public static final String INFO_HEADER_START = "##INFO"; + public static final String ALT_HEADER_START = "##ALT"; + public static final String CONTIG_HEADER_START = "##contig"; + // old indel alleles public static final char DELETION_ALLELE_v3 = 'D'; public static final char INSERTION_ALLELE_v3 = 'I'; diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFFilterHeaderLine.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFFilterHeaderLine.java index 418b80074..72504abd5 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFFilterHeaderLine.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFFilterHeaderLine.java @@ -1,5 +1,7 @@ package org.broadinstitute.sting.utils.codecs.vcf; +import java.util.Arrays; + /** * @author ebanks * A class representing a key=value entry for FILTER fields in the VCF header @@ -23,6 +25,6 @@ public class VCFFilterHeaderLine extends VCFSimpleHeaderLine { * @param version the vcf header version */ protected VCFFilterHeaderLine(String line, VCFHeaderVersion version) { - super(line, version, SupportedHeaderLineType.FILTER); + super(line, version, SupportedHeaderLineType.FILTER, Arrays.asList("ID", "Description")); } } \ No newline at end of file diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeader.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeader.java index 5c5df15ab..27bab8c41 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeader.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeader.java @@ -2,7 +2,6 @@ package org.broadinstitute.sting.utils.codecs.vcf; import org.broad.tribble.util.ParsingUtils; -import org.broadinstitute.sting.utils.variantcontext.Genotype; import java.util.*; @@ -126,11 +125,11 @@ public class VCFHeader { for ( VCFHeaderLine line : mMetaData ) { if ( line instanceof VCFInfoHeaderLine ) { VCFInfoHeaderLine infoLine = (VCFInfoHeaderLine)line; - mInfoMetaData.put(infoLine.getName(), infoLine); + mInfoMetaData.put(infoLine.getID(), infoLine); } else if ( line instanceof VCFFormatHeaderLine ) { VCFFormatHeaderLine formatLine = (VCFFormatHeaderLine)line; - mFormatMetaData.put(formatLine.getName(), formatLine); + mFormatMetaData.put(formatLine.getID(), formatLine); } else { mOtherMetaData.put(line.getKey(), line); diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeaderLineTranslator.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeaderLineTranslator.java index e39a09cb1..88fed75d7 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeaderLineTranslator.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFHeaderLineTranslator.java @@ -73,10 +73,14 @@ class VCF4Parser implements VCFLineParser { // validate the tags against the expected list index = 0; - if (ret.size() > expectedTagOrder.size()) throw new IllegalArgumentException("Unexpected tag count " + ret.size() + " in string " + expectedTagOrder.size()); - for (String str : ret.keySet()) { - if (!expectedTagOrder.get(index).equals(str)) throw new IllegalArgumentException("Unexpected tag " + str + " in string " + valueLine); - index++; + if ( expectedTagOrder != null ) { + if ( ret.size() > expectedTagOrder.size() ) + throw new IllegalArgumentException("Unexpected tag count " + ret.size() + " in string " + expectedTagOrder.size()); + for ( String str : ret.keySet() ) { + if ( !expectedTagOrder.get(index).equals(str) ) + throw new IllegalArgumentException("Unexpected tag " + str + " in string " + valueLine); + index++; + } } return ret; } diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFNamedHeaderLine.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFIDHeaderLine.java similarity index 91% rename from public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFNamedHeaderLine.java rename to public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFIDHeaderLine.java index f78e936b2..65321881a 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFNamedHeaderLine.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFIDHeaderLine.java @@ -24,7 +24,7 @@ package org.broadinstitute.sting.utils.codecs.vcf; -/** an interface for named header lines **/ -public interface VCFNamedHeaderLine { - String getName(); +/** an interface for ID-based header lines **/ +public interface VCFIDHeaderLine { + String getID(); } diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFSimpleHeaderLine.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFSimpleHeaderLine.java index 152043f28..ea485e956 100644 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFSimpleHeaderLine.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFSimpleHeaderLine.java @@ -1,7 +1,7 @@ package org.broadinstitute.sting.utils.codecs.vcf; -import java.util.Arrays; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; @@ -9,15 +9,16 @@ import java.util.Map; * @author ebanks * A class representing a key=value entry for simple VCF header types */ -public abstract class VCFSimpleHeaderLine extends VCFHeaderLine implements VCFNamedHeaderLine { +public class VCFSimpleHeaderLine extends VCFHeaderLine implements VCFIDHeaderLine { public enum SupportedHeaderLineType { - FILTER, ALT; + FILTER, GENERIC; } private String name; - private String description; + private Map genericFields = new LinkedHashMap(); + // our type of line, i.e. filter, alt, etc private final SupportedHeaderLineType lineType; @@ -25,18 +26,29 @@ public abstract class VCFSimpleHeaderLine extends VCFHeaderLine implements VCFNa /** * create a VCF filter header line * - * @param name the name for this header line - * @param description the description for this header line - * @param lineType the header line type + * @param name the name for this header line + * @param genericFields other fields for this header line + * @param lineType the header line type + */ + public VCFSimpleHeaderLine(String name, Map genericFields, SupportedHeaderLineType lineType) { + super(lineType.toString(), ""); + this.lineType = lineType; + initialize(name, genericFields); + } + + /** + * create a VCF filter header line + * + * @param name the name for this header line + * @param description description for this header line + * @param lineType the header line type */ public VCFSimpleHeaderLine(String name, String description, SupportedHeaderLineType lineType) { super(lineType.toString(), ""); this.lineType = lineType; - this.name = name; - this.description = description; - - if ( name == null || description == null ) - throw new IllegalArgumentException(String.format("Invalid VCFSimpleHeaderLine: key=%s name=%s desc=%s", super.getKey(), name, description )); + Map map = new LinkedHashMap(1); + map.put("Description", description); + initialize(name, map); } /** @@ -44,22 +56,29 @@ public abstract class VCFSimpleHeaderLine extends VCFHeaderLine implements VCFNa * * @param line the header line * @param version the vcf header version - * @param lineType the header line type + * @param lineType the header line type + * @param expectedTagOrdering the tag ordering expected for this header line */ - protected VCFSimpleHeaderLine(String line, VCFHeaderVersion version, SupportedHeaderLineType lineType) { + protected VCFSimpleHeaderLine(String line, VCFHeaderVersion version, SupportedHeaderLineType lineType, List expectedTagOrdering) { super(lineType.toString(), ""); this.lineType = lineType; - Map mapping = VCFHeaderLineTranslator.parseLine(version,line, Arrays.asList("ID","Description")); + Map mapping = VCFHeaderLineTranslator.parseLine(version, line, expectedTagOrdering); name = mapping.get("ID"); - description = mapping.get("Description"); - if ( description == null && ALLOW_UNBOUND_DESCRIPTIONS ) // handle the case where there's no description provided - description = UNBOUND_DESCRIPTION; + initialize(name, mapping); + } + + protected void initialize(String name, Map genericFields) { + if ( name == null || genericFields == null || genericFields.isEmpty() ) + throw new IllegalArgumentException(String.format("Invalid VCFSimpleHeaderLine: key=%s name=%s", super.getKey(), name)); + + this.name = name; + this.genericFields.putAll(genericFields); } protected String toStringEncoding() { - Map map = new LinkedHashMap(); + Map map = new LinkedHashMap(); map.put("ID", name); - map.put("Description", description); + map.putAll(genericFields); return lineType.toString() + "=" + VCFHeaderLine.toStringEncoding(map); } @@ -67,15 +86,21 @@ public abstract class VCFSimpleHeaderLine extends VCFHeaderLine implements VCFNa if ( !(o instanceof VCFSimpleHeaderLine) ) return false; VCFSimpleHeaderLine other = (VCFSimpleHeaderLine)o; - return name.equals(other.name) && - description.equals(other.description); + if ( !name.equals(other.name) || genericFields.size() != other.genericFields.size() ) + return false; + for ( Map.Entry entry : genericFields.entrySet() ) { + if ( !entry.getValue().equals(other.genericFields.get(entry.getKey())) ) + return false; + } + + return true; } - public String getName() { + public String getID() { return name; } - public String getDescription() { - return description; + public Map getGenericFields() { + return genericFields; } } \ No newline at end of file diff --git a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFUtils.java b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFUtils.java index 5bd6a9b32..238a06243 100755 --- a/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFUtils.java +++ b/public/java/src/org/broadinstitute/sting/utils/codecs/vcf/VCFUtils.java @@ -155,10 +155,10 @@ public class VCFUtils { for ( VCFHeader source : headers ) { //System.out.printf("Merging in header %s%n", source); for ( VCFHeaderLine line : source.getMetaData()) { - String key = line.getKey(); - if ( line instanceof VCFNamedHeaderLine) - key = key + "" + ((VCFNamedHeaderLine) line).getName(); + String key = line.getKey(); + if ( line instanceof VCFIDHeaderLine ) + key = key + "-" + ((VCFIDHeaderLine)line).getID(); if ( map.containsKey(key) ) { VCFHeaderLine other = map.get(key); @@ -166,8 +166,8 @@ public class VCFUtils { continue; else if ( ! line.getClass().equals(other.getClass()) ) throw new IllegalStateException("Incompatible header types: " + line + " " + other ); - else if ( line instanceof VCFFilterHeaderLine) { - String lineName = ((VCFFilterHeaderLine) line).getName(); String otherName = ((VCFFilterHeaderLine) other).getName(); + else if ( line instanceof VCFFilterHeaderLine ) { + String lineName = ((VCFFilterHeaderLine) line).getID(); String otherName = ((VCFFilterHeaderLine) other).getID(); if ( ! lineName.equals(otherName) ) throw new IllegalStateException("Incompatible header types: " + line + " " + other ); } else if ( line instanceof VCFCompoundHeaderLine ) {