Significant refactoring of the Haplotype Caller to handle problems with GGA. The main fix is that we now maintain a mapping from 'original' allele to 'Smith-Waterman-based' allele so that we no longer need to do a (buggy) matching throughout the calling process.
This commit is contained in:
parent
78ce822b6f
commit
ff180a8e02
|
|
@ -31,7 +31,6 @@ import net.sf.samtools.Cigar;
|
||||||
import net.sf.samtools.CigarElement;
|
import net.sf.samtools.CigarElement;
|
||||||
import org.apache.commons.lang.ArrayUtils;
|
import org.apache.commons.lang.ArrayUtils;
|
||||||
import org.broadinstitute.sting.gatk.walkers.genotyper.UnifiedGenotyperEngine;
|
import org.broadinstitute.sting.gatk.walkers.genotyper.UnifiedGenotyperEngine;
|
||||||
import org.broadinstitute.sting.gatk.walkers.genotyper.VariantCallContext;
|
|
||||||
import org.broadinstitute.sting.utils.*;
|
import org.broadinstitute.sting.utils.*;
|
||||||
import org.broadinstitute.sting.utils.collections.Pair;
|
import org.broadinstitute.sting.utils.collections.Pair;
|
||||||
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
import org.broadinstitute.sting.utils.exceptions.ReviewedStingException;
|
||||||
|
|
@ -52,153 +51,17 @@ public class GenotypingEngine {
|
||||||
noCall.add(Allele.NO_CALL);
|
noCall.add(Allele.NO_CALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// WARN
|
|
||||||
// This function is the streamlined approach, currently not being used by default
|
|
||||||
// WARN
|
|
||||||
// WARN: This function is currently only being used by Menachem. Slated for removal/merging with the rest of the code.
|
|
||||||
// WARN
|
|
||||||
@Requires({"refLoc.containsP(activeRegionWindow)", "haplotypes.size() > 0"})
|
|
||||||
public List<Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>> assignGenotypeLikelihoodsAndCallHaplotypeEvents( final UnifiedGenotyperEngine UG_engine,
|
|
||||||
final ArrayList<Haplotype> haplotypes,
|
|
||||||
final byte[] ref,
|
|
||||||
final GenomeLoc refLoc,
|
|
||||||
final GenomeLoc activeRegionWindow,
|
|
||||||
final GenomeLocParser genomeLocParser ) {
|
|
||||||
// Prepare the list of haplotype indices to genotype
|
|
||||||
final ArrayList<Allele> allelesToGenotype = new ArrayList<Allele>();
|
|
||||||
|
|
||||||
for( final Haplotype h : haplotypes ) {
|
|
||||||
allelesToGenotype.add( Allele.create(h.getBases(), h.isReference()) );
|
|
||||||
}
|
|
||||||
final int numHaplotypes = haplotypes.size();
|
|
||||||
|
|
||||||
// Grab the genotype likelihoods from the appropriate places in the haplotype likelihood matrix -- calculation performed independently per sample
|
|
||||||
final GenotypesContext genotypes = GenotypesContext.create(haplotypes.get(0).getSampleKeySet().size());
|
|
||||||
for( final String sample : haplotypes.get(0).getSampleKeySet() ) { // BUGBUG: assume all haplotypes saw the same samples
|
|
||||||
final double[] genotypeLikelihoods = new double[numHaplotypes * (numHaplotypes+1) / 2];
|
|
||||||
final double[][] haplotypeLikelihoodMatrix = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(haplotypes, sample);
|
|
||||||
int glIndex = 0;
|
|
||||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
|
||||||
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
|
||||||
genotypeLikelihoods[glIndex++] = haplotypeLikelihoodMatrix[iii][jjj]; // for example: AA,AB,BB,AC,BC,CC
|
|
||||||
}
|
|
||||||
}
|
|
||||||
genotypes.add(new GenotypeBuilder(sample, noCall).PL(genotypeLikelihoods).make());
|
|
||||||
}
|
|
||||||
final VariantCallContext call = UG_engine.calculateGenotypes(new VariantContextBuilder().loc(activeRegionWindow).alleles(allelesToGenotype).genotypes(genotypes).make(), UG_engine.getUAC().GLmodel);
|
|
||||||
if( call == null ) { return Collections.emptyList(); } // exact model says that the call confidence is below the specified confidence threshold so nothing to do here
|
|
||||||
|
|
||||||
// Prepare the list of haplotypes that need to be run through Smith-Waterman for output to VCF
|
|
||||||
final ArrayList<Haplotype> haplotypesToRemove = new ArrayList<Haplotype>();
|
|
||||||
for( final Haplotype h : haplotypes ) {
|
|
||||||
if( call.getAllele(h.getBases()) == null ) { // exact model removed this allele from the list so no need to run SW and output to VCF
|
|
||||||
haplotypesToRemove.add(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
haplotypes.removeAll(haplotypesToRemove);
|
|
||||||
|
|
||||||
if( OUTPUT_FULL_HAPLOTYPE_SEQUENCE ) {
|
|
||||||
final List<Pair<VariantContext, HashMap<Allele, ArrayList<Haplotype>>>> returnVCs = new ArrayList<Pair<VariantContext, HashMap<Allele, ArrayList<Haplotype>>>>();
|
|
||||||
// set up the default 1-to-1 haplotype mapping object
|
|
||||||
final HashMap<Allele,ArrayList<Haplotype>> haplotypeMapping = new HashMap<Allele,ArrayList<Haplotype>>();
|
|
||||||
for( final Haplotype h : haplotypes ) {
|
|
||||||
final ArrayList<Haplotype> list = new ArrayList<Haplotype>();
|
|
||||||
list.add(h);
|
|
||||||
haplotypeMapping.put(call.getAllele(h.getBases()), list);
|
|
||||||
}
|
|
||||||
returnVCs.add( new Pair<VariantContext, HashMap<Allele, ArrayList<Haplotype>>>(call,haplotypeMapping) );
|
|
||||||
return returnVCs;
|
|
||||||
}
|
|
||||||
|
|
||||||
final ArrayList<Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>> returnCalls = new ArrayList<Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>>();
|
|
||||||
|
|
||||||
// Using the cigar from each called haplotype figure out what events need to be written out in a VCF file
|
|
||||||
final TreeSet<Integer> startPosKeySet = new TreeSet<Integer>();
|
|
||||||
int count = 0;
|
|
||||||
if( DEBUG ) { System.out.println("=== Best Haplotypes ==="); }
|
|
||||||
for( final Haplotype h : haplotypes ) {
|
|
||||||
if( DEBUG ) {
|
|
||||||
System.out.println( h.toString() );
|
|
||||||
System.out.println( "> Cigar = " + h.getCigar() );
|
|
||||||
}
|
|
||||||
// Walk along the alignment and turn any difference from the reference into an event
|
|
||||||
h.setEventMap( generateVCsFromAlignment( h, h.getAlignmentStartHapwrtRef(), h.getCigar(), ref, h.getBases(), refLoc, "HC" + count++ ) );
|
|
||||||
startPosKeySet.addAll(h.getEventMap().keySet());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the VC merge priority list
|
|
||||||
final ArrayList<String> priorityList = new ArrayList<String>();
|
|
||||||
for( int iii = 0; iii < haplotypes.size(); iii++ ) {
|
|
||||||
priorityList.add("HC" + iii);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk along each position in the key set and create each event to be outputted
|
|
||||||
for( final int loc : startPosKeySet ) {
|
|
||||||
if( loc >= activeRegionWindow.getStart() && loc <= activeRegionWindow.getStop() ) {
|
|
||||||
final ArrayList<VariantContext> eventsAtThisLoc = new ArrayList<VariantContext>();
|
|
||||||
for( final Haplotype h : haplotypes ) {
|
|
||||||
final HashMap<Integer,VariantContext> eventMap = h.getEventMap();
|
|
||||||
final VariantContext vc = eventMap.get(loc);
|
|
||||||
if( vc != null && !containsVCWithMatchingAlleles(eventsAtThisLoc, vc) ) {
|
|
||||||
eventsAtThisLoc.add(vc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the allele mapping object which maps the original haplotype alleles to the alleles present in just this event
|
|
||||||
final ArrayList<ArrayList<Haplotype>> alleleMapper = createAlleleMapper( loc, eventsAtThisLoc, haplotypes );
|
|
||||||
|
|
||||||
// Merge the event to find a common reference representation
|
|
||||||
final VariantContext mergedVC = VariantContextUtils.simpleMerge(genomeLocParser, eventsAtThisLoc, priorityList, VariantContextUtils.FilteredRecordMergeType.KEEP_IF_ANY_UNFILTERED, VariantContextUtils.GenotypeMergeType.PRIORITIZE, false, false, null, false, false);
|
|
||||||
|
|
||||||
final HashMap<Allele, ArrayList<Haplotype>> alleleHashMap = new HashMap<Allele, ArrayList<Haplotype>>();
|
|
||||||
int aCount = 0;
|
|
||||||
for( final Allele a : mergedVC.getAlleles() ) {
|
|
||||||
alleleHashMap.put(a, alleleMapper.get(aCount++)); // BUGBUG: needs to be cleaned up and merged with alleleMapper
|
|
||||||
}
|
|
||||||
|
|
||||||
if( DEBUG ) {
|
|
||||||
System.out.println("Genotyping event at " + loc + " with alleles = " + mergedVC.getAlleles());
|
|
||||||
//System.out.println("Event/haplotype allele mapping = " + alleleMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Grab the genotype likelihoods from the appropriate places in the haplotype likelihood matrix -- calculation performed independently per sample
|
|
||||||
final GenotypesContext myGenotypes = GenotypesContext.create(haplotypes.get(0).getSampleKeySet().size());
|
|
||||||
for( final String sample : haplotypes.get(0).getSampleKeySet() ) { // BUGBUG: assume all haplotypes saw the same samples
|
|
||||||
final int myNumHaplotypes = alleleMapper.size();
|
|
||||||
final double[] genotypeLikelihoods = new double[myNumHaplotypes * (myNumHaplotypes+1) / 2];
|
|
||||||
final double[][] haplotypeLikelihoodMatrix = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(sample, alleleMapper);
|
|
||||||
int glIndex = 0;
|
|
||||||
for( int iii = 0; iii < myNumHaplotypes; iii++ ) {
|
|
||||||
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
|
||||||
genotypeLikelihoods[glIndex++] = haplotypeLikelihoodMatrix[iii][jjj]; // for example: AA,AB,BB,AC,BC,CC
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// using the allele mapping object translate the haplotype allele into the event allele
|
|
||||||
final Genotype g = new GenotypeBuilder(sample)
|
|
||||||
.alleles(findEventAllelesInSample(mergedVC.getAlleles(), call.getAlleles(), call.getGenotype(sample).getAlleles(), alleleMapper, haplotypes))
|
|
||||||
.phased(loc != startPosKeySet.first())
|
|
||||||
.PL(genotypeLikelihoods).make();
|
|
||||||
myGenotypes.add(g);
|
|
||||||
}
|
|
||||||
returnCalls.add( new Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>(
|
|
||||||
new VariantContextBuilder(mergedVC).log10PError(call.getLog10PError()).genotypes(myGenotypes).make(), alleleHashMap) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return returnCalls;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BUGBUG: Create a class to hold this complicated return type
|
// BUGBUG: Create a class to hold this complicated return type
|
||||||
@Requires({"refLoc.containsP(activeRegionWindow)", "haplotypes.size() > 0"})
|
@Requires({"refLoc.containsP(activeRegionWindow)", "haplotypes.size() > 0"})
|
||||||
public List<Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>> assignGenotypeLikelihoodsAndCallIndependentEvents( final UnifiedGenotyperEngine UG_engine,
|
public List<Pair<VariantContext, Map<Allele, List<Haplotype>>>> assignGenotypeLikelihoodsAndCallIndependentEvents( final UnifiedGenotyperEngine UG_engine,
|
||||||
final ArrayList<Haplotype> haplotypes,
|
final List<Haplotype> haplotypes,
|
||||||
final byte[] ref,
|
final byte[] ref,
|
||||||
final GenomeLoc refLoc,
|
final GenomeLoc refLoc,
|
||||||
final GenomeLoc activeRegionWindow,
|
final GenomeLoc activeRegionWindow,
|
||||||
final GenomeLocParser genomeLocParser,
|
final GenomeLocParser genomeLocParser,
|
||||||
final ArrayList<VariantContext> activeAllelesToGenotype ) {
|
final List<VariantContext> activeAllelesToGenotype ) {
|
||||||
|
|
||||||
final ArrayList<Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>> returnCalls = new ArrayList<Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>>();
|
final ArrayList<Pair<VariantContext, Map<Allele, List<Haplotype>>>> returnCalls = new ArrayList<Pair<VariantContext, Map<Allele, List<Haplotype>>>>();
|
||||||
|
|
||||||
// Using the cigar from each called haplotype figure out what events need to be written out in a VCF file
|
// Using the cigar from each called haplotype figure out what events need to be written out in a VCF file
|
||||||
final TreeSet<Integer> startPosKeySet = new TreeSet<Integer>();
|
final TreeSet<Integer> startPosKeySet = new TreeSet<Integer>();
|
||||||
|
|
@ -261,7 +124,15 @@ public class GenotypingEngine {
|
||||||
if( eventsAtThisLoc.isEmpty() ) { continue; }
|
if( eventsAtThisLoc.isEmpty() ) { continue; }
|
||||||
|
|
||||||
// Create the allele mapping object which maps the original haplotype alleles to the alleles present in just this event
|
// Create the allele mapping object which maps the original haplotype alleles to the alleles present in just this event
|
||||||
final ArrayList<ArrayList<Haplotype>> alleleMapper = createAlleleMapper( loc, eventsAtThisLoc, haplotypes );
|
Map<Allele, List<Haplotype>> alleleMapper = createAlleleMapper( loc, eventsAtThisLoc, haplotypes );
|
||||||
|
|
||||||
|
final Allele refAllele = eventsAtThisLoc.get(0).getReference();
|
||||||
|
final ArrayList<Allele> alleleOrdering = new ArrayList<Allele>(alleleMapper.size());
|
||||||
|
alleleOrdering.add(refAllele);
|
||||||
|
for ( final Allele allele : alleleMapper.keySet() ) {
|
||||||
|
if ( !refAllele.equals(allele) )
|
||||||
|
alleleOrdering.add(allele);
|
||||||
|
}
|
||||||
|
|
||||||
// Sanity check the priority list
|
// Sanity check the priority list
|
||||||
for( final VariantContext vc : eventsAtThisLoc ) {
|
for( final VariantContext vc : eventsAtThisLoc ) {
|
||||||
|
|
@ -283,12 +154,6 @@ public class GenotypingEngine {
|
||||||
final VariantContext mergedVC = VariantContextUtils.simpleMerge(genomeLocParser, eventsAtThisLoc, priorityList, VariantContextUtils.FilteredRecordMergeType.KEEP_IF_ANY_UNFILTERED, VariantContextUtils.GenotypeMergeType.PRIORITIZE, false, false, null, false, false);
|
final VariantContext mergedVC = VariantContextUtils.simpleMerge(genomeLocParser, eventsAtThisLoc, priorityList, VariantContextUtils.FilteredRecordMergeType.KEEP_IF_ANY_UNFILTERED, VariantContextUtils.GenotypeMergeType.PRIORITIZE, false, false, null, false, false);
|
||||||
if( mergedVC == null ) { continue; }
|
if( mergedVC == null ) { continue; }
|
||||||
|
|
||||||
HashMap<Allele, ArrayList<Haplotype>> alleleHashMap = new HashMap<Allele, ArrayList<Haplotype>>();
|
|
||||||
int aCount = 0;
|
|
||||||
for( final Allele a : mergedVC.getAlleles() ) {
|
|
||||||
alleleHashMap.put(a, alleleMapper.get(aCount++)); // BUGBUG: needs to be cleaned up and merged with alleleMapper
|
|
||||||
}
|
|
||||||
|
|
||||||
if( DEBUG ) {
|
if( DEBUG ) {
|
||||||
System.out.println("Genotyping event at " + loc + " with alleles = " + mergedVC.getAlleles());
|
System.out.println("Genotyping event at " + loc + " with alleles = " + mergedVC.getAlleles());
|
||||||
//System.out.println("Event/haplotype allele mapping = " + alleleMapper);
|
//System.out.println("Event/haplotype allele mapping = " + alleleMapper);
|
||||||
|
|
@ -299,7 +164,7 @@ public class GenotypingEngine {
|
||||||
for( final String sample : haplotypes.get(0).getSampleKeySet() ) { // BUGBUG: assume all haplotypes saw the same samples
|
for( final String sample : haplotypes.get(0).getSampleKeySet() ) { // BUGBUG: assume all haplotypes saw the same samples
|
||||||
final int numHaplotypes = alleleMapper.size();
|
final int numHaplotypes = alleleMapper.size();
|
||||||
final double[] genotypeLikelihoods = new double[numHaplotypes * (numHaplotypes+1) / 2];
|
final double[] genotypeLikelihoods = new double[numHaplotypes * (numHaplotypes+1) / 2];
|
||||||
final double[][] haplotypeLikelihoodMatrix = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(sample, alleleMapper);
|
final double[][] haplotypeLikelihoodMatrix = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(sample, alleleMapper, alleleOrdering);
|
||||||
int glIndex = 0;
|
int glIndex = 0;
|
||||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||||
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
||||||
|
|
@ -313,23 +178,23 @@ public class GenotypingEngine {
|
||||||
if( call.getAlleles().size() != mergedVC.getAlleles().size() ) { // some alleles were removed so reverseTrimming might be necessary!
|
if( call.getAlleles().size() != mergedVC.getAlleles().size() ) { // some alleles were removed so reverseTrimming might be necessary!
|
||||||
final VariantContext vcCallTrim = VariantContextUtils.reverseTrimAlleles(call);
|
final VariantContext vcCallTrim = VariantContextUtils.reverseTrimAlleles(call);
|
||||||
// also, need to update the allele -> haplotype mapping
|
// also, need to update the allele -> haplotype mapping
|
||||||
final HashMap<Allele, ArrayList<Haplotype>> alleleHashMapTrim = new HashMap<Allele, ArrayList<Haplotype>>();
|
final HashMap<Allele, List<Haplotype>> alleleHashMapTrim = new HashMap<Allele, List<Haplotype>>();
|
||||||
for( int iii = 0; iii < vcCallTrim.getAlleles().size(); iii++ ) { // BUGBUG: this is assuming that the original and trimmed alleles maintain the same ordering in the VC
|
for( int iii = 0; iii < vcCallTrim.getAlleles().size(); iii++ ) { // BUGBUG: this is assuming that the original and trimmed alleles maintain the same ordering in the VC
|
||||||
alleleHashMapTrim.put(vcCallTrim.getAlleles().get(iii), alleleHashMap.get(call.getAlleles().get(iii)));
|
alleleHashMapTrim.put(vcCallTrim.getAlleles().get(iii), alleleMapper.get(call.getAlleles().get(iii)));
|
||||||
}
|
}
|
||||||
|
|
||||||
call = vcCallTrim;
|
call = vcCallTrim;
|
||||||
alleleHashMap = alleleHashMapTrim;
|
alleleMapper = alleleHashMapTrim;
|
||||||
}
|
}
|
||||||
|
|
||||||
returnCalls.add( new Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>>(call, alleleHashMap) );
|
returnCalls.add( new Pair<VariantContext, Map<Allele,List<Haplotype>>>(call, alleleMapper) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return returnCalls;
|
return returnCalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void cleanUpSymbolicUnassembledEvents( final ArrayList<Haplotype> haplotypes ) {
|
protected static void cleanUpSymbolicUnassembledEvents( final List<Haplotype> haplotypes ) {
|
||||||
final ArrayList<Haplotype> haplotypesToRemove = new ArrayList<Haplotype>();
|
final ArrayList<Haplotype> haplotypesToRemove = new ArrayList<Haplotype>();
|
||||||
for( final Haplotype h : haplotypes ) {
|
for( final Haplotype h : haplotypes ) {
|
||||||
for( final VariantContext vc : h.getEventMap().values() ) {
|
for( final VariantContext vc : h.getEventMap().values() ) {
|
||||||
|
|
@ -348,7 +213,7 @@ public class GenotypingEngine {
|
||||||
haplotypes.removeAll(haplotypesToRemove);
|
haplotypes.removeAll(haplotypesToRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void mergeConsecutiveEventsBasedOnLD( final ArrayList<Haplotype> haplotypes, final TreeSet<Integer> startPosKeySet, final byte[] ref, final GenomeLoc refLoc ) {
|
protected void mergeConsecutiveEventsBasedOnLD( final List<Haplotype> haplotypes, final TreeSet<Integer> startPosKeySet, final byte[] ref, final GenomeLoc refLoc ) {
|
||||||
final int MAX_SIZE_TO_COMBINE = 15;
|
final int MAX_SIZE_TO_COMBINE = 15;
|
||||||
final double MERGE_EVENTS_R2_THRESHOLD = 0.95;
|
final double MERGE_EVENTS_R2_THRESHOLD = 0.95;
|
||||||
if( startPosKeySet.size() <= 1 ) { return; }
|
if( startPosKeySet.size() <= 1 ) { return; }
|
||||||
|
|
@ -395,7 +260,9 @@ public class GenotypingEngine {
|
||||||
final ArrayList<Haplotype> haplotypeList = new ArrayList<Haplotype>();
|
final ArrayList<Haplotype> haplotypeList = new ArrayList<Haplotype>();
|
||||||
haplotypeList.add(h);
|
haplotypeList.add(h);
|
||||||
for( final String sample : haplotypes.get(0).getSampleKeySet() ) {
|
for( final String sample : haplotypes.get(0).getSampleKeySet() ) {
|
||||||
final double haplotypeLikelihood = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods( haplotypeList, sample )[0][0];
|
final HashSet<String> sampleSet = new HashSet<String>(1);
|
||||||
|
sampleSet.add(sample);
|
||||||
|
final double haplotypeLikelihood = LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods( sampleSet, haplotypeList )[0][0];
|
||||||
if( thisHapVC == null ) {
|
if( thisHapVC == null ) {
|
||||||
if( nextHapVC == null ) { x11 = MathUtils.approximateLog10SumLog10(x11, haplotypeLikelihood); }
|
if( nextHapVC == null ) { x11 = MathUtils.approximateLog10SumLog10(x11, haplotypeLikelihood); }
|
||||||
else { x12 = MathUtils.approximateLog10SumLog10(x12, haplotypeLikelihood); }
|
else { x12 = MathUtils.approximateLog10SumLog10(x12, haplotypeLikelihood); }
|
||||||
|
|
@ -489,37 +356,71 @@ public class GenotypingEngine {
|
||||||
|
|
||||||
@Requires({"haplotypes.size() >= eventsAtThisLoc.size() + 1"})
|
@Requires({"haplotypes.size() >= eventsAtThisLoc.size() + 1"})
|
||||||
@Ensures({"result.size() == eventsAtThisLoc.size() + 1"})
|
@Ensures({"result.size() == eventsAtThisLoc.size() + 1"})
|
||||||
protected static ArrayList<ArrayList<Haplotype>> createAlleleMapper( final int loc, final ArrayList<VariantContext> eventsAtThisLoc, final ArrayList<Haplotype> haplotypes ) {
|
protected static Map<Allele, List<Haplotype>> createAlleleMapper( final int loc, final List<VariantContext> eventsAtThisLoc, final List<Haplotype> haplotypes ) {
|
||||||
final ArrayList<ArrayList<Haplotype>> alleleMapper = new ArrayList<ArrayList<Haplotype>>();
|
|
||||||
final ArrayList<Haplotype> refList = new ArrayList<Haplotype>();
|
final Allele refAllele = eventsAtThisLoc.get(0).getReference();
|
||||||
|
|
||||||
|
final Map<Allele, List<Haplotype>> alleleMapper = new HashMap<Allele, List<Haplotype>>(eventsAtThisLoc.size()+1);
|
||||||
for( final Haplotype h : haplotypes ) {
|
for( final Haplotype h : haplotypes ) {
|
||||||
if( h.getEventMap().get(loc) == null ) { // no event at this location so this is a reference-supporting haplotype
|
if( h.getEventMap().get(loc) == null ) { // no event at this location so this is a reference-supporting haplotype
|
||||||
refList.add(h);
|
if ( !alleleMapper.containsKey(refAllele) )
|
||||||
|
alleleMapper.put(refAllele, new ArrayList<Haplotype>());
|
||||||
|
alleleMapper.get(refAllele).add(h);
|
||||||
|
} else if ( h.isArtificialHaplotype() ) {
|
||||||
|
if ( !alleleMapper.containsKey(h.getArtificialAllele()) )
|
||||||
|
alleleMapper.put(h.getArtificialAllele(), new ArrayList<Haplotype>());
|
||||||
|
alleleMapper.get(h.getArtificialAllele()).add(h);
|
||||||
} else {
|
} else {
|
||||||
boolean foundInEventList = false;
|
|
||||||
for( final VariantContext vcAtThisLoc : eventsAtThisLoc ) {
|
for( final VariantContext vcAtThisLoc : eventsAtThisLoc ) {
|
||||||
if( h.getEventMap().get(loc).hasSameAllelesAs(vcAtThisLoc) ) {
|
if( h.getEventMap().get(loc).hasSameAllelesAs(vcAtThisLoc) ) {
|
||||||
foundInEventList = true;
|
final Allele altAllele = vcAtThisLoc.getAlternateAllele(0);
|
||||||
|
if ( !alleleMapper.containsKey(altAllele) )
|
||||||
|
alleleMapper.put(altAllele, new ArrayList<Haplotype>());
|
||||||
|
alleleMapper.get(altAllele).add(h);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( !foundInEventList ) { // event at this location isn't one of the genotype-able options (during GGA) so this is a reference-supporting haplotype
|
|
||||||
refList.add(h);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alleleMapper.add(refList);
|
|
||||||
for( final VariantContext vcAtThisLoc : eventsAtThisLoc ) {
|
for( final Haplotype h : haplotypes ) {
|
||||||
final ArrayList<Haplotype> list = new ArrayList<Haplotype>();
|
if ( h.getEventMap().get(loc) == null || h.isArtificialHaplotype() )
|
||||||
for( final Haplotype h : haplotypes ) {
|
continue;
|
||||||
if( h.getEventMap().get(loc) != null && h.getEventMap().get(loc).hasSameAllelesAs(vcAtThisLoc) ) {
|
|
||||||
list.add(h);
|
Allele matchingAllele = null;
|
||||||
|
for ( final Map.Entry<Allele, List<Haplotype>> alleleToTest : alleleMapper.entrySet() ) {
|
||||||
|
if ( alleleToTest.getKey().equals(refAllele) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
final Haplotype artificialHaplotype = alleleToTest.getValue().get(0);
|
||||||
|
if ( isSubSetOf(artificialHaplotype.getEventMap(), h.getEventMap()) ) {
|
||||||
|
matchingAllele = alleleToTest.getKey();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
alleleMapper.add(list);
|
|
||||||
|
if ( matchingAllele == null )
|
||||||
|
matchingAllele = refAllele;
|
||||||
|
alleleMapper.get(matchingAllele).add(h);
|
||||||
}
|
}
|
||||||
|
|
||||||
return alleleMapper;
|
return alleleMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static boolean isSubSetOf(final Map<Integer, VariantContext> subset, final Map<Integer, VariantContext> superset) {
|
||||||
|
|
||||||
|
for ( final Map.Entry<Integer, VariantContext> fromSubset : subset.entrySet() ) {
|
||||||
|
final VariantContext fromSuperset = superset.get(fromSubset.getKey());
|
||||||
|
if ( fromSuperset == null )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( !fromSuperset.hasAlternateAllele(fromSubset.getValue().getAlternateAllele(0)) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Ensures({"result.size() == haplotypeAllelesForSample.size()"})
|
@Ensures({"result.size() == haplotypeAllelesForSample.size()"})
|
||||||
protected static List<Allele> findEventAllelesInSample( final List<Allele> eventAlleles, final List<Allele> haplotypeAlleles, final List<Allele> haplotypeAllelesForSample, final ArrayList<ArrayList<Haplotype>> alleleMapper, final ArrayList<Haplotype> haplotypes ) {
|
protected static List<Allele> findEventAllelesInSample( final List<Allele> eventAlleles, final List<Allele> haplotypeAlleles, final List<Allele> haplotypeAllelesForSample, final ArrayList<ArrayList<Haplotype>> alleleMapper, final ArrayList<Haplotype> haplotypes ) {
|
||||||
if( haplotypeAllelesForSample.contains(Allele.NO_CALL) ) { return noCall; }
|
if( haplotypeAllelesForSample.contains(Allele.NO_CALL) ) { return noCall; }
|
||||||
|
|
|
||||||
|
|
@ -421,10 +421,8 @@ public class HaplotypeCaller extends ActiveRegionWalker<Integer, Integer> implem
|
||||||
// subset down to only the best haplotypes to be genotyped in all samples ( in GGA mode use all discovered haplotypes )
|
// subset down to only the best haplotypes to be genotyped in all samples ( in GGA mode use all discovered haplotypes )
|
||||||
final ArrayList<Haplotype> bestHaplotypes = ( UG_engine.getUAC().GenotypingMode != GenotypeLikelihoodsCalculationModel.GENOTYPING_MODE.GENOTYPE_GIVEN_ALLELES ? likelihoodCalculationEngine.selectBestHaplotypes( haplotypes ) : haplotypes );
|
final ArrayList<Haplotype> bestHaplotypes = ( UG_engine.getUAC().GenotypingMode != GenotypeLikelihoodsCalculationModel.GENOTYPING_MODE.GENOTYPE_GIVEN_ALLELES ? likelihoodCalculationEngine.selectBestHaplotypes( haplotypes ) : haplotypes );
|
||||||
|
|
||||||
for( final Pair<VariantContext, HashMap<Allele, ArrayList<Haplotype>>> callResult :
|
for( final Pair<VariantContext, Map<Allele, List<Haplotype>>> callResult :
|
||||||
( GENOTYPE_FULL_ACTIVE_REGION && UG_engine.getUAC().GenotypingMode != GenotypeLikelihoodsCalculationModel.GENOTYPING_MODE.GENOTYPE_GIVEN_ALLELES
|
genotypingEngine.assignGenotypeLikelihoodsAndCallIndependentEvents( UG_engine, bestHaplotypes, fullReferenceWithPadding, getPaddedLoc(activeRegion), activeRegion.getLocation(), getToolkit().getGenomeLocParser(), activeAllelesToGenotype ) ) {
|
||||||
? genotypingEngine.assignGenotypeLikelihoodsAndCallHaplotypeEvents( UG_engine, bestHaplotypes, fullReferenceWithPadding, getPaddedLoc(activeRegion), activeRegion.getExtendedLoc(), getToolkit().getGenomeLocParser() )
|
|
||||||
: genotypingEngine.assignGenotypeLikelihoodsAndCallIndependentEvents( UG_engine, bestHaplotypes, fullReferenceWithPadding, getPaddedLoc(activeRegion), activeRegion.getLocation(), getToolkit().getGenomeLocParser(), activeAllelesToGenotype ) ) ) {
|
|
||||||
if( DEBUG ) { System.out.println(callResult.getFirst().toStringWithoutGenotypes()); }
|
if( DEBUG ) { System.out.println(callResult.getFirst().toStringWithoutGenotypes()); }
|
||||||
|
|
||||||
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap = LikelihoodCalculationEngine.partitionReadsBasedOnLikelihoods( getToolkit().getGenomeLocParser(), perSampleReadList, perSampleFilteredReadList, callResult, UG_engine.getUAC().CONTAMINATION_FRACTION, UG_engine.getUAC().contaminationLog );
|
final Map<String, PerReadAlleleLikelihoodMap> stratifiedReadMap = LikelihoodCalculationEngine.partitionReadsBasedOnLikelihoods( getToolkit().getGenomeLocParser(), perSampleReadList, perSampleFilteredReadList, callResult, UG_engine.getUAC().CONTAMINATION_FRACTION, UG_engine.getUAC().contaminationLog );
|
||||||
|
|
|
||||||
|
|
@ -148,34 +148,21 @@ public class LikelihoodCalculationEngine {
|
||||||
return Math.min(b1.length, b2.length);
|
return Math.min(b1.length, b2.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Requires({"haplotypes.size() > 0"})
|
|
||||||
@Ensures({"result.length == result[0].length", "result.length == haplotypes.size()"})
|
|
||||||
public static double[][] computeDiploidHaplotypeLikelihoods( final ArrayList<Haplotype> haplotypes, final String sample ) {
|
|
||||||
// set up the default 1-to-1 haplotype mapping object, BUGBUG: target for future optimization?
|
|
||||||
final ArrayList<ArrayList<Haplotype>> haplotypeMapping = new ArrayList<ArrayList<Haplotype>>();
|
|
||||||
for( final Haplotype h : haplotypes ) {
|
|
||||||
final ArrayList<Haplotype> list = new ArrayList<Haplotype>();
|
|
||||||
list.add(h);
|
|
||||||
haplotypeMapping.add(list);
|
|
||||||
}
|
|
||||||
return computeDiploidHaplotypeLikelihoods( sample, haplotypeMapping );
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function takes just a single sample and a haplotypeMapping
|
// This function takes just a single sample and a haplotypeMapping
|
||||||
@Requires({"haplotypeMapping.size() > 0"})
|
@Requires({"haplotypeMapping.size() > 0"})
|
||||||
@Ensures({"result.length == result[0].length", "result.length == haplotypeMapping.size()"})
|
@Ensures({"result.length == result[0].length", "result.length == haplotypeMapping.size()"})
|
||||||
public static double[][] computeDiploidHaplotypeLikelihoods( final String sample, final ArrayList<ArrayList<Haplotype>> haplotypeMapping ) {
|
public static double[][] computeDiploidHaplotypeLikelihoods( final String sample, final Map<Allele, List<Haplotype>> haplotypeMapping, final List<Allele> alleleOrdering ) {
|
||||||
final TreeSet<String> sampleSet = new TreeSet<String>();
|
final TreeSet<String> sampleSet = new TreeSet<String>();
|
||||||
sampleSet.add(sample);
|
sampleSet.add(sample);
|
||||||
return computeDiploidHaplotypeLikelihoods(sampleSet, haplotypeMapping);
|
return computeDiploidHaplotypeLikelihoods(sampleSet, haplotypeMapping, alleleOrdering);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function takes a set of samples to pool over and a haplotypeMapping
|
// This function takes a set of samples to pool over and a haplotypeMapping
|
||||||
@Requires({"haplotypeMapping.size() > 0"})
|
@Requires({"haplotypeMapping.size() > 0"})
|
||||||
@Ensures({"result.length == result[0].length", "result.length == haplotypeMapping.size()"})
|
@Ensures({"result.length == result[0].length", "result.length == haplotypeMapping.size()"})
|
||||||
public static double[][] computeDiploidHaplotypeLikelihoods( final Set<String> samples, final ArrayList<ArrayList<Haplotype>> haplotypeMapping ) {
|
public static double[][] computeDiploidHaplotypeLikelihoods( final Set<String> samples, final Map<Allele, List<Haplotype>> haplotypeMapping, final List<Allele> alleleOrdering ) {
|
||||||
|
|
||||||
final int numHaplotypes = haplotypeMapping.size();
|
final int numHaplotypes = alleleOrdering.size();
|
||||||
final double[][] haplotypeLikelihoodMatrix = new double[numHaplotypes][numHaplotypes];
|
final double[][] haplotypeLikelihoodMatrix = new double[numHaplotypes][numHaplotypes];
|
||||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||||
Arrays.fill(haplotypeLikelihoodMatrix[iii], Double.NEGATIVE_INFINITY);
|
Arrays.fill(haplotypeLikelihoodMatrix[iii], Double.NEGATIVE_INFINITY);
|
||||||
|
|
@ -185,8 +172,8 @@ public class LikelihoodCalculationEngine {
|
||||||
// todo - needs to be generalized to arbitrary ploidy, cleaned and merged with PairHMMIndelErrorModel code
|
// todo - needs to be generalized to arbitrary ploidy, cleaned and merged with PairHMMIndelErrorModel code
|
||||||
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||||
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
||||||
for( final Haplotype iii_mapped : haplotypeMapping.get(iii) ) {
|
for( final Haplotype iii_mapped : haplotypeMapping.get(alleleOrdering.get(iii)) ) {
|
||||||
for( final Haplotype jjj_mapped : haplotypeMapping.get(jjj) ) {
|
for( final Haplotype jjj_mapped : haplotypeMapping.get(alleleOrdering.get(jjj)) ) {
|
||||||
double haplotypeLikelihood = 0.0;
|
double haplotypeLikelihood = 0.0;
|
||||||
for( final String sample : samples ) {
|
for( final String sample : samples ) {
|
||||||
final double[] readLikelihoods_iii = iii_mapped.getReadLikelihoods(sample);
|
final double[] readLikelihoods_iii = iii_mapped.getReadLikelihoods(sample);
|
||||||
|
|
@ -208,6 +195,42 @@ public class LikelihoodCalculationEngine {
|
||||||
return normalizeDiploidLikelihoodMatrixFromLog10( haplotypeLikelihoodMatrix );
|
return normalizeDiploidLikelihoodMatrixFromLog10( haplotypeLikelihoodMatrix );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function takes a set of samples to pool over and a haplotypeMapping
|
||||||
|
@Requires({"haplotypeMapping.size() > 0"})
|
||||||
|
@Ensures({"result.length == result[0].length", "result.length == haplotypeMapping.size()"})
|
||||||
|
public static double[][] computeDiploidHaplotypeLikelihoods( final Set<String> samples, final List<Haplotype> haplotypeList ) {
|
||||||
|
|
||||||
|
final int numHaplotypes = haplotypeList.size();
|
||||||
|
final double[][] haplotypeLikelihoodMatrix = new double[numHaplotypes][numHaplotypes];
|
||||||
|
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||||
|
Arrays.fill(haplotypeLikelihoodMatrix[iii], Double.NEGATIVE_INFINITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute the diploid haplotype likelihoods
|
||||||
|
// todo - needs to be generalized to arbitrary ploidy, cleaned and merged with PairHMMIndelErrorModel code
|
||||||
|
for( int iii = 0; iii < numHaplotypes; iii++ ) {
|
||||||
|
final Haplotype iii_haplotype = haplotypeList.get(iii);
|
||||||
|
for( int jjj = 0; jjj <= iii; jjj++ ) {
|
||||||
|
final Haplotype jjj_haplotype = haplotypeList.get(jjj);
|
||||||
|
double haplotypeLikelihood = 0.0;
|
||||||
|
for( final String sample : samples ) {
|
||||||
|
final double[] readLikelihoods_iii = iii_haplotype.getReadLikelihoods(sample);
|
||||||
|
final int[] readCounts_iii = iii_haplotype.getReadCounts(sample);
|
||||||
|
final double[] readLikelihoods_jjj = jjj_haplotype.getReadLikelihoods(sample);
|
||||||
|
for( int kkk = 0; kkk < readLikelihoods_iii.length; kkk++ ) {
|
||||||
|
// Compute log10(10^x1/2 + 10^x2/2) = log10(10^x1+10^x2)-log10(2)
|
||||||
|
// First term is approximated by Jacobian log with table lookup.
|
||||||
|
haplotypeLikelihood += readCounts_iii[kkk] * ( MathUtils.approximateLog10SumLog10(readLikelihoods_iii[kkk], readLikelihoods_jjj[kkk]) + LOG_ONE_HALF );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
haplotypeLikelihoodMatrix[iii][jjj] = Math.max(haplotypeLikelihoodMatrix[iii][jjj], haplotypeLikelihood);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize the diploid likelihoods matrix
|
||||||
|
return normalizeDiploidLikelihoodMatrixFromLog10( haplotypeLikelihoodMatrix );
|
||||||
|
}
|
||||||
|
|
||||||
@Requires({"likelihoodMatrix.length == likelihoodMatrix[0].length"})
|
@Requires({"likelihoodMatrix.length == likelihoodMatrix[0].length"})
|
||||||
@Ensures({"result.length == result[0].length", "result.length == likelihoodMatrix.length"})
|
@Ensures({"result.length == result[0].length", "result.length == likelihoodMatrix.length"})
|
||||||
protected static double[][] normalizeDiploidLikelihoodMatrixFromLog10( final double[][] likelihoodMatrix ) {
|
protected static double[][] normalizeDiploidLikelihoodMatrixFromLog10( final double[][] likelihoodMatrix ) {
|
||||||
|
|
@ -296,14 +319,7 @@ public class LikelihoodCalculationEngine {
|
||||||
final Set<String> sampleKeySet = haplotypes.get(0).getSampleKeySet(); // BUGBUG: assume all haplotypes saw the same samples
|
final Set<String> sampleKeySet = haplotypes.get(0).getSampleKeySet(); // BUGBUG: assume all haplotypes saw the same samples
|
||||||
final ArrayList<Integer> bestHaplotypesIndexList = new ArrayList<Integer>();
|
final ArrayList<Integer> bestHaplotypesIndexList = new ArrayList<Integer>();
|
||||||
bestHaplotypesIndexList.add( findReferenceIndex(haplotypes) ); // always start with the reference haplotype
|
bestHaplotypesIndexList.add( findReferenceIndex(haplotypes) ); // always start with the reference haplotype
|
||||||
// set up the default 1-to-1 haplotype mapping object
|
final double[][] haplotypeLikelihoodMatrix = computeDiploidHaplotypeLikelihoods( sampleKeySet, haplotypes ); // all samples pooled together
|
||||||
final ArrayList<ArrayList<Haplotype>> haplotypeMapping = new ArrayList<ArrayList<Haplotype>>();
|
|
||||||
for( final Haplotype h : haplotypes ) {
|
|
||||||
final ArrayList<Haplotype> list = new ArrayList<Haplotype>();
|
|
||||||
list.add(h);
|
|
||||||
haplotypeMapping.add(list);
|
|
||||||
}
|
|
||||||
final double[][] haplotypeLikelihoodMatrix = computeDiploidHaplotypeLikelihoods( sampleKeySet, haplotypeMapping ); // all samples pooled together
|
|
||||||
|
|
||||||
int hap1 = 0;
|
int hap1 = 0;
|
||||||
int hap2 = 0;
|
int hap2 = 0;
|
||||||
|
|
@ -347,7 +363,7 @@ public class LikelihoodCalculationEngine {
|
||||||
public static Map<String, PerReadAlleleLikelihoodMap> partitionReadsBasedOnLikelihoods( final GenomeLocParser parser,
|
public static Map<String, PerReadAlleleLikelihoodMap> partitionReadsBasedOnLikelihoods( final GenomeLocParser parser,
|
||||||
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleReadList,
|
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleReadList,
|
||||||
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleFilteredReadList,
|
final HashMap<String, ArrayList<GATKSAMRecord>> perSampleFilteredReadList,
|
||||||
final Pair<VariantContext, HashMap<Allele,ArrayList<Haplotype>>> call,
|
final Pair<VariantContext, Map<Allele,List<Haplotype>>> call,
|
||||||
final double downsamplingFraction,
|
final double downsamplingFraction,
|
||||||
final PrintStream downsamplingLog ) {
|
final PrintStream downsamplingLog ) {
|
||||||
final Map<String, PerReadAlleleLikelihoodMap> returnMap = new HashMap<String, PerReadAlleleLikelihoodMap>();
|
final Map<String, PerReadAlleleLikelihoodMap> returnMap = new HashMap<String, PerReadAlleleLikelihoodMap>();
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import org.broadinstitute.sting.BaseTest;
|
||||||
import org.broadinstitute.sting.utils.Haplotype;
|
import org.broadinstitute.sting.utils.Haplotype;
|
||||||
import org.broadinstitute.sting.utils.MathUtils;
|
import org.broadinstitute.sting.utils.MathUtils;
|
||||||
import org.testng.Assert;
|
import org.testng.Assert;
|
||||||
import org.testng.annotations.BeforeClass;
|
|
||||||
import org.testng.annotations.DataProvider;
|
import org.testng.annotations.DataProvider;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
@ -102,7 +101,9 @@ public class LikelihoodCalculationEngineUnitTest extends BaseTest {
|
||||||
haplotypes.add(haplotype);
|
haplotypes.add(haplotype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(haplotypes, "myTestSample");
|
final HashSet<String> sampleSet = new HashSet<String>(1);
|
||||||
|
sampleSet.add("myTestSample");
|
||||||
|
return LikelihoodCalculationEngine.computeDiploidHaplotypeLikelihoods(sampleSet, haplotypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ public class Haplotype {
|
||||||
private int alignmentStartHapwrtRef;
|
private int alignmentStartHapwrtRef;
|
||||||
public int leftBreakPoint = 0;
|
public int leftBreakPoint = 0;
|
||||||
public int rightBreakPoint = 0;
|
public int rightBreakPoint = 0;
|
||||||
|
private Allele artificialAllele = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a simple consensus sequence with provided bases and a uniform quality over all bases of qual
|
* Create a simple consensus sequence with provided bases and a uniform quality over all bases of qual
|
||||||
|
|
@ -71,6 +72,11 @@ public class Haplotype {
|
||||||
this(bases, 0);
|
this(bases, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Haplotype( final byte[] bases, final Allele artificialAllele ) {
|
||||||
|
this(bases, 0);
|
||||||
|
this.artificialAllele = artificialAllele;
|
||||||
|
}
|
||||||
|
|
||||||
public Haplotype( final byte[] bases, final GenomeLoc loc ) {
|
public Haplotype( final byte[] bases, final GenomeLoc loc ) {
|
||||||
this(bases);
|
this(bases);
|
||||||
this.genomeLocation = loc;
|
this.genomeLocation = loc;
|
||||||
|
|
@ -171,6 +177,14 @@ public class Haplotype {
|
||||||
this.cigar = cigar;
|
this.cigar = cigar;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isArtificialHaplotype() {
|
||||||
|
return artificialAllele != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Allele getArtificialAllele() {
|
||||||
|
return artificialAllele;
|
||||||
|
}
|
||||||
|
|
||||||
@Requires({"refInsertLocation >= 0"})
|
@Requires({"refInsertLocation >= 0"})
|
||||||
public Haplotype insertAllele( final Allele refAllele, final Allele altAllele, final int refInsertLocation ) {
|
public Haplotype insertAllele( final Allele refAllele, final Allele altAllele, final int refInsertLocation ) {
|
||||||
// refInsertLocation is in ref haplotype offset coordinates NOT genomic coordinates
|
// refInsertLocation is in ref haplotype offset coordinates NOT genomic coordinates
|
||||||
|
|
@ -182,7 +196,7 @@ public class Haplotype {
|
||||||
newHaplotypeBases = ArrayUtils.addAll(newHaplotypeBases, ArrayUtils.subarray(bases, 0, haplotypeInsertLocation)); // bases before the variant
|
newHaplotypeBases = ArrayUtils.addAll(newHaplotypeBases, ArrayUtils.subarray(bases, 0, haplotypeInsertLocation)); // bases before the variant
|
||||||
newHaplotypeBases = ArrayUtils.addAll(newHaplotypeBases, altAllele.getBases()); // the alt allele of the variant
|
newHaplotypeBases = ArrayUtils.addAll(newHaplotypeBases, altAllele.getBases()); // the alt allele of the variant
|
||||||
newHaplotypeBases = ArrayUtils.addAll(newHaplotypeBases, ArrayUtils.subarray(bases, haplotypeInsertLocation + refAllele.length(), bases.length)); // bases after the variant
|
newHaplotypeBases = ArrayUtils.addAll(newHaplotypeBases, ArrayUtils.subarray(bases, haplotypeInsertLocation + refAllele.length(), bases.length)); // bases after the variant
|
||||||
return new Haplotype(newHaplotypeBases);
|
return new Haplotype(newHaplotypeBases, altAllele);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class HaplotypeBaseComparator implements Comparator<Haplotype>, Serializable {
|
public static class HaplotypeBaseComparator implements Comparator<Haplotype>, Serializable {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue