From 1d86dd7fd19237114e119232d742708475739b14 Mon Sep 17 00:00:00 2001 From: depristo Date: Thu, 4 Feb 2010 20:55:49 +0000 Subject: [PATCH] Interface changes following Matt's advice. VariantContexts are now immutable, and there are special mutable versions, in case you need to change things. AttributedObject now a InferredGeneticContext and package protected. VariantContexts are now named, which makes them easier to use with the rod system git-svn-id: file:///humgen/gsa-scr1/gsa-engineering/svn_contents/trunk@2780 348d0f76-0448-11de-a6fe-93d51630548a --- .../oneoffprojects/variantcontext/Allele.java | 49 ++- .../variantcontext/Genotype.java | 145 +++----- ...bject.java => InferredGeneticContext.java} | 95 +++--- .../variantcontext/MutableGenotype.java | 71 ++++ .../variantcontext/MutableVariantContext.java | 211 ++++++++++++ .../TestVariantContextWalker.java | 4 +- .../variantcontext/VariantContext.java | 320 +++++------------- .../VariantContextAdaptors.java | 59 ++-- .../variantcontext/VariantContextUtils.java | 8 +- .../MendelianViolationEvaluator.java | 2 +- .../varianteval2/VariantEval2Walker.java | 2 +- .../gatk/walkers/diagnostics/SNPDensity.java | 2 +- .../variantcontext/VariantContextTest.java | 84 +++-- 13 files changed, 599 insertions(+), 453 deletions(-) rename java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/{AttributedObject.java => InferredGeneticContext.java} (63%) create mode 100755 java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableGenotype.java create mode 100755 java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableVariantContext.java diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Allele.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Allele.java index 000487ee4..f6e5a062f 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Allele.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Allele.java @@ -3,9 +3,13 @@ package org.broadinstitute.sting.oneoffprojects.variantcontext; import org.broadinstitute.sting.utils.BaseUtils; import java.util.Arrays; +import java.util.List; +import java.util.ArrayList; +import java.util.Collection; /** - * @author ebanks, depristo + * Immutable representation of an allele + * * Types of alleles: * * Ref: a t C g a // C is the reference base @@ -68,6 +72,8 @@ import java.util.Arrays; * * Note that Alleles store all bases as bytes, in **UPPER CASE**. So 'atc' == 'ATC' from the perspective of an * Allele. + + * @author ebanks, depristo */ public class Allele { private static final byte[] EMPTY_ALLELE_BASES = new byte[0]; @@ -200,6 +206,7 @@ public class Allele { * @return the segregating bases */ public byte[] getBases() { return bases; } + // todo -- can we make this immutable? /** * @param other the other allele @@ -256,4 +263,44 @@ public class Allele { public int length() { return bases.length; } + + // --------------------------------------------------------------------------------------------------------- + // + // useful static functions + // + // --------------------------------------------------------------------------------------------------------- + + public static Allele getMatchingAllele(Collection allAlleles, String alleleBases) { + return getMatchingAllele(allAlleles, alleleBases.getBytes()); + } + + public static Allele getMatchingAllele(Collection allAlleles, byte[] alleleBases) { + for ( Allele a : allAlleles ) { + if ( a.basesMatch(alleleBases) ) { + return a; + } + } + + return null; // couldn't find anything + } + + public static List resolveAlleles(List possibleAlleles, List alleleStrings) { + List myAlleles = new ArrayList(alleleStrings.size()); + + for ( String alleleString : alleleStrings ) { + Allele allele = getMatchingAllele(possibleAlleles, alleleString); + + if ( allele == null ) { + if ( Allele.wouldBeNoCallAllele(alleleString.getBytes()) ) { + allele = new Allele(alleleString); + } else { + throw new IllegalArgumentException("Allele " + alleleString + " not present in the list of alleles " + possibleAlleles); + } + } + + myAlleles.add(allele); + } + + return myAlleles; + } } diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Genotype.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Genotype.java index 7435c157d..df1667456 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Genotype.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/Genotype.java @@ -1,49 +1,31 @@ package org.broadinstitute.sting.oneoffprojects.variantcontext; import org.broadinstitute.sting.utils.Utils; +import org.broadinstitute.sting.utils.StingException; import java.util.*; /** - * @author ebanks - *

- * Class Genotype - *

- * This class emcompasses all the basic information about a genotype + * This class emcompasses all the basic information about a genotype. It is immutable. + * + * @author Mark DePristo */ -public class Genotype extends AttributedObject { - private List alleles = new ArrayList(); - private String sampleName = null; +public class Genotype { + protected InferredGeneticContext commonInfo; + protected List alleles = new ArrayList(); - // todo -- do genotypes need to have locations? Or is it sufficient to have an - // todo -- associated VC with a location? One nasty implication is that people will have to - // todo -- pass around both a Variant Context and genotypes. Although users can always just package up - // the associated genotypes into the VC itself. - - // todo -- this should really be something like subcontext -- fixme, maybe move into converter code - - // todo -- add flat variant manager class that is available via refmetadatatracker and provides simple - // access to VariantContexts that can be obtained from rod tracks. Add simple functions to get - // first record, all records, only those starting at current locus, etc. to deal with dbSNP monstrosity - - // todo -- add name to variant context - public Genotype(VariantContext vc, List alleles, String sampleName, double negLog10PError) { - this(resolveAlleles(vc, alleles), sampleName, negLog10PError); + public Genotype(String sampleName, List alleles, double negLog10PError, Set filters, Map attributes) { + this.alleles = Collections.unmodifiableList(alleles); + commonInfo = new InferredGeneticContext(sampleName, negLog10PError, filters, attributes); + validate(); } - public Genotype(VariantContext vc, List alleles, String sampleName) { - this(resolveAlleles(vc, alleles), sampleName); + public Genotype(String sampleName, List alleles, double negLog10PError) { + this(sampleName, alleles, negLog10PError, null, null); } - public Genotype(List alleles, String sampleName, double negLog10PError) { - setAlleles(alleles); - setSampleName(sampleName); - setNegLog10PError(negLog10PError); - } - - public Genotype(List alleles, String sampleName) { - setAlleles(alleles); - setSampleName(sampleName); + public Genotype(String sampleName, List alleles) { + this(sampleName, alleles, InferredGeneticContext.NO_NEG_LOG_10PERROR, null, null); } @@ -60,7 +42,7 @@ public class Genotype extends AttributedObject { if ( a.equals(allele) ) al.add(a); - return al; + return Collections.unmodifiableList(al); } public Allele getAllele(int i) { @@ -68,6 +50,7 @@ public class Genotype extends AttributedObject { } private final static String ALLELE_SEPARATOR = "/"; + public String getGenotypeString() { return Utils.join(ALLELE_SEPARATOR, getAllelesString()); } @@ -110,7 +93,7 @@ public class Genotype extends AttributedObject { /** * @return true if all observed alleles are the same (regardless of whether they are ref or alt) */ - public boolean isHom() { return isHomRef() || isHomVar(); } + public boolean isHom() { return isHomRef() || isHomVar(); } public boolean isHomRef() { return getType() == Type.HOM_REF; } public boolean isHomVar() { return getType() == Type.HOM_VAR; } @@ -124,41 +107,7 @@ public class Genotype extends AttributedObject { */ public boolean isNoCall() { return getType() == Type.NO_CALL; } -// /** -// * @return true if this is a variant genotype, false if it's reference -// */ -// public boolean isVariant() { -// for ( Allele allele : alleles ) { -// if ( allele.isNonReference() ) -// return true; -// } -// return false; -// } - - /** - * @return the sample name - */ - public String getSampleName() { - return sampleName; - } - - /** - * Sets the sample name - * - * @param sampleName the sample name - */ - public void setSampleName(String sampleName) { - if ( sampleName == null ) throw new IllegalArgumentException("Sample name cannot be null " + this); - this.sampleName = sampleName; - } - - /** - * - * @param alleles - */ - public void setAlleles(List alleles) { - this.alleles.clear(); - + public void validate() { // todo -- add validation checking here if ( alleles == null ) throw new IllegalArgumentException("BUG: alleles cannot be null in setAlleles"); @@ -168,35 +117,6 @@ public class Genotype extends AttributedObject { for ( Allele allele : alleles ) { nNoCalls += allele.isNoCall() ? 1 : 0; } if ( nNoCalls > 0 && nNoCalls != alleles.size() ) throw new IllegalArgumentException("BUG: alleles include some No Calls and some Calls, an illegal state " + this); - - for ( Allele allele : alleles ) { - addAllele(allele); - } - } - - public void addAllele(Allele allele) { - if ( allele == null ) throw new IllegalArgumentException("BUG: Cannot add a null allele to a genotype"); - this.alleles.add(allele); - } - - - private static List resolveAlleles(VariantContext vc, List alleleStrings) { - List alleles = new ArrayList(); - for ( String alleleString : alleleStrings ) { - Allele allele = vc.getAllele(alleleString); - - if ( allele == null ) { - if ( Allele.wouldBeNoCallAllele(alleleString.getBytes()) ) { - allele = new Allele(alleleString); - } else { - throw new IllegalArgumentException("Allele " + alleleString + " not present in the list of alleles in VariantContext " + vc); - } - } - - alleles.add(allele); - } - - return alleles; } public String toString() { @@ -243,4 +163,31 @@ public class Genotype extends AttributedObject { return true; } + + // --------------------------------------------------------------------------------------------------------- + // + // get routines to access context info fields + // + // --------------------------------------------------------------------------------------------------------- + public String getSampleName() { return commonInfo.getName(); } + public Set getFilters() { return commonInfo.getFilters(); } + public boolean isFiltered() { return commonInfo.isFiltered(); } + public boolean isNotFiltered() { return commonInfo.isNotFiltered(); } + public boolean hasNegLog10PError() { return commonInfo.hasNegLog10PError(); } + public double getNegLog10PError() { return commonInfo.getNegLog10PError(); } + + public Map getAttributes() { return commonInfo.getAttributes(); } + public boolean hasAttribute(String key) { return commonInfo.hasAttribute(key); } + public Object getAttribute(String key) { return commonInfo.getAttribute(key); } + + public Object getAttribute(String key, Object defaultValue) { + return commonInfo.getAttribute(key, defaultValue); + } + + public String getAttributeAsString(String key) { return commonInfo.getAttributeAsString(key); } + public String getAttributeAsString(String key, String defaultValue) { return commonInfo.getAttributeAsString(key, defaultValue); } + public int getAttributeAsInt(String key) { return commonInfo.getAttributeAsInt(key); } + public int getAttributeAsInt(String key, int defaultValue) { return commonInfo.getAttributeAsInt(key, defaultValue); } + public double getAttributeAsDouble(String key) { return commonInfo.getAttributeAsDouble(key); } + public double getAttributeAsDouble(String key, double defaultValue) { return commonInfo.getAttributeAsDouble(key, defaultValue); } } \ No newline at end of file diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/AttributedObject.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/InferredGeneticContext.java similarity index 63% rename from java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/AttributedObject.java rename to java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/InferredGeneticContext.java index f28d0a278..085c2d016 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/AttributedObject.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/InferredGeneticContext.java @@ -7,31 +7,51 @@ import java.util.*; /** - * Common superclass of VariantContext and Genotype + * Common utility routines for VariantContext and Genotype * * @author depristo */ -public abstract class AttributedObject { - public static final double NO_NEG_LOG_10PERROR = 0.0; +final class InferredGeneticContext { + public static final double NO_NEG_LOG_10PERROR = Double.MAX_VALUE; // todo -- is this really safe? + private double negLog10PError = NO_NEG_LOG_10PERROR; - private Set filters = new HashSet(); + private String name = null; + private Set filters = new HashSet(); + private Map attributes = new HashMap(); - private Map attributes = new HashMap(); +// public InferredGeneticContext(String name) { +// this.name = name; +// } +// +// public InferredGeneticContext(String name, double negLog10PError) { +// this(name); +// setNegLog10PError(negLog10PError); +// } - public AttributedObject() { } - - public AttributedObject(double negLog10PError) { + public InferredGeneticContext(String name, double negLog10PError, Set filters, Map attributes) { + this.name = name; setNegLog10PError(negLog10PError); + if ( filters != null ) + setFilters(filters); + if ( attributes != null ) + setAttributes(attributes); } - public AttributedObject(Map attributes) { - setAttributes(attributes); + /** + * @return the name + */ + public String getName() { + return name; } - public AttributedObject(Map attributes, double negLog10PError) { - this(attributes); - - setNegLog10PError(negLog10PError); + /** + * Sets the name + * + * @param name the name associated with this information + */ + public void setName(String name) { + if ( name == null ) throw new IllegalArgumentException("Name cannot be null " + this); + this.name = name; } @@ -41,8 +61,8 @@ public abstract class AttributedObject { // // --------------------------------------------------------------------------------------------------------- - public Set getFilters() { - return filters; + public Set getFilters() { + return Collections.unmodifiableSet(filters); } public boolean isFiltered() { @@ -53,15 +73,15 @@ public abstract class AttributedObject { return ! isFiltered(); } - public void addFilter(Object filter) { + public void addFilter(String filter) { if ( filter == null ) throw new IllegalArgumentException("BUG: Attempting to add null filter " + this); if ( getFilters().contains(filter) ) throw new IllegalArgumentException("BUG: Attempting to add duplicate filter " + filter + " at " + this); filters.add(filter); } - public void addFilters(Collection filters) { + public void addFilters(Collection filters) { if ( filters == null ) throw new IllegalArgumentException("BUG: Attempting to add null filters at" + this); - for ( Object f : filters ) + for ( String f : filters ) addFilter(f); } @@ -69,7 +89,7 @@ public abstract class AttributedObject { filters.clear(); } - public void setFilters(Collection filters) { + public void setFilters(Collection filters) { clearFilters(); addFilters(filters); } @@ -109,41 +129,41 @@ public abstract class AttributedObject { /** * @return the attribute map */ - public Map getAttributes() { - return attributes; + public Map getAttributes() { + return Collections.unmodifiableMap(attributes); } // todo -- define common attributes as enum - public void setAttributes(Map map) { + public void setAttributes(Map map) { this.attributes.clear(); putAttributes(map); } - public void putAttribute(Object key, Object value) { + public void putAttribute(String key, Object value) { putAttribute(key, value, false); } - public void putAttribute(Object key, Object value, boolean allowOverwrites) { + public void putAttribute(String key, Object value, boolean allowOverwrites) { if ( hasAttribute(key) && ! allowOverwrites ) throw new StingException("Attempting to overwrite key->value binding: key = " + key + " this = " + this); this.attributes.put(key, value); } - public void removeAttribute(Object key) { + public void removeAttribute(String key) { this.attributes.remove(key); } - public void putAttributes(Map map) { + public void putAttributes(Map map) { if ( map != null ) { - for ( Map.Entry elt : map.entrySet() ) { + for ( Map.Entry elt : map.entrySet() ) { putAttribute(elt.getKey(), elt.getValue()); } } } - public boolean hasAttribute(Object key) { + public boolean hasAttribute(String key) { return attributes.containsKey(key); } @@ -156,11 +176,11 @@ public abstract class AttributedObject { * * @return the attribute value for the given key (or null if not set) */ - public Object getAttribute(Object key) { + public Object getAttribute(String key) { return attributes.get(key); } - public Object getAttribute(Object key, Object defaultValue) { + public Object getAttribute(String key, Object defaultValue) { if ( hasAttribute(key) ) return attributes.get(key); else @@ -176,12 +196,11 @@ public abstract class AttributedObject { // return selected; // } + public String getAttributeAsString(String key) { return (String)getAttribute(key); } + public int getAttributeAsInt(String key) { return (Integer)getAttribute(key); } + public double getAttributeAsDouble(String key) { return (Double)getAttribute(key); } - public String getAttributeAsString(Object key) { return (String)getAttribute(key); } - public int getAttributeAsInt(Object key) { return (Integer)getAttribute(key); } - public double getAttributeAsDouble(Object key) { return (Double)getAttribute(key); } - - public String getAttributeAsString(Object key, String defaultValue) { return (String)getAttribute(key, defaultValue); } - public int getAttributeAsInt(Object key, int defaultValue) { return (Integer)getAttribute(key, defaultValue); } - public double getAttributeAsDouble(Object key, double defaultValue) { return (Double)getAttribute(key, defaultValue); } + public String getAttributeAsString(String key, String defaultValue) { return (String)getAttribute(key, defaultValue); } + public int getAttributeAsInt(String key, int defaultValue) { return (Integer)getAttribute(key, defaultValue); } + public double getAttributeAsDouble(String key, double defaultValue) { return (Double)getAttribute(key, defaultValue); } } \ No newline at end of file diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableGenotype.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableGenotype.java new file mode 100755 index 000000000..dc08504db --- /dev/null +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableGenotype.java @@ -0,0 +1,71 @@ +package org.broadinstitute.sting.oneoffprojects.variantcontext; + +import org.broadinstitute.sting.utils.Utils; + +import java.util.*; + +/** + * This class emcompasses all the basic information about a genotype. It is immutable. + * + * @author Mark DePristo + */ +public class MutableGenotype extends Genotype { + public MutableGenotype(Genotype parent) { + super(parent.getSampleName(), parent.getAlleles(), parent.getNegLog10PError(), parent.getFilters(), parent.getAttributes()); + } + + // todo -- add rest of genotype constructors here + public MutableGenotype(String sampleName, List alleles, double negLog10PError) { + super(sampleName, alleles, negLog10PError); + } + + public Genotype unmodifiableGenotype() { + return new Genotype(getSampleName(), getAlleles(), getNegLog10PError(), getFilters(), getAttributes()); + } + + + /** + * + * @param alleles + */ + public void setAlleles(List alleles) { + this.alleles.clear(); + + // todo -- add validation checking here + + if ( alleles == null ) throw new IllegalArgumentException("BUG: alleles cannot be null in setAlleles"); + if ( alleles.size() == 0) throw new IllegalArgumentException("BUG: alleles cannot be of size 0 in setAlleles"); + + int nNoCalls = 0; + for ( Allele allele : alleles ) { nNoCalls += allele.isNoCall() ? 1 : 0; } + if ( nNoCalls > 0 && nNoCalls != alleles.size() ) + throw new IllegalArgumentException("BUG: alleles include some No Calls and some Calls, an illegal state " + this); + + for ( Allele allele : alleles ) { + addAllele(allele); + } + } + + public void addAllele(Allele allele) { + if ( allele == null ) throw new IllegalArgumentException("BUG: Cannot add a null allele to a genotype"); + this.alleles.add(allele); + } + + // --------------------------------------------------------------------------------------------------------- + // + // InferredGeneticContext mutation operators + // + // --------------------------------------------------------------------------------------------------------- + public void setName(String name) { commonInfo.setName(name); } + public void addFilter(String filter) { commonInfo.addFilter(filter); } + public void addFilters(Collection filters) { commonInfo.addFilters(filters); } + public void clearFilters() { commonInfo.clearFilters(); } + public void setFilters(Collection filters) { commonInfo.setFilters(filters); } + public void setAttributes(Map map) { commonInfo.setAttributes(map); } + public void putAttribute(String key, Object value) { commonInfo.putAttribute(key, value); } + public void removeAttribute(String key) { commonInfo.removeAttribute(key); } + public void putAttributes(Map map) { commonInfo.putAttributes(map); } + public void setNegLog10PError(double negLog10PError) { commonInfo.setNegLog10PError(negLog10PError); } + public void putAttribute(String key, Object value, boolean allowOverwrites) { commonInfo.putAttribute(key, value, allowOverwrites); } + +} \ No newline at end of file diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableVariantContext.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableVariantContext.java new file mode 100755 index 000000000..59bb6877e --- /dev/null +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/MutableVariantContext.java @@ -0,0 +1,211 @@ +package org.broadinstitute.sting.oneoffprojects.variantcontext; + +import org.broadinstitute.sting.utils.GenomeLoc; +import org.broadinstitute.sting.utils.StingException; +import org.broadinstitute.sting.utils.BaseUtils; + +import java.util.*; + +/** + * Mutable version of VariantContext + * + * @author depristo + */ +public class MutableVariantContext extends VariantContext { + // --------------------------------------------------------------------------------------------------------- + // + // constructors + // + // --------------------------------------------------------------------------------------------------------- + + // todo -- add remaining context constructors + public MutableVariantContext(String name, GenomeLoc loc, Collection alleles, Collection genotypes, double negLog10PError, Set filters, Map attributes) { + super(name, loc, alleles, genotypes, negLog10PError, filters, attributes); + } + + public MutableVariantContext(String name, GenomeLoc loc, Collection alleles, Map genotypes, double negLog10PError, Set filters, Map attributes) { + super(name, loc, alleles, genotypes, negLog10PError, filters, attributes); + } + + public MutableVariantContext(String name, GenomeLoc loc, Collection alleles) { + this(name, loc, alleles, NO_GENOTYPES, InferredGeneticContext.NO_NEG_LOG_10PERROR, null, null); + } + + public MutableVariantContext(String name, GenomeLoc loc, Collection alleles, Collection genotypes) { + this(name, loc, alleles, genotypes, InferredGeneticContext.NO_NEG_LOG_10PERROR, null, null); + } + + public MutableVariantContext(VariantContext parent) { + this(parent.getName(), parent.getLocation(), parent.getAlleles(), parent.getGenotypes(), parent.getNegLog10PError(), parent.getFilters(), parent.getAttributes()); + } + + /** + * Sets the alleles segregating in this context to the collect of alleles. Each of which must be unique according + * to equals() in Allele. Validate() should be called when you are done modifying the context. + * + * @param alleles + */ + public void setAlleles(Collection alleles) { + this.alleles.clear(); + for ( Allele a : alleles ) + addAllele(a); + } + + /** + * Adds allele to the segregating allele list in this context to the collection of alleles. The new + * allele must be be unique according to equals() in Allele. + * Validate() should be called when you are done modifying the context. + * + * @param allele + */ + public void addAllele(Allele allele) { + final boolean allowDuplicates = false; // used to be a parameter + + type = null; + + for ( Allele a : alleles ) { + if ( a.basesMatch(allele) && ! allowDuplicates ) + throw new IllegalArgumentException("Duplicate allele added to VariantContext" + this); + } + + // we are a novel allele + alleles.add(allele); + } + + public void clearGenotypes() { + this.genotypes.clear(); + } + + /** + * Adds this single genotype to the context, not allowing duplicate genotypes to be added + * @param genotype + */ + public void addGenotypes(Genotype genotype) { + putGenotype(genotype.getSampleName(), genotype, false); + } + + /** + * Adds these genotypes to the context, not allowing duplicate genotypes to be added + * @param genotypes + */ + public void addGenotypes(Collection genotypes) { + for ( Genotype g : genotypes ) { + addGenotype(g); + } + } + + /** + * Adds these genotype to the context, not allowing duplicate genotypes to be added. + * @param genotypes + */ + public void addGenotypes(Map genotypes) { + + for ( Map.Entry elt : genotypes.entrySet() ) { + addGenotype(elt.getValue()); + } + } + + /** + * Adds these genotypes to the context. + * + * @param genotypes + */ + public void putGenotypes(Map genotypes) { + for ( Map.Entry g : genotypes.entrySet() ) + putGenotype(g.getKey(), g.getValue()); + } + + /** + * Adds these genotypes to the context. + * + * @param genotypes + */ + public void putGenotypes(Collection genotypes) { + for ( Genotype g : genotypes ) + putGenotype(g); + } + + /** + * Adds this genotype to the context, throwing an error if it's already bound. + * + * @param genotype + */ + public void addGenotype(Genotype genotype) { + addGenotype(genotype.getSampleName(), genotype); + } + + /** + * Adds this genotype to the context, throwing an error if it's already bound. + * + * @param genotype + */ + public void addGenotype(String sampleName, Genotype genotype) { + putGenotype(sampleName, genotype, false); + } + + /** + * Adds this genotype to the context. + * + * @param genotype + */ + public void putGenotype(Genotype genotype) { + putGenotype(genotype.getSampleName(), genotype); + } + + /** + * Adds this genotype to the context. + * + * @param genotype + */ + public void putGenotype(String sampleName, Genotype genotype) { + putGenotype(sampleName, genotype, true); + } + + private void putGenotype(String sampleName, Genotype genotype, boolean allowOverwrites) { + if ( hasGenotype(sampleName) && ! allowOverwrites ) + throw new StingException("Attempting to overwrite sample->genotype binding: " + sampleName + " this=" + this); + + if ( ! sampleName.equals(genotype.getSampleName()) ) + throw new StingException("Sample name doesn't equal genotype.getSample(): " + sampleName + " genotype=" + genotype); + + this.genotypes.put(sampleName, genotype); + } + + /** + * Removes the binding from sampleName to genotype. If this doesn't exist, throws an IllegalArgumentException + * @param sampleName + */ + public void removeGenotype(String sampleName) { + if ( ! this.genotypes.containsKey(sampleName) ) + throw new IllegalArgumentException("Sample name isn't contained in genotypes " + sampleName + " genotypes =" + genotypes); + + this.genotypes.remove(sampleName); + } + + /** + * Removes genotype from the context. If this doesn't exist, throws an IllegalArgumentException + * @param genotype + */ + public void removeGenotype(Genotype genotype) { + removeGenotype(genotype.getSampleName()); + } + + // todo -- add replace genotype routine + + // --------------------------------------------------------------------------------------------------------- + // + // InferredGeneticContext mutation operators + // + // --------------------------------------------------------------------------------------------------------- + public void setName(String name) { commonInfo.setName(name); } + public void addFilter(String filter) { commonInfo.addFilter(filter); } + public void addFilters(Collection filters) { commonInfo.addFilters(filters); } + public void clearFilters() { commonInfo.clearFilters(); } + public void setFilters(Collection filters) { commonInfo.setFilters(filters); } + public void setAttributes(Map map) { commonInfo.setAttributes(map); } + public void putAttribute(String key, Object value) { commonInfo.putAttribute(key, value); } + public void removeAttribute(String key) { commonInfo.removeAttribute(key); } + public void putAttributes(Map map) { commonInfo.putAttributes(map); } + public void setNegLog10PError(double negLog10PError) { commonInfo.setNegLog10PError(negLog10PError); } + public void putAttribute(String key, Object value, boolean allowOverwrites) { commonInfo.putAttribute(key, value, allowOverwrites); } +} \ No newline at end of file diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/TestVariantContextWalker.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/TestVariantContextWalker.java index c524fbf48..c204638ac 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/TestVariantContextWalker.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/TestVariantContextWalker.java @@ -23,7 +23,7 @@ public class TestVariantContextWalker extends RodWalker { for (ReferenceOrderedDatum d : dbsnpList) { rodDbSNP dbsnpRecord = (rodDbSNP)d; if ( dbsnpRecord.getLocation().getStart() == context.getLocation().getStart() ) { - VariantContext vc = VariantContextAdaptors.convertToVariantContext(dbsnpRecord); + VariantContext vc = VariantContextAdaptors.convertToVariantContext("dbsnp", dbsnpRecord); if ( vc != null ) { n++; System.out.printf("%s%n", vc); @@ -40,7 +40,7 @@ public class TestVariantContextWalker extends RodWalker { int n = 0; for (ReferenceOrderedDatum d : vcfList) { RodVCF vcfRecord = (RodVCF)d; - VariantContext vc = VariantContextAdaptors.convertToVariantContext(vcfRecord); + VariantContext vc = VariantContextAdaptors.convertToVariantContext("vcf", vcfRecord); if ( vc != null ) { n++; System.out.printf("%s%n", vc); diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContext.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContext.java index c26ecb07c..0b633ef51 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContext.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContext.java @@ -7,10 +7,7 @@ import org.broadinstitute.sting.utils.BaseUtils; import java.util.*; /** - * @author depristo - *

- * Class VariantContext - *

+ * Class VariantContext * * == High-level overview == * @@ -157,98 +154,62 @@ import java.util.*; * VariantContext vc12 = vc.subContextFromGenotypes(Arrays.asList(g1,g2)); * VariantContext vc1 = vc.subContextFromGenotypes(Arrays.asList(g1)); * + * + * @author depristo */ -public class VariantContext extends AttributedObject { +public class VariantContext { + protected InferredGeneticContext commonInfo = null; + /** The location of this VariantContext */ private GenomeLoc loc; /** The type (cached for performance reasons) of this context */ - private Type type = Type.UNDETERMINED; + protected Type type = null; /** A set of the alleles segregating in this context */ - private Set alleles = new HashSet(); + protected Set alleles = null; /** A mapping from sampleName -> genotype objects for all genotypes associated with this context */ - private Map genotypes = new HashMap(); + protected Map genotypes = null; + protected final static Map NO_GENOTYPES = Collections.unmodifiableMap(new HashMap()); // --------------------------------------------------------------------------------------------------------- // // constructors // // --------------------------------------------------------------------------------------------------------- - public VariantContext(GenomeLoc loc) { - super(); - - if ( loc == null ) { throw new StingException("GenomeLoc cannot be null"); } - this.loc = loc; - } - - // todo Add Allele... alleles syntax - - // todo Make root of VariantContext and Genotype immutatable, but extend the system to have MutableVariantContext - // and MutableGenotype, providing mutation operations. Then provide .freeze() method on mutable objects to - // make them immutable - - // todo -- - I'm personally not a huge fan of blanket types like Type.UNDETERMINED, especially when the types are - // todo public and you have to add 'DON'T USE THIS' to the Javadoc. Couldn't you use null to represent this type instead? - - // todo wrap collections that are returned directly so that users can't modify them. return Collections.unmodifiableSet() - - // todo -- rename I'm uncomfortable with the entire AttributedObject system. The name Object is too general for the application. The name AttributedObject suggests that it can be used to add attributes to any object, much like Lisp property lists. However, it contains a negLog10PError member, making the class only applicable to variants. // todo move all of attribute object attributes into Map<> and make special filter value for printing out values when // emitting VC -> VCF or whatever + + /** + * the complete constructor. Makes a complete VariantContext from its arguments + */ + public VariantContext(String name, GenomeLoc loc, Collection alleles, Map genotypes, double negLog10PError, Set filters, Map attributes) { + if ( loc == null ) { throw new StingException("GenomeLoc cannot be null"); } + this.loc = loc; + this.commonInfo = new InferredGeneticContext(name, negLog10PError, filters, attributes); - // todo -- Map in attributed object instead of Map - public VariantContext(GenomeLoc loc, Collection alleles) { - this(loc, alleles, (Map)null); - } + if ( alleles == null ) { throw new StingException("Alleles cannot be null"); } + this.alleles = Collections.unmodifiableSet(alleleCollectionToSet(new HashSet(), alleles)); - public VariantContext(GenomeLoc loc, Collection alleles, Map attributes) { - this(loc); + if ( genotypes == null ) { genotypes = NO_GENOTYPES; } + this.genotypes = Collections.unmodifiableMap(genotypes); - HashSet alleleSet = new HashSet(); - for ( Allele a : alleles ) { - if ( alleleSet.contains(a) ) - throw new IllegalArgumentException("List contains duplicate elements " + loc + " " + alleles ); - alleleSet.add(a); - } - - setAlleles(alleleSet); - setAttributes(attributes); validate(); } - public VariantContext(GenomeLoc loc, Collection alleles, Collection genotypes) { - this(loc); - setAlleles(alleles); - addGenotypes(genotypes); - validate(); + public VariantContext(String name, GenomeLoc loc, Collection alleles, Collection genotypes, double negLog10PError, Set filters, Map attributes) { + this(name, loc, alleles, genotypeCollectionToMap(new HashMap(), genotypes), negLog10PError, filters, attributes); } - public VariantContext(GenomeLoc loc, Collection alleles, - Collection genotypes, Map attributes, - double negLog10PError, Collection filters) { - this(loc); - setAlleles(alleles); - addGenotypes(genotypes); - setAttributes(attributes); - setNegLog10PError(negLog10PError); - setFilters(filters); - validate(); + public VariantContext(String name, GenomeLoc loc, Collection alleles) { + this(name, loc, alleles, NO_GENOTYPES, InferredGeneticContext.NO_NEG_LOG_10PERROR, null, null); } - public VariantContext(GenomeLoc loc, Collection alleles, - Map genotypes, Map attributes, - double negLog10PError, Collection filters) { - this(loc); - setAlleles(alleles); - addGenotypes(genotypes); - setAttributes(attributes); - setNegLog10PError(negLog10PError); - setFilters(filters); - validate(); + public VariantContext(String name, GenomeLoc loc, Collection alleles, Collection genotypes) { + this(name, loc, alleles, genotypes, InferredGeneticContext.NO_NEG_LOG_10PERROR, null, null); } // todo -- add clone method @@ -281,8 +242,7 @@ public class VariantContext extends AttributedObject { * @return */ public VariantContext subContextFromGenotypes(Collection genotypes) { - // todo -- we should check for uniqueness of genotypes - return new VariantContext(getLocation(), allelesOfGenotypes(genotypes), genotypes, getAttributes(), getNegLog10PError(), getFilters()); + return new VariantContext(getName(), getLocation(), allelesOfGenotypes(genotypes), genotypes, getNegLog10PError(), getFilters(), getAttributes()); } /** @@ -372,9 +332,6 @@ public class VariantContext extends AttributedObject { SNP, INDEL, MIXED, - - // special types - UNDETERMINED // do not use this value, it is reserved for the VariantContext itself } /** @@ -383,7 +340,7 @@ public class VariantContext extends AttributedObject { * @return the type of this VariantContext **/ public Type getType() { - if ( type == Type.UNDETERMINED ) + if ( type == null ) determineType(); return type; @@ -455,6 +412,34 @@ public class VariantContext extends AttributedObject { public GenomeLoc getLocation() { return loc; } + // --------------------------------------------------------------------------------------------------------- + // + // get routines to access context info fields + // + // --------------------------------------------------------------------------------------------------------- + public String getName() { return commonInfo.getName(); } + public Set getFilters() { return commonInfo.getFilters(); } + public boolean isFiltered() { return commonInfo.isFiltered(); } + public boolean isNotFiltered() { return commonInfo.isNotFiltered(); } + public boolean hasNegLog10PError() { return commonInfo.hasNegLog10PError(); } + public double getNegLog10PError() { return commonInfo.getNegLog10PError(); } + + public Map getAttributes() { return commonInfo.getAttributes(); } + public boolean hasAttribute(String key) { return commonInfo.hasAttribute(key); } + public Object getAttribute(String key) { return commonInfo.getAttribute(key); } + + public Object getAttribute(String key, Object defaultValue) { + return commonInfo.getAttribute(key, defaultValue); + } + + public String getAttributeAsString(String key) { return commonInfo.getAttributeAsString(key); } + public String getAttributeAsString(String key, String defaultValue) { return commonInfo.getAttributeAsString(key, defaultValue); } + public int getAttributeAsInt(String key) { return commonInfo.getAttributeAsInt(key); } + public int getAttributeAsInt(String key, int defaultValue) { return commonInfo.getAttributeAsInt(key, defaultValue); } + public double getAttributeAsDouble(String key) { return commonInfo.getAttributeAsDouble(key); } + public double getAttributeAsDouble(String key, double defaultValue) { return commonInfo.getAttributeAsDouble(key, defaultValue); } + + // --------------------------------------------------------------------------------------------------------- // // Working with alleles @@ -504,13 +489,7 @@ public class VariantContext extends AttributedObject { * @return The allele sharing the same bases as this byte[], or null if no such allele is present. */ public Allele getAllele(byte[] allele) { - for ( Allele a : getAlleles() ) { - if ( a.basesMatch(allele) ) { - return a; - } - } - - return null; // couldn't find anything + return Allele.getMatchingAllele(getAlleles(), allele); } /** @@ -553,7 +532,7 @@ public class VariantContext extends AttributedObject { altAlleles.add(allele); } - return altAlleles; + return Collections.unmodifiableSet(altAlleles); } /** @@ -572,40 +551,6 @@ public class VariantContext extends AttributedObject { throw new IllegalArgumentException("Requested " + i + " alternative allele but there are only " + n + " alternative alleles " + this); } - /** - * Sets the alleles segregating in this context to the collect of alleles. Each of which must be unique according - * to equals() in Allele. Validate() should be called when you are done modifying the context. - * - * @param alleles - */ - public void setAlleles(Collection alleles) { - this.alleles.clear(); - for ( Allele a : alleles ) - addAllele(a); - } - - /** - * Adds allele to the segregating allele list in this context to the collection of alleles. The new - * allele must be be unique according to equals() in Allele. - * Validate() should be called when you are done modifying the context. - * - * @param allele - */ - public void addAllele(Allele allele) { - final boolean allowDuplicates = false; // used to be a parameter - - type = Type.UNDETERMINED; - - for ( Allele a : alleles ) { - if ( a.basesMatch(allele) && ! allowDuplicates ) - throw new IllegalArgumentException("Duplicate allele added to VariantContext" + this); - } - - // we are a novel allele - alleles.add(allele); - } - - // --------------------------------------------------------------------------------------------------------- // // Working with genotypes @@ -725,124 +670,6 @@ public class VariantContext extends AttributedObject { return ! isMonomorphic(); } - public void clearGenotypes() { - this.genotypes.clear(); - } - - /** - * Adds this single genotype to the context, not allowing duplicate genotypes to be added - * @param genotype - */ - public void addGenotypes(Genotype genotype) { - putGenotype(genotype.getSampleName(), genotype, false); - } - - /** - * Adds these genotypes to the context, not allowing duplicate genotypes to be added - * @param genotypes - */ - public void addGenotypes(Collection genotypes) { - for ( Genotype g : genotypes ) { - addGenotype(g); - } - } - - /** - * Adds these genotype to the context, not allowing duplicate genotypes to be added. - * @param genotypes - */ - public void addGenotypes(Map genotypes) { - - for ( Map.Entry elt : genotypes.entrySet() ) { - addGenotype(elt.getValue()); - } - } - - /** - * Adds these genotypes to the context. - * - * @param genotypes - */ - public void putGenotypes(Map genotypes) { - for ( Map.Entry g : genotypes.entrySet() ) - putGenotype(g.getKey(), g.getValue()); - } - - /** - * Adds these genotypes to the context. - * - * @param genotypes - */ - public void putGenotypes(Collection genotypes) { - for ( Genotype g : genotypes ) - putGenotype(g); - } - - /** - * Adds this genotype to the context, throwing an error if it's already bound. - * - * @param genotype - */ - public void addGenotype(Genotype genotype) { - addGenotype(genotype.getSampleName(), genotype); - } - - /** - * Adds this genotype to the context, throwing an error if it's already bound. - * - * @param genotype - */ - public void addGenotype(String sampleName, Genotype genotype) { - putGenotype(sampleName, genotype, false); - } - - /** - * Adds this genotype to the context. - * - * @param genotype - */ - public void putGenotype(Genotype genotype) { - putGenotype(genotype.getSampleName(), genotype); - } - - /** - * Adds this genotype to the context. - * - * @param genotype - */ - public void putGenotype(String sampleName, Genotype genotype) { - putGenotype(sampleName, genotype, true); - } - - private void putGenotype(String sampleName, Genotype genotype, boolean allowOverwrites) { - if ( hasGenotype(sampleName) && ! allowOverwrites ) - throw new StingException("Attempting to overwrite sample->genotype binding: " + sampleName + " this=" + this); - - if ( ! sampleName.equals(genotype.getSampleName()) ) - throw new StingException("Sample name doesn't equal genotype.getSample(): " + sampleName + " genotype=" + genotype); - - this.genotypes.put(sampleName, genotype); - } - - /** - * Removes the binding from sampleName to genotype. If this doesn't exist, throws an IllegalArgumentException - * @param sampleName - */ - public void removeGenotype(String sampleName) { - if ( ! this.genotypes.containsKey(sampleName) ) - throw new IllegalArgumentException("Sample name isn't contained in genotypes " + sampleName + " genotypes =" + genotypes); - - this.genotypes.remove(sampleName); - } - - /** - * Removes genotype from the context. If this doesn't exist, throws an IllegalArgumentException - * @param genotype - */ - public void removeGenotype(Genotype genotype) { - removeGenotype(genotype.getSampleName()); - } - // --------------------------------------------------------------------------------------------------------- // // validation @@ -930,7 +757,7 @@ public class VariantContext extends AttributedObject { // --------------------------------------------------------------------------------------------------------- private void determineType() { - if ( type == Type.UNDETERMINED ) { + if ( type == null ) { if ( alleles.size() == 0 ) { throw new StingException("Unexpected requested type of VariantContext with no alleles!" + this); } else if ( alleles.size() == 1 ) { @@ -973,4 +800,29 @@ public class VariantContext extends AttributedObject { return String.format("[VC @ %s of type=%s alleles=%s attr=%s GT=%s", getLocation(), this.getType(), this.getAlleles(), this.getAttributes(), this.getGenotypes().values()); } + + // protected basic manipulation routines + private static Set alleleCollectionToSet(Set dest, Collection alleles) { + for ( Allele a : alleles ) { + for ( Allele b : dest ) { + if ( a.basesMatch(b) ) + throw new IllegalArgumentException("Duplicate allele added to VariantContext" + a); + } + + dest.add(a); + } + + return dest; + } + + private static Map genotypeCollectionToMap(Map dest, Collection genotypes) { + for ( Genotype a : genotypes ) { + if ( dest.containsKey(a.getSampleName() ) ) + throw new IllegalArgumentException("Duplicate genotype added to VariantContext " + a); + dest.put(a.getSampleName(), a); + } + + return dest; + } + } \ No newline at end of file diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextAdaptors.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextAdaptors.java index 3d8fddf96..fe5210c2c 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextAdaptors.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextAdaptors.java @@ -11,35 +11,34 @@ import java.util.*; public class VariantContextAdaptors { - public static boolean canBeConvertedToVariantContext(Object variantContainingObject) { - return convertToVariantContext(variantContainingObject) != null; + public static boolean canBeConvertedToVariantContext(String name, Object variantContainingObject) { + return convertToVariantContext(name, variantContainingObject) != null; } - public static VariantContext convertToVariantContext(Object variantContainingObject) { + public static VariantContext convertToVariantContext(String name, Object variantContainingObject) { if ( variantContainingObject instanceof rodDbSNP ) - return dbsnpToVariantContext((rodDbSNP)variantContainingObject); + return dbsnpToVariantContext(name, (rodDbSNP)variantContainingObject); else if ( variantContainingObject instanceof RodVCF ) - return vcfToVariantContext(((RodVCF)variantContainingObject).getRecord()); + return vcfToVariantContext(name, ((RodVCF)variantContainingObject).getRecord()); else if ( variantContainingObject instanceof VCFRecord ) - return vcfToVariantContext((VCFRecord)variantContainingObject); + return vcfToVariantContext(name, (VCFRecord)variantContainingObject); else return null; //throw new IllegalArgumentException("Cannot convert object " + variantContainingObject + " of class " + variantContainingObject.getClass() + " to a variant context"); } - private static VariantContext dbsnpToVariantContext(rodDbSNP dbsnp) { + private static VariantContext dbsnpToVariantContext(String name, rodDbSNP dbsnp) { if ( dbsnp.isSNP() || dbsnp.isIndel() || dbsnp.varType.contains("mixed") ) { - VariantContext vc = new VariantContext(dbsnp.getLocation()); - // add the reference allele if ( ! Allele.acceptableAlleleBases(dbsnp.getReference()) ) { //System.out.printf("Excluding dbsnp record %s%n", dbsnp); return null; } + List alleles = new ArrayList(); Allele refAllele = new Allele(dbsnp.getReference(), true); - vc.addAllele(refAllele); + alleles.add(refAllele); // add all of the alt alleles for ( String alt : dbsnp.getAlternateAlleleList() ) { @@ -47,60 +46,64 @@ public class VariantContextAdaptors { //System.out.printf("Excluding dbsnp record %s%n", dbsnp); return null; } - vc.addAllele(new Allele(alt, false)); + alleles.add(new Allele(alt, false)); } + VariantContext vc = new VariantContext(name, dbsnp.getLocation(), alleles); vc.validate(); return vc; } else return null; // can't handle anything else } - private static VariantContext vcfToVariantContext(VCFRecord vcf) { + private static VariantContext vcfToVariantContext(String name, VCFRecord vcf) { if ( vcf.isSNP() || vcf.isIndel() ) { - VariantContext vc = new VariantContext(vcf.getLocation()); - // add the reference allele if ( ! Allele.acceptableAlleleBases(vcf.getReference()) ) { System.out.printf("Excluding vcf record %s%n", vcf); return null; } - Allele refAllele = new Allele(vcf.getReference(), true); - vc.addAllele(refAllele); - vc.setNegLog10PError(vcf.getNegLog10PError()); - vc.setAttributes(vcf.getInfoValues()); - vc.putAttribute("ID", vcf.getID()); - if ( vcf.isFiltered() ) vc.setFilters(Arrays.asList(vcf.getFilteringCodes())); + Set filters = vcf.isFiltered() ? new HashSet(Arrays.asList(vcf.getFilteringCodes())) : null; + Map attributes = vcf.getInfoValues(); + attributes.put("ID", vcf.getID()); // add all of the alt alleles + List alleles = new ArrayList(); + Allele refAllele = new Allele(vcf.getReference(), true); + alleles.add(refAllele); for ( String alt : vcf.getAlternateAlleleList() ) { if ( ! Allele.acceptableAlleleBases(alt) ) { System.out.printf("Excluding vcf record %s%n", vcf); return null; } - vc.addAllele(new Allele(alt, false)); + alleles.add(new Allele(alt, false)); } + Map genotypes = new HashMap(); for ( VCFGenotypeRecord vcfG : vcf.getVCFGenotypeRecords() ) { - List alleleStrings = new ArrayList(); + List genotypeAlleles = new ArrayList(); for ( VCFGenotypeEncoding s : vcfG.getAlleles() ) - alleleStrings.add(s.getBases()); + genotypeAlleles.add(Allele.getMatchingAllele(alleles, s.getBases())); - double pError = vcfG.getNegLog10PError() == VCFGenotypeRecord.MISSING_GENOTYPE_QUALITY ? AttributedObject.NO_NEG_LOG_10PERROR : vcfG.getNegLog10PError(); - Genotype g = new Genotype(vc, alleleStrings, vcfG.getSampleName(), pError); + double pError = vcfG.getNegLog10PError() == VCFGenotypeRecord.MISSING_GENOTYPE_QUALITY ? InferredGeneticContext.NO_NEG_LOG_10PERROR : vcfG.getNegLog10PError(); + Map fields = new HashMap(); for ( Map.Entry e : vcfG.getFields().entrySet() ) { + // todo -- fixme if we put GQ and GF into key itself if ( ! e.getKey().equals(VCFGenotypeRecord.GENOTYPE_QUALITY_KEY) && ! e.getKey().equals(VCFGenotypeRecord.GENOTYPE_FILTER_KEY) ) - g.putAttribute(e.getKey(), e.getValue()); + fields.put(e.getKey(), e.getValue()); } + Set genotypeFilters = new HashSet(); if ( vcfG.isFiltered() ) // setup the FL genotype filter fields - g.setFilters(Arrays.asList(vcfG.getFields().get(VCFGenotypeRecord.GENOTYPE_FILTER_KEY.split(";")))); + genotypeFilters.addAll(Arrays.asList(vcfG.getFields().get(VCFGenotypeRecord.GENOTYPE_FILTER_KEY).split(";"))); - vc.addGenotype(g); + Genotype g = new Genotype(vcfG.getSampleName(), genotypeAlleles, pError, genotypeFilters, fields); + genotypes.put(g.getSampleName(), g); } + VariantContext vc = new VariantContext(name, vcf.getLocation(), alleles, genotypes, vcf.getNegLog10PError(), filters, attributes); vc.validate(); return vc; } else diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextUtils.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextUtils.java index f2cd20f31..98e0e9cd0 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextUtils.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextUtils.java @@ -57,8 +57,8 @@ public class VariantContextUtils { } public static Map match(VariantContext vc, Collection exps) { - // todo actually, we should implement a JEXL context interface to VariantContext, - // which just looks up the values assigned statically here. Much better approach + // todo -- actually, we should implement a JEXL context interface to VariantContext, + // todo -- which just looks up the values assigned statically here. Much better approach Map infoMap = new HashMap(); @@ -104,8 +104,8 @@ public class VariantContextUtils { } - private static void addAttributesToMap(Map infoMap, Map attributes, String prefix ) { - for (Map.Entry e : attributes.entrySet()) { + private static void addAttributesToMap(Map infoMap, Map attributes, String prefix ) { + for (Map.Entry e : attributes.entrySet()) { infoMap.put(prefix + String.valueOf(e.getKey()), String.valueOf(e.getValue())); } } diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/MendelianViolationEvaluator.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/MendelianViolationEvaluator.java index 7cf90e40f..274a447cd 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/MendelianViolationEvaluator.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/MendelianViolationEvaluator.java @@ -153,7 +153,7 @@ public class MendelianViolationEvaluator extends VariantEvaluator { int i = 0; for ( Allele momAllele : momVC.getAlleles() ) { for ( Allele dadAllele : dadVC.getAlleles() ) { - Genotype possibleChild = new Genotype(Arrays.asList(momAllele, dadAllele), "possibleGenotype" + i); + Genotype possibleChild = new Genotype("possibleGenotype" + i, Arrays.asList(momAllele, dadAllele)); if ( childG.sameGenotype(possibleChild, false) ) { return false; } diff --git a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/VariantEval2Walker.java b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/VariantEval2Walker.java index 37f64434e..561086f15 100755 --- a/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/VariantEval2Walker.java +++ b/java/src/org/broadinstitute/sting/oneoffprojects/variantcontext/varianteval2/VariantEval2Walker.java @@ -288,7 +288,7 @@ public class VariantEval2Walker extends RodWalker { if ( rodList != null ) { for ( ReferenceOrderedDatum rec : rodList.getRecords() ) { if ( rec.getLocation().getStart() == context.getLocation().getStart() ) { - VariantContext vc = VariantContextAdaptors.convertToVariantContext(rec); + VariantContext vc = VariantContextAdaptors.convertToVariantContext(name, rec); if ( vc != null ) { return vc; } diff --git a/java/src/org/broadinstitute/sting/playground/gatk/walkers/diagnostics/SNPDensity.java b/java/src/org/broadinstitute/sting/playground/gatk/walkers/diagnostics/SNPDensity.java index c7855b277..0c7cea819 100755 --- a/java/src/org/broadinstitute/sting/playground/gatk/walkers/diagnostics/SNPDensity.java +++ b/java/src/org/broadinstitute/sting/playground/gatk/walkers/diagnostics/SNPDensity.java @@ -47,7 +47,7 @@ public class SNPDensity extends RefWalker, SNPDe if (vcfList != null) { for (ReferenceOrderedDatum d : vcfList) { RodVCF vcfRecord = (RodVCF)d; - vc = VariantContextAdaptors.convertToVariantContext(vcfRecord); + vc = VariantContextAdaptors.convertToVariantContext("eval", vcfRecord); break; } } diff --git a/java/test/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextTest.java b/java/test/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextTest.java index f4e30e8eb..7519decb9 100755 --- a/java/test/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextTest.java +++ b/java/test/org/broadinstitute/sting/oneoffprojects/variantcontext/VariantContextTest.java @@ -67,7 +67,7 @@ public class VariantContextTest extends BaseTest { logger.warn("testCreatingSNPVariantContext"); List alleles = Arrays.asList(Aref, T); - VariantContext vc = new VariantContext(snpLoc, alleles); + VariantContext vc = new VariantContext("test", snpLoc, alleles); logger.warn("vc = " + vc); Assert.assertEquals(vc.getLocation(), snpLoc); @@ -98,7 +98,7 @@ public class VariantContextTest extends BaseTest { logger.warn("testCreatingRefVariantContext"); List alleles = Arrays.asList(Aref); - VariantContext vc = new VariantContext(snpLoc, alleles); + VariantContext vc = new VariantContext("test", snpLoc, alleles); logger.warn("vc = " + vc); Assert.assertEquals(vc.getLocation(), snpLoc); @@ -125,7 +125,7 @@ public class VariantContextTest extends BaseTest { logger.warn("testCreatingDeletionVariantContext"); List alleles = Arrays.asList(ATCref, del); - VariantContext vc = new VariantContext(delLoc, alleles); + VariantContext vc = new VariantContext("test", delLoc, alleles); logger.warn("vc = " + vc); Assert.assertEquals(vc.getLocation(), delLoc); @@ -153,7 +153,7 @@ public class VariantContextTest extends BaseTest { logger.warn("testCreatingInsertionVariantContext"); List alleles = Arrays.asList(delRef, ATC); - VariantContext vc = new VariantContext(insLoc, alleles); + VariantContext vc = new VariantContext("test", insLoc, alleles); logger.warn("vc = " + vc); Assert.assertEquals(vc.getLocation(), insLoc); @@ -179,45 +179,45 @@ public class VariantContextTest extends BaseTest { @Test (expected = IllegalArgumentException.class) public void testBadConstructorArgs1() { logger.warn("testBadConstructorArgs1"); - new VariantContext(insLoc, Arrays.asList(delRef, ATCref)); + new VariantContext("test", insLoc, Arrays.asList(delRef, ATCref)); } @Test (expected = IllegalArgumentException.class) public void testBadConstructorArgs2() { logger.warn("testBadConstructorArgs2"); - new VariantContext(insLoc, Arrays.asList(delRef, del)); + new VariantContext("test", insLoc, Arrays.asList(delRef, del)); } @Test (expected = IllegalArgumentException.class) public void testBadConstructorArgs3() { logger.warn("testBadConstructorArgs3"); - new VariantContext(insLoc, Arrays.asList(del)); + new VariantContext("test", insLoc, Arrays.asList(del)); } @Test (expected = IllegalArgumentException.class) public void testBadConstructorArgsDuplicateAlleles1() { logger.warn("testBadConstructorArgsDuplicateAlleles1"); - new VariantContext(insLoc, Arrays.asList(Aref, T, T)); + new VariantContext("test", insLoc, Arrays.asList(Aref, T, T)); } @Test (expected = IllegalArgumentException.class) public void testBadConstructorArgsDuplicateAlleles2() { logger.warn("testBadConstructorArgsDuplicateAlleles2"); - new VariantContext(insLoc, Arrays.asList(Aref, A)); + new VariantContext("test", insLoc, Arrays.asList(Aref, A)); } @Test (expected = IllegalStateException.class) public void testBadLoc1() { logger.warn("testBadLoc1"); List alleles = Arrays.asList(Aref, T, del); - VariantContext vc = new VariantContext(delLoc, alleles); + VariantContext vc = new VariantContext("test", delLoc, alleles); } @Test (expected = IllegalStateException.class) public void testBadTiTvRequest() { logger.warn("testBadConstructorArgsDuplicateAlleles2"); - new VariantContext(insLoc, Arrays.asList(Aref, ATC)).isTransition(); + new VariantContext("test", insLoc, Arrays.asList(Aref, ATC)).isTransition(); } @Test @@ -225,15 +225,14 @@ public class VariantContextTest extends BaseTest { logger.warn("testAccessingSimpleSNPGenotypes"); List alleles = Arrays.asList(Aref, T); - VariantContext vc = new VariantContext(snpLoc, alleles); + + Genotype g1 = new Genotype("AA", Arrays.asList(Aref, Aref), 10); + Genotype g2 = new Genotype("AT", Arrays.asList(Aref, T), 10); + Genotype g3 = new Genotype("TT", Arrays.asList(T, T), 10); + + VariantContext vc = new VariantContext("test", snpLoc, alleles, Arrays.asList(g1, g2, g3)); logger.warn("vc = " + vc); - Genotype g1 = new Genotype(Arrays.asList(Aref, Aref), "AA", 10); - Genotype g2 = new Genotype(Arrays.asList(Aref, T), "AT", 10); - Genotype g3 = new Genotype(Arrays.asList(T, T), "TT", 10); - - vc.addGenotypes(Arrays.asList(g1, g2, g3)); - Assert.assertTrue(vc.hasGenotypes()); Assert.assertFalse(vc.isMonomorphic()); Assert.assertTrue(vc.isPolymorphic()); @@ -265,18 +264,17 @@ public class VariantContextTest extends BaseTest { logger.warn("testAccessingCompleteGenotypes"); List alleles = Arrays.asList(Aref, T, del); - VariantContext vc = new VariantContext(snpLoc, alleles); + + Genotype g1 = new Genotype("AA", Arrays.asList(Aref, Aref), 10); + Genotype g2 = new Genotype("AT", Arrays.asList(Aref, T), 10); + Genotype g3 = new Genotype("TT", Arrays.asList(T, T), 10); + Genotype g4 = new Genotype("Td", Arrays.asList(T, del), 10); + Genotype g5 = new Genotype("dd", Arrays.asList(del, del), 10); + Genotype g6 = new Genotype("..", Arrays.asList(Allele.NO_CALL, Allele.NO_CALL), 10); + + VariantContext vc = new VariantContext("test", snpLoc, alleles, Arrays.asList(g1, g2, g3, g4, g5, g6)); logger.warn("vc = " + vc); - Genotype g1 = new Genotype(Arrays.asList(Aref, Aref), "AA", 10); - Genotype g2 = new Genotype(Arrays.asList(Aref, T), "AT", 10); - Genotype g3 = new Genotype(Arrays.asList(T, T), "TT", 10); - Genotype g4 = new Genotype(Arrays.asList(T, del), "Td", 10); - Genotype g5 = new Genotype(Arrays.asList(del, del), "dd", 10); - Genotype g6 = new Genotype(Arrays.asList(Allele.NO_CALL, Allele.NO_CALL), "..", 10); - - vc.addGenotypes(Arrays.asList(g1, g2, g3, g4, g5, g6)); - Assert.assertTrue(vc.hasGenotypes()); Assert.assertFalse(vc.isMonomorphic()); Assert.assertTrue(vc.isPolymorphic()); @@ -299,15 +297,13 @@ public class VariantContextTest extends BaseTest { List alleles2 = Arrays.asList(Aref); List alleles3 = Arrays.asList(Aref, T, del); for ( List alleles : Arrays.asList(alleles1, alleles2, alleles3)) { - VariantContext vc = new VariantContext(snpLoc, alleles); + + Genotype g1 = new Genotype("AA1", Arrays.asList(Aref, Aref), 10); + Genotype g2 = new Genotype("AA2", Arrays.asList(Aref, Aref), 10); + Genotype g3 = new Genotype("..", Arrays.asList(Allele.NO_CALL, Allele.NO_CALL), 10); + VariantContext vc = new VariantContext("test", snpLoc, alleles, Arrays.asList(g1, g2, g3)); logger.warn("vc = " + vc); - Genotype g1 = new Genotype(Arrays.asList(Aref, Aref), "AA1", 10); - Genotype g2 = new Genotype(Arrays.asList(Aref, Aref), "AA2", 10); - Genotype g3 = new Genotype(Arrays.asList(Allele.NO_CALL, Allele.NO_CALL), "..", 10); - - vc.addGenotypes(Arrays.asList(g1, g2, g3)); - Assert.assertTrue(vc.hasGenotypes()); Assert.assertTrue(vc.isMonomorphic()); Assert.assertFalse(vc.isPolymorphic()); @@ -325,9 +321,9 @@ public class VariantContextTest extends BaseTest { logger.warn("testFilters"); List alleles = Arrays.asList(Aref, T, del); - Genotype g1 = new Genotype(Arrays.asList(Aref, Aref), "AA", 10); - Genotype g2 = new Genotype(Arrays.asList(Aref, T), "AT", 10); - VariantContext vc = new VariantContext(snpLoc, alleles, Arrays.asList(g1,g2)); + Genotype g1 = new Genotype("AA", Arrays.asList(Aref, Aref), 10); + Genotype g2 = new Genotype("AT", Arrays.asList(Aref, T), 10); + MutableVariantContext vc = new MutableVariantContext("test", snpLoc, alleles, Arrays.asList(g1,g2)); logger.warn("vc = " + vc); Assert.assertTrue(vc.isNotFiltered()); @@ -358,12 +354,12 @@ public class VariantContextTest extends BaseTest { logger.warn("testVCromGenotypes"); List alleles = Arrays.asList(Aref, T, del); - Genotype g1 = new Genotype(Arrays.asList(Aref, Aref), "AA", 10); - Genotype g2 = new Genotype(Arrays.asList(Aref, T), "AT", 10); - Genotype g3 = new Genotype(Arrays.asList(T, T), "TT", 10); - Genotype g4 = new Genotype(Arrays.asList(Allele.NO_CALL, Allele.NO_CALL), "..", 10); - Genotype g5 = new Genotype(Arrays.asList(del, del), "--", 10); - VariantContext vc = new VariantContext(snpLoc, alleles, Arrays.asList(g1,g2,g3,g4,g5)); + Genotype g1 = new Genotype("AA", Arrays.asList(Aref, Aref), 10); + Genotype g2 = new Genotype("AT", Arrays.asList(Aref, T), 10); + Genotype g3 = new Genotype("TT", Arrays.asList(T, T), 10); + Genotype g4 = new Genotype("..", Arrays.asList(Allele.NO_CALL, Allele.NO_CALL), 10); + Genotype g5 = new Genotype("--", Arrays.asList(del, del), 10); + VariantContext vc = new VariantContext("test", snpLoc, alleles, Arrays.asList(g1,g2,g3,g4,g5)); logger.warn("vc = " + vc); VariantContext vc12 = vc.subContextFromGenotypes(Arrays.asList(g1,g2));