private void ComputeCoverageTest(BaseCalledAllele variant, List <AlleleCount> stagedCounts, int[] expectedCoverageByDirection, bool checkAux = true, int alleleSupport = 5, int expectedSnvRef = 0, int takenRefSupport = 0) { variant.AlleleSupport = alleleSupport; var mockStateManager = CreateMockStateManager(stagedCounts, takenRefSupport); var expectedCoverage = expectedCoverageByDirection.Sum(); CoverageCalculator.Compute(variant, mockStateManager); Assert.Equal(expectedCoverage, variant.TotalCoverage); for (var i = 0; i < expectedCoverageByDirection.Length; i++) { Assert.Equal(expectedCoverageByDirection[i], variant.TotalCoverageByDirection[i]); } if (checkAux) { //"Reference" Support should be the coverage less the variant support, if we don't have an SNV if (variant is CalledVariant && variant.Type != AlleleCategory.Snv) { Assert.Equal(expectedCoverage - variant.AlleleSupport, ((CalledVariant)variant).ReferenceSupport); } else { Assert.Equal(expectedSnvRef, ((CalledVariant)variant).ReferenceSupport); } //Frequency should be support/coverage Assert.Equal((float)variant.AlleleSupport / expectedCoverage, variant.Frequency); } }
public static void Compute(BaseCalledAllele allele, IStateManager alleleCountSource) { if (allele is CalledReference) { CalculateSinglePoint(allele, alleleCountSource); } else { var variant = (CalledVariant)allele; switch (variant.Type) { case AlleleCategory.Deletion: CalculateSpanning(variant, alleleCountSource, variant.Coordinate + 1, variant.Coordinate + variant.Length, true); break; case AlleleCategory.Mnv: CalculateSpanning(variant, alleleCountSource, variant.Coordinate, variant.Coordinate + variant.Length - 1, true); break; case AlleleCategory.Insertion: CalculateSpanning(variant, alleleCountSource, variant.Coordinate, variant.Coordinate + 1, false); break; default: CalculateSinglePoint(variant, alleleCountSource); break; } } }
private static bool OverlapMatches(BaseCalledAllele overlap, BaseCalledAllele alleleToReassign) { var overlapIndexInFailedMnv = overlap.Coordinate - alleleToReassign.Coordinate; var overlapAlleleLength = overlap.Alternate.Length; return(overlap.Alternate.Equals(alleleToReassign.Alternate.Substring(overlapIndexInFailedMnv, overlapAlleleLength))); }
public static void Process(BaseCalledAllele allele, GenotypeModel model, float minFrequency, int minCoverage, int?filterVariantQscore, bool filterSingleStrandVariants) { SetFractionNoCall(allele); ApplyFilters(allele, minCoverage, filterVariantQscore, filterSingleStrandVariants); SetGenotype(allele, model, minFrequency); }
private static bool VerifyCalledAlleleMatch(BaseCalledAllele expected, BaseCalledAllele actual) { return(expected.Coordinate == actual.Coordinate && expected.Type == actual.Type && expected.Reference == actual.Reference && expected.Alternate == actual.Alternate && expected.AlleleSupport == actual.AlleleSupport); }
private CandidateAllele Map(BaseCalledAllele called) { var candidateAllele = new CandidateAllele(called.Chromosome, called.Coordinate, called.Reference, called.Alternate, called.Type); Array.Copy(called.SupportByDirection, candidateAllele.SupportByDirection, called.SupportByDirection.Length); return(candidateAllele); }
private static bool IsPotentialOverlap(BaseCalledAllele callableAllele, BaseCalledAllele failedMnv) { return(callableAllele.Coordinate >= failedMnv.Coordinate && callableAllele.Chromosome == failedMnv.Chromosome && callableAllele.Coordinate <= (failedMnv.Coordinate + failedMnv.Alternate.Length) && callableAllele.Alternate.Length <= failedMnv.Alternate.Length && callableAllele.Coordinate + callableAllele.Alternate.Length <= (failedMnv.Coordinate + failedMnv.Alternate.Length) && (callableAllele.Type == AlleleCategory.Mnv || callableAllele.Type == AlleleCategory.Snv || callableAllele.Type == AlleleCategory.Reference)); }
private void ProcessVariant(IStateManager source, BaseCalledAllele variant) { // determine metrics CoverageCalculator.Compute(variant, source); QualityCalculator.Compute(variant, _config.MaxVariantQscore, _config.EstimatedBaseCallQuality); StrandBiasCalculator.Compute(variant, variant.SupportByDirection, _config.EstimatedBaseCallQuality, _config.StrandBiasFilterThreshold, _config.StrandBiasModel); // set genotype, filter, etc AlleleProcessor.Process(variant, _config.GenotypeModel, _config.MinFrequency, _config.MinCoverage, _config.VariantQscoreFilterThreshold, _config.FilterSingleStrandVariants); }
/// <summary> /// Assign a q-score to a SNP, given (CallCount / Coverage) frequency. /// </summary> public static void Compute(BaseCalledAllele allele, int maxQScore, int estimatedBaseCallQuality) { if (allele.TotalCoverage == 0) { allele.Qscore = 0; } else { allele.Qscore = AssignPoissonQScore(allele.AlleleSupport, allele.TotalCoverage, estimatedBaseCallQuality, maxQScore); } }
private static void SetFractionNoCall(BaseCalledAllele allele) { var allReads = (float)(allele.TotalCoverage + allele.NumNoCalls); if (allReads == 0) { allele.FractionNoCalls = 0; } else { allele.FractionNoCalls = allele.NumNoCalls / allReads; } }
public static void PrintBiasStats(StreamWriter writer, BaseCalledAllele variant) { if (variant.Reference == variant.Alternate) { return; //skip ref calls. } var strandBiasResults = StatsToString(variant.StrandBiasResults); StringBuilder sb = new StringBuilder(string.Format("{0}\t{1}\t{2}\t{3}\t", variant.Chromosome, variant.Coordinate, variant.Reference, variant.Alternate)); sb.Append(strandBiasResults); writer.WriteLine(sb.ToString()); }
private bool MatchVariants(BaseCalledAllele calledVariant, CandidateAllele candidateVariant, int?expectedSupport = null, float?expectedFreq = null) { if (calledVariant.Chromosome == candidateVariant.Chromosome && calledVariant.Coordinate == candidateVariant.Coordinate && calledVariant.Reference == candidateVariant.Reference && calledVariant.Alternate == candidateVariant.Alternate && calledVariant.Type == candidateVariant.Type && (expectedFreq == null || calledVariant.Frequency == expectedFreq) && (expectedSupport == null || calledVariant.AlleleSupport == expectedSupport) ) { return(true); } return(false); }
private static IEnumerable <BaseCalledAllele> CreateAllelesFromRemainder(BaseCalledAllele overlap, BaseCalledAllele alleleToReassign) { var remainders = new List <BaseCalledAllele>(); var overlapIndexInFailedMnv = overlap.Coordinate - alleleToReassign.Coordinate; var overlapAlleleLength = overlap.Alternate.Length; var rightSideOverlap = overlapIndexInFailedMnv + overlapAlleleLength; if (alleleToReassign.Alternate.Length - rightSideOverlap > 0 && rightSideOverlap <= alleleToReassign.Coordinate + alleleToReassign.Alternate.Length) { var rightRemainder = CreateVariant(alleleToReassign.Chromosome, alleleToReassign.Coordinate + rightSideOverlap, alleleToReassign.AlleleSupport, alleleToReassign.Alternate.Substring(rightSideOverlap, alleleToReassign.Alternate.Length - rightSideOverlap), alleleToReassign.Reference.Substring(rightSideOverlap, alleleToReassign.Alternate.Length - rightSideOverlap), alleleToReassign.SupportByDirection); if (!(rightRemainder is CalledReference)) { remainders.Add(rightRemainder); } } if (overlapIndexInFailedMnv > 0) { var leftRemainder = CreateVariant(alleleToReassign.Chromosome, alleleToReassign.Coordinate, alleleToReassign.AlleleSupport, alleleToReassign.Alternate.Substring(0, overlapIndexInFailedMnv), alleleToReassign.Reference.Substring(0, overlapIndexInFailedMnv), alleleToReassign.SupportByDirection ); if (!(leftRemainder is CalledReference)) { remainders.Add(leftRemainder); } } //if any remainders begin with ref, split those out into separate remainders. var remaindersWithRefsBrokenOut = new List <BaseCalledAllele>(); foreach (var remainder in remainders) { remaindersWithRefsBrokenOut.AddRange(BreakOffEdgeReferences(remainder)); } return(remaindersWithRefsBrokenOut); }
private static CalledReference Map(BaseCalledAllele variant) { return(new CalledReference() { Chromosome = variant.Chromosome, Coordinate = variant.Coordinate, Alternate = variant.Alternate, Reference = variant.Reference, StrandBiasResults = variant.StrandBiasResults, Filters = variant.Filters, Genotype = variant.Genotype, AlleleSupport = variant.AlleleSupport, FractionNoCalls = variant.FractionNoCalls, Qscore = variant.Qscore, TotalCoverage = variant.TotalCoverage }); }
private static void SetGenotype(BaseCalledAllele allele, GenotypeModel model, float minFrequency) { if (allele.Filters.Contains(FilterType.LowDepth)) { allele.Genotype = allele is CalledReference ? Genotype.RefLikeNoCall : Genotype.AltLikeNoCall; } else if (allele is CalledVariant && model != GenotypeModel.None) { var variant = (CalledVariant)allele; // if we see no evidence of a reference allele, according to the genotype model // then presume our variant is a homozygous alt if (variant.RefFrequency < (model == GenotypeModel.Symmetrical ? minFrequency : 0.25f)) { //if we are using the thresholding model, if we see less than 25% reference, variant.Genotype = Genotype.HomozygousAlt; } } }
private static IEnumerable <BaseCalledAllele> BreakDownToSingleNucCalls(BaseCalledAllele alleleToReassign) { var singleNucCalls = new List <BaseCalledAllele>(); for (var i = 0; i < alleleToReassign.Alternate.Length; i++) { var alternate = alleleToReassign.Alternate.Substring(i, 1); var reference = alleleToReassign.Reference.Substring(i, 1); var singleNucCall = CreateVariant(alleleToReassign.Chromosome, alleleToReassign.Coordinate + i, alleleToReassign.AlleleSupport, alternate, reference, alleleToReassign.SupportByDirection); if (!(singleNucCall is CalledReference)) { singleNucCalls.Add(singleNucCall); } } return(singleNucCalls); }
private void WriteVariant(StreamWriter writer, BaseCalledAllele variant) { try { string[] formatAndSampleString = ConstructFormatAndSampleString(variant); //CHROM writer.Write(variant.Chromosome + "\t"); //POS writer.Write(variant.Coordinate + "\t"); //ID writer.Write("." + "\t"); //REF writer.Write(variant.Reference + "\t"); //ALT if ((variant.Genotype == Genotype.HomozygousRef) || (variant.Genotype == Genotype.RefLikeNoCall)) { //note, nocall is only used for low-depth regions where we do not try to var-call. writer.Write("." + "\t"); } else { writer.Write((variant.Alternate ?? ".") + "\t"); } //QUAL writer.Write(variant.Qscore + "\t"); //FILTER writer.Write(MapFilters(variant.Filters) + "\t"); //INFO writer.Write(DepthInfo + "=" + variant.TotalCoverage + "\t"); //FORMAT writer.Write(formatAndSampleString[0] + "\t"); //SAMPLE writer.Write(formatAndSampleString[1] + "\n"); } catch (Exception ex) { OnException(ex); } }
public static IEnumerable <BaseCalledAllele> BreakOffEdgeReferences(BaseCalledAllele allele) { var alleles = new List <BaseCalledAllele>(); if (allele.Type != AlleleCategory.Mnv) { alleles.Add(allele); return(alleles); } var leftAdjust = 0; var rightAdjust = 0; for (var i = 0; i < allele.Reference.Length; i++) { if (allele.Reference[i] != allele.Alternate[i]) { break; } leftAdjust++; } for (var i = 0; i < allele.Reference.Length; i++) { var indexInAllele = allele.Reference.Length - 1 - i; if (allele.Reference[indexInAllele] != allele.Alternate[indexInAllele]) { break; } rightAdjust++; } var restOfMnv = CreateVariant(allele.Chromosome, allele.Coordinate + leftAdjust, allele.AlleleSupport, allele.Alternate.Substring(leftAdjust, allele.Alternate.Length - (leftAdjust + rightAdjust)), allele.Reference.Substring(leftAdjust, allele.Reference.Length - (leftAdjust + rightAdjust)), allele.SupportByDirection); alleles.Add(restOfMnv); return(alleles); }
private static void ProcessOverlap(int?blockMaxPos, BaseCalledAllele overlap, BaseCalledAllele alleleToReassign, List <BaseCalledAllele> remainderAlleles, List <BaseCalledAllele> outsideThisBlock) { overlap.AlleleSupport += alleleToReassign.AlleleSupport; for (int i = 0; i < alleleToReassign.SupportByDirection.Length; i++) { overlap.SupportByDirection[i] += alleleToReassign.SupportByDirection[i]; } remainderAlleles.Remove(alleleToReassign); var remainders = CreateAllelesFromRemainder(overlap, alleleToReassign); if (blockMaxPos.HasValue) { if (overlap.Coordinate > blockMaxPos) { remainderAlleles.Remove(overlap); outsideThisBlock.Add(overlap); } foreach (var remainder in remainders) { if (remainder.Coordinate <= blockMaxPos) { remainderAlleles.Add(remainder); } else { outsideThisBlock.Add(remainder); } } } else { remainderAlleles.AddRange(remainders); } }
private static void CalculateSinglePoint(BaseCalledAllele allele, IStateManager alleleCountSource) { var variant = allele as CalledVariant; for (var direction = 0; direction < Constants.NumDirectionTypes; direction++) { foreach (var alleleType in Constants.CoverageContributingAlleles) { allele.TotalCoverageByDirection[direction] += alleleCountSource.GetAlleleCount(allele.Coordinate, alleleType, (DirectionType)direction); if (alleleType != AlleleHelper.GetAlleleType(allele.Reference)) { continue; } if (variant != null) { variant.ReferenceSupport += alleleCountSource.GetAlleleCount(variant.Coordinate, alleleType, (DirectionType)direction); } } allele.TotalCoverage += allele.TotalCoverageByDirection[direction]; allele.NumNoCalls += alleleCountSource.GetAlleleCount(allele.Coordinate, AlleleType.N, (DirectionType)direction); } // adjust for reference counts already taken up by gapped mnvs var gappedRefCounts = alleleCountSource.GetGappedMnvRefCount(allele.Coordinate); if (allele.Type == AlleleCategory.Snv && variant != null) { variant.ReferenceSupport -= gappedRefCounts; } else if (allele.Type == AlleleCategory.Reference) { allele.AlleleSupport -= gappedRefCounts; } }
private string[] ConstructFormatAndSampleString(BaseCalledAllele variant) { var gtString = MapGenotype(variant.Genotype); var isReference = variant is CalledReference; var alleleCountString = isReference ? variant.AlleleSupport.ToString() : string.Format("{0},{1}", ((CalledVariant)variant).ReferenceSupport, variant.AlleleSupport); var frequencyString = (isReference ? (1 - variant.Frequency) : variant.Frequency).ToString(_frequencySigFigFormat); var formatStringBuilder = new StringBuilder("GT:GQ:AD:VF"); var sampleStringBuilder = new StringBuilder(string.Format("{0}:{1}:{2}:{3}", gtString, variant.Qscore, alleleCountString, frequencyString)); if (_config.ShouldOutputStrandBiasAndNoiseLevel) { var biasScoreString = (Math.Min(Math.Max(MinStrandBiasScore, variant.StrandBiasResults.GATKBiasScore), MaxStrandBiasScore)).ToString("0.0000"); formatStringBuilder.Append(":NL:SB"); sampleStringBuilder.Append(string.Format(":{0}:{1}", _config.EstimatedBaseCallQuality, biasScoreString)); } if (_config.ShouldOutputNoCallFraction) { var noCallFractionString = variant.FractionNoCalls.ToString("0.0000"); formatStringBuilder.Append(":NC"); sampleStringBuilder.Append(string.Format(":{0}", noCallFractionString)); } return(new [] { formatStringBuilder.ToString(), sampleStringBuilder.ToString() }); }
private bool IsCallable(BaseCalledAllele allele) { if (allele is CalledReference) // reference calls always get emitted { return(true); } // determine if we should discard variant if (allele.TotalCoverage < _config.MinCoverage && !_config.IncludeReferenceCalls) { return(false); // if gvcf, call but filter later } if (allele.TotalCoverage != 0 && allele.Frequency < _config.MinFrequency) { return(false); } if (allele.Qscore < _config.MinVariantQscore) { return(false); } return(true); }
private static void ApplyFilters(BaseCalledAllele allele, int minCoverage, int?variantQscoreThreshold, bool filterSingleStrandVariants) { //Reset filters allele.Filters = new List <FilterType>(); if (allele.TotalCoverage < minCoverage) { allele.AddFilter(FilterType.LowDepth); } if (variantQscoreThreshold.HasValue && allele.Qscore < variantQscoreThreshold) { allele.AddFilter(FilterType.LowQscore); } if (allele is CalledVariant) { if (!allele.StrandBiasResults.BiasAcceptable || (filterSingleStrandVariants && !allele.StrandBiasResults.VarPresentOnBothStrands)) { allele.AddFilter(FilterType.StrandBias); } } }
public void ReallocateMnvs_BlockStraddling() { var failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 99, Reference = "TTTT", Alternate = "AGCG", SupportByDirection = new [] { 10, 20, 30 } } }; // If there are any overlapping MNVs in the current block, reallocate to them. var calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 99, Reference = "TTT", Alternate = "AGC", }, }; var leftoversInNextBlock = MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles, 100); PrintResults(calledAlleles); Assert.Equal(1, calledAlleles.Count); Assert.True(calledAlleles.All(a => a.AlleleSupport == 6)); PrintResults(leftoversInNextBlock.ToList()); Assert.Equal(1, leftoversInNextBlock.Count()); Assert.True(VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Snv, Coordinate = 102, Reference = "T", Alternate = "G", AlleleSupport = 1 }, leftoversInNextBlock.First())); // If there are no overlapping MNVs in the current block to reallocate to, take what is in the current block // as new SNVs and pass the remaining chunk as an MNV for the next block to deal with. failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 99, Reference = "TTTT", Alternate = "AGCG", SupportByDirection = new [] { 10, 20, 30 } } }; calledAlleles = new List <BaseCalledAllele>(); leftoversInNextBlock = MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles, 100); PrintResults(calledAlleles); Assert.Equal(2, calledAlleles.Count); Assert.Equal(calledAlleles.Count(x => VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Snv, Coordinate = 100, Reference = "T", Alternate = "G", AlleleSupport = 1 }, x)), 1); PrintResults(leftoversInNextBlock.ToList()); Assert.Equal(1, leftoversInNextBlock.Count()); Assert.True(VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Mnv, Coordinate = 101, Reference = "TT", Alternate = "CG", AlleleSupport = 1 }, leftoversInNextBlock.First())); // If there are no overlapping MNVs in the current block to reallocate to, take what is in the current block // and reallocate to any existing SNVs and pass the remaining chunk as an MNV for the next block to deal with. failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 99, Reference = "TTTT", Alternate = "AGCG", SupportByDirection = new [] { 10, 20, 30 } } }; var existingSNV = new BaseCalledAllele { AlleleSupport = 5, Coordinate = 99, Reference = "T", Alternate = "A", }; calledAlleles = new List <BaseCalledAllele> { existingSNV }; leftoversInNextBlock = MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles, 100); PrintResults(calledAlleles); Assert.Equal(2, calledAlleles.Count); Assert.True(calledAlleles.First(x => VerifyCalledAlleleMatch(existingSNV, x)).AlleleSupport == 6); Assert.Equal(calledAlleles.Count(x => VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Snv, Coordinate = 100, Reference = "T", Alternate = "G", AlleleSupport = 1 }, x)), 1); PrintResults(leftoversInNextBlock.ToList()); Assert.Equal(1, leftoversInNextBlock.Count()); Assert.True(VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Mnv, Coordinate = 101, Reference = "TT", Alternate = "CG", AlleleSupport = 1 }, leftoversInNextBlock.First())); // When passing remaining chunk to next block, if it has now been trimmed such that there is a reference edge, // pass it as a reference plus the rest of the MNV failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 99, Reference = "TTTTT", Alternate = "AGTCG", SupportByDirection = new [] { 10, 20, 30 } } }; calledAlleles = new List <BaseCalledAllele>(); leftoversInNextBlock = MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles, 100); PrintResults(calledAlleles); Assert.Equal(2, calledAlleles.Count); Assert.Equal(calledAlleles.Count(x => VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Snv, Coordinate = 99, Reference = "T", Alternate = "A", AlleleSupport = 1 }, x)), 1); Assert.Equal(calledAlleles.Count(x => VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Snv, Coordinate = 100, Reference = "T", Alternate = "G", AlleleSupport = 1 }, x)), 1); PrintResults(leftoversInNextBlock.ToList()); Assert.Equal(1, leftoversInNextBlock.Count()); Assert.Equal(0, leftoversInNextBlock.Count(x => VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Reference, Coordinate = 101, Reference = "T", Alternate = "T", AlleleSupport = 1 }, x))); Assert.Equal(1, leftoversInNextBlock.Count(x => VerifyCalledAlleleMatch( new BaseCalledAllele { Type = AlleleCategory.Mnv, Coordinate = 102, Reference = "TT", Alternate = "CG", AlleleSupport = 1 }, x))); }
public void ReallocateFailedMnvs() { var failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 101, Reference = "TTTTTTT", Alternate = "ATCAGGC", SupportByDirection = new [] { 10, 20, 30 } } }; //Happy path - break into three existing alleles, and up their support var calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC", }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 104, Reference = "TT", Alternate = "AG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 106, Reference = "TT", Alternate = "GC" }, }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(3, calledAlleles.Count); Assert.True(calledAlleles.All(a => a.AlleleSupport == 6)); //Second half of big MNV could go to two called alleles or one bigger MNV - should take the big one. var triNucVariant = new BaseCalledAllele() { AlleleSupport = 5, Coordinate = 104, Reference = "TTT", Alternate = "AGG", SupportByDirection = new [] { 5, 6, 1 } }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 104, Reference = "TT", Alternate = "AG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 106, Reference = "TT", Alternate = "GC" }, triNucVariant }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(2, calledAlleles.Count(a => a.AlleleSupport == 6)); Assert.True(calledAlleles.Where(a => a.Alternate.Length == 2).All(a => a.AlleleSupport == 5)); Assert.Equal(6, triNucVariant.AlleleSupport); //Support by direction should be incremented by the amount of the failed variant Assert.Equal(new[] { 15, 26, 31 }, triNucVariant.SupportByDirection); //Big MNV has two valid sub-MNVs of equal length. Should take the one with higher support. var lowSupportTNV = new BaseCalledAllele() { AlleleSupport = 3, Coordinate = 103, Reference = "TTT", Alternate = "CAG" }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 104, Reference = "TT", Alternate = "AG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 106, Reference = "TT", Alternate = "GC" }, lowSupportTNV }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(3, calledAlleles.Count(a => a.AlleleSupport == 6)); Assert.Equal(3, lowSupportTNV.AlleleSupport); Assert.Equal(new[] { 0, 0, 0 }, lowSupportTNV.SupportByDirection); //MNV at end has some overlap but extends beyond big MNV. Should not get any support from big MNV var mnvExtendsPastBigMnv = new BaseCalledAllele() { AlleleSupport = 3, Coordinate = 106, Reference = "TTT", Alternate = "GCC" }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 104, Reference = "TT", Alternate = "AG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 106, Reference = "TT", Alternate = "GC" }, mnvExtendsPastBigMnv }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(3, calledAlleles.Count(a => a.AlleleSupport == 6)); Assert.Equal(3, mnvExtendsPastBigMnv.AlleleSupport); //MNV at beginning has some overlap but starts before big MNV. Should not get any support from big MNV var mnvStartsBeforeBigMnv = new BaseCalledAllele() { AlleleSupport = 3, Coordinate = 100, Reference = "TTT", Alternate = "GAT" }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 104, Reference = "TT", Alternate = "AG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 106, Reference = "TT", Alternate = "GC" }, mnvStartsBeforeBigMnv }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(3, calledAlleles.Count(a => a.AlleleSupport == 6)); Assert.Equal(3, mnvStartsBeforeBigMnv.AlleleSupport); //Should not reallocate anything to indels var deletion = new BaseCalledAllele() { Coordinate = 101, AlleleSupport = 5, Alternate = "ATC", Type = AlleleCategory.Deletion }; calledAlleles = new List <BaseCalledAllele>() { deletion }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(5, deletion.AlleleSupport); //Should work with overlaps that are not at the first base failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 100, Reference = "TTTTTTTT", Alternate = "GATCAGGC" } }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 104, Reference = "TT", Alternate = "AG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 106, Reference = "TT", Alternate = "GC" }, }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(3, calledAlleles.Count(a => a.Alternate.Length > 1)); //All three original MNVs should still be there Assert.Equal(1, calledAlleles.Count(a => a.Alternate.Length == 1)); //Should have an additional SNV for the first base Assert.Equal(1, calledAlleles.First(a => a.Alternate.Length == 1).AlleleSupport); Assert.Equal(AlleleCategory.Snv, calledAlleles.First(a => a.Alternate.Length == 1).Type); Assert.True(calledAlleles.Where(a => a.Alternate.Length > 1).All(a => a.AlleleSupport == 6)); //If MNV can't be fully attributed to MNVs, break out into SNVs failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 101, Reference = "TTTTTTTT", Alternate = "ATCAGGCA" } }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 105, Reference = "TT", Alternate = "GG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 107, Reference = "TT", Alternate = "CA" }, }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); var expectedSnv = new BaseCalledAllele { AlleleSupport = 1, Reference = "T", Alternate = "A", Coordinate = 104 }; Assert.Equal(3, calledAlleles.Count(a => a.Alternate.Length > 1)); //All three original MNVs should still be there Assert.Equal(1, calledAlleles.Count(a => a.Alternate.Length == 1)); //Should have an additional SNV for the first base Assert.True(VerifyCalledAlleleMatch(expectedSnv, calledAlleles.First(a => a.Alternate.Length == 1))); Assert.True(calledAlleles.Where(a => a.Alternate.Length > 1).All(a => a.AlleleSupport == 6)); //If MNV includes some reference bases, make sure they are accounted for as refs failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 101, Reference = "TTTTTTTT", Alternate = "ATCTGGCA" } }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 105, Reference = "TT", Alternate = "GG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 107, Reference = "TT", Alternate = "CA" }, }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); var expectedRef = new CalledReference() { AlleleSupport = 1, Reference = "T", Alternate = "T", Coordinate = 104 }; Assert.Equal(3, calledAlleles.Count(a => a.Alternate.Length > 1)); //All three original MNVs should still be there Assert.Equal(0, calledAlleles.Count(a => a.Alternate.Length == 1)); //Should NOT have an additional SNV for the first base Assert.True(calledAlleles.Where(a => a.Alternate.Length > 1).All(a => a.AlleleSupport == 6)); //If MNV can't be fully attributed to MNVs, break out into SNVs failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 101, Reference = "TTTTTTTT", Alternate = "ATCAGGCA" } }; expectedSnv = new BaseCalledAllele { AlleleSupport = 1, Reference = "T", Alternate = "A", Coordinate = 104 }; calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 105, Reference = "TT", Alternate = "GG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 107, Reference = "TT", Alternate = "CA" }, expectedSnv }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(3, calledAlleles.Count(a => a.Alternate.Length > 1)); //All three original MNVs should still be there Assert.Equal(1, calledAlleles.Count(a => a.Alternate.Length == 1)); //Should have an additional SNV for the first base Assert.Equal(2, calledAlleles.First(a => a.Alternate.Length == 1).AlleleSupport); Assert.True(calledAlleles.Where(a => a.Alternate.Length > 1).All(a => a.AlleleSupport == 6)); //If MNV includes some reference bases - allocate to existing references if exist failedMnvs = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 1, Coordinate = 101, Reference = "TTTTTTTT", Alternate = "ATCTGGCA" } }; expectedRef = new CalledReference { AlleleSupport = 1, Reference = "T", Alternate = "T", Coordinate = 104 }; //Don't output references ever calledAlleles = new List <BaseCalledAllele> { new BaseCalledAllele { AlleleSupport = 5, Coordinate = 101, Reference = "TTT", Alternate = "ATC" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 105, Reference = "TT", Alternate = "GG" }, new BaseCalledAllele { AlleleSupport = 5, Coordinate = 107, Reference = "TT", Alternate = "CA" }, }; MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); MnvReallocator.ReallocateFailedMnvs(failedMnvs, calledAlleles); PrintResults(calledAlleles); Assert.Equal(3, calledAlleles.Count(a => a.Alternate.Length > 1)); //All three original MNVs should still be there Assert.False(calledAlleles.Any(a => a is CalledReference)); }
private bool ShouldReport(BaseCalledAllele allele) { return(_intervalSet == null || _intervalSet.Intervals.Any(i => i.ContainsPosition(allele.Coordinate))); }
public static void Compute(BaseCalledAllele variant, int[] supportByDirection, int qNoise, double acceptanceCriteria, StrandBiasModel strandBiasModel) { variant.StrandBiasResults = CalculateStrandBiasResults(variant.TotalCoverageByDirection, supportByDirection, qNoise, acceptanceCriteria, strandBiasModel); }