Bio::SeqIO處理fasta和fastq文件
(2012-07-05 11:12:41)
標籤:
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 <fastqF> <barcodeF>\n" unless (@ARGV == 2);
my ($fastqF, $barcodeF) = @ARGV;
my �rcode;
my �r_num;
my $n = 0;
open (IN, $barcodeF) or die;
while (<IN>) {
$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表示的是對數組的引用。