I have tried debugging and optimizing this code, yet I cannot find the source of this error to save my life.
I am getting a 'floating point exception' when I run the code pasted below.
I am running with 'use strict' and 'use warnings'. My program takes a sequence and BLASTs it. We take the BLAST results and add them to a hash. We then take the results and BLAST them and add them to the hash.
Any help would be greatly appreciated. I cannot seem to find good documentation within perdocs, perl.org, or elsewhere as to what exactly causes a 'floating point exception'. I thought it was a mistake in using float data types; however, I never get the error on the same iteration, and I am not performing any math.
Thanks!
Stephen
sub ash_hash() {
my $ash_hash = {};
##### Open files
open(ERR,">>$files{dir}$files{error}"); # open error file handle
open(WARN,">>$files{dir}$files{warning}"); # open warning file handle
#### First Blast Query
print "Running seed query";
my $blast_temp = ash_sab(\$seed{seq},\$seed{acc});
chmod(0777,$blast_temp); # share the file
if(!-e $blast_temp) { die("No BLAST data returned.\n"); } # kill program if no blast data
#### Parse Blast Query
$ash_hash->{$seed{acc}} = ash_sabParse($blast_temp); # parse BLAST data
unlink($blast_temp); # destroy the file
##### Build the Hash
while($flags{count} < $flags{iterations}) {
foreach my $branch (keys(%{$ash_hash})) { # loop through seq w/ returned blast queries
foreach my $leaf (keys(%{$ash_hash->{$branch}})) { # loop through seq returned in the blast queries
if(!(defined $ash_hash->{$leaf})) { # skip if we already have this sequence
if(exists($bad_sequences{$leaf})) { # if we've already logged this seq, skip it entirely
delete $ash_hash->{$branch}->{$leaf};
next;
}
my $seq = acc2seq($leaf); # retrieve the sequence REFERENCE!!!
if($seq <= 0) { # no string data -- no seq
if($seq == -1) { # not a protein sequence
print ERR "Nucleotide sequence: $leaf.\n"; }
elsif($seq == 0) { # unable to get a sequence returned
print ERR "Bad sequence: $leaf.\n"; }
else {
print ERR "Unknown value returned: $leaf.\n"; }
$bad_sequences{$leaf} = 1;
delete $ash_hash->{$branch}->{$leaf};
next;
}
##### output iteration count ON THE SAME LINE
#$| = 1;
print "\rRunning iteration $flags{count}:\t$leaf ";
#$| = 0;
my $blast_temp = ash_sab($seq,\$leaf); # run BLAST
chmod(0777,$blast_temp); # share the file
if(!-e $blast_temp) {
die("\n\nNo BLAST data returned.\n"); } # kill program if no blast data
if(!($ash_hash->{$leaf} = ash_sabParse($blast_temp))) { # add results to hash
print ERR "No BLAST sequences returned: $leaf.\n";
delete $ash_hash->{$leaf};
$bad_sequences{$leaf} = 1;
next;
}
if($flags{save_everything}) { # move the file to the blast folder or
move($blast_temp,$files{dir}."BLAST/".$leaf.".blast");
} else { unlink($blast_temp); } # destroy the file
$flags{count}++;
}
}
}
}
...
}
sub ash_sab( $ $ ) {
my $seq = shift or die("No sequence data.\n"); # read in variables
my $acc = shift or die("No accession number.\n");
my $out = "$files{dir}$files{temp}";
my @params = ( # blast factory parameters
'program' => $blast{program},
'database' => $blast{db},
'outfile' => $out,
'expect' => $blast{evalue});
# 'method' => $blast{method}); # parameter variable for factory creation
my $factory = Bio::Tools::Run::StandAloneBlast->new(@params); # create handler for SAB
my $seqobj = Bio::Seq->new(-id=> $$acc,-seq => $$seq); # create a Seq object from seq string
my $blast_report = $factory->blastall($seqobj); # run BLAST on SEQ object
return $out;
}
sub ash_sabParse($) {
my $in = shift; # get filename
my $scores = (); # hash ref to hold chosen scores
my $count = 0; # number of results
my $acc = 0; my $bs = 0; my $ev = 0; # values pulled from the blast file
open(BF,$in); # open the blast file
my @blast_file = <BF>; # read in entire file
close(BF); # close the file handle
undef $in;
splice(@blast_file,0,20); # deletes the beginning file information
##### Open files
#open(ERR,">>$files{dir}$files{error}"); # open error file handle
#open(WARN,">>$files{dir}$files{warning}"); # open warning file handle
foreach my $line (@blast_file) { # iterate through file
# no more data
if($line =~ m/$>/ || $line =~ m/Matrix\:/) {
@blast_file = {}; # clear remaining data in blast file;
}
# Getting the good data
if($line =~ m/^>/) { last; }
elsif($line =~ m/^(gb|dbj|emb|ref)\|([\w\d]*).*\s+([\d\.]+)\s+(\d+(e-|\.)\d*)/) {
# This section collects the normal data
$acc = $2; # accession number
$bs = $3; # raw score
$ev = $4; # e-value
} elsif($line =~ m/^([\w\d]*) hypothetical protein.*\s+([\d\.]+)\s+(\d+(e-|\.)\d*)/ && $flags{hypotheticals}) {
# This section collects most of the hypothetical data
$acc = $1; # accession number
$bs = $2; # raw score
$ev = $3; # e-value
} elsif($line =~ m/^(\w\d+).*\s+([\d\.]+)\s+(\d+(e-|\.)\d*)/) {
# This section collects a few others
$acc = $1; # accession number
$bs = $2; # raw score
$ev = $3; # e-value
} else {
print WARN "NOT USED: $line";
}
# saving the good data or printing to error file
if(!$acc && !$ev && !$bs) { next; # not enough data collected
} elsif($acc =~ m/XP_/i) { print WARN "NOT USED, experimental: $line"; # skip experimental data
} elsif(exists($bad_sequences{$acc})) { print WARN "SKIPPED: noted bad seq: $acc\n"; # skip found bad sequence
} elsif($flags{score_type} eq 'bitscore' && $bs) { # save raw score and accn no.
$scores->{$acc} = $bs;
$count++;
} elsif($flags{score_type} eq 'evalue' && $ev) { # save e-value and accn no.
$scores->{$acc} = $ev;
$count++; }
else {}
}
##### close files
#close(ERR);
#close(WARN);
##### release variables
undef $acc;
undef $bs;
undef $ev;
$count > 0 ? return $scores : return 0;
}