sub next_result
{ my ($self) = @_;
local $/ = "\n";
local $_;
$self->{'_last_data'} = '';
my ($seentop, $qfull, @hsps, %alignment, $format);
my $hit_direction = 1;
$self->start_document();
$self->start_element({'Name' => 'Sim4Output'});
my $lastquery = '';
while( defined($_ = $self->_readline) ) {
next if( /^\s+$/); chomp;
if (!$seentop) {
if ( /^\#:lav/ ) { $format = 2; }
elsif ( /^<|>/ ) { $format = 5; }
$self->throw("Bio::SearchIO::sim4 module cannot parse 'type $format' outputs.") if $format;
}
if( /^seq1\s*=\s*(\S+),\s+(\d+)/ ) {
my ($nm,$desc) = ($1,$2);
if ( ! $seentop ) {
$self->element( {'Name' => 'Sim4Output_query-def',
'Data' => $nm} );
$self->element( {'Name' => 'Sim4Output_query-len',
'Data' => $desc} );
$seentop = 1;
} elsif( $nm ne $lastquery ) {
$self->_pushback($_);
last;
}
$lastquery = $nm;
$self->end_element({'Name' => 'Hsp'}) if ( $self->in_element('hsp') );
if ( $self->in_element('hit') ) {
foreach (@hsps) {
$self->start_element({'Name' => 'Hsp'});
while (my ($name, $data) = each %$_) {
$self->{'_currentHSP'}{$name} = $data;
}
$self->end_element({'Name' => 'Hsp'});
$self->{'_currentHSP'} = {};
}
$format = 0 if @hsps;
@hsps = ();
%alignment = ();
$qfull = 0;
$hit_direction = 1;
$self->end_element({'Name' => 'Hit'});
}
} elsif( /^seq2\s*=\s*(\S+)\s+\(>?(\S+)\s*\),\s*(\d+)/ ) {
$self->start_element({'Name' => 'Hit'});
$self->element( {'Name' => 'Hit_id', 'Data' => $2} );
$self->element( {'Name' => 'Hit_desc', 'Data' => $1} );
$self->element( {'Name' => 'Hit_len', 'Data' => $3} );
} elsif( /^>(\S+)\s*(.*)?/ ) {
if( $qfull ) {
$format = 4 if !$format;
$self->element({'Name' => 'Hit_desc', 'Data' => $2});
} else {
$self->element({'Name' => 'Sim4Output_query-desc', 'Data' => $2});
$qfull = 1;
}
} elsif( /^\(complement\)/ ) {
$hit_direction = -1;
} elsif( /^\(?(\d+)\-(\d+)\)?\s+\(?(\d+)\-(\d+)\)?\s+(\d+)/ ) {
my ($qs,$qe,$hs,$he,$pid) = ($1,$2,$3,$4,$5);
push @hsps, {
'Hsp_query-from' => $qs,
'Hsp_query-to' => $qe,
'Hsp_hit-from' => $hit_direction >= 0 ? $hs : $he,
'Hsp_hit-to' => $hit_direction >= 0 ? $he : $hs,
'Hsp_identity' => 0, 'Hsp_qlength' => abs($qe - $qs) + 1,
'Hsp_hlength' => abs($he - $hs) + 1,
'Hsp_align-len' => abs($qe - $qs) + 1,
};
} elsif( /^\s+(\d+)\s/ ) {
for( my $i = 0; defined($_) && $i < 4; $i++ ) {
my ($start, $string) = /^\s+(\d*)\s(.*)/;
$alignment{$ALIGN_TYPES{$i}} = { start => $start, string => $i != 2
? $string
: (' ' x (length($alignment{$ALIGN_TYPES{$i-1}}{string}) - length($string))) . $string
};
$_ = $self->_readline();
}
if ($alignment{Ruler}{start} == 0) {
$format = @hsps ? 3 : 1 if !$format;
$self->end_element({'Name' => 'Hsp'}) if ( $self->in_element('hsp') );
$self->start_element({'Name' => 'Hsp'});
$self->{'_currentHSP'} = @hsps ? shift @hsps : {
'Hsp_query-from' => $alignment{Query}{start},
'Hsp_hit-from' => $alignment{Sbjct}{start},
}
}
if ( $alignment{Mid}{string} =~ /<|>/g ) {
my ($hsp_start, $hsp_end);
if ( $self->in_element('hsp') ) {
$hsp_end = (pos $alignment{Mid}{string}) - 1;
$self->{'_currentHSP'}{'Hsp_querygaps'} +=
($self->{'_currentHSP'}{'Hsp_qseq'} .= substr($alignment{Query}{string}, 0, $hsp_end)) =~ s/ /-/g;
$self->{'_currentHSP'}{'Hsp_hitgaps'} +=
($self->{'_currentHSP'}{'Hsp_hseq'} .= substr($alignment{Sbjct}{string}, 0, $hsp_end)) =~ s/ /-/g;
($self->{'_currentHSP'}{'Hsp_midline'} .= substr($alignment{Mid}{string}, 0, $hsp_end)) =~ s/-/ /g;
$self->end_element({'Name' => 'Hsp'});
if ( $alignment{Mid}{string} =~ /\|/g ) {
$hsp_start = (pos $alignment{Mid}{string}) - 1;
$self->start_element({'Name' => 'Hsp'});
$self->{'_currentHSP'} = @hsps ? shift @hsps : {};
$self->{'_currentHSP'}{'Hsp_querygaps'} +=
($self->{'_currentHSP'}{'Hsp_qseq'} = substr($alignment{Query}{string}, $hsp_start)) =~ s/ /-/g;
$self->{'_currentHSP'}{'Hsp_hitgaps'} +=
($self->{'_currentHSP'}{'Hsp_hseq'} = substr($alignment{Sbjct}{string}, $hsp_start)) =~ s/ /-/g;
($self->{'_currentHSP'}{'Hsp_midline'} = substr($alignment{Mid}{string}, $hsp_start)) =~ s/-/ /g;
}
}
else {
$hsp_start = index($alignment{Mid}{string}, '|');
$self->start_element({'Name' => 'Hsp'});
$self->{'_currentHSP'} = @hsps ? shift @hsps : {
'Hsp_query-from' => $alignment{Query}{start},
};
$self->{'_currentHSP'}{'Hsp_querygaps'} +=
($self->{'_currentHSP'}{'Hsp_qseq'} = substr($alignment{Query}{string}, $hsp_start)) =~ s/ /-/g;
$self->{'_currentHSP'}{'Hsp_hitgaps'} +=
($self->{'_currentHSP'}{'Hsp_hseq'} = substr($alignment{Sbjct}{string}, $hsp_start)) =~ s/ /-/g;
($self->{'_currentHSP'}{'Hsp_midline'} = substr($alignment{Mid}{string}, $hsp_start)) =~ s/-/ /g;
next;
}
}
else {
if ( !$self->in_element('hsp') ) {
$self->start_element({'Name' => 'Hsp'});
$self->{'_currentHSP'} = @hsps ? shift @hsps : {
'Hsp_query-from' => $alignment{Query}{start},
'Hsp_hit-from' => $alignment{Sbjct}{start},
}
}
$self->{'_currentHSP'}{'Hsp_query-from'} ||=
$alignment{Query}{start} -
length($self->{'_currentHSP'}{'Hsp_qseq'} || '');
$self->{'_currentHSP'}{'Hsp_hit-from'} ||=
$alignment{Sbjct}{start} -
length($self->{'_currentHSP'}{'Hsp_hseq'} || '');
$self->{'_currentHSP'}{'Hsp_querygaps'} +=
($self->{'_currentHSP'}{'Hsp_qseq'} .=
$alignment{Query}{string}) =~ s/ /-/g;
$self->{'_currentHSP'}{'Hsp_hitgaps'} +=
($self->{'_currentHSP'}{'Hsp_hseq'} .=
$alignment{Sbjct}{string}) =~ s/ /-/g;
($self->{'_currentHSP'}{'Hsp_midline'} .=
$alignment{Mid}{string}) =~ s/-/ /g;
}
}
}
if( $seentop ) {
$self->end_element({'Name' => 'Hsp'}) if ( $self->in_element('hsp') );
if ( $self->in_element('hit') ) {
foreach (@hsps) {
$self->start_element({'Name' => 'Hsp'});
while (my ($name, $data) = each %$_) {
$self->{'_currentHSP'}{$name} = $data;
}
$self->end_element({'Name' => 'Hsp'});
}
$self->end_element({'Name' => 'Hit'});
}
$self->element({'Name' => 'Sim4Output_program',
'Data' => $DEFAULTFORMAT . ' (A=' . (defined $format ? $format : '?') . ')'});
$self->end_element({'Name' => 'Sim4Output'});
return $self->end_document();
}
return;} |
sub end_element
{ my ($self,$data) = @_;
my $nm = $data->{'Name'};
my $type = $MODEMAP{$nm};
my $rc;
if( $nm eq 'Hsp' ) {
$self->{'_currentHSP'}{'Hsp_midline'} ||= '';
$self->{'_currentHSP'}{'Hsp_query-to'} ||=
$self->{'_currentHSP'}{'Hsp_query-from'} + length($self->{'_currentHSP'}{'Hsp_qseq'}) - 1 - $self->{'_currentHSP'}{'Hsp_querygaps'};
$self->{'_currentHSP'}{'Hsp_hit-to'} ||=
$self->{'_currentHSP'}{'Hsp_hit-from'} + length($self->{'_currentHSP'}{'Hsp_hseq'}) - 1 - $self->{'_currentHSP'}{'Hsp_hitgaps'};
$self->{'_currentHSP'}{'Hsp_identity'} ||=
($self->{'_currentHSP'}{'Hsp_midline'} =~ tr/\|//);
$self->{'_currentHSP'}{'Hsp_qlength'} ||= abs($self->{'_currentHSP'}{'Hsp_query-to'} - $self->{'_currentHSP'}{'Hsp_query-from'}) + 1;
$self->{'_currentHSP'}{'Hsp_hlength'} ||= abs($self->{'_currentHSP'}{'Hsp_hit-to'} - $self->{'_currentHSP'}{'Hsp_hit-from'}) + 1;
$self->{'_currentHSP'}{'Hsp_align-len'} ||= abs($self->{'_currentHSP'}{'Hsp_query-to'} - $self->{'_currentHSP'}{'Hsp_query-from'}) + 1;
$self->{'_currentHSP'}{'Hsp_score'} ||= int(100 * ($self->{'_currentHSP'}{'Hsp_identity'} / $self->{'_currentHSP'}{'Hsp_align-len'})); foreach (keys %{$self->{'_currentHSP'}}) {
$self->element({'Name' => $_, 'Data' => delete ${$self->{'_currentHSP'}}{$_}});
}
}
if( $type = $MODEMAP{$nm} ) {
if( $self->_will_handle($type) ) {
my $func = sprintf("end_%s",lc $type);
$rc = $self->_eventHandler->$func($self->{'_reporttype'},
$self->{'_values'});
}
shift @{$self->{'_elements'}};
} elsif( $MAPPING{$nm} ) {
if ( ref($MAPPING{$nm}) =~ /hash/i ) {
my $key = (keys %{$MAPPING{$nm}})[0];
$self->{'_values'}->{$key}->{$MAPPING{$nm}->{$key}} = $self->{'_last_data'};
} else {
$self->{'_values'}->{$MAPPING{$nm}} = $self->{'_last_data'};
}
} else {
$self->debug( "unknown nm $nm, ignoring\n");
}
$self->{'_last_data'} = ''; $self->{'_result'} = $rc if( defined $type && $type eq 'result' );
return $rc;} |
The rest of the documentation details each of the object methods.
Internal methods are usually preceded with a _