private void SetupMocksandExecute(IAlignmentExtractor extractorForRealign, IRealignmentWriter writer, bool skipDups, int maxShift, string chrReference = null, ITargetCaller targetCaller = null, IStateManager stateManager = null) { var extractorForCandidates = new Mock <IAlignmentExtractor>(); var ranker = new Mock <IIndelRanker>(); var indel = new CandidateIndel(new CandidateAllele("chr", 10, "C", "CTATATA", AlleleCategory.Insertion)); var indelFinder = new Mock <IIndelCandidateFinder>(); if (targetCaller == null) { var mocktargetCaller = new Mock <ITargetCaller>(); mocktargetCaller.Setup(x => x.Call(It.IsAny <List <CandidateIndel> >(), It.IsAny <IAlleleSource>())) .Returns(new List <CandidateIndel>() { indel }); targetCaller = mocktargetCaller.Object; } var realigner = new ChrRealigner(new ChrReference() { Sequence = chrReference ?? string.Join(string.Empty, Enumerable.Repeat("ACGT", 10)) }, extractorForCandidates.Object, extractorForRealign, indelFinder.Object, ranker.Object, targetCaller, new RealignStateManager(), writer, skipDuplicates: skipDups, maxRealignShift: maxShift); realigner.Execute(); }
public void GetCandidateGroup() { var stateManager = new RealignStateManager(); var indel1 = new CandidateIndel(new CandidateAllele("chr1", 500, "A", "AT", AlleleCategory.Insertion)); var indel2 = new CandidateIndel(new CandidateAllele("chr1", 510, "A", "AT", AlleleCategory.Insertion)); var indel3 = new CandidateIndel(new CandidateAllele("chr1", 505, "A", "AT", AlleleCategory.Insertion)); var indel4 = new CandidateIndel(new CandidateAllele("chr1", 1500, "A", "AT", AlleleCategory.Insertion)); var indel5 = new CandidateIndel(new CandidateAllele("chr1", 1510, "A", "AT", AlleleCategory.Insertion)); var indel6 = new CandidateIndel(new CandidateAllele("chr1", 3000, "A", "AT", AlleleCategory.Insertion)); var indel7 = new CandidateIndel(new CandidateAllele("chr1", 3010, "A", "AT", AlleleCategory.Insertion)); var allCandidates1 = new List <CandidateIndel> { indel1, indel2, indel3 }; var allCandidates2 = new List <CandidateIndel> { indel4, indel5 }; var allCandidates3 = new List <CandidateIndel> { indel6, indel7 }; var testCandidates1 = new List <CandidateIndel> { indel1, indel2 }; var testCandidates2 = new List <CandidateIndel> { indel3, indel2 }; var testCandidates3 = new List <CandidateIndel> { indel1, indel3 }; stateManager.AddCandidates(allCandidates1); stateManager.AddCandidates(allCandidates2); stateManager.AddCandidates(allCandidates3); var candidateIndelGroup = stateManager.GetCandidateGroups(1); Assert.True(candidateIndelGroup.Count == 0); candidateIndelGroup = stateManager.GetCandidateGroups(2001); Assert.True(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel1.ToString(), indel3.ToString(), indel2.ToString()))); Assert.True(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel1.ToString(), indel3.ToString(), null))); Assert.True(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel3.ToString(), indel2.ToString(), null))); Assert.False(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel1.ToString(), indel2.ToString(), null))); Assert.False(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel2.ToString(), indel3.ToString(), null))); Assert.True(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel4.ToString(), indel5.ToString(), null))); Assert.False(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel5.ToString(), indel4.ToString(), null))); Assert.False(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel6.ToString(), indel7.ToString(), null))); candidateIndelGroup = stateManager.GetCandidateGroups(4000); Assert.True(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel1.ToString(), indel3.ToString(), indel2.ToString()))); Assert.True(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel4.ToString(), indel5.ToString(), null))); Assert.True(candidateIndelGroup.Contains(new Tuple <string, string, string>(indel6.ToString(), indel7.ToString(), null))); }
private bool IsCallable(CandidateIndel indel, IAlleleSource alleleSource) { // set frequency var callable = AlleleHelper.Map(indel); _coverageCalculator.Compute(callable, alleleSource); indel.Frequency = callable.Frequency; return(indel.IsKnown || callable.Frequency >= _frequencyCutoff); }
// Evaluate insertions at read ends to determine if they are partial or unanchored // minimumUnanchoredInsertionLength applies to the indel target that is being realigned against. public static bool EvaluateInsertionAtReadEnds(CigarOp cigar, CandidateIndel indel, int minimumUnanchoredInsertionLength, bool maskPartialInsertion) { if (cigar.Type == 'I') { var isPartial = maskPartialInsertion && cigar.Length < indel.Length; var isUnanchored = indel.Length < minimumUnanchoredInsertionLength; return(isPartial || isUnanchored); } return(false); }
public bool CanCoexist(CandidateIndel indel1, CandidateIndel indel2) { if (indel1.ReferencePosition - indel2.ReferencePosition == 0 && indel1.Type == indel2.Type) { return(false); } // Assumption is that we are dealing with simple insertions & deletions. i.e. either ref or alt will have single base, and the other will have that single base + the varying bases. var indel1Bases = indel1.Type == AlleleCategory.Insertion ? indel1.AlternateAllele : indel1.ReferenceAllele; var indel2Bases = indel2.Type == AlleleCategory.Insertion ? indel2.AlternateAllele : indel2.ReferenceAllele; if (indel1.ReferencePosition - indel2.ReferencePosition == 0 && indel1Bases == indel2Bases) { return(false); } // Note that the "End" only makes sense here if we are talking about deletions. Appropriately, it is not used in any of the insertion cases below. var indel1Start = indel1.ReferencePosition + 1; var indel1End = indel1.ReferencePosition + indel1.Length; var indel2Start = indel2.ReferencePosition + 1; var indel2End = indel2.ReferencePosition + indel2.Length; if (indel1.Type == AlleleCategory.Deletion) { if (indel2.Type == AlleleCategory.Deletion) { // no overlapping deletions if ((indel1Start >= indel2Start && indel1Start <= indel2End) || (indel2Start >= indel1Start && indel2Start <= indel1End)) { return(false); } } else { // insertion cannot start within deletion if (indel2Start > indel1Start && indel2Start <= indel1End) { return(false); } } } else if (indel2.Type == AlleleCategory.Deletion) { // insertion cannot start within deletion if (indel1Start > indel2Start && indel1Start <= indel2End) { return(false); } } return(true); }
public int CompareRightAnchor(CandidateIndel c1, CandidateIndel c2) { var coordinateResult = c1.ReferencePosition.CompareTo(c2.ReferencePosition); if (coordinateResult == 0) { if (c1.Type == AlleleCategory.Insertion) // return insertions first { return(1); } return(-1); } return(coordinateResult); }
private RealignmentResult AddIndelAndGetResult(string readSequence, CandidateIndel priorIndel, string refSequence, bool anchorLeft, int[] positionMap) { var foundIndel = false; var insertionPostionInReadStart = -1; var insertionPositionInReadEnd = -1; if (anchorLeft) { // move along position map to see if we can insert indel for (var i = 0; i < positionMap.Length; i++) { if (positionMap[i] == priorIndel.ReferencePosition && i != positionMap.Length - 1) // make sure we dont end right before indel { foundIndel = true; if (priorIndel.Type == AlleleCategory.Insertion) { insertionPostionInReadStart = i + 1; // stick in -1 for insertion length, then adjust positions after for (var j = i + 1; j < positionMap.Length; j++) { if (j - i <= priorIndel.Length) { positionMap[j] = -1; if (j - i == priorIndel.Length || j == positionMap.Length - 1) { insertionPositionInReadEnd = j; } } else { if (positionMap[j] != -1) // preserve existing insertions { positionMap[j] = positionMap[j] - priorIndel.Length; } } } break; } if (priorIndel.Type == AlleleCategory.Deletion) { // offset positions after deletion for (var j = i + 1; j < positionMap.Length; j++) { if (positionMap[j] != -1) // preserve existing insertions { positionMap[j] += priorIndel.Length; } } break; } } } } else { // walk backwards along position map to see if we can insert indel if (priorIndel.Type == AlleleCategory.Insertion) { for (var i = positionMap.Length - 1; i >= 0; i--) { if (positionMap[i] == priorIndel.ReferencePosition + 1 && i != 0) { foundIndel = true; insertionPositionInReadEnd = i - 1; } else if (positionMap[i] == priorIndel.ReferencePosition && i != positionMap.Length - 1) { foundIndel = true; insertionPositionInReadEnd = i; } if (foundIndel) { // stick in -1 for insertion length, then adjust positions for (var j = insertionPositionInReadEnd; j >= 0; j--) { if (insertionPositionInReadEnd - j + 1 <= priorIndel.Length) { positionMap[j] = -1; if (insertionPositionInReadEnd - j + 1 == priorIndel.Length || j == 0) { insertionPostionInReadStart = j; } } else { if (positionMap[j] != -1) // Don't update position map for things that were already -1 { positionMap[j] = positionMap[j] + priorIndel.Length; } } } break; } } } else if (priorIndel.Type == AlleleCategory.Deletion) { for (var i = positionMap.Length - 1; i >= 1; i--) { if (positionMap[i] == priorIndel.ReferencePosition + priorIndel.Length + 1) //deletions must be fully anchored to be observed { foundIndel = true; // offset positions after deletion for (var j = i - 1; j >= 0; j--) { if (positionMap[j] != -1) // preserve existing insertions { positionMap[j] -= priorIndel.Length; } } break; } } } } if (!foundIndel || !Helper.IsValidMap(positionMap, refSequence)) { return(null); } // verify insertion matches if (priorIndel.Type == AlleleCategory.Insertion) { if (insertionPostionInReadStart == -1 || insertionPositionInReadEnd == -1) { return(null); // weird, this shouldnt ever happen } var readInsertedSequence = readSequence.Substring(insertionPostionInReadStart, insertionPositionInReadEnd - insertionPostionInReadStart + 1); var indelSequence = priorIndel.AlternateAllele.Substring(1); var clippedPriorSequence = anchorLeft ? indelSequence.Substring(0, readInsertedSequence.Length) : indelSequence.Substring(indelSequence.Length - readInsertedSequence.Length); var mismatches = Helper.GetNumMismatches(readInsertedSequence, clippedPriorSequence); if (mismatches == null || mismatches > 0) { return(null); // inserted sequence doesn't match read } } var newCigar = Helper.ConstructCigar(positionMap); var newSummary = Extensions.GetAlignmentSummary(positionMap.First(p => p >= 0) - 1, newCigar, refSequence, readSequence); if (newSummary == null) { return(null); } var readHasPosition = positionMap.Any(p => p >= 0); if (!readHasPosition) { throw new InvalidDataException(string.Format("Trying to generate result and read does not have any alignable bases. ({0}, {1})", newCigar, string.Join(",", positionMap))); } return(new RealignmentResult() { Cigar = newCigar, NumIndels = newCigar.NumIndels(), Position = positionMap.First(p => p >= 0), NumMismatches = newSummary.NumMismatches, NumNonNMismatches = newSummary.NumNonNMismatches, NumMismatchesIncludeSoftclip = newSummary.NumMismatchesIncludeSoftclip, NumSoftclips = newSummary.NumSoftclips, NumNonNSoftclips = newSummary.NumNonNSoftclips, NumIndelBases = newSummary.NumIndelBases }); }