2016-10-24 5 views
2

私は、fastaファイルを読み込み、シーケンス(fasta)ファイルからすべての利用可能な(重複している)長さ15 k-mersを含むテキストファイルを出力しようとしています。このプログラムは重複していないk-mersを探しているときにはうまく動作しますが、重複しているk-mersを見つけるためにコード化した場合、実行するのにずっと時間がかかり、Cygwinは12時間後にkillされたプログラムを終了します。すべての重複するk-merを見つけて印刷する

#!/usr/bin/perl 
use strict; 
use warnings; 

my $k = 15; 
my $input = 'fasta.fasta'; 
my $output = 'text.txt'; 
my $match_count = 0; 

#Open File 
unless (open(FASTA, "<", $input)){ 
    die "Unable to open fasta file", $!; 
    } 

    #Unwraps the FASTA format file 
    $/=">"; 
    #Separate header and sequence 
    #Remove spaces 
unless (open(OUTPUT, ">", $output)){ 
die "Unable to open file", $!; 
} 

    while (my $line = <FASTA>){ 
      my($header, @seq) = split(/\n/, $line); 
        my $sequence = join '', @seq; 

    while (length($sequence) >= $k){ 
     $sequence =~ m/(.{$k})/; 
     print OUTPUT "$1\n"; 
     $sequence = substr($sequence, 1, length($sequence)-1); 
    } 
} 

(私はその行を無視すること自由に感じなさい、合計をカウントするためにそこにmatch_countを残した)私が探しています結果は次のとおりです。事前に

A total of 20938309 k-mers printed in the text file when I use the wc -l command. 

ありがとう!

+0

kmerの合計数を探しているのですか、すべてのkmersを含むファイルが必要ですか? –

+1

約20Mの部分文字列を生成することは、そのループがあまり効率的ではないにもかかわらず、* * *を取るべきではありません。どのくらいの大きさ(バイトとレコード)が入力ファイルですか? 大量の文字列変更を避けるために、最後の 'while'ループには次のものを使用することができます:' my $ i(0..length($ sequence) - $ k){ print OUTPUT substr i、$ k)、 "\ n"; } ' – mbethke

+0

@ChrisCharleyすべてのkmersでファイルが必要です。私はwc -lコマンドを使って合計20m kmを確保するだけです。 – Kaiser

答えて

2

希望の結果が得られない理由がわかりません。

問題の説明に使用した2つのプログラムを投稿すると思いました。

最初のものは、私がテストに使用したファイル(fasta_dat.txt)のkmersを数えるだけです。それはそれらを印刷しませんが、そこにいくつのkmersがあるかを見るためのチェックに過ぎません。

#!/usr/bin/perl 
use strict; 
use warnings; 
use Bio::SeqIO; 

my $in = Bio::SeqIO->new(-file => "fasta_dat.txt" , 
          -format => 'fasta'); 

my $count_kmers; 
my $k = 15; 
while (my $seq = $in->next_seq) { 
    $count_kmers += $seq->length - $k + 1; 
} 

print $count_kmers; 

__END__ 
C:\Old_Data\perlp>perl t9.pl 
18657 

私はあなたのコードを使用してそれらをプリントアウトするときは、(__END__トークンの後に)数を見ることができ、18657.このカウントはkmersのカウントと合意しました。ハッシュサイズのメモリ内の100倍の増加を示した私は走った

#!/usr/bin/perl 
use strict; 
use warnings; 
use 5.014; 
use Devel::Size 'total_size'; 

my $k = 15; 
my $input = 'fasta_dat.txt'; 
my $output = 'kmers.txt'; 
my $match_count = 0; 

#Open File 
unless (open(FASTA, "<", $input)){ 
    die "Unable to open fasta file", $!; 
    } 

    #Unwraps the FASTA format file 
    $/=">"; 
    #Separate header and sequence 
    #Remove spaces 
unless (open(OUTPUT, ">", $output)){ 
    die "Unable to open file", $!; 
} 

<FASTA>; # discard 'first' 'empty' record 

my %seen; 
while (my $line = <FASTA>){ 
    chomp $line; 
    my($header, @seq) = split(/\n/, $line); 
    my $sequence = join '', @seq; 

    for my $i (0 .. length($sequence) - $k) { 
     my $kmer = substr($sequence, $i, $k); 
     print OUTPUT $kmer, "\n" unless $seen{$kmer}++; 
    } 
} 
print total_size(\%seen); 

更新をテストします。テストでのkmersの数は約18500でした。その結果、ハッシュサイズは1.8MBになりました。

kmerが22Mのデータの場合、ハッシュサイズは2.2GBになります。これがあなたの記憶容量を超えるかどうかは分かりません。

+0

私はあなたのコードをテストしました。私の書いたものとまったく同じ23mのk-mersも与えています。私は余分な2mのk-mersが '繰り返される' k-mers(正確に同じ配列のk-mers)から来ると仮定しています。 – Kaiser

+0

別個のk-merだけをプリントアウトする方法はありますか?ありがとう。 – Kaiser

+0

@Sunny、私は重複したkmersを排除するために私のコードを編集し、結果は約10%少ないkmers(重複を除いて)を示しています。 –

関連する問題