修改perl脚本以不打印重复项并提取一定长度的序列

时间:2016-07-29 14:36:50

标签: perl

我想首先为这篇文章的生物学性质道歉。我想我应该先发布一些背景信息。我有一组基因文件,其中包含来自不同物种的一到五个DNA序列。我使用bash shell脚本执行blastn,每个基因文件作为查询和来自五个物种的所有转录组序列(all_transcriptome_seq.fasta)的文件作为主题。我现在想要处理这些输出文件(并且有很多),以便我可以获得每个基因命中一个文件的所有主题序列,删除重复序列(除了保留一个),并确保我得到的长度实际命中查询的序列。

以下是一个基因文件的blastn输出(列:qseqid qlen sseqid slen qframe qstart qend sframe sstart send evalue bitscore pident nident length

Acur_01000750.1_OFAS014956-RA-EXON04    248 Apil_comp17195_c0_seq1  1184    1   1   248 1   824 1072    2e-73    259    85.60   214 250
Acur_01000750.1_OFAS014956-RA-EXON04    248 Atri_comp5613_c0_seq1   1067    1   2   248 1   344 96  8e-97    337    91.16   227 249
Acur_01000750.1_OFAS014956-RA-EXON04    248 Acur_01000750.1 992 1   1   248 1   655 902 1e-133   459    100.00  248 248
Acur_01000750.1_OFAS014956-RA-EXON04    248 Btri_comp17734_c0_seq1  1001    1   1   248 1   656 905 5e-69    244    84.40   211 250
Btri_comp17734_c0_seq1_OFAS014956-RA-EXON04 250 Atri_comp5613_c0_seq1   1067    1   2   250 1   344 96  1e-60    217    82.33   205 249
Btri_comp17734_c0_seq1_OFAS014956-RA-EXON04 250 Acur_01000750.1 992 1   1   250 1   655 902 5e-69    244    84.40   211 250
Btri_comp17734_c0_seq1_OFAS014956-RA-EXON04 250 Btri_comp17734_c0_seq1  1001    1   1   250 1   656 905 1e-134   462    100.00  250 250

我一直在研究一个perl脚本,简而言之,它将sseqid列从all_transcriptome_seq.fasta文件中提取相应的序列,将它们放入一个新文件中,然后修剪成绩单到sstartsend位置。到目前为止,这是脚本:

#!/usr/bin/env perl

use warnings;
use strict;
use Data::Dumper;

############################################################################
# blastn_post-processing.pl v. 1.0 by Michael F., XXXXXX
############################################################################

my($progname) = $0;

############################################################################
# Initialize variables
############################################################################

my($jter);

my($com);
my($t1);

if ( @ARGV != 2 ) {
    print "Usage:\n  \$ $progname <infile> <transcriptomes>\n";
    print "  infile         = tab-delimited blastn text file\n";
    print "  transcriptomes = fasta file of all transcriptomes\n";
    print "exiting...\n";
    exit;
}

my($infile)=$ARGV[0];
my($transcriptomes)=$ARGV[1];

############################################################################
# Read the input file
############################################################################
print "Reading the input file... ";
open (my $INF, $infile) or die "Unable to open file";
my @data = <$INF>;
print @data;
close($INF) or die "Could not close file $infile.\n";
my($nlines) = $#data + 1;
my($inlines) = $nlines - 1;
print "$nlines blastn hits read\n\n";

############################################################################
# Extract hits and place sequences into new file
############################################################################
my @temparray;
my @templine;
my($seqfname);

open ($INF, $infile) or die "Could not open file $infile for input.\n";
@temparray = <$INF>;
close($INF) or die "Could not close file $infile.\n";
$t1 = $#temparray + 1;
print "$infile\t$t1\n";
$seqfname = "$infile" . ".fasta";
if ( -e $seqfname ) {
        print "    --> $seqfname exists. overwriting\n";
        unlink($seqfname);
    }   

# iterate through the individual hits
for ($jter=0; $jter<$t1; $jter++) {
    (@templine) = split(/\s+/, $temparray[$jter]);
    $com = "./extract_from_genome2 $transcriptomes $templine[2] $templine[8] $templine[9] $templine[2]";
    # print "$com\n";
    system("$com");
    system("cat temp.3 >> $seqfname");
    } # end for ($jter=0; $jter<$t1...

# Arguments for "extract_from_genome2"
#   // argv[1] = name of genome file
#   // argv[2] = gi number for contig
#   // argv[3] = start of subsequence
#   // argv[4] = end of subsequence
#   // argv[5] = name of output sequence

使用这个脚本,这是我得到的输出:

>Apil_comp17195_c0_seq1
GATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAACA
>Atri_comp5613_c0_seq1
GAGAATTCTAGCATCAGCAGTGAGGCCTGAAATACTCATGCCTATGTGACTATCTAGAGGTATTATTTTTTTTTGATGAGCTGACAGTTCAGAAGAAGCTCTTTTGAGAGCTACAAGAACTGCATACTGTTTATTTTTTACTCCAACTGTTGCTGCTCCAAGCTTTACAGCCTCCATTGCATATTCCACTTGGTGTAAACGCCCCTGAGGACTCCATACCGTAACATCAGAATCATACTGATTACGGA
>Acur_01000750.1
GAATTCTAGCGTCAGCAGTGAGTCCTGAAATACTCATCCCTATGTGGCTATCTAGAGGTATTATTTTTTCTGATGGGCCGACAGTTCAGAGGATGCTCTTTTAAGAGCCACAAGAACTGCATACTCTTTATTTTTACTCCAACAGTAGCAGCTCCAAGCTTCACAGCCTCCATTGCATATTCCACCTGGTGTAAACGTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Btri_comp17734_c0_seq1
GAATCCTTGCATCTGCAGTAAGTCCAGAAATGCTCATTCCAATATGGCTATCTAATGGTATTATTTTTTTCTGGTGAGCAGACAATTCAGATGATGCTCTTTTAAGAGCTACCAGTACTGCAAAATCATTGTTCTTCACTCCAACAGTTGCAGCACCTAATTTGACTGCCTCCATTGCATACTCCACTTGGTGCAATCTTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Atri_comp5613_c0_seq1
GAGAATTCTAGCATCAGCAGTGAGGCCTGAAATACTCATGCCTATGTGACTATCTAGAGGTATTATTTTTTTTTGATGAGCTGACAGTTCAGAAGAAGCTCTTTTGAGAGCTACAAGAACTGCATACTGTTTATTTTTTACTCCAACTGTTGCTGCTCCAAGCTTTACAGCCTCCATTGCATATTCCACTTGGTGTAAACGCCCCTGAGGACTCCATACCGTAACATCAGAATCATACTGATTACGGA
>Acur_01000750.1
GAATTCTAGCGTCAGCAGTGAGTCCTGAAATACTCATCCCTATGTGGCTATCTAGAGGTATTATTTTTTCTGATGGGCCGACAGTTCAGAGGATGCTCTTTTAAGAGCCACAAGAACTGCATACTCTTTATTTTTACTCCAACAGTAGCAGCTCCAAGCTTCACAGCCTCCATTGCATATTCCACCTGGTGTAAACGTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Btri_comp17734_c0_seq1
GAATCCTTGCATCTGCAGTAAGTCCAGAAATGCTCATTCCAATATGGCTATCTAATGGTATTATTTTTTTCTGGTGAGCAGACAATTCAGATGATGCTCTTTTAAGAGCTACCAGTACTGCAAAATCATTGTTCTTCACTCCAACAGTTGCAGCACCTAATTTGACTGCCTCCATTGCATACTCCACTTGGTGCAATCTTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA

正如你所看到的,它非常接近我想要的东西。以下是我遇到的两个问题,似乎无法弄清楚如何使用我的脚本解决问题。 第一个是一个序列可能在sseqid列中出现多次,并且脚本以其当前形式出现,它将打印出这些序列的重复。我只需要一个。如何修改我的脚本以不重复序列(即,我如何仅保留一个但删除其他重复项)?预期产出:

>Apil_comp17195_c0_seq1
GATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAACA
>Atri_comp5613_c0_seq1
GAGAATTCTAGCATCAGCAGTGAGGCCTGAAATACTCATGCCTATGTGACTATCTAGAGGTATTATTTTTTTTTGATGAGCTGACAGTTCAGAAGAAGCTCTTTTGAGAGCTACAAGAACTGCATACTGTTTATTTTTTACTCCAACTGTTGCTGCTCCAAGCTTTACAGCCTCCATTGCATATTCCACTTGGTGTAAACGCCCCTGAGGACTCCATACCGTAACATCAGAATCATACTGATTACGGA
>Acur_01000750.1
GAATTCTAGCGTCAGCAGTGAGTCCTGAAATACTCATCCCTATGTGGCTATCTAGAGGTATTATTTTTTCTGATGGGCCGACAGTTCAGAGGATGCTCTTTTAAGAGCCACAAGAACTGCATACTCTTTATTTTTACTCCAACAGTAGCAGCTCCAAGCTTCACAGCCTCCATTGCATATTCCACCTGGTGTAAACGTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA
>Btri_comp17734_c0_seq1
GAATCCTTGCATCTGCAGTAAGTCCAGAAATGCTCATTCCAATATGGCTATCTAATGGTATTATTTTTTTCTGGTGAGCAGACAATTCAGATGATGCTCTTTTAAGAGCTACCAGTACTGCAAAATCATTGTTCTTCACTCCAACAGTTGCAGCACCTAATTTGACTGCCTCCATTGCATACTCCACTTGGTGCAATCTTCCCTGAGGGCTCCATACCGTAACATCAGAATCATACTGGTTACGGAACA

第二是脚本没有完全提取正确的碱基对。它非常接近,只有一两个,但不完全正确。

例如,将第一个主题点击Apil_comp17195_c0_seq1sstartsend值分别为824和1072。当我去all_transcriptome_seq.fasta时,我得到了

AAGATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAAC

在那个碱基对范围内,而不是

GATTCTTGCATCTGCAGTAAGACCAGAAATGCTCATTCCTATATGGCTATCTAATGGTATTATTTTTTTCTGATGTGCTGATAATTCAGACGAAGCTCTTTTAAGAGCCACAAGAACTGCATACTGCTTGTTTTTTACTCCAACAGTAGCAGCTCCCAGTTTTACAGCTTCCATTGCATATTCGACTTGGTGCAGGCGTCCCTGGGGACTCCAGACGGTAACGTCAGAATCATACTGGTTACGGAACA
由我的脚本输出的

,这正是我所期待的。您还会注意到我的脚本输出的序列比它应该略短。有谁知道如何在我的脚本中修复这些问题?

谢谢,对于冗长的帖子感到抱歉!

编辑1:提供了适用于某些infiles的解决方案。但是,有些导致脚本输出的序列少于预期。这是一个有9个命中的infile,我只期待4个序列。

注意:此问题已在很大程度上基于答案部分下方提供的解决方案得到解决

Apil_comp16418_c0_seq1_OFAS000119-RA-EXON01 1587    Apil_comp16418_c0_seq1  2079    1   1   1587    1   416 2002    0.0 2931    100.00  1587    1587
Apil_comp16418_c0_seq1_OFAS000119-RA-EXON01 1587    Atri_comp13712_c0_seq1  1938    1   1   1587    1   1651    75  0.0 1221    80.73   1286    1593
Apil_comp16418_c0_seq1_OFAS000119-RA-EXON01 1587    Ctom_01003023.1 2162    1   1   1406    1   1403    1   0.0 1430    85.07   1197    1407
Atri_comp13712_c0_seq1_OFAS000119-RA-EXON01 1441    Apil_comp16418_c0_seq1  2079    1   1   1437    1   1866    430 0.0 1170    81.43   1175    1443
Atri_comp13712_c0_seq1_OFAS000119-RA-EXON01 1441    Atri_comp13712_c0_seq1  1938    1   1   1441    1   201 1641    0.0 2662    100.00  1441    1441
Atri_comp13712_c0_seq1_OFAS000119-RA-EXON01 1441    Acur_01000228.1 2415    1   1   1440    1   2231    797 0.0 1906    90.62   1305    1440
Ctom_01003023.1_OFAS000119-RA-EXON01    1289    Apil_comp16418_c0_seq1  2079    1   3   1284    1   1714    430 0.0 1351    85.69   1102    1286
Ctom_01003023.1_OFAS000119-RA-EXON01    1289    Acur_01000228.1 2415    1   1   1287    1   2084    797 0.0 1219    83.81   1082    1291
Ctom_01003023.1_OFAS000119-RA-EXON01    1289    Ctom_01003023.1 2162    1   1   1289    1   106 1394    0.0 2381    100.00  1289    1289

编辑2:偶尔输出的序列缺少比预期更少的序列,尽管从编辑1 建议(即,反向计算)中修改我的脚本后没有那么多。我无法弄清楚为什么脚本会在这些其他情况下输出更少的序列。在有问题的infile下面。输出缺少 Btri_comp15171_c0_seq1

Apil_comp19456_c0_seq1_OFAS000248-RA-EXON07 2464    Apil_comp19456_c0_seq1  3549    1   1   2464    1   761 3224    0.0 4551    100.00  2464    2464
Apil_comp19456_c0_seq1_OFAS000248-RA-EXON07 2464    Btri_comp15171_c0_seq1  3766    1   1   2456    1   3046    591 0.0 1877    80.53   1985    2465
Btri_comp15171_c0_seq1_OFAS000248-RA-EXON07 2457    Apil_comp19456_c0_seq1  3549    1   1   2457    1   3214    758 0.0 1879    80.54   1986    2466
Btri_comp15171_c0_seq1_OFAS000248-RA-EXON07 2457    Atri_comp28646_c0_seq1  1403    1   1256    2454    1   1401    203 0.0  990    81.60   980 1201
Btri_comp15171_c0_seq1_OFAS000248-RA-EXON07 2457    Btri_comp15171_c0_seq1  3766    1   1   2457    1   593 3049    0.0 4538    100.00  2457    2457

1 个答案:

答案 0 :(得分:1)

您可以使用哈希删除重复项

波纹管代码根据主题长度删除重复项(保留较大的主题长度行)。

只需使用

更新#遍历各个匹配部分
# iterate through the individual hits
my %filterhash;
my $subject_length;
for ($jter=0; $jter<$t1; $jter++) {
    (@templine) = split(/\s+/, $temparray[$jter]);
        $subject_length = $templine[9] -$templine[8];
        if(exists $filterhash{$templine[2]} ){
                if($filterhash{$templine[2]} < $subject_length){

                        $filterhash{$templine[2]}= $subject_length;
                }
        }
        else{
                $filterhash{$templine[2]}= $subject_length;
        }
    }
my %printhash;
for ($jter=0; $jter<$t1; $jter++) {
    (@templine) = split(/\s+/, $temparray[$jter]);
        $subject_length = $templine[9] -$templine[8];
         if(not exists $printhash{$templine[2]})
        {
            $printhash{$templine[2]}=1;
            if(exists $filterhash{$templine[2]} and $filterhash{$templine[2]} == $subject_length ){

                    $com = "./extract_from_genome2 $transcriptomes $templine[2] $templine[8] $templine[9] $templine[2]";
                    # print "$com\n";
                    system("$com");
                    system("cat temp.3 >> $seqfname");
            }
        }
        else{
            if(exists $filterhash{$templine[2]} and $filterhash{$templine[2]} == $subject_length ){

                    $com = "./extract_from_genome2 $transcriptomes $templine[2] $templine[8] $templine[9] $templine[2]";
                    #print "$com\n";
                    system("$com");
                    system("cat temp.3 >> $seqfname");
            }
        }

    } # end for ($jter=0; $jter<$t1...

希望这会对你有所帮助。

修改零件更新

对于否定立场,您需要更换

 $subject_length = $templine[9] -$templine[8];

if($templine[8] > $templine[9]){
                $subject_length = $templine[8] -$templine[9];
        }else{
                $subject_length = $templine[9] -$templine[8];
        }

您还需要更新extract_from_genome2负链序列代码。