在蛋白质序列中搜索motif?

时间:2009-05-06 20:41:39

标签: perl

我编写了以下脚本来搜索蛋白质序列(字符串)中的motif(substring)。我是初学者,写这个对我来说很难。我有两个相同的问题: 的 1。错误:以下脚本几乎没有错误。我已经相当一段时间了,但还没弄清楚是什么以及为什么? 2.编写以下脚本以搜索蛋白质序列(字符串)中的一个motif(子串)。我的下一个任务是在相同的蛋白质序列(字符串)中按特定顺序搜索多个基序(例如:motif1 motif2 motif 3 motif4此顺序不能更改)

        use strict;
        use warnings;

        my @file_data=();
        my $motif ='';
        my $protein_seq='';
        my $h= '[VLIM]';   
        my $s= '[AG]';
        my $x= '[ARNDCEQGHILKMFPSTWYV]';
        my $regexp = "($h){4}D($x){4}D"; #motif to be searched is hhhhDxxxxD
        my @locations=();

        @file_data= get_file_data("seq.txt");

        $protein_seq= extract_sequence(@file_data); 

    #searching for a motif hhhhDxxxxD in each protein sequence in the give file

        foreach my $line(@file_data){
        if ($motif=~ /$regexp/){
        print "found motif \n\n";
        }
        else {
        print "not found \n\n";
        }
        }
#recording the location/position of motif to be outputed

        @locations= match_position($regexp,$seq);
        if (@locations){ 
        print "Searching for motifs $regexp \n";
        print "Catalytic site is at location:\n";
        }
        else{
        print "motif not found \n\n";
        }
        exit;

        sub get_file_data{
        my ($filename)=@_;
        use strict;
        use warnings;
        my $sequence='';

        foreach my $line(@file_data){

        if ($line=~ /^\s*$/){
        next;
                }
        elsif ($line=~ /^\s*#/){
        next;
        }
        elsif ($line=~ /^>/){
        next;
        }
        else {
        $sequence.=$line;
        }
        }
        $sequence=~ s/\s//g;
        return $sequence;
        }

        sub(match_positions) {
        my ($regexp, $sequence)=@_;
        use strict;
        my @position=();
        while ($sequence=~ /$regexp/ig){
        push (@position, $-[0]);
        }
        return @position;
        }

2 个答案:

答案 0 :(得分:3)

  1. 首先,关键字为elsif,其次是您不需要它。您可以将get_file_data循环中的代码压缩为:

    next if $line =~ /^\s*$|^>/; 
    $sequence .= $line;
    

    只要您要使用正则表达式 - 除非过于笨拙 - 您也可以搜索您想要忽略的所有情况。如果您发现实际的第二种情况,可以将其添加为另一种交替。假设您要排除以#-开头的行。然后你可以像这样添加它:/^\s*$|^>|^#-/

  2. 另一件事是my position=();需要@ sigil,在位置之前,或者其他方式,perl认为你正在通过调用position()来尝试一些棘手的事情

  3. 您需要进行以下更改:

     my $h= '[VLIM]';   
     my $s= '[AG]';
     my $x= '[ARNDCEQGHILKMFPSTWYV]';
    

    否则,您只是将$h分配给数组引用,其中包含从 sub VLIM返回的任何内容填充的单个插槽。

  4. 第三,不要使用$&。替换pos($sequence)-length($&)+1

    push @positions, $-[0];
    

    或者更好的是,使用English

    use English qw<-no_match_vars>;
    ...
    push @positions, $LAST_MATCH_START[0];
    
  5. 我建议以下文件阅读:

    use IO::File;
    ...
    # Use real file handles
    my $fh = IO::File->new( "<seq.txt" );
    get_file_data( $fh ); # They can be passed
    ...
    sub get_file_data{
        my $file_handle = shift; 
        ...
        # while loop conserves resources
        while ( my $line = <$file_handle> ) { 
            next if $line =~ /^\s*$|^>/;
            $sequence .= $line;
        } 
    
  6. 关于前进的建议 - 这对我有很大的帮助:

    一个。安装Smart::Comments

    B中。把它放在脚本的顶部:

     use Smart::Comments;
    

    ℃。每次你不确定你到目前为止所做的事情,比如你想看到$sequence的当前内容,请在代码中放置以下内容:

    ### $sequence
    exit 0;
    

    只是展示并退出。如果打印输出太多,请将其删除。

答案 1 :(得分:0)

  • 使用“elsif”代替“elseif”。
  • @file_data和@fasta_file_data应该是一回事吗?

match_positions

  • 删除子名称周围的括号。
  • 将“我的位置”改为“我的@position”。
  • 将模式从/ regexp / ig更改为/ $ regexp / ig。