private void ProcessGroup(LcpTree interval) { var size = interval.Lcp; // размер совпадения var cnt = interval.RightBound - interval.LeftBound + 1; // число совпавших if (size < _minGroupSize || size > 100) return; Debug.Assert(cnt > 1); // определим позиции совпавших кусков ДНК var pos = new uint[cnt]; Array.Copy(_suftab, interval.LeftBound, pos, 0, cnt); // определим сам совпавший кусок var str = CutAndCheck(pos[0], size); if (str == null) return; if (_elementGroups.Count > 0) { // проверим, не стоит ли слить с предыдущей группой var last = _elementGroups.Last(); if (last.Count < cnt && str.Length < last.Chain.Length && str.SequenceEqual(last.Chain.Take(str.Length))) { _elementGroups[_elementGroups.Count-1] =new ElementGroup(str, pos); return; } } // сформируем группу и сохраним её var group = new ElementGroup(str, pos); _elementGroups.Add(group); }
/// <summary> /// Миша: уже заполнение хеш-таблицы childtab /// </summary> /// <param name="root"></param> /// <param name="lcpIntervals"></param> /// <param name="dictionary"></param> private void BuildHashTableCustomStack(LcpTree root, List<Interval>[] lcpIntervals, Dictionary<HashKey, LcpValue> dictionary) { var stack = new Stack<KeyValuePair<LcpTree, int>>(); stack.Push(new KeyValuePair<LcpTree, int>(root, 0)); while (stack.Count != 0) { var item = stack.Pop(); var tree = item.Key; var childId = item.Value; if (childId == 0) { lcpIntervals[tree.Lcp].Add(new Interval(tree.LeftBound, tree.RightBound)); AddInterval(tree, dictionary); //AddSingleHashes(tree, dictionary); } if (tree.ChildList.Count > childId) { var childTree = tree.ChildList[childId]; stack.Push(new KeyValuePair<LcpTree, int>(tree, childId + 1)); stack.Push(new KeyValuePair<LcpTree, int>(childTree, 0)); } } }
/// <summary> /// Добавляет в таблицу значение Хеш-Интервал ( начало - конец ) /// </summary> /// <param name="interval"></param> /// <param name="dic"></param> private void AddInterval(LcpTree interval, Dictionary<HashKey, LcpValue> dic) { foreach (var child in interval.ChildList) { var id = _suftab[child.LeftBound] + interval.Lcp; var hash = _hashes[id]; dic[new HashKey(hash, interval)] = new LcpValue(child); } AddSingleHashes(interval, dic); }
/// <summary> /// Добавляет значение хешей на одиночных интервалах ( когда конец и начало интервала одинаковы) в хештаблицу. /// </summary> private void AddSingleHashes(LcpTree interval, Dictionary<HashKey, LcpValue> hashTable) { var left = interval.LeftBound; var right = interval.RightBound; foreach (var c in interval.ChildList) { while (left < c.LeftBound) { var hash = _hashes[_suftab[left] + interval.Lcp]; hashTable[new HashKey(hash, interval.LeftBound, interval.RightBound)] = new LcpValue((_hashesLength - (int)_suftab[left]) - 1, left, left); left++; } left = c.RightBound + 1; } while (left <= right) { var hash = _hashes[_suftab[left] + interval.Lcp]; hashTable[new HashKey(hash, interval.LeftBound, interval.RightBound)] = new LcpValue((_hashesLength - (int)_suftab[left]) - 1, left, left); left++; } }
public LcpValue(LcpTree interval) { Lcp = interval.Lcp; Left = interval.LeftBound; Right = interval.RightBound; }