use
vars
qw(%MAPPING %MODEMAP $DEFAULT_WRITER_CLASS $DefaultProgramName)
;
$DefaultProgramName
=
'BLAT'
;
$DEFAULT_WRITER_CLASS
=
'Bio::Search::Writer::HitTableWriter'
;
%MODEMAP
= (
'PSLOutput'
=>
'result'
,
'Result'
=>
'result'
,
'Hit'
=>
'hit'
,
'Hsp'
=>
'hsp'
);
%MAPPING
= (
'Hsp_bit-score'
=>
'HSP-bits'
,
'Hsp_score'
=>
'HSP-score'
,
'Hsp_evalue'
=>
'HSP-evalue'
,
'Hsp_query-from'
=>
'HSP-query_start'
,
'Hsp_query-to'
=>
'HSP-query_end'
,
'Hsp_hit-from'
=>
'HSP-hit_start'
,
'Hsp_hit-to'
=>
'HSP-hit_end'
,
'Hsp_positive'
=>
'HSP-conserved'
,
'Hsp_identity'
=>
'HSP-identical'
,
'Hsp_mismatches'
=>
'HSP-mismatches'
,
'Hsp_qgapblocks'
=>
'HSP-query_gapblocks'
,
'Hsp_hgapblocks'
=>
'HSP-hit_gapblocks'
,
'Hsp_gaps'
=>
'HSP-hsp_gaps'
,
'Hsp_hitgaps'
=>
'HSP-hit_gaps'
,
'Hsp_querygaps'
=>
'HSP-query_gaps'
,
'Hsp_align-len'
=>
'HSP-hsp_length'
,
'Hsp_query-frame'
=>
'HSP-query_frame'
,
'Hsp_hit-frame'
=>
'HSP-hit_frame'
,
'Hit_id'
=>
'HIT-name'
,
'Hit_len'
=>
'HIT-length'
,
'Hit_accession'
=>
'HIT-accession'
,
'Hit_def'
=>
'HIT-description'
,
'Hit_signif'
=>
'HIT-significance'
,
'Hit_score'
=>
'HIT-score'
,
'Hit_bits'
=>
'HIT-bits'
,
'PSLOutput_program'
=>
'RESULT-algorithm_name'
,
'PSLOutput_version'
=>
'RESULT-algorithm_version'
,
'PSLOutput_query-def'
=>
'RESULT-query_name'
,
'PSLOutput_query-len'
=>
'RESULT-query_length'
,
'PSLOutput_query-acc'
=>
'RESULT-query_accession'
,
'PSLOutput_querydesc'
=>
'RESULT-query_description'
,
'PSLOutput_db'
=>
'RESULT-database_name'
,
'PSLOutput_db-len'
=>
'RESULT-database_entries'
,
'PSLOutput_db-let'
=>
'RESULT-database_letters'
,
);
sub
_initialize {
my
(
$self
,
@args
) =
@_
;
$self
->SUPER::_initialize(
@args
);
my
(
$pname
) =
$self
->_rearrange([
qw(PROGRAM_NAME)
],
@args
);
$self
->program_name(
$pname
||
$DefaultProgramName
);
$self
->_eventHandler->register_factory(
'result'
, Bio::Search::Result::ResultFactory->new(
-type
=>
'Bio::Search::Result::GenericResult'
));
$self
->_eventHandler->register_factory(
'hit'
, Bio::Search::Hit::HitFactory->new(
-type
=>
'Bio::Search::Hit::GenericHit'
));
$self
->_eventHandler->register_factory(
'hsp'
, Bio::Search::HSP::HSPFactory->new(
-type
=>
'Bio::Search::HSP::PSLHSP'
));
}
sub
next_result{
my
(
$self
) =
@_
;
my
(
$lastquery
,
$lasthit
);
local
$/ =
"\n"
;
local
$_
;
while
(
defined
(
$_
=
$self
->_readline) ) {
if
(/^psLayout/){
while
(!/^\d+\s+\d+\s+/) {
$_
=
$self
->_readline;
}
}
my
(
$matches
,
$mismatches
,
$rep_matches
,
$n_count
,
$q_num_insert
,
$q_base_insert
,
$t_num_insert
,
$t_base_insert
,
$strand
,
$q_name
,
$q_length
,
$q_start
,
$q_end
,
$t_name
,
$t_length
,
$t_start
,
$t_end
,
$block_count
,
$block_sizes
,
$q_starts
,
$t_starts
) =
split
;
my
$score
=
sprintf
"%.2f"
, ( 100 * (
$matches
+
$mismatches
+
$rep_matches
) /
$q_length
);
my
$percent_id
=
sprintf
"%.2f"
, ( 100 * (
$matches
+
$rep_matches
)/(
$matches
+
$mismatches
+
$rep_matches
)
);
if
(
defined
$lastquery
&&
$lastquery
ne
$q_name
) {
$self
->end_element({
'Name'
=>
'Hit'
});
$self
->end_element({
'Name'
=>
'PSLOutput'
});
$self
->_pushback(
$_
);
return
$self
->end_document;
}
elsif
( !
defined
$lastquery
) {
$self
->{
'_result_count'
}++;
$self
->start_element({
'Name'
=>
'PSLOutput'
});
$self
->element({
'Name'
=>
'PSLOutput_program'
,
'Data'
=>
$self
->program_name});
$self
->element({
'Name'
=>
'PSLOutput_query-def'
,
'Data'
=>
$q_name
});
$self
->element({
'Name'
=>
'PSLOutput_query-len'
,
'Data'
=>
$q_length
});
$self
->start_element({
'Name'
=>
'Hit'
});
$self
->element({
'Name'
=>
'Hit_id'
,
'Data'
=>
$t_name
});
$self
->element({
'Name'
=>
'Hit_len'
,
'Data'
=>
$t_length
});
$self
->element({
'Name'
=>
'Hit_score'
,
'Data'
=>
$score
});
}
elsif
(
$lasthit
ne
$t_name
) {
$self
->end_element({
'Name'
=>
'Hit'
});
$self
->start_element({
'Name'
=>
'Hit'
});
$self
->element({
'Name'
=>
'Hit_id'
,
'Data'
=>
$t_name
});
$self
->element({
'Name'
=>
'Hit_len'
,
'Data'
=>
$t_length
});
$self
->element({
'Name'
=>
'Hit_score'
,
'Data'
=>
$score
});
}
my
$identical
=
$matches
+
$rep_matches
;
$self
->start_element({
'Name'
=>
'Hsp'
});
$self
->element({
'Name'
=>
'Hsp_score'
,
'Data'
=>
$score
});
$self
->element({
'Name'
=>
'Hsp_identity'
,
'Data'
=>
$identical
});
$self
->element({
'Name'
=>
'Hsp_positive'
,
'Data'
=>
$identical
});
$self
->element({
'Name'
=>
'Hsp_mismatches'
,
'Data'
=>
$mismatches
});
$self
->element({
'Name'
=>
'Hsp_gaps'
,
'Data'
=>
$q_base_insert
+
$t_base_insert
});
$self
->element({
'Name'
=>
'Hsp_querygaps'
,
'Data'
=>
$t_base_insert
});
$self
->element({
'Name'
=>
'Hsp_hitgaps'
,
'Data'
=>
$q_base_insert
});
if
(
$strand
eq
'+'
) {
$self
->element({
'Name'
=>
'Hsp_query-from'
,
'Data'
=>
$q_start
+ 1});
$self
->element({
'Name'
=>
'Hsp_query-to'
,
'Data'
=>
$q_end
});
}
else
{
$self
->element({
'Name'
=>
'Hsp_query-to'
,
'Data'
=>
$q_start
+ 1});
$self
->element({
'Name'
=>
'Hsp_query-from'
,
'Data'
=>
$q_end
});
}
my
$hsplen
=
$q_base_insert
+
$t_base_insert
+
abs
(
$t_end
-
$t_start
) +
abs
(
$q_end
-
$q_start
);
$self
->element({
'Name'
=>
'Hsp_hit-from'
,
'Data'
=>
$t_start
+ 1 });
$self
->element({
'Name'
=>
'Hsp_hit-to'
,
'Data'
=>
$t_end
});
$self
->element({
'Name'
=>
'Hsp_align-len'
,
'Data'
=>
$hsplen
});
$block_sizes
=~ s/\,$//;
$q_starts
=~ s/\,$//;
$t_starts
=~ s/\,$//;
my
@blocksizes
=
split
(/,/,
$block_sizes
);
my
@qstarts
=
split
(/,/,
$q_starts
);
my
@tstarts
=
split
(/,/,
$t_starts
);
my
(
@qgapblocks
,
@hgapblocks
);
for
(
my
$i
= 0;
$i
<
$block_count
;
$i
++) {
if
(
$strand
eq
'+'
) {
push
@qgapblocks
, [
$qstarts
[
$i
] + 1,
$blocksizes
[
$i
]];
}
else
{
push
@qgapblocks
, [
$q_length
-
$qstarts
[
$i
],
$blocksizes
[
$i
]];
}
push
@hgapblocks
, [
$tstarts
[
$i
] + 1,
$blocksizes
[
$i
]];
}
$self
->element({
'Name'
=>
'Hsp_qgapblocks'
,
'Data'
=> \
@qgapblocks
});
$self
->element({
'Name'
=>
'Hsp_hgapblocks'
,
'Data'
=> \
@hgapblocks
});
$self
->end_element({
'Name'
=>
'Hsp'
});
$lastquery
=
$q_name
;
$lasthit
=
$t_name
;
}
if
(
defined
$lasthit
||
defined
$lastquery
) {
$self
->end_element({
'Name'
=>
'Hit'
});
$self
->end_element({
'Name'
=>
'Result'
});
return
$self
->end_document;
}
}
sub
start_element{
my
(
$self
,
$data
) =
@_
;
my
$nm
=
$data
->{
'Name'
};
if
(
my
$type
=
$MODEMAP
{
$nm
} ) {
$self
->_mode(
$type
);
if
(
$self
->_eventHandler->will_handle(
$type
) ) {
my
$func
=
sprintf
(
"start_%s"
,
lc
$type
);
$self
->_eventHandler->
$func
(
$data
->{
'Attributes'
});
}
unshift
@{
$self
->{
'_elements'
}},
$type
;
}
if
(
$nm
eq
'PSLOutput'
) {
$self
->{
'_values'
} = {};
$self
->{
'_result'
}=
undef
;
$self
->{
'_mode'
} =
''
;
}
}
sub
end_element {
my
(
$self
,
$data
) =
@_
;
my
$nm
=
$data
->{
'Name'
};
my
$rc
;
if
(
my
$type
=
$MODEMAP
{
$nm
} ) {
if
(
$self
->_eventHandler->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
->
warn
( __PACKAGE__.
"::end_element: unknown nm '$nm', ignoring\n"
);
}
$self
->{
'_last_data'
} =
''
;
$self
->{
'_result'
} =
$rc
if
(
defined
$nm
&&
defined
$MODEMAP
{
$nm
} &&
$MODEMAP
{
$nm
} eq
'result'
);
return
$rc
;
}
sub
element{
my
(
$self
,
$data
) =
@_
;
$self
->start_element(
$data
);
$self
->characters(
$data
);
$self
->end_element(
$data
);
}
sub
characters{
my
(
$self
,
$data
) =
@_
;
return
unless
(
defined
$data
->{
'Data'
} );
if
(
$data
->{
'Data'
} =~ /^\s+$/ ) {
return
unless
$data
->{
'Name'
} =~ /Hsp\_(midline|qseq|hseq)/;
}
if
(
$self
->in_element(
'hsp'
) &&
$data
->{
'Name'
} =~ /Hsp\_(qseq|hseq|midline)/ ) {
$self
->{
'_last_hspdata'
}->{
$data
->{
'Name'
}} .=
$data
->{
'Data'
};
}
$self
->{
'_last_data'
} =
$data
->{
'Data'
};
}
sub
_mode{
my
(
$self
,
$value
) =
@_
;
if
(
defined
$value
) {
$self
->{
'_mode'
} =
$value
;
}
return
$self
->{
'_mode'
};
}
sub
within_element{
my
(
$self
,
$name
) =
@_
;
return
0
if
( !
defined
$name
&&
!
defined
$self
->{
'_elements'
} ||
scalar
@{
$self
->{
'_elements'
}} == 0) ;
foreach
( @{
$self
->{
'_elements'
}} ) {
if
(
$_
eq
$name
) {
return
1;
}
}
return
0;
}
sub
in_element{
my
(
$self
,
$name
) =
@_
;
return
0
if
!
defined
$self
->{
'_elements'
}->[0];
return
(
$self
->{
'_elements'
}->[0] eq
$name
)
}
sub
start_document{
my
(
$self
) =
@_
;
$self
->{
'_lasttype'
} =
''
;
$self
->{
'_values'
} = {};
$self
->{
'_result'
}=
undef
;
$self
->{
'_mode'
} =
''
;
$self
->{
'_elements'
} = [];
}
sub
end_document{
my
(
$self
,
@args
) =
@_
;
return
$self
->{
'_result'
};
}
sub
result_count {
my
$self
=
shift
;
return
$self
->{
'_result_count'
};
}
sub
report_count {
shift
->result_count }
sub
program_name{
my
$self
=
shift
;
$self
->{
'program_name'
} =
shift
if
@_
;
return
$self
->{
'program_name'
} ||
$DefaultProgramName
;
}
1;