void AssignPloidyCallsGaussianMixture()
{
// For segments with (almost) no variants alleles at all, we'll assign them a dummy MAF, and
// we simply won't consider MAF when determining the closest ploidy:
double dummyMAF = -1;
foreach (CanvasSegment segment in this.Segments)
{
// Compute (MAF, Coverage) for this segment:
List<double> MAF = new List<double>();
foreach (float VF in segment.VariantFrequencies) MAF.Add(VF > 0.5 ? 1 - VF : VF);
double medianCoverage = CanvasCommon.Utilities.Median(segment.Counts);
double medianMAF = dummyMAF;
SegmentPloidy bestPloidy = null;
double bestProbability = 0;
if (MAF.Count >= 10)
{
medianMAF = Utilities.Median(MAF);
}
Dictionary<SegmentPloidy, double> posteriorProbabilities = GaussianMixtureModel.EMComputePosteriorProbs(AllPloidies, medianMAF, medianCoverage);
// Find the closest ploidy.
foreach (SegmentPloidy ploidy in AllPloidies)
{
if (bestPloidy == null || posteriorProbabilities[ploidy] > bestProbability)
{
bestProbability = posteriorProbabilities[ploidy];
bestPloidy = ploidy;
}
}
if (bestProbability == 0)
{
// Sanity-check: If we didn't find anything with probability > 0, then fall back to the simplest possible
// thing: Call purely on coverage.
segment.CopyNumber = (int)Math.Round(2 * medianCoverage / this.DiploidCoverage);
segment.MajorChromosomeCount = null;
}
else
{
segment.CopyNumber = bestPloidy.CopyNumber;
segment.MajorChromosomeCount = bestPloidy.MajorChromosomeCount;
if (MAF.Count < 10) segment.MajorChromosomeCount = null; // Don't assign MCC if we don't have variant allele frequencies
}
}
}