2016-07-08 5 views
0

私はこの問題を抱えています。ディレクトリにある(非常に汚いと矛盾している)ジェンファイル(例GBKはここにファイル:ftp://ftp.ncbi.nlm.nih.gov/genomes/archive/old_genbank/Bacteria/Acetobacter_pasteurianus_IFO_3283_01_uid31129/AP011121.gbk)を
1.プロセス:
2.分割各ファイルを遺伝子によって
3をforeachの中で、私はperlスクリプトを持っていますループは各遺伝子に関する関連情報を得ます
4.各遺伝子の情報を各ループの最後に表示します

問題:特定のファイルの途中でランダムにぶら下がっていますが、それらが停止している遺伝子は、72K以上のファイル全体に分散しています。それが停止すると、コマンドラインに出力される出力は、ファイルに出力された出力の前にいくつかのループ(遺伝子)があります(画像参照)。

トラブルシューティング:さまざまなファイルで停止する変数が異なる場合、変数の印刷中にハングすることがあり、RAM/CPU使用率が低く、ハングアップしてもメモリ/ CPUが使用され、両方のウィンドウでハングします最新バージョンのstrawberry perl)とlinux(flux HPC)システムの場合、出力には何も問題はありません(コマンドライン出力がファイル出力より先行しているので、その間にハングしている遺伝子を処理できることがわかりますファイルへの印刷)。
Perlがハングしている可能性があります。おそらく印刷に関連しています。

申し訳ありませんが、私は微生物学者ですので、私がstackoverflowで見るコードのいくつかと同じように賢明ではありません(Genbankファイルはフォーマット/言語に非常に矛盾しています。その周りのプログラム)。私は他のコードの提案を実装して満足しています。

#!/usr/bin/perl 
use warnings; 

##### open output files ##### 
$GBKINFO = 'L:\NCBI_DAT\GBFF\Bacteria_tablist.txt'; 
open(GBKINFO,'>', $GBKINFO)||die "unable to open $GBKINFO:$!\n"; 
$debug  = 'L:\NCBI_DAT\GBFF\Bacteria_debug.txt'; 
open(DEBUG,'>', $debug)||die "unable to open $debug:$!\n"; 
$GBKGENOMES = 'L:\NCBI_DAT\GBFF\Bacteria_taxonomy.txt'; 

##### load taxonomy hash ##### 
$taxons = 'R:\1_Downloads\taxa.Bacteria.dat'; 
open(TAXONS, $taxons) || die "unable to open $taxons: $!\n"; 
my %TAXhash; 
while(<TAXONS>){ 
(my $orgID, my $phylog)=split('\t',$_); $TAXhash{$orgID}=$phylog;} 
close(TAXONS); 

##### load protIDs hash ##### 
$protid = 'R:\1_Downloads\geneinfo.Bacteria.dat'; 
open(PROTID, $protid) || die "unable to open $taxons: $!\n"; 
my %IDhash; 
while(<PROTID>){ 
(my $prot, my $ID)=split('\t',$_); 
$prot =~ s/\s//g; $ID =~ s/\n//g; 
$IDhash{$prot}=$ID;} 
close(PROTID); 

##### get genbank files ##### 
my $dir = 'L:\NCBI_DAT\GBFF\Bacteria'; 
die unless opendir DIR, $dir; 
foreach my $file (readdir DIR) { 
    $/="\n//\n"; 
    next if $file eq '.' or $file eq '..'; 
    $gbk = $dir.'/'.$file; 
    $gbk =~ s/\//\\/g; 
    $gbk =~ /GCA_(\d+)/; 

####### open .gbk file and split contigs ####### 
if(-f $gbk && $gbk =~ /\.(gbk|gbff)/ && $gbk !~ /gz$/){ 
    open(GBK, $gbk) || die "unable to open $gbk: $!\n"; 
    $i=1; $count =0; 

    while(<GBK>){ 
     $BIG=$_; 
     $BIG =~ s/[\@<>\%\n]//g; 
     if($BIG =~ /(\s+CDS\s{5}|\s+\S*RNA\s{5})/){ 

      # Get Phylogeny 
      $BIG =~ ~ /db_xref\=\"taxon:(\d+)/; 
      $taxID=$1; $count = 1; 
      $BIG =~ /ORGANISM\s+(.*?)\s+(\w+\;.*?)\./; 
      $SPECIES = $1; $PHYLOGENY = $2; 
      $PHYLOGENY =~ s/\(.*?\)//g; $PHYLOGENY =~ s/[^\w\;]//g; 
      $taxonomy = $TAXhash{$taxID}; 
      if($taxonomy =~ /\w/){ 
       $taxonomy =~ s/(\s+\;$|\s+$|\s+\;\s+$)//g; 
       $PHYLOGENY = $taxonomy;} 
      else{$PHYLOGENY=$PHYLOGENY."\;".$SPECIES;} 
      $PHYLOGENY =~ s/[\t\n]//g; 

      if($PHYLOGENY =~ /Bacteria/i){$org="B";} 
      elsif($PHYLOGENY =~ /Virus/i){$org="V";} 
      elsif($PHYLOGENY =~ /Fungi/i){$org="F";} 
      elsif($PHYLOGENY =~ /Archaea/i){$org="A";} 
      elsif($PHYLOGENY =~ /Chordata/i){$org="C";} 
      elsif($PHYLOGENY =~ /(Viridiplantae|Stramenopiles|Rhodophyta)/i){$org="P";} 
      elsif($PHYLOGENY =~ /Eukaryota/i && $org !~ /[ABCFHPRV]/){$org="I";} 
      else{$org="U";} 

      # Print Phylogeny 
      open(GENO, '>>', $GBKGENOMES)||die "unable to open $GBKGENOMES:$!\n"; 
      print GENO "$taxID\t$PHYLOGENY\n"; close(GENO); 

      # get genome seq ### 
      $BIG =~ /ORIGIN(.+)/; 
      $GenomeSeq=$1; 
      $GenomeSeq =~ s/[^a-z]//ig; 
      $GenomeSeq = uc($GenomeSeq); 
      if(length($GenomeSeq)<100){next;} # eg Bos Taurus genome had no gene seqs 

      # split file by genes 
      $BIG =~ /VERSION\s{5,}(\w.*?)\s/; $Accession = $1; 
      $BIG =~ s/(\s+gene\s{5})/\%$1/g; 
      $BIG =~ s/(\s+[a-z]RNA\s{5})/\%$1/g; 
      $BIG =~ s/(\s+CDS\s{5})/\%$1/g; 
      $BIG =~ s/order\((\d+)\W*.*?\W(\d+)\)+/$1\.\.$2/g; 
      $BIG =~ s/join\((\d+)\W*.*?\W(\d+)\)+/$1\.\.$2/g; 
      @genes = split("\%",$BIG); $junk=shift(@genes); 

      # get gene info 
      foreach(@genes){ 
       $gline = $_; 
       if($gline =~ /^\s+gene\s+/){next;} 

       # get gene type 
       if($gline =~ /\s+CDS\s+[\dc]/)  {$type = "Protein";} 
       elsif($gline =~ /\s\/pseudo/)   {$type = "Pseudo";} 
       elsif($gline =~ /\s+\S*[^mr]RNA\s{5}/){$type = "ncRNA"; 
        $gline =~ /\/note\=\".*\;*(.*)\"/; $LOC=$1; 
        if($LOCUS !~ /\w/){$LOCUS=$LOC;}} 
       elsif($gline =~ /\s+rRNA\s{5}/)  {$type = "rRNA";} 
       elsif($gline =~ /\s+tRNA\s{5}/)  {$type = "tRNA";} 
       else{next;} 

       # get gene names and ids 
       if($gline =~ /\/note\=\".*(COG\d\d\d\d)/)  {$COG = $1; $COG =~ s/\s//g;} else{$COG ='';} 
       if($gline =~ /\/note\=\".*:(K\d\d\d\d\d)/) {$KO = $1; $KO =~ s/\s//g;} else{$KO ='';} 
       if($gline =~ /\/locus_tag\=\"(.*?)\"/)  {$LOCUS = $1; $LOCUS =~ s/\s//g;} else{$LOCUS ='';} 
       if($gline =~ /\/protein_id\=\"(.*?)\"/)  {$ProtID = $1; $ProtID =~ s/\s//g;} else{$ProtID ='';} 
       if($gline =~ /\/product\=\"(.*?)\"/)   {$Product = $1;} else{$Product ='';} 
       if($gline =~ /\/gene\=\"(.*?)\"/)    {$GName = $1;} else{$GName ='';} 
       if($gline =~ /\/inference\=\".*(RF\d+)\"/) {$Rfam = $1;} else{$Rfam ='';} 
       if($gline =~ /\/translation\=\"([\w\s]+)\"/) {$AAseq = $1; $AAseq =~ s/\s//g;} else{$AAseq ='';} 

       # get gene seq and coords     
       if($gline =~/(RNA|CDS)\s+(\d+)\D*\.\.\D*(\d+)/){ 
        if($2>$3){$start = $3; $end = $2;} 
        else{$start = $2; $end = $3;} 
        $strand = "\+"; $seq= substr $GenomeSeq, $start-1, $end-$start+1;} 
       elsif($gline =~/(RNA|CDS)\s+compl\S*?(\d+)\D*\.\.\D*(\d+)/){ 
        if($2>$3){$start = $3; $end = $2;} 
        else{$start = $2; $end = $3;} 
        $strand = "\-"; $seq= substr $GenomeSeq, $start-1, $end-$start+1; 
        $seq =~ tr/atgcrykmbvhdATGCRYKMBVHD/tacgyrmkvbdhTACGYRMKVBDH/; 
        $rseq=reverse($seq); $seq=$rseq;} 
       else{print DEBUG "no coords $gline\t$gbk\n"; next;} 

       $seq=uc($seq); $Glen = length($seq); $coords = "$start\.\.$end"; 
       if($Glen < 5){print DEBUG "gene length issue $gline\t$gbk\n"; next;} 

       # get gene IDs 
       print "prot id $ProtID and $gbk\n"; 
       $IDS = $IDhash{$ProtID}; $IDS =~ s/\n//g; $IDS =~ s/.*\&//; $Func = ''; $DATname = ''; 
       if($IDS =~ /\#/){($DATname, $Func) = split("\#", $IDS); $Func =~ s/(\s+$|^\s+)//;} 
       if($Func !~ /$COG/ && $COG =~ /COG\d\d\d\d/){$Func = $COG."\@".$Func;} 
       if($Func !~ /$KO/ && $KO =~ /K\d\d\d\d\d/){$Func = $KO."\@".$Func;} 
       $Func =~ s/(\@$|^\@)//g; 

       # fix gene name issues 
       if($GName =~ /((hypothetical|uncharacterized|conserved|predicted)\s+protein|unknown function|scaffold|contig)/i || length($GName)<3 || $GName !~ /\w/){ 
         if(length($Product)>length($GName) && $Product !~ /((hypothetical|uncharacterized|conserved|predicted)\s+protein|unknown function|scaffold|contig)/i){$GName=$Product;} 
        elsif(length($DATname)>length($GName) && $DATname !~ /((hypothetical|uncharacterized|conserved|predicted)\s+protein|unknown function|scaffold|contig)/i){$GName=$DATname;} 
       else{ if($type =~ /(protein|pseudo)/i){$GName = "Uncharacterized protein";} else{$GName = "Uncharacterized gene";}}}     
       $GName =~ s/([\;\,\.\@\<\>\%\|]|\(.*\))//g; $GName =~ s/(\s$|^\s)//g; $GName =~ s/\s+/_/g; 
       if($LOCUS !~ /\w/){$LOCUS = $Accession."&".$coords;} 

       $FINAL = "$LOCUS\t$ProtID\t$GName\t$type\t$Glen\t$strand\t$taxID\t$org\t$Func\t$AAseq\t$seq"; $FINAL =~ s/\n//g; 
       if($LOCUS =~ /\w/){print GBKINFO "$FINAL\n";} 

      } # foreach gene 
       last; 
      } # if big matches protein 
      else{$i++; print "no protein $i\n"; next;} 
     } # close while gbk 
     close(GBK)||die "unable to close GBK:$!\n"; #just added to check it is closing 

     if($count==0){ print "no genes unlinked $gbk\n"; unlink $gbk or warn "Could not unlink $gbk: $!"; next;} 
    } # closes 1st if for getting genomes 
} # closes 1st foreach file 

close(GBKINFO); 
close(DEBUG); 

Image showing command line print is ahead of print to file and memory use is fine

+1

誰かが印刷物が凍っていると不平を言うと、それは通常間違いであり、バッファリングによってだまされます。 '$ fh-> autoflush'を使ってバッファリングを無効にすることができます。 – ikegami

+0

本当に凍っている印刷物は、パイプに書き込んでバッファがいっぱいであるためです。書き込みが完了する前に、パイプのリーダーがデータを読み取る必要があります。 – ikegami

+0

出力がファイルに送られても何か変更はありますか?または、コマンドプロンプトの設定がこの[回答](http://superuser.com/a/1053104/544510)のように変更された場合 –

答えて

0

ありがとうございます!私は、一般的な$ | = 1の両方を使ってバッファをフラッシュすることを試みました。すべてのネストされたFHで動作しなかったFH固有のもの、そして
select((select(FH)、$ | = 1)[0]);
それは、それがぶら下がっていた場所を見つけるのを助けました...ある正規表現は、いくつかのgbkファイルの混乱をうまく網羅していません。悪い正規表現 - > $ gline =〜// note \ = \ "\;(。*)\" /;

関連する問題