Commit 03956ef1 authored by Sebastien Moretti's avatar Sebastien Moretti
Browse files

change all \t into 4 blanks & remove blanks at the end of line

parent 5fcebdb2
This diff is collapsed.
......@@ -73,7 +73,7 @@ GetOptions("msa|in=s" => \$msa, #Input sequences
"help|h" => \$help, #Print full help message
"run_name=s" => \$run_name, #Use another name, instead of input seq name, for result files
"cache=s" => \$Cache, #Specify what cache parameter
"hideBOJ" => \$hideBOJ,
"hideBOJ" => \$hideBOJ,
"template=s" => \$template, #Use a template file
"lim=i" => \$lim, #Limite number of input query sequences
"tmp" => \$tmp, #To keep traces of fake intermediate files like fake xml from NCBI, fake aln, ...
......@@ -162,7 +162,7 @@ while(<$MSA>){
$seqq =~ s/[^A-Za-z\-\*\n\r]//g; #Remove all the non-gap or non-alphabetic characters from the seq
chomp($seqq);
#fasta sequence on 1 line
if ( !exists($original_seq[$fasta_checker]) ){
if ( !exists($original_seq[$fasta_checker]) ){
@original_seq = (@original_seq, $seqq);
}
else {
......@@ -267,11 +267,11 @@ for(my $r=0; $r<=$#input_order; $r++){
print "\n\n$r done\n\nBlastP template for $r:\t$templP->{$templ_name}\n\n**********************************************************************\n\n";
}
else{
## --> send them to webblast
## --> send them to webblast
$quiet = '-quiet=on ' if ( $r>0 ); #Show webblast parameters only for the first webblast run
&launchWebblast("$cache/${date}_seq2blast.fas${r}", $quiet, $athome, $db, $species, $blast_exe, "$cache/${date}.blastp${r}");
##Get the BLASTp hit(s) acc number
##Get the BLASTp hit(s) acc number
open(my $BLASTP, '<', "${cache}/${date}.blastp${r}");
while(<$BLASTP>){
@multipleequalblasthits = (@multipleequalblasthits, $1) if ( $_ =~ /^>\s*\d+@?\w?\w?\w?__([^\s\|\.]+).*$/ ); #Warning: double '_'
......@@ -365,7 +365,7 @@ for(my $r=0; $r<=$#input_order; $r++){
$nameLess = $bestNucleotide if ( %$BOJ eq 0 && $intronStep==0 && ($bestNucleotide =~ /^N[CTWZG]_/ || $bestNucleotide =~ /^AC_/) );
my ($BOJresult, $bestGenomic) = &prepareResults4BOJ($BOJ, $multipleequalblasthits[$qq], ${original_seq[$r]}, $right_name, $intronLess, $nameLess);
$resultBOJ .= $BOJresult if ( $bestGenomic ne '' && $BOJresult ne '' && $resultBOJ !~ /_G_$bestGenomic[ \-]/ );
# print " $intronStep $POS->{0} [@intronStatus] {$BOJresult} $bestNucleotide - $bestGenomic \t $BOJ->{0}\n";
# print " $intronStep $POS->{0} [@intronStatus] {$BOJresult} $bestNucleotide - $bestGenomic \t $BOJ->{0}\n";
}
......@@ -415,10 +415,10 @@ if ( exists($tmpFiles[0]) ){
if ( -s "${originalMSA}.cds" || -s "${originalMSA}.out"){
print "\n\nTERMINATION STATUS: SUCCESS\n";
print "OUTPUT RESULTS\n";
print " #### File Type= MSA Format= fasta_CDS Name= ${originalMSA}.cds\n" if ( -s "${originalMSA}.cds");
print " #### File Type= MSA Format= fasta_CDS+Query Name= ${originalMSA}.cdsP\n" if ( -s "${originalMSA}.cdsP");
print " #### File Type= MSA Format= Rejected_seq Name= ${originalMSA}.out\n" if ( -s "${originalMSA}.out");
print " #### File Type= MSA Format= fasta_Exon-Boundaries Name= ${originalMSA}.boj\n" if ( -s "${originalMSA}.boj" && -s "${originalMSA}.cds" && $hideBOJ==0);
print " #### File Type= MSA Format= fasta_CDS Name= ${originalMSA}.cds\n" if ( -s "${originalMSA}.cds");
print " #### File Type= MSA Format= fasta_CDS+Query Name= ${originalMSA}.cdsP\n" if ( -s "${originalMSA}.cdsP");
print " #### File Type= MSA Format= Rejected_seq Name= ${originalMSA}.out\n" if ( -s "${originalMSA}.out");
print " #### File Type= MSA Format= fasta_Exon-Boundaries Name= ${originalMSA}.boj\n" if ( -s "${originalMSA}.boj" && -s "${originalMSA}.cds" && $hideBOJ==0);
}
else{
&failure;
......@@ -572,7 +572,7 @@ sub checkCacheAccessibility{
elsif ( -d "$cachedir/" ){
if ( -o "$cachedir/" ){
chmod 0754, "$cachedir/";
}
}
else{
print {*STDERR} "\n\t** Warning ** :\n\tPermissions do NOT seem to be valide for the current cache directory\n\n";
}
......@@ -1105,7 +1105,7 @@ sub runExonerate{
next RUN_EXONERATE;
}
print "\tProtein-Nucleotide aln was successful for $targetNT with $right_name\n";
#Parse Exonerate output
my ($posiTions, $posBOJ) = &loci_from_Exonerate::parser("$cache/${date}_${order}.exon");
......
#
#Version: 3.2.3
#OS: Linux
#OS: Linux
#Author: Sebastien Moretti
#E-mail: moretti.sebastien@gmail.com
#
......@@ -32,128 +32,128 @@ History of ProtoGene/PACMAN improvements:
Correct when first seq is revtrans and check for nt
3.0.2
Print an error message when input files are already nucleotides
Print an error message when input files are already nucleotides
2.2.5
Best management when only one gene match and alignment fails:
$intronStep==1 and $POS->{0} doesn't exist.
Best management of fake downloads:
- > without sequences
- sequences with Error: or <>
- ...
Best management when only one gene match and alignment fails:
$intronStep==1 and $POS->{0} doesn't exist.
Best management of fake downloads:
- > without sequences
- sequences with Error: or <>
- ...
2.2.4
Change intronless behavior if best nucleotide return
a GI number.
Change intronless behavior if best nucleotide return
a GI number.
2.2.3
Change gene locus coordinates to zero if they become
negative with +/- 5000 expansion.
Change gene locus coordinates to zero if they become
negative with +/- 5000 expansion.
2.2.2
Manage boj output when there are several intronless genes
for one query.
Manage boj output when there are several intronless genes
for one query.
2.2.1
Add a $lim variable to be able to fix max number of query
sequences as an input option.
Manage several geneIDs ?!?
Add a $lim variable to be able to fix max number of query
sequences as an input option.
Manage several geneIDs ?!?
2.2.0
New Release:
Better memory management
Code splits into more functions
Clean code
Write results when they are available, no more only at the exit
New Release:
Better memory management
Code splits into more functions
Clean code
Write results when they are available, no more only at the exit
1.2.8
Add an option to keep abnormal temporary files.
Increase size threshold for result file of exonerate, i.e.
no result or result.
Add an option to keep abnormal temporary files.
Increase size threshold for result file of exonerate, i.e.
no result or result.
1.2.6
Manage fake BLASTP acc when they have space, point or pipe
characters.
Check and correct perl POD text format.
Enhance fasta header for boj output like cds output.
Manage fake BLASTP acc when they have space, point or pipe
characters.
Check and correct perl POD text format.
Enhance fasta header for boj output like cds output.
1.2.4
Add an option to hide BOJ output for the IGS web server.
Output two CDS files: a standard one, and one with query prot
interleaved.
Add an option to hide BOJ output for the IGS web server.
Output two CDS files: a standard one, and one with query prot
interleaved.
1.2.2
Manage multiple runs of PACMAN and the co-occurance query name:
0.fas and 0.fas => now use temp name to limit this.
And temp names are mix of current date-time and a random nbr.
Manage multiple runs of PACMAN and the co-occurance query name:
0.fas and 0.fas => now use temp name to limit this.
And temp names are mix of current date-time and a random nbr.
1.2.0
Remove duplicated lines when a query, with multiple blastp hits
returns a single nucleotide for all hits. So, keeps only one.
Debug mode for BOJ, now available as a result file.
Enhance output for log files.
RefSeq -> 100% filters to avoid mis-species attribution
then NR -> 95%.
Remove duplicated lines when a query, with multiple blastp hits
returns a single nucleotide for all hits. So, keeps only one.
Debug mode for BOJ, now available as a result file.
Enhance output for log files.
RefSeq -> 100% filters to avoid mis-species attribution
then NR -> 95%.
1.0.4
Add a webblast step againt nr if refseq webblast returns no
hit: RefSeq, elsif nr, else NO HIT
Add a webblast step againt nr if refseq webblast returns no
hit: RefSeq, elsif nr, else NO HIT
1.0.3
Add an option to add the original peptide query beneath the
back-translated nt seq
Add the b,o,j identification in the Exonerate parser module
Add an option to add the original peptide query beneath the
back-translated nt seq
Add the b,o,j identification in the Exonerate parser module
1.0.2
New header format in the cds output
New header format in the cds output
1.0.1
Add standard log files for the web server
Manage multiple equal blast best hits
Mix PACMAN and Exoset, specially in the Exonerate parser
Add standard log files for the web server
Manage multiple equal blast best hits
Mix PACMAN and Exoset, specially in the Exonerate parser
0.99
Process the alignment between every nucleotide sequence found and use
the best one (transcript and genomic sequences)
Process the alignment between every nucleotide sequence found and use
the best one (transcript and genomic sequences)
0.98
Add a 'old' argument for the cache option to remove only 15 days
old files from the cache directory
Hide webblast parameters when it runs but the first one
Manage return lines from windows '^M'
Remove all the non-gap and non-alphabetic characters into the query
sequences
Add a 'old' argument for the cache option to remove only 15 days
old files from the cache directory
Hide webblast parameters when it runs but the first one
Manage return lines from windows '^M'
Remove all the non-gap and non-alphabetic characters into the query
sequences
0.97
Create a more robust 'cache directory' process
Add triplet to sure mismatches, i.e. Met and Trp
Create a more robust 'cache directory' process
Add triplet to sure mismatches, i.e. Met and Trp
0.96
Add a second result file, as library, with storage of accession
numbers resulting from blast query and prot-nt correspondances.
Add a second result file, as library, with storage of accession
numbers resulting from blast query and prot-nt correspondances.
0.95 - 24 oct 2005
Correct hash table variable define as semi-local, and not strictly as
local, in loci_from_Exonerate.pm because some value were kept between
module executions due to misplaced brackets.
Clean loci_from_Exonerate.pm file and remove usage of strand, exonup
list and genomic length because they are unnecessary here.
Correct hash table variable define as semi-local, and not strictly as
local, in loci_from_Exonerate.pm because some value were kept between
module executions due to misplaced brackets.
Clean loci_from_Exonerate.pm file and remove usage of strand, exonup
list and genomic length because they are unnecessary here.
0.9 - 20 oct 2005
Perldoc
Perldoc
19 oct 2005
Addition of a test to avoid to download the same file if
it has ever been downloaded in the past half day.
Addition of stop codon triplet management
Addition of a process to select the best alignment if there
are several nt sequences of the same category for a query
Addition of a test to avoid to download the same file if
it has ever been downloaded in the past half day.
Addition of stop codon triplet management
Addition of a process to select the best alignment if there
are several nt sequences of the same category for a query
18 oct 2005
Get genomic and transcript acc, sort them to get only the
best category of sequences:
transcripts > chromosomes > contigs > bac,cosmid,... for RefSeqN
sort by size for other acc
Get genomic and transcript acc, sort them to get only the
best category of sequences:
transcripts > chromosomes > contigs > bac,cosmid,... for RefSeqN
sort by size for other acc
17 oct 2005
Addition of a version option and variable
Addition of a version option and variable
......@@ -11,17 +11,17 @@ my $seq='';
my $flag=0;
while(<FILE>){
if ($_ =~ /^>/){
print $_ if ($flag==0);
print "\n$_" if ($flag>0);
$flag++;
print $_ if ($flag==0);
print "\n$_" if ($flag>0);
$flag++;
}
else {
$seq=$_;
chomp($seq);
$seq =~ s/ //g;
$seq =~ s/\d//g;
$seq =~ s/(.)/_${1}_/g;
print $seq;
$seq=$_;
chomp($seq);
$seq =~ s/ //g;
$seq =~ s/\d//g;
$seq =~ s/(.)/_${1}_/g;
print $seq;
}
}
close FILE;
......
......@@ -12,7 +12,7 @@ use LWP::UserAgent;
my $ua = LWP::UserAgent->new;
use HTTP::Request::Common qw(POST);
use Getopt::Long ;
use Getopt::Long ;
my ($program, $evalue, $vvalue, $dbname, $inputfile, $outputmethod, $filter, $html) = ('', '1.e-10',20, '', '', 0, 'on', 'off'); #Default values
my $ret = GetOptions( 'p=s' => \$program,
'e=s' => \$evalue,
......@@ -37,29 +37,29 @@ if( $filter eq 'T' || $filter eq 'on' ){
$filter = 'on';
}
else {
$filter = 'off';
$filter = 'off';
}
$html = 'on' if( $html eq 'T' );
# Build Command script
# Build Command script
my @command;
# Add program
push( @command , "Program=$program" ) ;
push( @command , "Program=$program" ) ;
# Add database
push( @command , "$dbtype=$dbname" ) ;
push( @command , "evalue=$evalue" ) ;
push( @command , "vvalue=$vvalue" ) ;
push( @command , "filter=$filter" ) ;
push( @command , "outputmethod=$outputmethod" ) ;
push( @command , "html=$html" ) ;
push( @command , "blastmethod=new" ) ;
push( @command , "raw=on" ) ;
push( @command , "$dbtype=$dbname" ) ;
push( @command , "evalue=$evalue" ) ;
push( @command , "vvalue=$vvalue" ) ;
push( @command , "filter=$filter" ) ;
push( @command , "outputmethod=$outputmethod" ) ;
push( @command , "html=$html" ) ;
push( @command , "blastmethod=new" ) ;
push( @command , "raw=on" ) ;
# Read sequence
# Read sequence
my $sequence = '';
if ( $inputfile eq '' ){
while( <STDIN> ){
......@@ -96,9 +96,9 @@ else{
sub RunBlast{
my $mybody = join('&' , (@command , 'sequence='.uri_escape($sequence) )) ;
my $mybody = join('&' , (@command , 'sequence='.uri_escape($sequence) )) ;
# print $mybody ;
# print $mybody ;
# my $r = HTTP::GHTTP->new();
# $r->set_uri("http://www.igs.cnrs-mrs.fr/adele/~database/blast.cgi");
# $r->set_uri("http://www.igs.cnrs-mrs.fr/adele/~database/newblast.cgi");
......
......@@ -194,7 +194,7 @@ else {
}
exit 0;
##############
############################################### FONCTIONS ####################################################################
##############
......@@ -239,10 +239,10 @@ sub NCBI_DATABASE {
else{
return (1);
}
}
}
#------------------------------------------------------------------------------------------------------------------------
sub HELP
{
{
my ($org, @orga) = &LIST_ORGA();
my ($list_orga) = join(', ', @orga);
......@@ -288,33 +288,33 @@ sub HELP
return;
}
#-----------------------------------------------------------------------------------------
sub OPTIONS_GET {
sub OPTIONS_GET {
my %opt = ();
GetOptions
(
'infile=s' =>\$opt{infile},
'outfile=s' =>\$opt{outfile},
'program=s' =>\$opt{program},
'database=s' =>\$opt{database},
'blast_dir=s' =>\$opt{blast_dir},
'identity=f' =>\$opt{treshold},
'cover=f' =>\$opt{cover},
'evalue=f' =>\$opt{evalue},
'hits=i' =>\$opt{hits},
'matrix=s' =>\$opt{matrix},
'filter=s' =>\$opt{filter},
'method=s' =>\$opt{method},
'infile=s' =>\$opt{infile},
'outfile=s' =>\$opt{outfile},
'program=s' =>\$opt{program},
'database=s' =>\$opt{database},
'blast_dir=s' =>\$opt{blast_dir},
'identity=f' =>\$opt{treshold},
'cover=f' =>\$opt{cover},
'evalue=f' =>\$opt{evalue},
'hits=i' =>\$opt{hits},
'matrix=s' =>\$opt{matrix},
'filter=s' =>\$opt{filter},
'method=s' =>\$opt{method},
'organism=s' =>\$opt{organism},
'processor=i' =>\$opt{processor},
'quiet=s' =>\$opt{quiet},
'gigablast=s' =>\$opt{gigablast},
);
'processor=i' =>\$opt{processor},
'quiet=s' =>\$opt{quiet},
'gigablast=s' =>\$opt{gigablast},
);
if ( $ARGV[0] ){
print "Unprocessed by Getopt::Long\n $ARGV[0]\n";
&HELP();
}
}
my($evalue_tresh) = $opt{'evalue'}; unless ($evalue_tresh) { $evalue_tresh = 1;};
my($cover_tresh) = $opt{'cover'}; unless (defined $cover_tresh) { $cover_tresh = 30;};
......@@ -337,35 +337,35 @@ sub OPTIONS_GET {
print {*STDERR} "unknown method for the flag -method\n";
&HELP();
}
if ( $treshold<0 || $treshold>100 ){
if ( $treshold<0 || $treshold>100 ){
print {*STDERR} "\nout of range for the option -treshold \n";
&HELP();
}
if ( $cover_tresh<0 || $cover_tresh>100 ){
if ( $cover_tresh<0 || $cover_tresh>100 ){
print {*STDERR} "\nout of range for the option -cover \n";
&HELP();
}
if ( $align<0 ){
if ( $align<0 ){
print {*STDERR} "\n error with option align\n";
&HELP();
}
if ( $gigablast !~ /^yes$|^no$/i ){
if ( $gigablast !~ /^yes$|^no$/i ){
print {*STDERR} "invalid argument for gigaglast option: yes/no\n";
exit 1;
}
if ( $filter !~ /^[TFRLMCV]{1}$|^off$/i ){
if ( $filter !~ /^[TFRLMCV]{1}$|^off$/i ){
print {*STDERR} "valid values for -filter are T,F,R,L,M,C,or V!\n";
exit 1;
}
if ( $matrix !~ /PAM30|PAM70|BLOSUM45|BLOSUM80|BLOSUM62/ ){
if ( $matrix !~ /PAM30|PAM70|BLOSUM45|BLOSUM80|BLOSUM62/ ){
print {*STDERR} "valid values for -matrix are PAM30,PAM70,BLOSUM45,BLOSUM80 or BLOSUM62\n";
exit 1;
}
if ( $outfil eq '' && $method=~ /^profile$/i ){
if ( $outfil eq '' && $method=~ /^profile$/i ){
$outfil = 'default_profile.template';
}
if ( $param!~ /^on$|^off$/i ){
if ( $param!~ /^on$|^off$/i ){
print {*STDERR} "valid values for -quiet is on or off\n";
exit 1;
}
......@@ -528,21 +528,21 @@ sub WEB_BLAST {
while (){
sleep 3;
$req = new HTTP::Request GET => "http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Get&FORMAT_TYPE=$format&FILTER=off&EXPECT=$Eval&ALIGNMENTS=$align&DESCRIPTIONS=$align&ALIGNMENT_VIEW=$aln_view&RID=$rid";
$response = $ua -> request($req);
if ($response->content =~ /Altschul/i) { print {*STDERR} "Search Complete\n"; push(@list_pdb,$response -> content);last; }
else { next; }
}
print {$SOR1} (@list_pdb);
++$i;
}
$req = new HTTP::Request GET => "http://www.ncbi.nlm.nih.gov/blast/Blast.cgi?CMD=Get&FORMAT_TYPE=$format&FILTER=off&EXPECT=$Eval&ALIGNMENTS=$align&DESCRIPTIONS=$align&ALIGNMENT_VIEW=$aln_view&RID=$rid";
$response = $ua -> request($req);
if ($response->content =~ /Altschul/i) { print {*STDERR} "Search Complete\n"; push(@list_pdb,$response -> content);last; }
else { next; }
}
print {$SOR1} (@list_pdb);
++$i;
}
undef (@list_encoded);
close $SOR1;
return (@list_pdb);
}
#-----------------------------------------------------------------------------------------------------------------------
sub LOCAL_BLAST
......@@ -551,11 +551,11 @@ sub LOCAL_BLAST
$method, $matrix, $filter, $process, $gigablast,
$database_expresso, $blast_dir_expresso, $runblast) = @_;
my $n = 0;
if ( $method=~ /^profile$/i && $gigablast=~ /^no$/i ){
if ( $method=~ /^profile$/i && $gigablast=~ /^no$/i ){
open (COM,"$blast_dir -p blastp -d $database -i $query_file -m 6 -M $matrix -v $align -b $align -F $filter -e $Eval -a $process|") or die;
}
elsif ( $method=~ /^geneid$/i && $gigablast=~ /^no$/i )
{
elsif ( $method=~ /^geneid$/i && $gigablast=~ /^no$/i )
{
open (COM,"$blast_dir -p blastp -d $database -i $query_file -v $align -b $align -F $filter -M $matrix -e $Eval -a $process|") or die;
}
elsif ( $method=~ /^geneid$|^pdbid$/i && $gigablast=~ /^yes$/i )
......@@ -570,49 +570,49 @@ sub LOCAL_BLAST
}
elsif ( $method=~ /^profile$/i && $gigablast=~ /^yes$/i){
print {*STDERR} "\nSorry method profile can't be used with -gigablast option\n";exit;
}
elsif ( $method=~ /^pdbid$/i && $database=~ /expressopdb/ ){
#BLAST pour Expresso
open (COM,"$BLASTMAT; $BLASTDB; $blast_dir_expresso -p blastp -d $database_expresso -i $query_file -F $filter -e $Eval -M $matrix -v $align -b $align |") or die;
}
else{
elsif ( $method=~ /^pdbid$/i && $database=~ /expressopdb/ ){
#BLAST pour Expresso
open (COM,"$BLASTMAT; $BLASTDB; $blast_dir_expresso -p blastp -d $database_expresso -i $query_file -F $filter -e $Eval -M $matrix -v $align -b $align |") or die;
}
else{
open (COM,"$blast_dir -p blastp -d $database -i $query_file -v 1 -b 1 -F $filter -e $Eval -M $matrix -v $align -b $align -a $process |") or die;
}
unless ( $quiet=~ /on/ ) { print {*STDERR} "\nrun BLAST..."; }
unless ( $quiet=~ /on/ ) { print {*STDERR} "\nrun BLAST..."; }
my ($name_database, $posted, $version) = ('', '', '');
open (my $SOR2, '>', 'blast_result.txt') or die;
$/ = 'Query=';
while (<COM>){
if ( $_=~ /Database:\s+(\S+)/g ) { $name_database = $1;}
if ( $_=~ /Posted date:\s+(.+?)\n/ ) { $posted = $1;}
if ( $_=~ /(BLASTP\s+\S+)/o ) { $version = $1;}
print {$SOR2} $_;
push (@list_pdb, $_) ;
push (@list_pdb, $_) ;
if ( $_=~ /\s*(.+?)\s/ ){
print {*STDERR} "\n$1 done";
}
}
}
close COM;
close $SOR2;
print {*STDERR} "\n";
$name_database = $database if ( $name_database =~ m{/} );
unless ($quiet=~ /on/i) {
unless ($quiet=~ /on/i) {
print {*STDOUT} "
Version: $version
Database: $name_database
Posted date: $posted\n\n";
}
shift (@list_pdb);
shift (@list_pdb);
return (@list_pdb);
}
#-----------------------------------------------------------------------------------------------------------------------------
sub PARSING {
sub PARSING {
my ($list_pdb, $locale, $distant, $method, $quiet, $database, $gigablast) = @_;
my (@list_pdb) = @$list_pdb;
......@@ -650,7 +650,7 @@ sub PARSING {
# $database_d = $database if ( $database_d =~ m{/} );
unless ($quiet=~ /on/i || $n>0){
++$n;
print {*STDOUT} "
print {*STDOUT} "
Version: $version_d
Database: $database_d
Posted date: $poste_d\n\n";
......@@ -766,15 +766,15 @@ sub MULTI_EQUIVALENT
my($query,$identity,$recouvrement,$bits,$evalue,$intra_res)=@_;
my @result=();
while ($intra_res=~ />.*?(gb|prf|emb|sp|pir|tpe|ref|prf|dbj|ddbj|pdb)[\|]+([A-Za-z0-9_\.]+?)(\s|\|(.{1}))/g)
{
my $databank =$1;
my $last =$4;
my $refseq =$2;
if ($databank eq 'pdb') { $refseq.=$last }