/// <summary> /// Выравнивание двух последовательностей. /// Учитывает перестановки A-T и G-C, а также реверсии. /// </summary> public static AlignmentResult Align(Nucleotide[] a0, Nucleotide[] b0, int id1 = 0, int id2 = 0) { var bestDir = Direction.Straight; var bestMask = string.Empty; int bestWeight = -1; int bestShift1 = 0; int bestShift2 = 0; var tmp = new StringBuilder(Math.Max(a0.Length, b0.Length)); foreach (Direction direction in Enum.GetValues(typeof(Direction))) { var a = a0; var b = b0.GetChain(direction); for (int s = 0; s < b.Length + a.Length - 1; s++) // s - смещение a относительно b { int w = 0; var sa = Math.Max(0, a.Length - s - 1); // откуда начинать отсчёт от a var sb = Math.Max(0, s + 1 - a.Length); // откуда начинать отсчёт от b var len = Math.Min(a.Length - sa, b.Length - sb); for (int i = 0; i < len; i++) // безим по смещённым последовательностям { var na = a[sa + i]; var nb = b[sb + i]; if (na == nb) { tmp.Append(na); w++; } else tmp.Append("?"); } if (w > bestWeight) { bestWeight = w; bestMask = tmp.ToString(); bestDir = direction; bestShift1 = sa; bestShift2 = sb; } tmp.Clear(); } } if (bestMask.StartsWith("?")) { var cnt = bestMask.TakeWhile(p => p == '?').Count(); bestShift1 += cnt; bestShift2 += cnt; bestMask = bestMask.Trim('?'); } else bestMask = bestMask.TrimEnd('?'); return new AlignmentResult(bestWeight, bestMask, bestDir, bestShift1, bestShift2, id1, id2); }
public double CalcMaxScore(Nucleotide[] data, CalcMode? mode = null) { var ret = 0.0; foreach (Direction direction in Enum.GetValues(typeof (Direction))) { var b = data.GetChain(direction); for (int i = 0; i < data.Length - Length; i++) { var tmp = CalcScore(b, i, mode); if (tmp > ret) ret = tmp; } } return ret; }