Найти все шаблоны в файле мультифаста, включая перекрывающиеся мотивы - PullRequest
0 голосов
/ 11 января 2019

У меня есть файл мультифаста, он выглядит так:

>NP_001002156.1
MKTAVDRRKLDLLYSRYKDPQDENKIGVDGIQQFCDDLMLDPASVSVLIVAWKFRAATQCEFSRQEFLDG
MTDLGCDSPEKLKSLLPRLEQELKDSGKFRDFYRFTFSFAKSPGQKCLDLEMAVAYWNLILSGRFKFLGL
WNTFLLEHHKKSIPKDTWNLLLDFGNMIADDMSNYAEEGAWPVLIDDFVEFARPIVTAENLQTL
>NP_957070.2
MAKDAGLKETNGEIKLFINQSPGKAAGVLQLLTVHPASITTVKQILPKTLTVTGAHVLPHMVVSTPQRPT
IPVLLTSPHTPTAQTQQESSPWSSGHCRRADKSGKGLRHFSMKVCEKVQKKVVTSYNEVADELVQEFSSA
DHSSISPNDAVSSCHVYDQKNIRRRVYDALNVLMAMNIISKDKKEIKWIGFPTNSAQECEDLKAERQRRQ
ERIKQKQSQLQELIVQQIAFKNLVQRNREVEQQSKRSPSANTIIQLPFIIINTSKKTIIDCSISNDKFEY
LFNFDSMFEIHDDVEVLKRLGLALGLESGRCSAEQMKIATSLVSKALQPYVTEMAQGSVNQPMDFSHVAA
ERRASSSTSSRVETPTSLMEEDEEDEEEDYEEEDD
>NP_123456.1
MALLLLLGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
...

Хотя существует отличный скрипт на python для обработки поиска по мотивам в мультифактовом файле (https://www.biostars.org/p/14305/),, если использовался шаблон "[KHR] {3}", он вернет только список мотивов и множество пустых результатов:

>NP_001002156.1
:['RRK']
>NP_001002156.1
:[]
>NP_001002156.1
:['HHK']
>NP_957070.2
:[]
>NP_957070.2
:['RRR']
...

и какой-то мотив (HKK) просочился в той же последовательности.

Здесь я нашел другой скрипт на python:

#coding:utf-8
import re
pattern = "[KHR]{3}"
with open('seq.fasta') as fh:
    fh.readline() 
    seq = ""
    for line in fh:
         seq += line.strip() 
rgx = re.compile(pattern)
result = rgx.search(seq)
patternfound = result.group()
span = result.span()
leftpos = span[0]-10
if leftpos < 0:
   leftpos = 0
print(seq[leftpos:span[0]].lower() + patternfound + seq[span[1]:span[1]+10].lower())

возвращает первый соответствующий мотив, найденный в контексте (вперед 10 аминокислот после сопоставленного мотива, и назад на 10 перед соответствующим мотивом) только для одной последовательности (1-й), для первой серии последовательность NP_001002156.1 с использованием scirpt, возвращенный результат:

mktavdRRKldllysrykd

но у него нет заголовка файла "> NP_001002156.1", а остальные 2 мотива в контексте были опущены:

glwntfllehHHKksipkdtwnl
lwntfllehhHKKsipkdtwnll

Здесь я хочу, чтобы требуемый скрипт возвращал совпавший мотив с его отправкой в ​​контексте каждой записи последовательность в файле мультифаста, и он будет представлять результаты следующим образом:

>NP_001002156.1_matchnumber_1_(7~9)
mktavdrRRKldllysrykd
>NP_001002156.1_matchnumber_2_(148~150) 
glwntfllehHHKksipkdtwnl
>NP_001002156.1_matchnumber_3_(149~151)
lwntfllehhHKKsipkdtwnll
>NP_957070.2_matchnumber_1_(163~165)
chvydqknirRRRvydalnvlma
>NP_123456.1
no match found

Примечание: Положение совмещенного шаблона не является положением контекста.

Кто-нибудь может мне помочь? Заранее спасибо.

1 Ответ

0 голосов
/ 11 января 2019

«Мотив» здесь представляет собой любую длинную комбинацию символов [HKR]; мотивы могут совпадать.

Перекрытие разрешается с помощью «заглядывания» в регулярное выражение. Подробности смотрите ниже. Похоже, что ни один из цитируемых или показанных ресурсов не справляется с этим, и я не вижу, как они уловили бы перекрывающиеся мотивы.

use warnings;
use strict;
use feature 'say';

my $file = shift || die "Usage: $0 fasta-file\n";    
open my $fh, '<', $file or die "Can't open $file: $!";

my ($seq, $seq_name);
while (<$fh>) {
    chomp;
    if (/^>(.*)/) {
        # Process the previous assembled sequence
        if ($seq) {
            proc_seq($seq_name, $seq);
            $seq = ''; 
        }
        $seq_name = $1; 
        next;
    }   
    $seq .= $_; 
}
# Process the last one    
proc_seq($seq_name, $seq);

sub proc_seq {
    my ($seq_name, $seq, $multiline) = @_; 

    # Build output in the loop, as motifs are found. By default, print all
    # output for one seq_name in one line. To print each motif on its own
    # line instead, invoke this sub with a true third argument (1 will do).
    my $output = ">$seq_name";

    my $cnt = 0;
    while ($seq =~ /([HKR])(?=([HKR]{2}))/g) { 
        ++$cnt;shot/
        my $motif = $1 . $2; 
        my $pos = pos($seq);
        my $pre_context = ($pos >= 11) 
            ? substr($seq, $pos-11, 10) 
            : substr($seq, 0,       $pos-1);
        my $post_context = substr $seq, $pos+2, 10;

        $output .= " n$cnt($pos~" . ($pos+2) . ") ";
        $output .= "\n"  if $multiline;
        $output .= lc($pre_context) . $motif . lc($post_context);
    } 
    say ($cnt > 0  ? $output  : $output . ' no match found');
}

Примечание к регулярному выражению: нам нужен прогноз для второго и третьего символа, чтобы иметь возможность также поймать перекрывающиеся мотивы.

Пример. В первой последовательности HHKK с перекрывающимися мотивами HHK и HKK. Если регулярное выражение соответствует HHK с использованием /[HKR]{3}/, то после этого положение механизма регулярных выражений в строке будет после первого K, так как оно «потребляется» HHK. Таким образом, все, что он может видеть дальше, это только один K, и поэтому нет [HKR]{3}, чтобы соответствовать следующему, и поэтому он пропускает следующий мотив.

Итак, вместо этого я сопоставляю только одну букву и делаю «заглядывание» для следующих двух. Затем после сопоставления H (и «увидев», что действительно HK следует) только одна буква расходуется, и двигатель прошел только эту первую H, и она позиционируется перед второй H для следующей матч. Теперь он сможет в следующий раз сопоставить HKK таким же образом (и, таким образом, он сможет сопоставлять даже многократно перекрывающиеся мотивы).

Это идентифицирует все, что указано в желаемом выводе (который имеет опечатку); обратите внимание на изменение требований в комментарии, чтобы напечатать все мотивы для одной последовательности в одной строке. Так что печатает

>NP_001002156.1 n1(7~9) mktavdRRKldllysrykd n2(148~150) lglwntflleHHKksipkdtwnl n3(149~151) glwntfllehHKKsipkdtwnll
>NP_957070.2 n1(163~165) schvydqkniRRRvydalnvlma
>NP_bogus_with_no_motifs  no match found

со всеми мотивами для одного и того же имени последовательности в одной строке, как и хотелось. Я добавил фиктивную строку для ввода без мотивов, чтобы проверить добавление no match found; это нарисовало последнюю строку в выводе выше.


По-прежнему есть возможность печатать каждый мотив на отдельной строке, как это было первоначально необходимо: вызвать функцию proc_seq с дополнительным третьим аргументом, который имеет значение true, например,

proc_seq($seq_name, $seq, 1)

и тогда он напечатает

>NP_001002156.1 n1(7~9) 
mktavdRRKldllysrykd n2(148~150) 
lglwntflleHHKksipkdtwnl n3(149~151) 
glwntfllehHKKsipkdtwnll
>NP_957070.2 n1(163~165) 
schvydqkniRRRvydalnvlma
>NP_bogus_with_no_motifs  no match found
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...