2016-04-27 23 views
1

こんにちは私は私のバイオインフォマティクスクラスのためにこのプログラムを書いています。ここで私はテキストファイルからシーケンスを得てからシーケンスを突然変異させます。その後、私はベースペアを比較してスコアを作るために比較を行うと仮定しています。私はすべてのコードを書いていますが、私はなぜ0のスコアを得ているのか分かりません。私はコードを処理する部分が間違っていると仮定しています。$sum = 0;私はいくつか私のコードが適切に動作するようにこの問題を修正するのに役立ちます。ここで私が使用しているシーケンスです。Perl配列アライメントスコア計算エラー

AGGGCACCTCTCAGTTCTCATTCTAACACCACATAATTTTTATTTGTATTATTCAGATTTTTCATGAACTTTTCCACAT 
AGAATGAAGTTGACATTGTTATTTCTCAGGGTCTCGGTTCACCAGTATTTGACAAACTTGAAGCTGAACTAGCTAAAGC 

 

use strict; 

my $sum = 0; 
my @seq; 
my $seqString; 
my $seqShuf; 
my $line; 

unless(open FILE, "test_seq.txt") 
{ 
    print "Cannot open file!"; 
    exit; 
} 

while (chomp($line = <FILE>)) 
{ 
    next if (/^>/); 
    @seq = <FILE>; 
} 

$seqString = join("",@seq); 
chomp($seqShuf = shuffle_string($seqString)); 
$seqShuf =~ s/\s+//g; 
#print "Original sequence is:\n"; 
#print "$seqString\n"; 
#print "Mutated Sequence is:\n"; 
#print "$seqShuf\n"; 

my @shufSeq = split("", $seqShuf, length($seqShuf)); 

my %test = (
      AA => 0, 
      AG => -1, 
      AT => -2, 
      AC => -2, 
      GA => -1, 
      GG => 0, 
      GT => -2, 
      GC => -2, 
      TA => -2, 
      TG => -2, 
      TT => 0, 
      TC => -1, 
      CA => -2, 
      CG => -2, 
      CT => -1, 
      CC => 0 
      ); 

my @base_pairs = make_base_pairs(@seq, @shufSeq); 
foreach my $bp (@base_pairs) 
{ 
    $sum += $test{$bp}; 
} 

print "@base_pairs\n"; 
print "The score is ", $sum, "\n"; 

# Shuffles original sequence 
sub shuffle_string 
{ 
    my ($string) = @_; 
    my $length = length $string; 
    for (my $i = 0; $i < $length-1; $i++) 
    { 
     my $j = random_int ($i, $length-1); 
     my $tmp = substr($string, $i, 1); 
     substr($string, $i, 1) = substr($string, $j, 1); 
     substr($string, $j, 1) = $tmp; 
    } 
    return $string; 
} 

# created random int between two parameters 
sub random_int 
{ 
    (my $par1, my $par2) = @_; 
    my $num = (1+$par1) + int(rand($par2 - $par1)); 
} 

# aligns base pairs based on index location 
sub make_base_pairs 
{ 
    (my @orig, my @shuf) = @_; 
    my $idx = 0; 
    my @bps; 
    foreach my $base (@orig) 
    { 
     push @bps, $base , $shuf[$idx]; 
     $idx++; 
    } 
    return @bps; 
} 
+0

あなたのプログラムをデバッグするために何をしましたか? – Mort

+0

'警告を使う;'厳密よりも重要です – ysth

答えて

2

残念ながら、簡単なPerlのバグの数、ではないに言及し、いくつかのアルゴリズムのものが一覧表示するにはあまりにも多いです。以下のコードを調べて比較するだけです。

ここでは、クリーンアップされたコードです。 [無償スタイルのクリーンアップをご容赦ください]それはまだいくつかのバグを持っているかもしれないが、少なくとも、それが非ゼロを出力します。

#!/usr/bin/perl 

use strict; 

my $sum = 0; 
my @seq; 
my $seqString; 
my $seqShuf; 
my $line; 

open(FILE, "test_seq.txt") or 
    die("unable to open file -- $!\n"); 

while ($line = <FILE>) { 
    chomp($line); 
    push(@seq,split(//,$line)); 
} 

close(FILE); 

my @shufSeq = shuffle_string(@seq); 
#print "Original sequence is:\n"; 
#print "$seqString\n"; 
#print "Mutated Sequence is:\n"; 
#print "$seqShuf\n"; 

my %test = (
AA => 0, 
    AG => -1, 
    AT => -2, 
    AC => -2, 
    GA => -1, 
    GG => 0, 
    GT => -2, 
    GC => -2, 
    TA => -2, 
    TG => -2, 
    TT => 0, 
    TC => -1, 
    CA => -2, 
    CG => -2, 
    CT => -1, 
    CC => 0 
); 

my @base_pairs = make_base_pairs(\@seq, \@shufSeq); 
foreach my $bp (@base_pairs) 
{ 
    ###printf("DEBUG bp='%s'\n",$bp); 
    $sum += $test{$bp}; 
} 

print("base_pairs: ",join(" ",@base_pairs),"\n"); 
print "The score is ", $sum, "\n"; 

# Shuffles original sequence 
sub shuffle_string 
{ 
    my (@string) = @_; 
    my $length = @string; 

    for (my $i = 0; $i < $length-1; $i++) { 
     my $j = random_int ($i, $length-1); 

     my $tmp = $string[$i]; 
     $string[$i] = $string[$j]; 
     $string[$j] = $tmp; 
    } 

    @string; 
} 

# created random int between two parameters 
sub random_int 
{ 
    my($par1,$par2) = @_; 
    my $num = (1+$par1) + int(rand($par2 - $par1)); 
    $num; 
} 

# aligns base pairs based on index location 
sub make_base_pairs 
{ 
    my($orig,$shuf) = @_; 
    my $idx = 0; 
    my @bps; 

    foreach my $base (@$orig) { 
     push(@bps,$base . $shuf->[$idx]); 
     $idx++; 
    } 

    return @bps; 
} 

UPDATE:

これはトンを支援ありがとうございましたそんなに。これは私の最初のプログラミングクラスで、それはすべての学期中に私を殺している。追加のバグを取り除くためにコードを見て編集していきます。

私が行った変更の仕組みを理解するのに役立つメモがあります。

プログラムが基本的に動作しているので、ランダム化とシャッフルコードがアルゴリズム的に適切かどうか(つまり十分にランダムでシャッフルが機能するかどうか)を確認できます。

例えば、私はiループが< $length-1代わりの< $lengthであるため、シャッフルの最後の要素は常には、元の最後の要素になると思い。私はもう一度ループすることでこれを修正しようとしましたが、配列の境界を超えました。


ファイルI/O:

単一文字の上にファイルデータと分割を読み込むためのコードはかなり慣用的です。

コードでは、@seq = <FILE>は、最初の行が$line = <FILE>によってプルされたため、最後の行のテキストの配列を提供します。

ループの値がchompの値ではありません。それは多分、一種の作品ですが、私はそれを決してしませんでした。

$_で動作するため、next ifは何も行いません。$lineでは動作しません。

だから、最後に、@seq@seq要素ごとに1つの文字に代わりにファイル分割のすべての文字で、[改行ストリップなし]最後の行をした単一の要素を持っているでしょう。 @seqはまだ改行を持っていた

ので、あなたが二chomp後で


シャッフルを持っていた理由、それはおそらくです:shuffle_seqへの主な変更点は、配列にインデックスを付ける代わりにすることによって動作することである

スカラー内でスワップするにはsubstrを使用します。あなたのコードではjoin@seqにしてshuffle_seqに電話してからsplitにしました。アレイ上でshuffle_seqを動作させることで、作業が簡単になります。


構文:

[それが有効かもしれない - 私はチェックしませんでした]を前に、私は(my $par1, my $par2) = @_;構文を見たことがありません。 @seq@shufSeq両方がmake_base_pairの@origに終わるだろうし、その@shufが空になるのあなたのmake_base_pairsすべて要素で

:私はちょうどmy($par1,$par2) = @_;


make_base_pairを使用しています。

シーケンスをmake_base_pair(\@seq,\@shufSeq)に変更しました[機能内で対応する変更を加えました]。これにより、配列値を渡すのではなく、スカラー参照が各配列に渡されます。参照で、関数の内部で、構文は、これらの変更により@$orig$shuf->[$idx]

に変更をアクセスすること

注意、アルゴリズムの結果が正しい可能性が高いです。

があなたのpush各ループにの要素を追加します。:それらなし

make_base_pairsはまだ動作するが、それはショーストッパーだったもの、最終的なバグがありましたX,""は[@shufが空だったことを覚えています]。したがって、最後の結果は、単一のchar要素[または空]の配列であり、ではなくの2つの配列要素がであり、2つの文字が希望通りにになりました。

プッシュへマイ変化

push(@bps,$base . $shuf->[$idx]);はPerlの文字列連結演算子を使用:.baseshuf [単一文字はそれぞれ2つの文字の出力要素を生成するために連結します。

主なバグがmake_base_pairs 2つの文字要素がありませんでした配列を返すされたことだったので、それらを合計するループはは非ゼロを作ることはありませんことができます。

+0

これはトンがあなたにとても感謝するのを助けます。これは私の最初のプログラミングクラスで、それはすべての学期中に私を殺している。追加のバグを取り除くためにコードを見て編集していきます。 –