/// <summary> /// Left aligns the variant using base rotation /// </summary> /// <returns>Tuple of new position, ref and alt allele</returns> public Tuple <int, string, string> LeftAlign(int refPosition, string refAllele, string altAllele) { var trimmedAllele = BiDirectionalTrimmer.Trim(refPosition, refAllele, altAllele); var trimmedPos = trimmedAllele.Item1; var trimmedRefAllele = trimmedAllele.Item2; var trimmedAltAllele = trimmedAllele.Item3; // alignment only makes sense for insertion and deletion if (!(trimmedAltAllele.Length == 0 || trimmedRefAllele.Length == 0)) { return(null); } var upstreamSeq = GetUpstreamSeq(trimmedPos, MaxRotationRange); if (upstreamSeq == null) { throw new InvalidDataException("Reference sequence not set, please check that it is loaded"); } // compressed seq is 0 based var combinedSeq = upstreamSeq; int repeatLength; int i; if (trimmedRefAllele.Length > trimmedAltAllele.Length) { // deletion combinedSeq += trimmedRefAllele; repeatLength = trimmedRefAllele.Length; for (i = combinedSeq.Length - 1; i >= repeatLength; i--, trimmedPos--) { if (combinedSeq[i] != combinedSeq[i - repeatLength]) { break; } } var newRefAllele = combinedSeq.Substring(i + 1 - repeatLength, repeatLength); return(Tuple.Create(trimmedPos, newRefAllele, "")); //alt is empty for deletion } else { //insertion combinedSeq += trimmedAltAllele; repeatLength = trimmedAltAllele.Length; for (i = combinedSeq.Length - 1; i >= repeatLength; i--, trimmedPos--) { if (combinedSeq[i] != combinedSeq[i - repeatLength]) { break; } } var newAltAllele = combinedSeq.Substring(i + 1 - repeatLength, repeatLength); return(Tuple.Create(trimmedPos, "", newAltAllele)); } }
/// <summary> /// Right aligns the variant using base rotation /// </summary> /// <returns>Tuple of new position, ref and alt allele</returns> public Tuple <int, string, string> RightAlign(int refPosition, string refAllele, string altAllele) { var trimmedAllele = BiDirectionalTrimmer.Trim(refPosition, refAllele, altAllele); var trimmedPos = trimmedAllele.Item1; var trimmedRefAllele = trimmedAllele.Item2; var trimmedAltAllele = trimmedAllele.Item3; //alignment only makes sense for insertion and deletion if (!(trimmedAltAllele.Length == 0 || trimmedRefAllele.Length == 0)) { return(null); } var downStreamSeq = GetDownstreamSeq(trimmedPos, MaxRotationRange); if (downStreamSeq == null) { throw new InvalidDataException("Reference sequence not set, please check that it is loaded"); } string combinedSeq; int repeatLength; int i; if (trimmedRefAllele.Length > trimmedAltAllele.Length) { // deletion repeatLength = trimmedRefAllele.Length; combinedSeq = downStreamSeq; for (i = 0; i < combinedSeq.Length - repeatLength; i++, trimmedPos++) { if (combinedSeq[i] != combinedSeq[i + repeatLength]) { break; } } var newRefAllele = combinedSeq.Substring(i, repeatLength); return(Tuple.Create(trimmedPos, newRefAllele, "")); //alt is empty for deletion } else { //insertion combinedSeq = trimmedAltAllele + downStreamSeq; repeatLength = trimmedAltAllele.Length; for (i = 0; i < combinedSeq.Length - repeatLength; i++, trimmedPos++) { if (combinedSeq[i] != combinedSeq[i + repeatLength]) { break; } } var newAltAllele = combinedSeq.Substring(i, repeatLength); return(Tuple.Create(trimmedPos, "", newAltAllele)); } }