在multifasta文件中查找所有图案,包括重叠的图案

时间:2019-01-11 04:45:28

标签: python perl

我有一个multifasta文件,它看起来像这样:

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

尽管有一个很棒的python脚本可以处理multifasta文件(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个),仅用于一个fasta(第一个)序列,对于第一个fasta 使用脚本序列NP_001002156.1,返回结果:

mktavdRRKldllysrykd

但没有文件头“>”> NP_001002156.1“,并且上下文中的其他2个主题都被省略:

glwntfllehHHKksipkdtwnl
lwntfllehhHKKsipkdtwnll

在这里,我希望所需的脚本在每个fasta的上下文中返回匹配的主题及其位置 序列在multifasta文件中,它将显示以下结果:

>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 :(得分:2)

此处的“主题”是[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');
}

关于正则表达式的注意事项:第二个和第三个字符需要一个lookahead,以便也能够捕获重叠的图案。

一个例子。第一个序列中有HHKK,其主题有HHKHKK重叠。如果正则表达式使用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