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.
This commit is contained in:
parent
069ccdfdd4
commit
2324c5a74f
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ public class VariantAnnotator extends RodWalker<Integer, Integer> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -216,12 +216,12 @@ public class VariantsToVCF extends RodWalker<Integer, Integer> {
|
|||
Set<VCFHeaderLine> hInfo = new HashSet<VCFHeaderLine>();
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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<String, String> genericFields = new LinkedHashMap<String, String>();
|
||||
|
||||
|
||||
// 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<String, String> 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<String, String> map = new LinkedHashMap<String, String>(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<String> expectedTagOrdering) {
|
||||
super(lineType.toString(), "");
|
||||
this.lineType = lineType;
|
||||
Map<String,String> mapping = VCFHeaderLineTranslator.parseLine(version,line, Arrays.asList("ID","Description"));
|
||||
Map<String, String> 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<String, String> 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<String,Object> map = new LinkedHashMap<String,Object>();
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
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<String, String> 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<String, String> getGenericFields() {
|
||||
return genericFields;
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue