/// <summary> /// Fit a Gaussian mixture model. /// Fix the means to the model MAF and Coverage and run the EM algorithm until convergence. /// Compute the empirical MAF and Coverage. /// Fix the means to the empirical MAF and Coverage and run the EM algorithm again until convergence. /// Always estimate the full covariance matrix? /// </summary> /// <param name="model"></param> /// <param name="segments"></param> /// <param name="debugPath"></param> /// <returns></returns> private double FitGaussians(CoverageModel model, List <SegmentInfo> segments, string debugPath = null) { List <ModelPoint> modelPoints = InitializeModelPoints(model); GaussianMixtureModel gmm = new GaussianMixtureModel(modelPoints, segments, this.MeanCoverage, this.CoverageWeightingFactor, 0); double likelihood = gmm.Fit(); if (debugPath != null) { // write Gaussian mixture model to debugPath using (FileStream stream = new FileStream(debugPath, FileMode.Create, FileAccess.Write)) using (StreamWriter writer = new StreamWriter(stream)) { writer.WriteLine("CN\tMajor Chr #\tMAF\tCoverage\tOmega\tMu0\tMu1\tSigma00\tSigma01\tSigma10\tSigma11"); foreach (ModelPoint modelPoint in modelPoints) { writer.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}", modelPoint.Ploidy.CopyNumber, modelPoint.Ploidy.MajorChromosomeCount, modelPoint.Ploidy.MixedMinorAlleleFrequency, modelPoint.Ploidy.MixedCoverage, modelPoint.Ploidy.Omega, modelPoint.Ploidy.Mu[0], modelPoint.Ploidy.Mu[1], modelPoint.Ploidy.Sigma[0][0], modelPoint.Ploidy.Sigma[0][1], modelPoint.Ploidy.Sigma[1][0], modelPoint.Ploidy.Sigma[1][1]); } writer.WriteLine(""); writer.WriteLine("MAF\tCoverage\tPosterior Probabilities"); StringBuilder sb = new StringBuilder(); foreach (SegmentInfo segment in segments) { sb.Clear(); sb.AppendFormat("{0}\t{1}", segment.MAF, segment.Coverage); foreach (ModelPoint modelPoint in modelPoints) { sb.AppendFormat("\t{0}", segment.PosteriorProbs[modelPoint]); } writer.WriteLine(sb.ToString()); } } } return(likelihood); }