public T repair(final T line) { final T standard = get(line.getID(), false); if ( standard != null ) { final boolean badCountType = line.getCountType() != standard.getCountType(); final boolean badCount = line.isFixedCount() && ! badCountType && line.getCount() != standard.getCount(); final boolean badType = line.getType() != standard.getType(); final boolean badDesc = ! line.getDescription().equals(standard.getDescription()); final boolean needsRepair = badCountType || badCount || badType || (REPAIR_BAD_DESCRIPTIONS && badDesc); if ( needsRepair ) { if ( GeneralUtils.DEBUG_MODE_ENABLED ) { System.err.println("Repairing standard header line for field " + line.getID() + " because" + (badCountType ? " -- count types disagree; header has " + line.getCountType() + " but standard is " + standard.getCountType() : "") + (badType ? " -- type disagree; header has " + line.getType() + " but standard is " + standard.getType() : "") + (badCount ? " -- counts disagree; header has " + line.getCount() + " but standard is " + standard.getCount() : "") + (badDesc ? " -- descriptions disagree; header has '" + line.getDescription() + "' but standard is '" + standard.getDescription() + "'": "")); } return standard; } else { return line; } } else { return line; } }
/** * returns true if we're equal to another compounder header line * @param o a compound header line * @return true if equal */ public boolean equals(Object o) { if ( !(o instanceof VCFCompoundHeaderLine) ) return false; VCFCompoundHeaderLine other = (VCFCompoundHeaderLine)o; return equalsExcludingDescription(other) && description.equals(other.description); }
public Configuration configure(VCFCompoundHeaderLine line) { this.otherFieldsMap.put(line.getKey(), Pair.of(line.getType(), line.getCountType())); return this; }
public Flag(final VCFCompoundHeaderLine headerLine, final Map<String, Integer> dict ) { super(headerLine, dict, BCF2Type.INT8); if ( ! headerLine.isFixedCount() || headerLine.getCount() != 0 ) throw new IllegalStateException("Flag encoder only supports atomic flags for field " + getField()); }
private BCF2FieldEncoder createFieldEncoder(final VCFCompoundHeaderLine line, final BCF2Encoder encoder, final Map<String, Integer> dict, final boolean createGenotypesEncoders ) { if ( createGenotypesEncoders && intGenotypeFieldAccessors.getAccessor(line.getID()) != null ) { if ( GeneralUtils.DEBUG_MODE_ENABLED && line.getType() != VCFHeaderLineType.Integer ) System.err.println("Warning: field " + line.getID() + " expected to encode an integer but saw " + line.getType() + " for record " + line); return new BCF2FieldEncoder.IntArray(line, dict); } else if ( createGenotypesEncoders && line.getID().equals(VCFConstants.GENOTYPE_KEY) ) { return new BCF2FieldEncoder.GenericInts(line, dict); } else { switch ( line.getType() ) { case Character: case String: return new BCF2FieldEncoder.StringOrCharacter(line, dict); case Flag: return new BCF2FieldEncoder.Flag(line, dict); case Float: return new BCF2FieldEncoder.Float(line, dict); case Integer: if ( line.isFixedCount() && line.getCount() == 1 ) return new BCF2FieldEncoder.AtomicInt(line, dict); else return new BCF2FieldEncoder.GenericInts(line, dict); default: throw new IllegalArgumentException("Unexpected type for field " + line.getID()); } } }
@Test(dataProvider = "RepairHeaderTest") public void testRepairHeaderTest(final RepairHeaderTest cfg) { final VCFHeader toRepair = new VCFHeader(Collections.singleton((VCFHeaderLine)cfg.original)); final VCFHeader repaired = VCFStandardHeaderLines.repairStandardHeaderLines(toRepair); VCFCompoundHeaderLine repairedLine = (VCFCompoundHeaderLine)repaired.getFormatHeaderLine(cfg.original.getID()); if ( repairedLine == null ) repairedLine = (VCFCompoundHeaderLine)repaired.getInfoHeaderLine(cfg.original.getID()); Assert.assertNotNull(repairedLine, "Repaired header didn't contain the expected line"); Assert.assertEquals(repairedLine.getID(), cfg.expectedResult.getID()); Assert.assertEquals(repairedLine.getType(), cfg.expectedResult.getType()); Assert.assertEquals(repairedLine.getCountType(), cfg.expectedResult.getCountType()); if ( repairedLine.getCountType() == VCFHeaderLineCount.INTEGER ) { Assert.assertEquals(repairedLine.getCount(), cfg.expectedResult.getCount()); } } }
private final Map<String, Object> fullyDecodeAttributes(final Map<String, Object> attributes, final VCFHeader header, final boolean lenientDecoding) { final Map<String, Object> newAttributes = new HashMap<>(10); for ( final Map.Entry<String, Object> attr : attributes.entrySet() ) { final String field = attr.getKey(); if ( field.equals(VCFConstants.GENOTYPE_FILTER_KEY) ) continue; // gross, FT is part of the extended attributes final VCFCompoundHeaderLine format = VariantContextUtils.getMetaDataForField(header, field); final Object decoded = decodeValue(field, attr.getValue(), format); if ( decoded != null && ! lenientDecoding && format.getCountType() != VCFHeaderLineCount.UNBOUNDED && format.getType() != VCFHeaderLineType.Flag ) { // we expect exactly the right number of elements final int obsSize = decoded instanceof List ? ((List) decoded).size() : 1; final int expSize = format.getCount(this); if ( obsSize != expSize ) { throw new TribbleException.InvalidHeader("Discordant field size detected for field " + field + " at " + getContig() + ":" + getStart() + ". Field had " + obsSize + " values " + "but the header says this should have " + expSize + " values based on header record " + format); } } newAttributes.put(field, decoded); } return newAttributes; }
if (!(compLine).equalsExcludingDescription(compOther)) { if (compLine.getType().equals(compOther.getType())) { compOther.setNumberToUnbounded(); } else if (compLine.getType() == VCFHeaderLineType.Integer && compOther.getType() == VCFHeaderLineType.Float) { } else if (compLine.getType() == VCFHeaderLineType.Float && compOther.getType() == VCFHeaderLineType.Integer) { if (!compLine.getDescription().equals(compOther.getDescription())) conflictWarner.warn(line, "Allowing unequal description fields through: keeping " + compOther + " excluding " + compLine); } else {
public final String getField() { return headerLine.getID(); }
/** * @return the number of elements, assuming this field has a constant number of elements. */ public int numElements() { return headerLine.getCount(); }
private final Object decodeOne(final String field, final String string, final VCFCompoundHeaderLine format) { try { if ( string.equals(VCFConstants.MISSING_VALUE_v4) ) return null; else { switch ( format.getType() ) { case Character: return string; case Flag: final boolean b = Boolean.valueOf(string) || string.equals("1"); if ( b == false ) throw new TribbleException("VariantContext FLAG fields " + field + " cannot contain false values" + " as seen at " + getContig() + ":" + getStart()); return b; case String: return string; case Integer: return Integer.valueOf(string); case Float: return Double.valueOf(string); default: throw new TribbleException("Unexpected type for field" + field); } } } catch (NumberFormatException e) { throw new TribbleException("Could not decode field " + field + " with value " + string + " of declared type " + format.getType()); } }
protected final VCFHeaderLineCount getCountType() { return headerLine.getCountType(); }
throw new TribbleException(mapping.get("Type") + " is not a valid type in the VCF specification (note that types are case-sensitive)"); if (type == VCFHeaderLineType.Flag && !allowFlagValues()) throw new IllegalArgumentException("Flag is an unsupported type for this kind of field"); validate();
public int getCount() { if (!isFixedCount()) throw new TribbleException("Asking for header line count when type is not an integer"); return count; }
private void validate() { if (type != VCFHeaderLineType.Flag && countType == VCFHeaderLineCount.INTEGER && count <= 0) throw new IllegalArgumentException(String.format("Invalid count number, with fixed count the number should be 1 or higher: key=%s name=%s type=%s desc=%s lineType=%s count=%s", getKey(), name, type, description, lineType, count)); if (name == null || type == null || description == null || lineType == null) throw new IllegalArgumentException(String.format("Invalid VCFCompoundHeaderLine: key=%s name=%s type=%s desc=%s lineType=%s", getKey(), name, type, description, lineType)); if (name.contains("<") || name.contains(">")) throw new IllegalArgumentException("VCFHeaderLine: ID cannot contain angle brackets"); if (name.contains("=")) throw new IllegalArgumentException("VCFHeaderLine: ID cannot contain an equals sign"); if (type == VCFHeaderLineType.Flag && count != 0) { count = 0; if (GeneralUtils.DEBUG_MODE_ENABLED) { System.err.println("FLAG fields must have a count value of 0, but saw " + count + " for header line " + getID() + ". Changing it to 0 inside the code"); } } }
private BCF2FieldEncoder createFieldEncoder(final VCFCompoundHeaderLine line, final BCF2Encoder encoder, final Map<String, Integer> dict, final boolean createGenotypesEncoders ) { if ( createGenotypesEncoders && intGenotypeFieldAccessors.getAccessor(line.getID()) != null ) { if ( GeneralUtils.DEBUG_MODE_ENABLED && line.getType() != VCFHeaderLineType.Integer ) System.err.println("Warning: field " + line.getID() + " expected to encode an integer but saw " + line.getType() + " for record " + line); return new BCF2FieldEncoder.IntArray(line, dict); } else if ( createGenotypesEncoders && line.getID().equals(VCFConstants.GENOTYPE_KEY) ) { return new BCF2FieldEncoder.GenericInts(line, dict); } else { switch ( line.getType() ) { case Character: case String: return new BCF2FieldEncoder.StringOrCharacter(line, dict); case Flag: return new BCF2FieldEncoder.Flag(line, dict); case Float: return new BCF2FieldEncoder.Float(line, dict); case Integer: if ( line.isFixedCount() && line.getCount() == 1 ) return new BCF2FieldEncoder.AtomicInt(line, dict); else return new BCF2FieldEncoder.GenericInts(line, dict); default: throw new IllegalArgumentException("Unexpected type for field " + line.getID()); } } }
final String id = line.getID(); if(id.equals(VCFConstants.GENOTYPE_KEY)) return line.getType().equals(VCFHeaderLineType.String) && line.getCount()==1 ; else if(id.equals(VCFConstants.GENOTYPE_QUALITY_KEY)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCount()==1; else if(id.equals(VCFConstants.DEPTH_KEY)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCount()==1; else if(id.equals(VCFConstants.GENOTYPE_PL_KEY)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCountType().equals(VCFHeaderLineCount.G); else if(id.equals(VCFConstants.GENOTYPE_ALLELE_DEPTHS)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCountType().equals(VCFHeaderLineCount.R); else if(id.equals(VCFConstants.GENOTYPE_FILTER_KEY)) return line.getType().equals(VCFHeaderLineType.String) && line.getCountType().equals(VCFHeaderLineCount.UNBOUNDED); else if(id.equals(VCFConstants.PHASE_QUALITY_KEY)) return line.getType().equals(VCFHeaderLineType.Float) && line.getCount()==1; else if(id.equals(VCFConstants.END_KEY)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCount()==1; else if(id.equals(VCFConstants.DBSNP_KEY)) return line.getType().equals(VCFHeaderLineType.Flag) && line.getCount()==0; else if(id.equals(VCFConstants.DEPTH_KEY)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCount()==1; else if(id.equals(VCFConstants.STRAND_BIAS_KEY)) return line.getType().equals(VCFHeaderLineType.Float) && line.getCount()==1; else if(id.equals(VCFConstants.ALLELE_FREQUENCY_KEY)) return line.getType().equals(VCFHeaderLineType.Float) && line.getCountType().equals(VCFHeaderLineCount.A); else if(id.equals(VCFConstants.ALLELE_COUNT_KEY)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCountType().equals(VCFHeaderLineCount.A); else if(id.equals(VCFConstants.ALLELE_NUMBER_KEY)) return line.getType().equals(VCFHeaderLineType.Integer) && line.getCount()==1;
private final Map<String, Object> fullyDecodeAttributes(final Map<String, Object> attributes, final VCFHeader header, final boolean lenientDecoding) { final Map<String, Object> newAttributes = new HashMap<>(10); for ( final Map.Entry<String, Object> attr : attributes.entrySet() ) { final String field = attr.getKey(); if ( field.equals(VCFConstants.GENOTYPE_FILTER_KEY) ) continue; // gross, FT is part of the extended attributes final VCFCompoundHeaderLine format = VariantContextUtils.getMetaDataForField(header, field); final Object decoded = decodeValue(field, attr.getValue(), format); if ( decoded != null && ! lenientDecoding && format.getCountType() != VCFHeaderLineCount.UNBOUNDED && format.getType() != VCFHeaderLineType.Flag ) { // we expect exactly the right number of elements final int obsSize = decoded instanceof List ? ((List) decoded).size() : 1; final int expSize = format.getCount(this); if ( obsSize != expSize ) { throw new TribbleException.InvalidHeader("Discordant field size detected for field " + field + " at " + getContig() + ":" + getStart() + ". Field had " + obsSize + " values " + "but the header says this should have " + expSize + " values based on header record " + format); } } newAttributes.put(field, decoded); } return newAttributes; }
if (! (compLine).equalsExcludingDescription(compOther) ) { if ( compLine.getType().equals(compOther.getType()) ) { compOther.setNumberToUnbounded(); } else if ( compLine.getType() == VCFHeaderLineType.Integer && compOther.getType() == VCFHeaderLineType.Float ) { } else if ( compLine.getType() == VCFHeaderLineType.Float && compOther.getType() == VCFHeaderLineType.Integer ) { if ( ! compLine.getDescription().equals(compOther.getDescription()) ) conflictWarner.warn(line, "Allowing unequal description fields through: keeping " + compOther + " excluding " + compLine); } else {
public Flag(final VCFCompoundHeaderLine headerLine, final Map<String, Integer> dict ) { super(headerLine, dict, BCF2Type.INT8); if ( ! headerLine.isFixedCount() || headerLine.getCount() != 0 ) throw new IllegalStateException("Flag encoder only supports atomic flags for field " + getField()); }