Wyszukiwanie ciągu pozwalającego na jedną niedopasowanie w dowolnym miejscu łańcucha

Pracuję z sekwencjami DNA o długości 25 (patrz przykłady poniżej). Mam listę 230 000 i muszę poszukać każdej sekwencji w całym genomie (pasożyt toxoplasma gondii). Nie jestem pewien, jak duży jest Genom, ale znacznie dłuższy niż 230 000 sekwencji.

Muszę poszukać każdej z moich sekwencji po 25 znaków, na przykład (AGCCTCCCATGATTGAACAGATCAT).

Genom jest sformatowany jako ciąg ciągły, tzn. (CATGGGAGGCTTGCGGAGCCTGAGGGCGGAGCCTGAGGTGGGAGGCTTGCGGAGTGCGGAGCCTGAGCCTGAGGGCGGAGCCTGAGGTGGGAGGCTT....)

Nie obchodzi mnie gdzie i ile razy to jest znalezione, tylko czy jest czy nie.
To chyba proste --

str.find(AGCCTCCCATGATTGAACAGATCAT)

Ale też co znaleźć bliskie dopasowanie zdefiniowane jako złe (niedopasowane) w dowolnym miejscu, ale tylko w jednym miejscu, i zapisać lokalizację w sekwencji. Nie wiem, jak to zrobić. Jedyne, co przychodzi mi do głowy, to używanie wieloznaczności i wykonywanie wyszukiwania z wieloznacznością w każdej pozycji. Czyli, Szukaj 25 razy.

Na przykład,

AGCCTCCCATGATTGAACAGATCAT    
AGCCTCCCATGATAGAACAGATCAT

Bliski mecz z niedopasowaniem na pozycji 13.

Prędkość jest nie jest to duży problem, bo robię to tylko 3 razy, choć byłoby miło, gdyby był szybki.

Są programy, które to robią -- znajdź dopasowania i częściowe dopasowania -- ale szukam typu częściowego dopasowania, które nie jest wykrywalne w tych aplikacjach.

Oto podobny post dla Perla, chociaż porównują one tylko sekwencje i nie przeszukują ciągów ciągłych:

Related post

Author: 0x90, 2010-03-10

13 answers

Zanim przeczytasz , zapoznałeś się zbiopytonem ?

Wygląda na to, że chcesz znaleźć przybliżone dopasowania z jednym błędem podstawienia i zerowym błędem wstawiania/usuwania, tzn. odległość Hamminga wynosi 1.

Jeśli masz funkcję Hamming distance match (patrz np. link podany przez Ignacio), możesz użyć go w ten sposób, aby wyszukać pierwszy mecz:

any(Hamming_distance(genome[x:x+25], sequence) == 1 for x in xrange(len(genome)))

Ale byłoby to raczej powolne, ponieważ (1) funkcja odległości Hamminga zachowałaby podczas szlifowania po drugim błędzie podstawienia (2) po niepowodzeniu przesuwa kursor o jeden, a nie przeskakuje do przodu w oparciu o to, co zobaczył(jak robi to wyszukiwanie Boyer-Moore).

Możesz pokonać (1) za pomocą funkcji takiej jak:

def Hamming_check_0_or_1(genome, posn, sequence):
    errors = 0
    for i in xrange(25):
        if genome[posn+i] != sequence[i]:
            errors += 1
            if errors >= 2:
                return errors
    return errors 

Uwaga: to celowo nie Pythonic, to Cic, ponieważ musisz użyć C (być może przez Cython), aby uzyskać rozsądną prędkość.

Niektóre prace na bit-parallel przybliżone wyszukiwania Levenshtein z pominięciem zostały wykonane przez Navarro i Raffinot (google "Navarro Raffinot nrgrep") i to może być dostosowane do wyszukiwania Hamming. Zauważ, że metody bitowo-równoległe mają ograniczenia dotyczące długości łańcucha zapytania i rozmiaru alfabetu, ale twoje są odpowiednio 25 i 4, więc nie ma problemów. Update: pomijanie prawdopodobnie niewiele pomaga z rozmiarem alfabetu 4.

Kiedy wyszukasz w google dla wyszukiwania odległości Hamminga, zauważysz wiele rzeczy na temat implementacji go w sprzęcie, a nie wiele w oprogramowaniu. To jest wielka wskazówka, że może cokolwiek algorytm, który wymyśliłeś powinien być zaimplementowany w C lub innym skompilowanym języku.

Aktualizacja: Kod roboczy metody bitowo-równoległej

Dostarczyłem również uproszczoną metodę pomagającą w sprawdzaniu poprawności i spakowałem odmianę kodu Paula re do niektórych porównań. Zauważ, że używając re.finditer() dostarcza wyniki nie nakładające się na siebie, a to może spowodować, że dopasowanie na odległość-1 spowoduje Cień dokładnego dopasowania; zobacz mój ostatni przypadek testowy.

The metoda bitowo-równoległa ma następujące cechy: gwarantowane zachowanie liniowe O (n), gdzie N jest długością tekstu. Uwaga metoda naiwna to o (NM), podobnie jak metoda regex (M to długość wzoru). Metoda Boyera-Moore ' a byłaby najgorszym przypadkiem O (NM) i oczekiwanym O (N). Również metoda bit-parallel może być łatwo używana, gdy dane wejściowe muszą być buforowane: może być zasilana bajtem lub megabajtem na raz; bez patrzenia w przyszłość, bez problemów z granicami bufora. Duża zaleta: szybkość tego prostego kodu na wejście-bajt po zakodowaniu w C.

Wady: długość wzorca jest skutecznie ograniczona do liczby bitów w szybkim rejestrze, np. 32 lub 64. W tym przypadku długość wzoru wynosi 25; nie ma problemu. Używa dodatkowej pamięci (S_table) proporcjonalnej do liczby różnych znaków we wzorze. W tym przypadku "rozmiar alfabetu" wynosi tylko 4; nie ma problemu.

Szczegóły z niniejszego raportu technicznego . Algorytm istnieje dla przybliżonego wyszukiwania usin Levenshtein odległość. Aby przekonwertować Na za pomocą Hamminga dystans, ja po prostu (!) usunięto fragmenty instrukcji 2.1, które obsługują wstawianie i usuwanie. Zauważysz wiele odniesień do" R "z" D " indeksem górnym. "d" to odległość. Potrzebujemy tylko 0 i 1. Te"R" stają się zmiennymi R0 i R1 w poniższym kodzie.

# coding: ascii

from collections import defaultdict
import re

_DEBUG = 0


# "Fast Text Searching with Errors" by Sun Wu and Udi Manber
# TR 91-11, Dept of Computer Science, University of Arizona, June 1991.
# http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.20.8854

def WM_approx_Ham1_search(pattern, text):
    """Generate (Hamming_dist, start_offset)
    for matches with distance 0 or 1"""
    m = len(pattern)
    S_table = defaultdict(int)
    for i, c in enumerate(pattern):
        S_table[c] |= 1 << i
    R0 = 0
    R1 = 0
    mask = 1 << (m - 1)
    for j, c in enumerate(text):
        S = S_table[c]
        shR0 = (R0 << 1) | 1
        R0 = shR0 & S
        R1 = ((R1 << 1) | 1) & S | shR0
        if _DEBUG:
            print "j= %2d msk=%s S=%s R0=%s R1=%s" \
                % tuple([j] + map(bitstr, [mask, S, R0, R1]))
        if R0 & mask: # exact match
            yield 0, j - m + 1
        elif R1 & mask: # match with one substitution
            yield 1, j - m + 1

if _DEBUG:

    def bitstr(num, mlen=8):
       wstr = ""
       for i in xrange(mlen):
          if num & 1:
             wstr = "1" + wstr
          else:
             wstr = "0" + wstr
          num >>= 1
       return wstr

def Ham_dist(s1, s2):
    """Calculate Hamming distance between 2 sequences."""
    assert len(s1) == len(s2)
    return sum(c1 != c2 for c1, c2 in zip(s1, s2))

def long_check(pattern, text):
    """Naively and understandably generate (Hamming_dist, start_offset)
    for matches with distance 0 or 1"""
    m = len(pattern)
    for i in xrange(len(text) - m + 1):
        d = Ham_dist(pattern, text[i:i+m])
        if d < 2:
            yield d, i

def Paul_McGuire_regex(pattern, text):
    searchSeqREStr = (
        '('
        + pattern
        + ')|('
        + ')|('.join(
            pattern[:i]
            + "[ACTGN]".replace(c,'')
            + pattern[i+1:]
            for i,c in enumerate(pattern)
            )
        + ')'
        )
    searchSeqRE = re.compile(searchSeqREStr)
    for match in searchSeqRE.finditer(text):
        locn = match.start()
        dist = int(bool(match.lastindex - 1))
        yield dist, locn


if __name__ == "__main__":

    genome1 = "TTTACGTAAACTAAACTGTAA"
    #         01234567890123456789012345
    #                   1         2

    tests = [
        (genome1, "ACGT ATGT ACTA ATCG TTTT ATTA TTTA"),
        ("T" * 10, "TTTT"),
        ("ACGTCGTAAAA", "TCGT"), # partial match can shadow an exact match
        ]

    nfailed = 0
    for genome, patterns in tests:
        print "genome:", genome
        for pattern in patterns.split():
            print pattern
            a1 = list(WM_approx_Ham1_search(pattern, genome))
            a2 = list(long_check(pattern, genome))
            a3 = list(Paul_McGuire_regex(pattern, genome))
            print a1
            print a2
            print a3
            print a1 == a2, a2 == a3
            nfailed += (a1 != a2 or a2 != a3)
    print "***", nfailed
 27
Author: John Machin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-11 21:19:31

Biblioteka Pythona regex obsługuje dopasowywanie rozmytych wyrażeń regularnych. Jedną z zalet w stosunku do TRE jest to, że pozwala znaleźć wszystkie dopasowania wyrażenia regularnego w tekście (obsługuje również nakładające się dopasowania).

import regex
m=regex.findall("AA", "CAG")
>>> []
m=regex.findall("(AA){e<=1}", "CAAG") # means allow up to 1 error
m
>>> ['CA', 'AG']
 23
Author: sefakilic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 19:44:02

Wyszukałem w googlach "Toxoplasma gondii parasite genome", aby znaleźć niektóre z tych plików genomu w Internecie. Znalazłem to, co myślę, że było blisko, plik zatytułowany " TgondiiGenomic_ToxoDB-6.0.fasta " at http://toxodb.org , rozmiar około 158Mb. Użyłem następującej ekspresji pyparsingu do wyodrębnienia sekwencji genów, zajęło to niecałe 2 minuty:

fname = "TgondiiGenomic_ToxoDB-6.0.fasta"
fastasrc = open(fname).read()   # yes! just read the whole dang 158Mb!

"""
Sample header:
>gb|scf_1104442823584 | organism=Toxoplasma_gondii_VEG | version=2008-07-23 | length=1448
"""
integer = Word(nums).setParseAction(lambda t:int(t[0]))
genebit = Group(">gb|" + Word(printables)("id") + SkipTo("length=") + 
                "length=" + integer("genelen") + LineEnd() + 
                Combine(OneOrMore(Word("ACGTN")),adjacent=False)("gene"))

# read gene data from .fasta file - takes just under a couple of minutes
genedata = OneOrMore(genebit).parseString(fastasrc)

(niespodzianka! niektóre sekwencje genów obejmują Run ' N ' S! O co tu chodzi?!)

Potem napisałem tę klasę jako podklasę z klasy Pyparsing Token, do wykonywania zbliżeń:

class CloseMatch(Token):
    def __init__(self, seq, maxMismatches=1):
        super(CloseMatch,self).__init__()
        self.name = seq
        self.sequence = seq
        self.maxMismatches = maxMismatches
        self.errmsg = "Expected " + self.sequence
        self.mayIndexError = False
        self.mayReturnEmpty = False

    def parseImpl( self, instring, loc, doActions=True ):
        start = loc
        instrlen = len(instring)
        maxloc = start + len(self.sequence)

        if maxloc <= instrlen:
            seq = self.sequence
            seqloc = 0
            mismatches = []
            throwException = False
            done = False
            while loc < maxloc and not done:
                if instring[loc] != seq[seqloc]:
                    mismatches.append(seqloc)
                    if len(mismatches) > self.maxMismatches:
                        throwException = True
                        done = True
                loc += 1
                seqloc += 1
        else:
            throwException = True

        if throwException:
            exc = self.myException
            exc.loc = loc
            exc.pstr = instring
            raise exc

        return loc, (instring[start:loc],mismatches)

Dla każdego dopasowania zwróci krotkę zawierającą rzeczywisty ciąg, który został dopasowany, oraz listę lokalizacji niedopasowania. Dokładne dopasowanie zwróci oczywiście pustą listę dla drugiej wartości. (Lubię tę klasę, myślę, że dodam ją do następnego wydania pyparsingu.)

Następnie uruchomiłem ten kod, aby wyszukać dopasowania" do-2-niedopasowania " we wszystkich sekwencjach odczytanych z .FASTA file (przypomnijmy, że genedata jest sekwencją grup ParseResults, z których każda zawiera id, długość całkowitą i ciąg sekwencji):

searchseq = CloseMatch("ATCATCGAATGGAATCTAATGGAAT", 2)
for g in genedata:
    print "%s (%d)" % (g.id, g.genelen)
    print "-"*24
    for t,startLoc,endLoc in searchseq.scanString(g.gene):
        matched, mismatches = t[0]
        print "MATCH:", searchseq.sequence
        print "FOUND:", matched
        if mismatches:
            print "      ", ''.join(' ' if i not in mismatches else '*' 
                            for i,c in enumerate(searchseq.sequence))
        else:
            print "<exact match>"
        print "at location", startLoc
        print
    print

Wziąłem sekwencję wyszukiwania losowo z jednego z bitów genu, aby być pewnym, że mogę znaleźć dokładne dopasowanie, i tak z ciekawości, aby zobaczyć, ile było 1-i 2-elementowych niedopasowań.

Trochę to trwało. Po 45 minutach miałem to wyjście, wymieniając każdy identyfikator i długość genu oraz znalezione częściowe dopasowania:
scf_1104442825154 (964)
------------------------

scf_1104442822828 (942)
------------------------

scf_1104442824510 (987)
------------------------

scf_1104442823180 (1065)
------------------------
...

I was getting zniechęcony, Nie zobaczyć żadnych meczów do:

scf_1104442823952 (1188)
------------------------
MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAACGGAATCGAATGGAAT
                *      *        
at location 33

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCGAATGGAAT
                       *        
at location 175

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCGAATGGAAT
                       *        
at location 474

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCGAATGGAAT
                       *        
at location 617

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCGAATAGAAT
                       *   *    
at location 718

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGATTCGAATGGAAT
                    *  *        
at location 896

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCGAATGGTAT
                       *     *  
at location 945

I wreszcie mój dokładny mecz na:

scf_1104442823584 (1448)
------------------------
MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGACTCGAATGGAAT
                    *  *        
at location 177

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCAAATGGAAT
                       *        
at location 203

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCAAATGGAATCGAATGGAAT
             *         *        
at location 350

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCGAATGGAAA
                       *       *
at location 523

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCAAATGGAATCGAATGGAAT
             *         *        
at location 822

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCATCGAATGGAATCTAATGGAAT
<exact match>
at location 848

MATCH: ATCATCGAATGGAATCTAATGGAAT
FOUND: ATCGTCGAATGGAGTCTAATGGAAT
          *         *           
at location 969

Więc chociaż to nie ustanowiło żadnych rekordów prędkości, wykonałem robotę i znalazłem kilka 2-pasujących, na wypadek, gdyby mogły być interesujące.

Dla porównania, tutaj jest wersja RE-based, który znajduje 1-niedopasowania pasuje tylko:

import re
seqStr = "ATCATCGAATGGAATCTAATGGAAT"
searchSeqREStr = seqStr + '|' + \
    '|'.join(seqStr[:i]+"[ACTGN]".replace(c,'') +seqStr[i+1:] 
             for i,c in enumerate(seqStr))

searchSeqRE = re.compile(searchSeqREStr)

for g in genedata:
    print "%s (%d)" % (g.id, g.genelen)
    print "-"*24
    for match in searchSeqRE.finditer(g.gene):
        print "MATCH:", seqStr
        print "FOUND:", match.group(0)
        print "at location", match.start()
        print
    print

(na początku próbowałem przeszukiwać surowe źródło pliku FASTA, ale byłem zaskoczony, dlaczego tak mało pasuje w porównaniu do wersji pyparsing. Wtedy Ja zdałem sobie sprawę, że niektóre dopasowania muszą przekraczać podziały linii, ponieważ wyjście pliku fasta jest zawinięte na n znaków.)

Więc po pierwszym przejściu pyparsingu, aby wyodrębnić sekwencje genów, aby dopasować się, ten ponownie oparty Wyszukiwacz zajął około 1-1 / 2 minut, aby zeskanować wszystkie sekwencje nie-texttwrapped, aby znaleźć wszystkie te same wpisy 1-niedopasowania, które rozwiązanie pyparsing zrobił.

 6
Author: PaulMcG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-11 05:59:49

Możesz znaleźć różne procedury w Python-Levenshtein jakiegoś zastosowania.

 3
Author: Ignacio Vazquez-Abrams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 20:49:21
>>> import re
>>> seq="AGCCTCCCATGATTGAACAGATCAT"
>>> genome = "CATGGGAGGCTTGCGGAGCCTGAGGGCGGAGCCTGAGGTGGGAGGCTTGCGGAGTGCGGAGCCTGAGCCTGAGGGCGGAGCCTGAGGTGGGAGGCTT..."
>>> seq_re=re.compile('|'.join(seq[:i]+'.'+seq[i+1:] for i in range(len(seq))))

>>> seq_re.findall(genome)  # list of matches
[]  

>>> seq_re.search(genome) # None if not found, otherwise a match object

Ten zatrzymuje pierwszy mecz, więc może być nieco szybszy, gdy jest wiele meczów

>>> print "found" if any(seq_re.finditer(genome)) else "not found"
not found

>>> print "found" if seq_re.search(genome) else "not found" 
not found

>>> seq="CAT"
>>> seq_re=re.compile('|'.join(seq[:i]+'.'+seq[i+1:] for i in range(len(seq))))
>>> print "found" if seq_re.search(genome) else "not found"
found

Dla genomu o długości 10,000,000 patrzymy na około 2,5 dnia na pojedynczy wątek do skanowania 230,000 sekwencji, więc możesz chcieć podzielić zadanie na kilka rdzeni/procesorów.

Zawsze możesz zacząć implementować wydajniejszy algorytm, gdy ten jest uruchomiony:)

Jeśli chcesz wyszukać pojedyncze upuszczone lub dodane elementy Zmień Wyrażenie regularne na this

>>> seq_re=re.compile('|'.join(seq[:i]+'.{0,2}'+seq[i+1:] for i in range(len(seq))))
 2
Author: John La Rooy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 21:33:24

To podpowiedź najdłuższy wspólny problem . Problem z podobieństwem ciągów polega na tym, że musisz przetestować ciąg ciągły 230000 sekwencji; więc jeśli porównujesz jedną z Twoich 25 sekwencji do ciągów ciągłych, uzyskasz bardzo niskie podobieństwo.

Jeśli obliczysz najdłuższą ciągłość wspólną pomiędzy 25 sekwencjami a ciągiem ciągłym, będziesz wiedział, czy jest w ciągu, jeśli długości są takie same.

 1
Author: Pierre-Antoine LaFayette,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 21:02:37

Możesz zrobić trie ze wszystkich różnych sekwencji, które chcesz dopasować. Teraz jest trudną częścią tworzenia funkcji wyszukiwania głębi w dół trie, która pozwala co najwyżej na jedną niedopasowanie.

Zaletą tej metody jest to, że przeszukiwasz wszystkie sekwencje naraz. Pozwoli to zaoszczędzić wiele porównań. Na przykład, kiedy zaczynasz od górnego węzła i idziesz w dół gałęzi "A", właśnie zaoszczędziłeś sobie wiele tysięcy porównań, ponieważ masz po prostu natychmiast dopasowane do wszystkich sekwencji, które zaczynają się od 'A'. Dla innego argumentu, rozważ kawałek genomu, który pasuje dokładnie do danej sekwencji. Jeśli masz inną sekwencję na liście sekwencji, która różni się tylko ostatnim symbolem, to użycie trie właśnie zapisało ci 23 operacje porównawcze.

Oto jeden ze sposobów realizacji tego. Przelicz "A", "C", T", G " na 0,1,2,3 lub jego wariant. Następnie użyj krotek krotek jako struktury dla trie. Na każdym węzeł, pierwszy element w tablicy odpowiada 'A', drugi ' C ' i tak dalej. Jeśli' A ' jest gałęzią tego węzła, to istnieje kolejna krotka z 4 elementów jako pierwsza element krotki tego węzła. Jeśli nie ma gałęzi 'A', to ustaw pierwszą pozycję na 0. Na dole trie znajdują się węzły, które mają id tej sekwencji, dzięki czemu można ją umieścić na liście dopasowań.

Oto rekurencyjne funkcje wyszukiwania pozwalające na jedną niezgodność dla tego rodzaju trie: {]}

def searchnomismatch(node,genome,i):
    if i == 25:
        addtomatches(node)
    else:
        for x in range(4):
            if node[x]:
                if x == genome[i]:
                    searchnomismatch(node[x],genome,i+1)
                else:
                    searchmismatch(node[x],genome,i+1,i)

def searchmismatch(node,genome,i,where):
    if i == 25:
        addtomatches(node,where)
    else:
        if node[genome[i]]:
            searchmismatch(node[genome[i]],genome,i+1,where)

Tutaj zaczynam poszukiwania od czegoś w rodzaju

searchnomismatch(trie,genome[ind:ind+25],0)

I addtomatches jest czymś podobnym do

def addtomatches(id,where=-1):
    matches.append(id,where)

Gdzie równe -1 oznacza, że nie było niedopasowania. W każdym razie, mam nadzieję, że wyraziłem się jasno, żebyś zrozumiał.

 1
Author: Justin Peel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-11 00:13:39

Próbowałem niektórych rozwiązań, ale jak już napisano, są one powolne, gdy mamy do czynienia z dużą ilością sekwencji (ciągów).

Wymyśliłem użycie bowtie i mapowanie podłańcucha zainteresowania (soi) na plik referencyjny, który zawiera ciągi znaków w formacie FASTA. Możesz podać liczbę dozwolonych niedopasowań (0..3) i dostajesz z powrotem ciągi, do których soi mapowane biorąc pod uwagę dozwolone niedopasowania. To działa dobrze i dość szybko.

 1
Author: sebastian.boegel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-07 15:44:02

Możesz użyć Pythonów wbudowanych w możliwości wyszukiwania z dopasowaniem wyrażeń regularnych.

Moduł Re w Pythonie http://docs.python.org/library/re.html

Podkład wyrażenia regularnego http://www.regular-expressions.info/

 0
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-10 20:49:15

Myślę, że to może przyjść trochę późno, ale jest narzędzie o nazwie PatMaN, które robi dokładnie to, co chcesz: http://bioinf.eva.mpg.de/patman/

 0
Author: cpp1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-27 17:46:45

Możesz użyć regex matching library TRE, dla "approximate matching". Posiada również powiązania dla Pythona, Perla i Haskella.

import tre

pt = tre.compile("Don(ald)?( Ervin)? Knuth", tre.EXTENDED)
data = """
In addition to fundamental contributions in several branches of
theoretical computer science, Donnald Erwin Kuth is the creator of
the TeX computer typesetting system, the related METAFONT font
definition language and rendering system, and the Computer Modern
family of typefaces.
"""

fz = tre.Fuzzyness(maxerr = 3)
print fz
m = pt.search(data, fz)

if m:
    print m.groups()
    print m[0]

Który wyświetli

tre.Fuzzyness(delcost=1,inscost=1,maxcost=2147483647,subcost=1, maxdel=2147483647,maxerr=3,maxins=2147483647,maxsub=2147483647)
((95, 113), (99, 108), (102, 108))
Donnald Erwin Kuth

Http://en.wikipedia.org/wiki/TRE_%28computing%29

Http://laurikari.net/tre/

 0
Author: sefakilic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-06-11 18:45:12

Myślałem, że poniższy kod jest prosty i wygodny.

in_pattern = "";
in_genome = "";
in_mistake = d;
out_result = ""


kmer = len(in_pattern)

def FindMistake(v):
    mistake = 0
    for i in range(0, kmer, 1):
        if (v[i]!=in_pattern[i]):
            mistake+=1
        if mistake>in_mistake:
            return False
    return True


for i in xrange(len(in_genome)-kmer+1):
    v = in_genome[i:i+kmer]
    if FindMistake(v):
        out_result+= str(i) + " "

print out_result

Możesz łatwo wstawić genomy i segmenty, które chcesz sprawdzić, a także ustawić wartość niedopasowania.

 0
Author: nosense,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-30 19:19:33

To jest dość stare, ale być może to proste rozwiązanie mogłoby zadziałać. pętli przez sekwencję biorąc 25charakter plastry. Konwertuj plasterek na tablicę numpy. Porównaj z łańcuchem 25char (również jako tablica numpy). Sum odpowiedź i jeśli odpowiedź jest 24 wydrukuj pozycję w pętli i niedopasowanie.

Te kolejne wiersze pokazują, że działa

Import numpy jako np

A = ["A", "B", "C"]

B = np.array (a)

B

Array (["A", "B", "C"], dtype="

C = ["A", "D", "C"]

D = np.array (c)

B= = d

Array ([True, False, True])

Sum (b==d)

2

 0
Author: Alan Johnstone,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-24 11:42:58