de.charite.compbio.jannovar.mendel.GenotypeCalls Maven / Gradle / Ivy
package de.charite.compbio.jannovar.mendel;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSortedMap;
import de.charite.compbio.jannovar.Immutable;
import java.util.Iterator;
import java.util.Map.Entry;
/**
* A list of genotypes (at an implicitely assumed site) in multiple individuals
*
* This list contains the core information for the filtration of variants by mendelian inheritance.
*
* This list is not called GenotypeList
as "list" indicates more of a "vertical" arrangement (multiple
* sites) of genotypes instead of a "horizontal" one (one site, multiple samples).
*
* Note: of course, the class is only immutable as long as payload
is immutable!
*
* @author Manuel Holtgrewe
*/
@Immutable
public final class GenotypeCalls implements Iterable> {
private final static Genotype GT_NO_CALL = new Genotype(ImmutableList.of(Genotype.NO_CALL));
/**
* Type of the chromosome that the variant lies on (autosomal, X-chromosomal, etc.)
*/
private final ChromosomeType chromType;
/**
* Mapping from sample name to {@link Genotype}
*/
private final ImmutableSortedMap sampleToGenotype;
/**
* List of sample names
*/
private final ImmutableList sampleNames;
/**
* A payload object for later easier reidentification
*/
private final Object payload;
/**
* Initialize {@link GenotypeCalls} with mapping from sample to genotype
*
* @param chromType type of the chromosome of this genotype call site
* @param sampleToGenotype {@link Iterable} with mapping from sample name to {@link Genotype}
*/
public GenotypeCalls(ChromosomeType chromType, Iterable> sampleToGenotype) {
this(chromType, sampleToGenotype, null);
}
/**
* Initialize {@link GenotypeCalls} with mapping from sample to genotype and an additional "payload" object
*
* @param chromType type of the chromosome of this genotype call site
* @param sampleToGenotype {@link Iterable} with mapping from sample name to {@link Genotype}
* @param payload An arbitrary payload object. This could be something to later match the constructed
* GenotypeCalls
back to an object in your application (e.g., the HTSJDK
* VariantContext
that was used for constructing the {@link GenotypeCalls}).
*/
public GenotypeCalls(ChromosomeType chromType, Iterable> sampleToGenotype,
Object payload) {
this.chromType = chromType;
this.sampleToGenotype = ImmutableSortedMap.copyOf(sampleToGenotype);
this.sampleNames = ImmutableList.copyOf(this.sampleToGenotype.keySet());
this.payload = payload;
}
/**
* @return number of samples in genotype list
*/
public int getNSamples() {
return sampleNames.size();
}
/**
* @param sample name of the sample to return {@link Genotype} for
* @return {@link Genotype} for the given sample, a not-observed genotype if the sample is unknown instead of
* null
*/
public Genotype getGenotypeForSample(String sample) {
Genotype result = sampleToGenotype.get(sample);
// TODO(holtgrewe): using Optional<> here would make handling empty return values more elegant in the calling
// code such that the behaviour could change then
if (result == null)
return GT_NO_CALL;
return result;
}
/**
* @param sampleNo 0-based sample number to return {@link Genotype} for
* @return {@link Genotype} by sample number
*/
public Genotype getGenotypeBySampleNo(int sampleNo) {
return sampleToGenotype.get(sampleNames.get(sampleNo));
}
/**
* @return type of the chromosome
*/
public ChromosomeType getChromType() {
return chromType;
}
/**
* @return Sample to genotype map
*/
public ImmutableSortedMap getSampleToGenotype() {
return sampleToGenotype;
}
/**
* @return Sample names
*/
public ImmutableList getSampleNames() {
return sampleNames;
}
/**
* @return Payload object
*/
public Object getPayload() {
return payload;
}
@Override
public String toString() {
return "GenotypeCalls [chromType=" + chromType + ", sampleToGenotype=" + sampleToGenotype + ", sampleNames="
+ sampleNames + ", payload=" + payload + "]";
}
@Override
public Iterator> iterator() {
return sampleToGenotype.entrySet().iterator();
}
@Override
public int hashCode() {
// Yes, we really need object identity here
return System.identityHashCode(this);
}
@Override
public boolean equals(Object obj) {
if (obj == null)
return false;
// Yes, we really need object identity here
return (this.hashCode() == obj.hashCode());
}
}