/** Parse fields */ void parseFields() { if (fields != null) return; try { fields = new HashMap<String, String>(); if (values.isEmpty()) return; // Values are missing? Nothing to do String fieldNames[] = vcfEntry.getFormat().split(":"); String fieldValues[] = values.split(":"); int min = Math.min(fieldValues.length, fieldNames.length); for (int i = 0; i < min; i++) { String name = fieldNames[i]; String value = fieldValues[i]; fields.put(name, value); if (name.equals("GT")) parseGt(value); else if (name.equals("PL")) parsePl(value); else if (name.equals("GQ")) gQuality = Gpr.parseDoubleSafe(value); } } catch (Exception e) { throw new RuntimeException( "Error parsing fields on line:\n\tFormat: '" + vcfEntry.getFormat() + "'\n\tValues: '" + values + "'", e); } }
/** * Get genotype string by index * * <p>WARNING: If the genotype is missing, it returns an empty string. E.g.: './.' -> * getGenotype(0) = "" * * @return */ public String getGenotype(int idx) { parseFields(); // Lazy parse if (genotype == null) return ""; // Missing genotype int num = genotype[idx]; if (num < 0) return ""; // Missing genotype return num == 0 ? vcfEntry.getRef() : vcfEntry.getAlts()[num - 1]; }
/** * Is any genotype different than REF? Note: This is calculated for the most likely genotype (GT * field) * * @return */ public boolean isVariant() { if (values.isEmpty()) return false; parseFields(); // Lazy parse if (genotype != null) { // Any genotype is different than REF? => This is a variant for (int i = 0; i < genotype.length; i++) if (genotype[i] > 0) return true; return false; } return vcfEntry.isVariant(); }
/** * Is the most likely genotype homozygous? * * @return */ public boolean isHomozygous() { parseFields(); // Lazy parse if (genotype != null) { // Any genotype is different? => not homozygous for (int i = 1; i < genotype.length; i++) if (genotype[i] != genotype[i - 1]) return false; return true; // Homozygous } return vcfEntry.isBiAllelic(); }
/** * Parse GT field * * @param value */ void parseGt(String value) { String gtStr[] = null; if (value.indexOf('|') >= 0) { gtStr = value.split("\\|"); phased = true; // Phased } else { gtStr = value.split("/"); phased = false; // Unphased } // Create fields genotype = new int[gtStr.length]; for (int i = 0; i < genotype.length; i++) if (gtStr[i].isEmpty() || gtStr[i].equals(".")) genotype[i] = -1; // Genotype '-1' means missing values else { genotype[i] = Gpr.parseIntSafe(gtStr[i]); // Sanity check if ((genotype[i] - 1) >= vcfEntry.getAlts().length) { boolean plural = vcfEntry.getAlts().length > 1; throw new RuntimeException( "Error: Bad genotype field '" + value + "'. Genotype says '" + genotype[i] + "' but there " + (plural ? "are" : "is") + " only '" + vcfEntry.getAlts().length + "' allele" + (plural ? "s" : "") + " ('" + vcfEntry.getAltsStr() + "')."); } } }
/** * Return genotypes as string (e.g. "A/C") * * @return */ public String getGenotypeStr() { parseFields(); // Lazy parse StringBuilder sb = new StringBuilder(); if (genotype != null) { for (int i = 0; i < genotype.length; i++) { int num = genotype[i]; String gen = "."; if (num == 0) gen = vcfEntry.getRef(); else if (num > 0) gen = vcfEntry.getAlts()[num - 1]; sb.append(gen); if (i < (genotype.length - 1)) { if (isPhased()) sb.append("|"); else sb.append("/"); } } } return sb.toString(); }
/** * Add a name=value pair WARNING: This method does NOT change the FORMAT field. Use * VcfEntry.addFormat() method * * @param name * @param value */ public void add(String name, String value) { // Sanity check value if ((value.indexOf(' ') >= 0) // || (value.indexOf('\t') >= 0) // || (value.indexOf('=') >= 0) // ) throw new RuntimeException( "Error: Attempt to add a value containin illegal characters: no white-space, semi-colons, or equals-signs permitted\n\tname : '" + name + "'\n\tvalue : '" + value + "'"); // Sanity check format if (vcfEntry.getFormat().indexOf(name) < 0) throw new RuntimeException( "Error Attempt to add a field (name=" + name + ") that is not present in FORMAT field. Use VcfEntry.addFormat() method first!"); // Finally, add the values values += (values.endsWith(":") ? "" : ":") + value; // Add to value string if (fields != null) fields.put(name, value); // Add value to hash (if needed) }