3

私はPerlのイントロクラスの学生です。課題への取り組み方についての提案を探しています。私の教授はフォーラムを奨励しています。割り当ては次のとおりです。

コマンドラインから酵素ファイルとDNAファイルの2つのファイルを取得するPerlプログラムを作成します。制限酵素を含むファイルを読み取り、制限酵素をDNAファイルに適用します。

出力は、dnaファイルで発生する順序で配置されたDNAのフラグメントになります。出力ファイルの名前は、制限酵素の名前をDNAファイルの名前にアンダースコアを付けて追加することによって作成する必要があります。

たとえば、酵素がEcoRIであり、DNAファイルの名前がBC161026の場合、出力ファイルの名前はBC161026_EcoRIである必要があります。

私のアプローチは、次のようにメインプログラムと2つのサブプログラムを作成することです。

メイン:私の潜水艦を一緒に結ぶ方法がわかりませんか?

サブプログラム$DNA:DNAファイルを取得し、新しい行を削除して1つの文字列を作成します

サブプログラム酵素:コマンドラインからの酵素ファイルから行を読み取って保存します。酵素の頭字語をカットの位置から分離するようにファイルを解析します。カットの位置を正規表現としてハッシュテーブルに保存する頭字語の名前をハッシュテーブルに保存する

酵素ファイル形式に関する注意:酵素ファイルは、Stadenと呼ばれる形式に従います。例:

AatI/AGG'CCT//
AatII/GACGT'C//
AbsI/CC'TCGAGG//

酵素の頭字語は、最初のスラッシュの前の文字で構成されます(最初の例では、AatI。認識シーケンスは、最初のスラッシュと2番目のスラッシュの間のすべてです(最初の例では、AGG'CCT)。カットポイントは、認識シーケンスのアポストロフィ酵素内のdnaには、次のような標準的な略語があります。

R=GまたはAB= Aではない(CまたはGまたはT)など..

メインチャンクの推奨事項に加えて、私が省略した欠落部分はありますか?このプログラムにパッチを適用するのに役立つと思われる特定のツールをお勧めしますか?

入力酵素の例:TryII/RRR'TTT//

読み取る文字列の例:CCCCCCGGGTTTCCCCCCCCCCCCAAATTTCCCCCCCCCCCCAGATTTCCCCCCCCCCGAGTTTCCCCC

出力は次のようになります。

CCCCCCGGG

TTTCCCCCCCCCCCCAAA

TTTCCCCCCCCCCCCAGA

TTTCCCCCCCCCCGAG

TTTCCCCC

4

4 に答える 4

3

これが私が問題を解決しようと試みた方法です(以下のコード)。
1)引数からファイル名を取得し、それぞれfilehandlesを作成します。
2)指定された形式の出力ファイル用に新しいファイルハンドルが作成されます
。3)最初のファイルから「カットポイント」が抽出されます
。4)2番目のファイルのDNAシーケンスは、手順3で取得したカットポイント上でループされます。

#!/usr/bin/perl
use strict;
use warnings;
my $file_enzyme=$ARGV[0];
my $file_dna=$ARGV[1];

open DNASEQ, ">$file_dna"."_"."$file_enzyme";
open ENZYME, "$file_enzyme";
open DNA, "$file_dna";
while (<ENZYME>) {
 chomp;
  if( /'(.*)\/\//) { # Extracts the cut point between ' & // in the enzyme file
    my $pattern=$1;
    while (<DNA>) {
     chomp;
     #print $pattern;
     my @output=split/$pattern/,;
     print DNASEQ shift @output,"\n"; #first recognized sequence being output
     foreach (@output) {
        print DNASEQ "$pattern$_\n"; #prefixing the remaining sequences with the cut point pattern
     }
   }
 }
}
close DNA;
close ENZYME;
close DNASEQ;
于 2010-11-28T06:50:01.577 に答える
3

酵素では、酵素をハッシュに保存する場合、酵素の名前がキーであり、サイトが値である必要があることに注意してください(原則として2つの酵素が同じサイトを持つ可能性があるため)。

メインルーチンでは、ハッシュを反復処理できます。酵素ごとに1つの出力ファイルを生成します。最も直接的な方法は、サイトを正規表現に変換し(他の正規表現を使用して)、それをDNAシーケンスに適用することですが、他の方法もあります。(これを少なくとも1つの他のサブに分割することはおそらく価値があります。)

于 2010-11-28T06:24:00.593 に答える
3

さて、私はあなたの宿題をするだけではいけないことを知っていますが、これにはいくつかの楽しいトリックがあったので、私はそれで遊んだ。コピーするだけでなく、これから学びましょう。コメントが苦手でしたので、わからないことがありましたらお問い合わせください。これには、クラスでカバーしていなければ教授が知っているというちょっとした魔法がありますので、必ず理解してください。

#!/usr/bin/env perl

use strict;
use warnings;

use Getopt::Long;

my ($enzyme_file, $dna_file);
my $write_output = 0;
my $verbose = 0;
my $help = 0;
GetOptions(
  'enzyme=s' => \$enzyme_file,
  'dna=s' => \$dna_file,
  'output' => \$write_output,
  'verbose' => \$verbose,
  'help' => \$help
);

$help = 1 unless ($dna_file && $enzyme_file);
help() if $help; # exits

# 'Main'
my $dna = getDNA($dna_file);
my %enzymes = %{ getEnzymes($enzyme_file) }; # A function cannot return a hash, so return a hashref and then store the referenced hash
foreach my $enzyme (keys %enzymes) {
  print "Applying enzyme " . $enzyme . " gives:\n";
  my $dna_holder = $dna;
  my ($precut, $postcut) = ($enzymes{$enzyme}{'precut'}, $enzymes{$enzyme}{'postcut'});

  my $R = qr/[GA]/;
  my $B = qr/[CGT]/;

  $precut =~ s/R/${R}/g;
  $precut =~ s/B/${B}/g;
  $postcut =~ s/R/${R}/g;
  $postcut =~ s/B/${B}/g;
  print "\tPre-Cut pattern: " . $precut . "\n" if $verbose;
  print "\tPost-Cut pattern: " . $postcut . "\n" if $verbose;

  #while(1){
  #  if ($dna_holder =~ s/(.*${precut})(${postcut}.*)/$1/ ) {
  #    print "\tFound section:" . $2 . "\n" if $verbose;
  #    print "\tRemaining DNA: " . $1 . "\n" if $verbose;
  #    unshift @{ $enzymes{$enzyme}{'cut_dna'} }, $2;
  #  } else {
  #    unshift @{ $enzymes{$enzyme}{'cut_dna'} }, $dna_holder;
  #    print "\tNo more cuts.\n" if $verbose;
  #    print "\t" . $_ . "\n" for @{ $enzymes{$enzyme}{'cut_dna'} };
  #    last;
  #  }
  #}
  unless ($dna_holder =~ s/(${precut})(${postcut})/$1'$2/g) {
    print "\tHas no effect on given strand\n" if $verbose;
  }
  @{ $enzymes{$enzyme}{'cut_dna'} } = split(/'/, $dna_holder);
  print "\t$_\n" for @{ $enzymes{$enzyme}{'cut_dna'} };

  writeOutput($dna_file, $enzyme, $enzymes{$enzyme}{'cut_dna'}) if $write_output; #Note that $enzymes{$enzyme}{'cut_dna'} is an arrayref already
  print "\n";
}

sub getDNA {
  my ($dna_file) = @_;

  open(my $dna_handle, '<', $dna_file) or die "Cannot open file $dna_file";
  my @dna_array = <$dna_handle>;
  chomp(@dna_array);

  my $dna = join('', @dna_array);

  print "Using DNA:\n" . $dna . "\n\n" if $verbose;
  return $dna;
}

sub getEnzymes {
  my ($enzyme_file) = @_;
  my %enzymes;

  open(my $enzyme_handle, '<', $enzyme_file) or die "Cannot open file $enzyme_file";
  while(<$enzyme_handle>) {
    chomp;
    if(m{([^/]*)/([^']*)'([^/]*)//}) {
      print "Found Enzyme " . $1 . ":\n\tPre-cut: " . $2 . "\n\tPost-cut: " . $3 . "\n" if $verbose;
      $enzymes{$1} = {
        precut => $2,
        postcut => $3,
        cut_dna => [] #Added to show the empty array that will hold the cut DNA sections
      };
    }
  }

  print "\n" if $verbose;
  return \%enzymes;
}

sub writeOutput {

  my ($dna_file, $enzyme, $cut_dna_ref) = @_;

  my $outfile = $dna_file . '_' . $enzyme;
  print "\tSaving data to $outfile\n" if $verbose; 
  open(my $outfile_handle, '>', $outfile) or die "Cannot open $outfile for writing";

  print $outfile_handle $_ . "\n" for @{ $cut_dna_ref };
}

sub help {

  my $filename = (split('/', $0))[-1];

  my $enzyme_text = <<'END';
AatI/AGG'CCT//
AatII/GACGT'C//
AbsI/CC'TCGAGG//
TryII/RRR'TTT//
Test/AAA'TTT//
END

  my $dna_text = <<'END';
CCCCCCGGGTTTCCCCCCC
CCCCCAAATTTCCCCCCCCCCCCAGATTTC
CCCCCCCCCGAGTTTCCCCC
END

  print <<END;
Usage: 
    $filename --enzyme (-e) <enzyme-filename> --dna (-d) <dna-filename> [options] (files may come in either order)
    $filename -h    (shows this help)

Options: 
    --verbose (-v)  print additional (debugging) information
    --output (-o)   output final data to files


Files:
The DNA file contains one DNA string which may be broken over many lines. E.G.:

$dna_text

The enzymes file constains enzyme definitions, one per line. E.G.:

$enzyme_text
END

exit;
}

編集:これは各酵素の最終結果ホルダーであるため、cut_dnaの初期化を明示的に追加しました。したがって、より明確に表示するのがよいと思いました。

編集2:出力ルーチン、呼び出し、フラグ、および対応するヘルプを追加しました。

編集3:ループを削除しながら、カナバニンの最良の方法を組み込むようにメインルーチンを変更しました。これで、一時的なカットマーク(')を追加し、カットマークを配列に分割するグローバル置換になりました。古い方法をコメントとして残し、新しい方法は次の5行です。

編集4:複数のファイルに書き込むための追加のテストケース。(下)

my @names = ('cat','dog','sheep'); 
foreach my $name (@names) { #$name is lexical, ie dies after each loop
  open(my $handle, '>', $name); #open a lexical handle for the file, also dies each loop
  print $handle $name; #write to the handle
  #$handles closes automatically when it "goes out of scope"
}
于 2010-11-28T17:36:50.783 に答える
2

すでにいくつかの答えがあることは知っていますが、ちょっと...運試しをしたいと思ったので、ここに私の提案があります:

#!/usr/bin/perl

use warnings;
use strict;
use Getopt::Long;

my ($enz_file, $dna_file);

GetOptions( "e=s" => \$enz_file,
            "d=s" => \$dna_file,
          );

if (! $enz_file || ! $dna_file) {
   # some help text 
   print STDERR<<EOF; 

   Usage: restriction.pl -e enzyme_file -d DNA_file

   The enzyme_file should contain one enzyme entry per line.
   The DNA_file may contain the sequence on one single or on
   several lines; all lines will be concatenated to yield a
   single string.
EOF      
   exit();
}

my %enz_and_patterns; # stores enzyme name and corresponding pattern

open ENZ, "<$enz_file" or die "Could not open file $enz_file: $!";
while (<ENZ>) {
   if (m#^(\w+)/([\w']+)//$#) {
      my $enzyme  = $1; # could also remove those two lines and use 
      my $pattern = $2; # the match variables directly, but this is clearer

      $enz_and_patterns{$enzyme} = $pattern;
   }
}
close ENZ;

my $dna_sequence;

open DNA, "<$dna_file" or die "Could not open file $dna_file: $!";
while (my $line = <DNA>) {
   chomp $line;
   $dna_sequence .= $line; # append the current bit to the sequence
                           # that has been read so far
}
close DNA;

foreach my $enzyme (keys %enz_and_patterns) {
   my $dna_seq_processed = $dna_sequence; # local copy so that we retain the original

   # now translate the restriction pattern to a regular expression pattern:
   my $pattern = $enz_and_patterns{$enzyme};
   $pattern    =~ s/R/[GA]/g; # use character classes
   $pattern    =~ s/B/[^A]/g;
   $pattern    =~ s/(.+)'(.+)/($1)($2)/; # remove the ', but due to the grouping
                                         # we "remember" its position

   $dna_seq_processed =~ s/$pattern/$1\n$2/g; # in effect we are simply replacing
                                              # each ' with a newline character
   my $outfile = "${dna_file}_$enzyme";
   open OUT, ">$outfile" or die "Could not open file $outfile: $!";
   print OUT $dna_seq_processed , "\n";
   close OUT;
}

私はあなたのTryIIの例で私のコードをテストしましたが、それはうまくいきました。

これは繰り返しのないコードを数行書くだけで処理できるタスクなので、個別のサブルーチンを作成することが正当化されるとは思いませんでした。私は許されることを願っています...:)

于 2010-11-28T20:29:27.030 に答える