This code is to read the blast file, in this subroutines
parse_blast($filename, \$beginning, \$ending, \@HSPs);
it seems can't get @HSPs value by reference, I can't find why it can't get value. all subroutines seems works i can also directly print value in sub parse_one_HSP.
use strict;
use warnings;
my $filename = q/..\test\input.txt/;
my ($beginning, $ending);
my @HSPs;
parse_blast($filename, \$beginning, \$ending, \@HSPs); #Can't get the HSPs value
print $beginning;
foreach my $t(@HSPs){
print_HSP(%{$t}); #can't print anything here
}
print $ending;
sub print_HSP{
my(%HSP)=@_;
print "\n-> Expect value: $HSP{expect}\n";
print "\n-> Query string: $HSP{query}\n";
print "\n-> Query range: $HSP{query_range}\n";
print "\n-> Subject String: $HSP{subject}\n";
print "\n-> Subject range: $HSP{subject_range}\n";
}
sub parse_blast {
my ($filename, $beginning_ref, $ending_ref, $HSPs) = @_;
# parse the blast output into 3 sections
my ($part1, $part2, $part3); # beginning, alignments and ending
my $in_beginning = 0;
my $in_alignment = 0;
my $in_ending = 0;
open IN, $filename || die;
while (<IN>) {
if (/^T?BLAST[NPX]/) {$in_beginning = 1}
if (/^ALIGNMENTS/) {$in_beginning = 0; $in_alignment = 1; next}
if (/^\s\sDatabase/) {$in_alignment = 0; $in_ending = 1;}
if ($in_beginning) {$part1 .= $_;}
if ($in_alignment) {$part2 .= $_;}
if ($in_ending) {$part3 .= $_;}
}
close IN;
$$beginning_ref = $part1;
$$ending_ref = $part3;
# split the alignments into an array
my @alignments;
split_alignments($part2, \@alignments);
# parse each alignment
foreach my $alignment (@alignments) {
parse_one_alignment($alignment, \@$HSPs);
}
}
sub split_alignments{
my ($alignments, $aligns) = @_;
my @alignment;
while ($alignments =~ /^>.*\n(^(?!>).*\n)+/gm) {
push @$aligns, $&;
}
}
sub parse_one_alignment{
my ($align, $HSPs) = @_;
my ($part1, $part2) = $align =~ /(.*?)( Score =.*)/s;
while ($part2 =~ /^ Score =.*\n(^(?! Score =).*\n)+/mg) {
my %hsp;
parse_one_HSP($part2, \%hsp);
push @$HSPs, %hsp;
}
}
sub parse_one_HSP {
my ($data, $hsp) = @_;
#my $hsp = shift; # reference to hash
# parsing one HSP ...
# declare and initialize variables
my($expect) = '';
my($query) = '';
my($query_range) = '';
my($subject) = '';
my($subject_range) = '';
($expect) = ($data =~ /Expect = (\S+)/);
$query = join ( '' , ($data =~ /^Query.*\n/gm) );
$subject = join ( '' , ($data =~ /^Sbjct.*\n/gm) );
$query_range = join('..', ($data =~ /(\d+).*\D(\d+)/s));
$subject_range = join('..', ($data =~ /(\d+).*\D(\d+)/s));
$query =~ s/[^acgt]//g;
$subject =~ s/[^acgt]//g;
$hsp->{expect} = $expect;
$hsp->{query} = $query;
$hsp->{query_range} = $query_range;
$hsp->{subject} = $subject;
$hsp->{subject_range} = $subject_range;
#print_HSP(%$hsp);
}
@HSPsvalue'?@HSPsis empty when you call parse_blast(). BTW It would be much easier to help if you indented the code in the blocks. - szabgab\@$HSPsis decidedly wrong. Just use$HSPs. - Chris Jester-Youngopen IN, $filename || die;is incorrect because||is binding stronger than,. It needs to be writtenopen(IN, $filename) || die;though I'd really recommend:open(my $in, '<', $filename) or die;See perlmaven.com/always-use-3-argument-open - szabgab$beginning, $ending, @HSPsthat will make the code much simpler. - szabgab