标签: bioperlseqio |
分类: Bioinformatics |
Bioperl里提供的Bio::SeqIO包可以帮助我们很方便地处理fasta和fastq等文件。
====================Fasta格式====================
>ago18rsv3_1 119439||21
TCGCTTGGTGCAGATCGGGAC
Fasta格式的一条记录是两行。其中第一行的ago18rsv3_1为序列的ID,119439||21为序列的optional description,可有可无。第二行是序列。
在Bio::SeqIO里,如果一个序列对象用$obj表示(具体请见代码),那么:
$obj->id 表示id;
$obj->desc 表示description;
$obj->seq 表示序列;
$obj->length 表示序列长度。
以下程序读取一个fasta文件,并输出长度在18~28之间的序列。
#!/usr/bin/perl -w
use strict;
use warnings;
use Bio::SeqIO;
die "perl $0 fastqfile" if (@ARGV<1);
my $fastqF = $ARGV[0];
my $ina = Bio::SeqIO->new(-file => $fastaF, -format => 'fasta');
while(my $obj = $ina->next_seq()){
my $id = $obj->id;
my $desc = $obj->desc;
my $seq = $obj->seq;
my $len = $obj->length;
if($len >=18 && $len<=28){
print “>$id $desc\n$seq\n”;
}
}
====================Fastq格式====================
@HWUSI-EAS455_0018_FC708LRAAXX:5:1:1029:19221#0/1
TGCTGAAGCTGCCAGCATGATCTACNNTANGCNNNATCAANC
+HWUSI-EAS455_0018_FC708LRAAXX:5:1:1029:19221#0/1
f_Yfffaffffa_affRadfadd[dDDZZD^^DDDV^WZVEa
一共四行。第一行以@开头,为序列identifier,有时候后面还会跟一个optional description。第二行是序列。第三行以+开头,然后重复第一行的序列identifier。第四行是质量值。
在Bio::SeqIO里,如果一个序列对象用$obj表示(具体请见代码),那么:
$obj->id 表示id;
$obj->seq 表示序列;
$obj->length 表示序列长度。
$qual = join(' ',@{$obj->qual}) 表示质量值。这里$obj->qual表示的是对一个数组的引用,因此我们用@{$obj->qual}将这个数组的值取出来,再join到一起,赋值给$qual。
以下程序(split.pl)根据序列5’端的三个碱基barcode的不同,对fastq文件进行拆分,并且去掉5’端的三个碱基。
#! /usr/bin/perl -w
use strict;
use warnings;
use Bio::SeqIO::fastq;
die "Usage:\n\t perl $0
my ($fastqF, $barcodeF) = @ARGV;
my �rcode;
my �r_num;
my $n = 0;
open (IN, $barcodeF) or die;
while (
$barcode{$2} = $1 if (/^(\S+)\s+(\S+)$/);
}
close (IN);
my $in = Bio::SeqIO->new(-format => 'fastq-Illumina', -file => $fastqF);
while(my $obj=$in->next_seq()){
$n ++;
my $id = $obj->id;
my $seq = $obj->seq;
my $qual = join(' ',@{$obj->qual});
my @te = split / /,$qual;
my @te1;
shift @te;
shift @te;
shift @te;
for my $i(@te){
my $j = chr($i+64);
push @te1, $j;
}
$qual = join('', @te1);
my($bar) = $seq =~ /^([ATCGN]{3})/g;
die "$0: Incorrecr seq line.\n" unless ($bar);
$seq =~ s/^$bar//;
if(exists $barcode{$bar}){
if(exists $barcode{$bar}){
$bar_num{$bar} ++;
open(OUT, ">>$barcode{$bar}.fq") or die;
print OUT "\@$id\n$seq\n+\n$qual\n";
}
}
print STDERR "$fastqF\tNumber\tRatio\n", "-" x 40, "\n";
foreach (sort keys �r_num) {
print STDERR "$barcode{$_}($_)\t$bar_num{$_}\t", $bar_num{$_}/$n*100, "%\n";
}
print STDERR "-" x 40, "\nTotal reads\t$n\t100%\n";
barcode文件示例:
A TCG
B TGC
C GCG
运行:perl split.pl fastaqfile barcode &> sta.log
Tips:a.由于序列要去掉前三个碱基,因此对应的质量值也要去掉三个。
b. my $qual = join(' ',@{$obj->qual});通过这种方法取出来到quality值被转化成了ASCⅡ码,而输出的时候我们要将之转化为ASCⅡ码对应的字符。本例中的数据是GA Pipeline1.3以上的版本产生的,转化为字符时应将ASCⅡ码数值加上64再用perl里面提供的chr()函数转化。
延伸一下,如何将字符转化为ASCⅡ码呢?对于GA Pipeline1.3以上的版本而言,Qphred =ord(ASCⅡ码)-64.
Qphred 是如何产生出来的?Qphred =-10 log10(e)。e表示出错的概率,越小越好。因此Qphred值越大越好。一般接近40质量就很好了。
====================学会找错哦====================
Fastq文件处理时,由于$obj->qual表示的是对一个数组的引用,直接输出这个值会得出错误的结果,如ARRAY(0x115f320)。为了看看到底$obj->qual里面是什么,可调用Data::Dumper这个包。
#! /usr/bin/perl -w
use strict;
use warnings;
use Bio::SeqIO::fastq;
use Data::Dumper;
die "perl $0 fastqF\n" unless (@ARGV);
my $fastqf = $ARGV[0];
my $in = Bio::SeqIO->new(-format => 'fastq-illumina',-file => $fastqf);
while (my $obj = $in->next_seq) {
print Data::Dumper->Dump($obj->qual);
}
运行程序输出如下:
$VAR1 = 38;
$VAR2 = 31;
$VAR3 = 25;
$VAR4 = 38;
$VAR5 = 38;
$VAR6 = 38;
$VAR7 = 33;
$VAR8 = 38;
……
结合ARRAY(0x115f320)这个错误的输出形式,我们大概可以判断$obj->qual表示的是对数组的引用。