У меня есть файл мультифаста, это выглядит так:
>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
Здесь я хочу, чтобы требуемый скрипт возвращал совпавший мотив с его отправкой в контексте каждой последовательности fastta в мультифактовом файле, и он представлял бы результаты следующим образом:
>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
Примечание. Положение совмещенного шаблона не является положением контекста.
Кто-нибудь может мне помочь? Заранее спасибо.
"Мотив" здесь - любая длинная комбинация символов [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