如何从Perl中的DNA序列中提取起始和结束密码子?

时间:2009-10-13 04:03:45

标签: perl bioinformatics

我有一个代码,试图确定给定DNA序列的起始和结束密码子的位置。 我们将起始密码子定义为 ATG 序列,将末端密码子定义为 TGA,TAA,TAG 序列。

我遇到的问题是下面的代码仅适用于前两个序列(DM208659和AF038953),但不适用于其余的序列。

我的方法下面有什么问题?

此代码可以从here复制粘贴。

      #!/usr/bin/perl -w


while (<DATA>) {
    chomp;
    print "$_\n";
    my ($id,$rna_sq) = split(/\s+/,$_);

    local $_ = $rna_sq;
    while (/atg/g) {
        my $start = pos() - 2;

        if (/tga|taa|tag/g) {

            my $stop    = pos();
            my $gene    = substr( $_, $start - 1, $stop - $start + 1 ),$/;
            my $genelen = length($gene);
            my $ct      = "$id $start $stop $gene $genelen";
            print "\t$ct\n";

        }

    }

}

__DATA__
DM208659    gtgggcctcaaatgtggagcactattctgatgtccaagtggaaagtgctgcgacatttgagcgtcac
AF038953    gatcccagacctcggcttgcagtagtgttagactgaagataaagtaagtgctgtttgggctaacaggatctcctcttgcagtctgcagcccaggacgctgattccagcagcgccttaccgcgcagcccgaagattcactatggtgaaaatcgccttcaatacccctaccgccgtgcaaaaggaggaggcgcggcaagacgtggaggccctcctgagccgcacggtcagaactcagatactgaccggcaaggagctccgagttgccacccaggaaaaagagggctcctctgggagatgtatgcttactctcttaggcctttcattcatcttggcaggacttattgttggtggagcctgcatttacaagtacttcatgcccaagagcaccatttaccgtggagagatgtgcttttttgattctgaggatcctgcaaattcccttcgtggaggagagcctaacttcctgcctgtgactgaggaggctgacattcgtgaggatgacaacattgcaatcattgatgtgcctgtccccagtttctctgatagtgaccctgcagcaattattcatgactttgaaaagggaatgactgcttacctggacttgttgctggggaactgctatctgatgcccctcaatacttctattgttatgcctccaaaaaatctggtagagctctttggcaaactggcgagtggcagatatctgcctcaaacttatgtggttcgagaagacctagttgctgtggaggaaattcgtgatgttagtaaccttggcatctttatttaccaactttgcaataacagaaagtccttccgccttcgtcgcagagacctcttgctgggtttcaacaaacgtgccattgataaatgctggaagattagacacttccccaacgaatttattgttgagaccaagatctgtcaagagtaagaggcaacagatagagtgtccttggtaataagaagtcagagatttacaatatgactttaacattaaggtttatgggatactcaagatatttactcatgcatttactctattgcttatgccgtaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
BC021011    ggggagtccggggcggcgcctggaggcggagccgcccgctgggctaaatggggcagaggccgggaggggtgggggttccccgcgccgcagccatggagcagcttcgcgccgccgcccgtctgcagattgttctg
DM208660    gggatactcaaaatgggggcgctttcctttttgtctgtactgggaagtgcttcgattttggggtgtccc
AF038954    ggacccaagggggccttcgaggtgccttaggccgcttgccttgctctcagaatcgctgccgccatggctagtcagtctcaggggattcagcagctgctgcaggccgagaagcgggcagccgagaaggtgtccgaggcccgcaaaagaaagaaccggaggctgaagcaggccaaagaagaagctcaggctgaaattgaacagtaccgcctgcagagggagaaagaattcaaggccaaggaagctgcggcattgggatcccgtggcagttgcagcactgaagtggagaaggagacccaggagaagatgaccatcctccagacatacttccggcagaacagggatgaagtcttggacaacctcttggcttttgtctgtgacattcggccagaaatccatgaaaactaccgcataaatggatagaagagagaagcacctgtgctgtggagtggcattttagatgccctcacgaatatggaagcttagcacagctctagttacattcttaggagatggccattaaattatttccatatattataagagaggtccttccactttttggagagtagccaatctagctttttggtaacagacttagaaattagcaaagatgtccagctttttaccacagattcctgagggattttagatgggtaaatagagtcagactttgaccaggttttgggcaaagcacatgtatatcagtgtggacttttcctttcttagatctagtttaaaaaaaaaaaccccttaccattctttgaagaaaggaggggattaaataattttttcccctaacactttcttgaaggtcaggggctttatctatgaaaagttagtaaatagttctttgtaacctgtgtgaagcagcagccagccttaaagtagtccattcttgctaatggttagaacagtgaatactagtggaattgtttgggctgcttttagtttctcttaatcaaaattactagatgatagaattcaagaacttgttacatgtattacttggtgtatcgataatcatttaaaagtaaagactctgtcatgcaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

3 个答案:

答案 0 :(得分:4)

我删除了$_的使用(当你local使用它时我特别颤抖 - 你这样做是正确的,但为什么要强迫自己担心如果其他一些功能会破坏{{1} ,而不是使用已经可用的$_

此外,我将$rna_sq$start更正为字符串中基于0的索引(这使得数学的其余部分更加直接),并提前计算$stop所以它可以直接在$genelen操作中使用。 (或者,您可以将substr本地化为1以使用基于1的数组索引,请参阅perldoc perlvar。)

$[

答案 1 :(得分:1)

if (/tga|taa|tag/g)无法找到最终密码子时,它永远不会脱离你的内循环。它反复匹配/atg/g,永远不会进一步推进。你可以强行将它从内循环中弹出:

if (/tga|taa|tag/g) {
    ...
}
else {
    last;
}

答案 2 :(得分:1)

这完全取决于您是否要生成可能重叠的序列。例如,序列AF038954包含atgaccatcctccagacatacttccggcagaacagggatga,其末尾与atgaagtcttggacaacctcttggcttttgtctgtga重叠。你想报告他们吗?

如果您不想报告重叠的序列,这是一个非常简单的问题,您只需使用一个正则表达式即可解决:

while (<DATA>) {
    chomp;
    print "processing $_\n";
    my ($id, $rna_sq) = split;

    while ($rna_sq =~ /(atg.*?(?:tga|taa|tag))/g) {
      printf "\t%8s %4i %4i %s %i\n",
             $id,
             pos($rna_sq) - length($1) + 1,
             pos($rna_sq),
             $1,
             length($1);
      }
}

正则表达式(atg.*?(?:tga|taa|tag))匹配您所需的开始,然后尽可能少地匹配接下来的内容(?以阻止.*“贪婪”)然后您需要的结束。使用while循环对其进行迭代,在此匹配后重新启动,这符合不查找重叠的要求。

如果你想要报告重叠序列,你需要一个两阶段的过程:找到开始,找到结束,然后找到另一个开始,从你离开的地方开始寻找最后一次开始。但是你仍然可以使用第二个正则表达式做一个更简单的工作:

while (<DATA>) {
    chomp;
    print "processing $_\n";
    my ($id, $rna_sq) = split;

    while ($rna_sq =~ /atg/g) {
      if ($' =~ /(.*?(?:tga|taa|tag))/) {
        my $match = "atg$1";
        printf "\t%8s %4i %4i %s %i\n",
               $id,
               pos($rna_sq) - 2,
               pos($rna_sq) - 3 + length($match),
               $match,
               length($match);
      }
    }
}

这里我们使用(通常是非推荐的)$'特殊变量,它包含匹配后的内容。我们查看此序列以查找序列的结尾并输出详细信息。因为我们与$rna_seq的主要全局匹配不包括序列(如上所述),所以我们重新开始搜索上一次搜索停止的开始,即在我们找到的开始之后。这样我们包含重叠序列。