4

以下に、特定の DNA 配列の開始コドンと終了コドンの位置を特定しようとするコードを示します。開始コドンをATG配列終了コドンTGA、TAA、TAG配列と定義します。

私が抱えている問題は、以下のコードが最初の 2 つのシーケンス (DM208659 と AF038953) でのみ機能し、残りは機能しないことです。

以下の私のアプローチの何が問題になっていますか?

このコードは、ここからコピーして貼り付けることができます。

      #!/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
4

3 に答える 3

4

の使用を削除しました$_(特に、あなたがそれを化したときは身震いしました-あなたは正しくそれを行いましたが、すでに使用可能なものを使用するのではなく、local他の関数が clobber になるのではないかと心配する必要はありませんか?$_$rna_sq

さらに、文字列の 0 ベースのインデックスになるように修正$startし(これにより、残りの計算がより簡単になりました)、演算で直接使用できるように早期に計算しました。(あるいは、1 から始まる配列インデックスを使用するために 1 にローカライズすることもできます。 perldoc perlvarを参照してください。)$stop$genelensubstr$[

use strict;
use warnings;
while (my $line = <DATA>) {
    chomp $line;
    print "processing $line\n";
    my ($id, $rna_sq) = split(/\s+/, $line);

    while ($rna_sq =~ /atg/g) {
        # $start and $stop are 0-based indexes
        my $start = pos($rna_sq) - 3; # back up to include the start sequence

        # discard remnant if no stop sequence can be found
        last unless $rna_sq =~ /tga|taa|tag/g;

        my $stop    = pos($rna_sq);
        my $genelen = $stop - $start;

        my $gene    = substr($rna_sq, $start, $genelen);
        print "\t" . join(' ', $id, $start+1, $stop, $gene, $genelen) . "\n";
    }
}
于 2009-10-13T04:54:27.600 に答える
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再開されます。これは、重複を探しないという要件を満たしています。

重複するシーケンスを報告する場合、2段階のプロセスが必要です。開始を見つけ、終了を見つけ、次に別の開始を見つけて、最後に開始を探していたところから再開します。ただし、2番目の正規表現を使用してさらに簡単な作業を行うことができます。

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にはシーケンスが含まれていないため(上記のように)、前の検索が中断したところから開始するために検索を再開します。これは、検出した開始の直後です。このようにして、重複するシーケンスを含めます。

于 2009-10-13T08:57:32.387 に答える
1

if (/tga|taa|tag/g)が終了コドンを見つけられなくても、内側のループから抜け出すことはありません。マッチング/atg/gを繰り返し、それ以上進むことはありません。内部ループから強制的に排出できます。

if (/tga|taa|tag/g) {
    ...
}
else {
    last;
}
于 2009-10-13T04:14:56.420 に答える