Uliniawianie całych genomów 7 czerwca 2006 1 Wprowadzenie Dzięki postępowi technologicznemu jesteśmy w stanie sekwencjonować całe genomy organizmów. Pojawia się zatem zapotrzebowanie na narzędzia umożliwiające ich porównywanie. Standardowe metody uliniawiania sekwencji są w tym kontekście stosunkowo mało użyteczne z dwóch powodów: biorą pod uwagę jedynie punktowe mutacje, insercje i delecje, a chcemy również zwracać uwagę na transpozycje, insercje i delecje dużych fragmentów łańcucha DNA, potrzebują zbyt wiele zasobów, by mogły działać na tak dużą skalę. Omówimy na tym wykładzie podejście do problemu uliniawiania całych genomów bazujące na następującej definicji. Definicja 1. Dane są dwa słowa v i w. MUMem 1 nazwiemy każde wspólne podsłowo v i w, spełniające warunki: jest dłuższe niż pewien ustalony parametr, jest maksymalne w sensie zawierania (tzn. nie jest zawarte w żadnym innym wspólnym podsłowie v i w), występuje dokładnie raz w każdym ze słów v i w. Z dużym prawdopodobieństwem MUMy są częścią uliniowienia dwóch genomów. Podstawowym zadaniem będzie więc znajdywanie MUMów (zajmiemy się tym w sekcji 2). 2 Znajdywanie MUMów Wiele problemów dotyczących słów (w tym problem znajdywania MUMów) można rozwiązać efektywnie wykorzystując drzewa sufiksowe. W ostatnich latach pojawiło się wiele prac pokazujących jak algorytmy działające na drzewach sufiksowych przekształcać w algorytmy wykorzystujące tablice sufiksowe 1 ang. Maximal Unique Match 1
wzbogacone o pewne dodatkowe struktury danych. Nowe wersje tych algorytmów mają mniejsze zapotrzebowanie na pamięć (mniejsza stała przy złożoności pamięciowej) i działają szybciej ze względu na większą lokalność odwołań do pamięci. W pracach [AKO04, AKO02] autorzy pokazują w jaki sposób można wykorzystać wzbogacone tablice sufiksowe 2 do znajdywania MUMów. Poniżej wprowadzamy odpowiednie definicje i przedstawiamy algorytm rozwiązujący to zadanie w czasie liniowym względem długości słów (przy odpowiednich założeniach dotyczących alfabetu). 2.1 Notacja Będziemy używali oznaczenia u[i, j] na podsłowo słowa u składające się z liter na pozycjach 3 od i do j włącznie. Przez t oznaczamy długość tablicy lub słowa t. Jeśli t jest tablicą, to t 1 oznacza tablicę taką, że t 1 [i] = j t[j] = i. Tam gdzie będziemy korzystali z tej notacji, tablica t będzie zawierać liczby ze zbioru {0,..., t 1}. Jest jasne, że w takim przypadku znając tablicę t można utworzyć tablicę t 1 w czasie i pamięci liniowej względem t. 2.2 Tablice sufiksowe Definicja 2. Dane jest słowo u nad alfabetem {1,..., u }. Tablicą sufiksową suf nazywamy tablicę długości u zawierającą indeksy początków sufiksów słowa u w kolejności leksykograficznej. Tabela 1: Tablica sufiksowa dla słowa MISSISSIPPI. i 0 1 2 3 4 5 6 7 8 9 10 suf[i] 10 7 4 1 0 9 8 6 3 5 2 Algorytm 1 Budowanie tablicy suf. 1: if u 3 then 2: zbuduj tablicę suf bezpośrednio 3: else 4: posortuj sufiksy u zaczynające się na pozycjach {i i mod 3 0} {powyższy krok może wymagać rekurencyjnego wywołania} 5: posortuj sufiksy u zaczynające się na pozycjach {i i mod 3 = 0} 6: zbuduj tablicę suf scalając obydwa porządki 7: end if 2 ang. enhenced suffix arrays 3 indeksujemy od 0 2
Pochodzący z pracy [KS03] algorytm 1 służy do budowy tablicy sufiksowej. Aby wykonać krok 4 znajdujemy etykiety e i {1,..., 2n 4 3 }, dla i mod 3 0, takie że e i e j u[i, i + 2] u[j, j + 2]. Odzwierciedlają one porządek leksykograficzny na podsłowach słowa u długości 3, zaczynających się na pozycjach {i i mod 3 0} (zakładamy przy tym, że dla i = u 2 oraz i = u 1 bierzemy odpowiednio podsłowa u[i, i + 1]0 oraz u[i]00). Aby etykiety te znaleźć, wystarczy posortować opisane wyżej podsłowa algorytmem radix sort (czas liniowy) i nadać im kolejne numery. Jeśli etykiety są parami różne, to odzwierciedlają porządek leksykograficzny na sufiksach słowa u zaczynających się na pozycjach {i i mod 3 0} i krok 4 jest zakończony. W przeciwnym przypadku budujemy słowo u [e i i mod 3 = 1][e i i mod 3 = 2] (zobacz rysunek 1) i znajdujemy rekurencyjnie tablicę sufiksową suf tego słowa. Dzięki dopisa- Rysunek 1: Dla słowa u = MISSISSIPPI, słowo u ma następującą postać (etykiety e i odpowiadają trójliterowym podsłowom). ISS ISS IPP I00 SSI SSI PPI niu na końcu słowa u liter 00, tablica suf opisuje porządek leksykograficzny na sufiksach słowa u zaczynających się na pozycjach {i i mod 3 0}. Krok 5 wykonujemy sortując pary (u[i], u[i + 1, u 1]), dla i mod 3 = 0. Porządek na drugich elementach tych par został wyliczony w poprzednim kroku, więc sortowanie możemy przeprowadzić w czasie liniowym za pomocą algorytmu radix sort. W kroku 6 musimy umieć porównywać słowa u[i, u 1] dla pewnego i mod 3 0 oraz u[j, u 1] dla pewnego j mod 3 = 0. Jeśli i mod 3 = 1, to porównujemy pary (u[i], u[i + 1, u 1]) oraz (u[j], u[j + 1, u 1]), jeśli natomiast i mod 3 = 2, to porównujemy trójki (u[i], u[i + 1], u[i + 2, u 1]) oraz (u[j], u[j +1], u[j + 2, u 1]). Porządek na drugich elementach powyższych par i trzecich elementach powyższych trójek został wyliczony w kroku 4. Czas działania algorytmu 1 spełnia równanie rekurencyjne T ( u ) = O( u ) + T ( 2 3 u ), dla u 3 i T ( u ) = O(1), dla u < 3, zatem algorytm działa w czasie liniowym względem długości wejściowego słowa. 2.3 Tablice najdłuższych wspólnych prefiksów Definicja 3. Dane jest słowo u. Tablica najdłuższych wspólnych prefiksów lcp 4 na i-tej pozycji, dla i {1,..., u 1} przechowuje długość najdłuższego wspólnego prefiksu słów u[suf[i 1], u 1] i u[suf[i], u 1]. Przyjmujemy dodatkowo, że lcp[0] = 0. Łatwo zinterpretować tablicę lcp patrząc na drzewo sufiksowe danego słowa (tabela 2 i rysunek 2). 4 ang. longest common prefix 3
Tabela 2: Tablica najdłuższych wspólnych prefiksów dla słowa MISSISSIPPI. i 0 1 2 3 4 5 6 7 8 9 10 lcp[i] 0 1 1 4 0 0 1 0 2 1 3 Rysunek 2: Drzewo sufiksowe dla słowa MISSISSI (znak $ jest jedynie po to, by każdemu sufiksowi odpowiadał liść w drzewie). W liściach znajdują się indeksy początków odpowiadających im sufiksów. Liście są uporządkowane od lewej do prawej zgodnie z porządkiem leksykograficznym na sufiksach. Dla każdych dwóch kolejnych liści tablica lcp zawiera długość ścieżki (liczoną w literach) od korzenia do najdalszego wspólnego przodka tych liści. I P S 11 10 $ $ SSI MISSISSI I$ PI$ I SI 7 4 SSI 1 0 9 8 SSI SSI 2 6 5 3 Algorytm 2 buduje tablicę lcp. Pochodzi on z pracy [KLA + 01]. W głównej pętli badamy kolejno sufiksy zaczynające się na pozycjach i = 0,..., u 1. Dla ustalonego i zmienna j jest pozycją początku sufiksu, który jest bezpośrednio leksykograficznie mniejszy. Szukamy długości najdłuższego wspólnego prefiksu tych sufiksów. Jest ona liczona w krokach 6-8. Zauważmy, że w kolejnym obrocie głównej pętli nie musimy porównywać sufiksów od początku. Skoro bowiem sufiks na pozycji i pokrywał się z sufiksem na pozycji j na pierwszych p literach, to sufiks na pozycji i + 1 pokrywa się z sufiksem na pozycji j + 1 na pierwszych p 1 literach. Zatem sufiks leksykograficznie bezpośrednio poprzedzający sufiks na pozycji i + 1 pokrywa się z sufiksem na pozycji i + 1 na co najmniej p 1 pierwszych literach. 2.4 Wykorzystanie tablicy sufiksowej i tablicy najdłuższych wspólnych prefiksów do znajdywania MUMów W celu wyznaczenia MUMów słów u i v budujemy tablice suf i lcp dla słowa u#v, dzie # jest symbolem, który nie występuje w u ani v. Każdy MUM jest prefiksem dwóch sąsiadujących ze sobą leksykograficznie sufiksów. Jeden z tych sufiksów musi się zaczynać na pozycji 0 i < u, 4
Algorytm 2 Budowanie tablicy lcp. 1: p 0 2: lcp[0] 0 3: for i = 0,..., u 1 do 4: if suf 1 [i] > 0 then 5: j suf[suf 1 [i] 1] 6: while u[i + p] = u[j + p] do 7: p p + 1 8: end while 9: lcp[suf 1 [i]] p 10: if p > 0 then 11: p p 1 12: end if 13: end if 14: end for a drugi na pozycji u + 1 j < u + v, przy czym suf 1 [i] + 1 = suf 1 [j] lub suf 1 [j] + 1 = suf 1 [i]. Przyjmijmy, że zachodzi pierwszy przypadek rozważania dla drugiego są analogiczne. Żeby zapewnić maksymalność MUMa musi być spełniony warunek u[i 1] v[j u 2] oraz max(lcp[suf 1 [j] 1], lcp[suf 1 [j] + 1]) < lcp[suf 1 [j]]. Łatwo również sprawdzić ewentualne ograniczenie na długość MUMa (jest ona zapisana w lcp[suf 1 [j]]). Jeśli warunki te wydają się niejasne, warto wyobrazić sobie jaką interpretację miałyby dla drzew sufiksowych. Algorytm znajdywania MUMów wyszukuje w tablicy lcp lokalne maksima, a następnie dla każdego z nich w czasie stałym sprawdza, czy zachodzą warunki opisane w poprzednim akapicie. 3 Uliniawianie genomów (program MUMmer) Dla zadanej pary genomów liczba wykrywanych MUMów jest dużo większa niż liczba znanych zakonserwowanych odpowiadających sobie par genów. Wiele z tych MUMów stanowi szum, dlatego próbuje się wybrać te, które wydają się bardziej znaczące. W tym celu program MUMmer1 szuka najdłuższego wspólnego podciągu ciągów MUMów w dwóch genomach. Postępowanie takie jest uzasadniane faktem, że kolejność zakonserwowanych genów na chromosomach u dwóch blisko spokrewnionych gatunków jest zazwyczaj bardzo podobna (w przypadku chromosomu 16 myszy i chromosomu 16 człowieka na 31 zakonserwowanych par genów wystarczy usunąć tylko 1 parę, aby pozostałe miały taką samą kolejność). Łatwo jest zrealizować powyższy algorytm. Ponumerujmy znalezione MUMy na pierwszym genomie kolejnymi liczbami naturalnymi. Wyznacza to pewien ciąg liczb na drugim genomie. Wystarczy teraz znaleźć w tym ciągu najdłuższy 5
podciąg monotoniczny. Można to zrobić w czasie O(n ln n), gdzie n jest długością ciągu. Niestety takie podejście nie zadziała dobrze, gdy w genomie nastąpiły znaczące przesunięcia. W programie MUMmer2 (oprócz poprawek algorytmicznych) dodano moduł, który grupuje kolejne leżące blisko siebie MUMy. Najdłuższy wspólny podciąg MUMów jest obliczany w każdej grupie oddzielnie. Program MUMmer3 to dalsze poprawki algorytmiczne i implementacyjne. Wszystkie trzy wymienione programy korzystają z drzew sufiksowych. W czasie kiedy powstawały nie były znane algorytmy umożliwiające konstrukcję tablicy sufiksowej w czasie liniowym bez konstruowania drzewa sufiksowego. Literatura [AKO02] [AKO04] Mohamed Ibrahim Abouelhoda, Stefan Kurtz, and Enno Ohlebusch. The enhanced suffix array and its applications to genome analysis. In 2nd Workshop on Algorithms in Bioinformatics, LNCS, 2002. Mohamed Ibrahim Abouelhoda, Stefan Kurtz, and Enno Ohlebusch. Replacing suffix trees with enhanced suffix arrays. J. of Discrete Algorithms, 2(1):53 86, 2004. [KLA + 01] Toru Kasai, Gunho Lee, Hiroki Arimura, Setsuo Arikawa, and Kunsoo Park. Linear-time longest-common-prefix computation in suffix arrays and its applications. In CPM 01: Proceedings of the 12th Annual Symposium on Combinatorial Pattern Matching, pages 181 192, London, UK, 2001. Springer-Verlag. [KS03] [Sun05] J. Kärkkäinen and P. Sanders. Simple linear work suffix array construction. In Proc. 13th International Conference on Automata, Languages and Programming. Springer, 2003. Wing-Kin Sung. Whole genome alignment, 2005. (notatki do wykładu). 6