sub
new {
my
(
$caller
,
@args
) =
@_
;
my
$self
=
$caller
->SUPER::new(
@args
);
$self
->_initialize(
@args
);
return
$self
;
}
sub
execute {
my
(
$self
,
@args
) =
@_
;
my
(
$seq
) =
$self
->_rearrange([
qw(SEQ)
],
@args
);
$self
->throw(
"You must provide a sequence to evaluate the rule"
,
$seq
)
unless
$seq
;
if
(
$seq
->isa(
'Bio::SeqIO'
)){
my
@feats
= ();
while
(
my
$s
=
$seq
->next_seq){
push
(
@feats
, @{
$self
->execute(
-seq
=>
$s
)})
}
return
wantarray
?
@feats
: \
@feats
;
}
$self
->throw(
"Impossible to qualify a boolean outside a Rule Set (Bio::Polloc::RuleIO)"
,
$self
)
unless
defined
$self
->ruleset;
$self
->throw(
"Illegal object as Rule Set"
,
$self
->ruleset)
unless
$self
->ruleset->isa(
'Bio::Polloc::RuleIO'
);
$self
->value(
$self
->value);
$self
->throw(
"Illegal class of sequence '"
.
ref
(
$seq
).
"'"
,
$seq
)
unless
$seq
->isa(
'Bio::Seq'
);
$self
->throw(
"Impossible to compare with '"
.
$self
->operator.
"' on undefined second object"
,
$self
->rule2)
if
$self
->operator and not
defined
$self
->rule2;
my
@feats
= ();
for
my
$feat_obj
(@{
$self
->rule1->execute(
-seq
=>
$seq
)}){
if
(
$self
->operator eq
'and'
or
$self
->operator eq
'not'
){
my
$sbj_seq
= Bio::Seq->new(
-display_id
=>
$seq
->display_id,
-seq
=>
$seq
->subseq(
$feat_obj
->from,
$feat_obj
->to) );
my
@feat_sbjs
= @{
$self
->rule2->execute(
-seq
=>
$sbj_seq
) };
next
if
$#feat_sbjs
<0 and
$self
->operator eq
'and'
;
next
if
$#feat_sbjs
>=0 and
$self
->operator eq
'not'
;
if
(
$self
->operator eq
'not'
){
$feat_obj
->comments(
'Not '
.
$self
->rule2->stringify);
push
@feats
,
$feat_obj
;
}
else
{
my
$comm
=
'And '
.
$self
->rule2->stringify .
'{'
;
for
my
$feat_sbj
(
@feat_sbjs
){
my
$ft_comm
=
defined
$feat_sbj
->comments ?
" ("
.(
$feat_sbj
->comments).
")"
:
""
;
$ft_comm
=~ s/[\n\r]+/; /g;
$comm
.=
$feat_sbj
->stringify .
$ft_comm
.
", "
;
}
$feat_obj
->comments(
substr
(
$comm
,0,-2) .
'}'
);
push
@feats
,
$feat_obj
;
}
}
elsif
(
$self
->operator eq
'or'
|| not
defined
$self
->rule2){
push
@feats
,
$feat_obj
;
}
else
{
$self
->throw(
"Unsupported operator"
,
$self
->operator,
'Bio::Polloc::Polloc::UnexpectedException'
);
}
}
if
(
$self
->operator eq
'or'
){
push
@feats
, @{
$self
->rule2->execute(
-seq
=>
$seq
)};
}
return
wantarray
?
@feats
: \
@feats
;
}
sub
rule1 {
my
(
$self
,
$value
) =
@_
;
$self
->{
'_rule1'
} =
$value
if
defined
$value
;
$self
->{
'_rule1'
} =
$self
->safe_value(
'rule1'
)
unless
defined
$self
->{
'_rule1'
};
return
$self
->{
'_rule1'
};
}
sub
operator {
my
(
$self
,
$value
) =
@_
;
if
(
$value
){
$value
=
lc
$value
;
$value
=~ s/\&/and/;
$value
=~ s/\|/or/;
$value
=~ s/\^/not/;
$self
->throw(
"Unsupported operator"
,
$value
)
if
$value
!~ /^(and|or|not)$/;
$self
->{
'_operator'
} =
$value
;
}
unless
(
$self
->{
'_operator'
}){
my
$op
=
$self
->value;
$self
->operator(
$op
)
if
$op
;
}
unless
(
$self
->{
'_operator'
}){
my
$op
=
$self
->safe_value(
'operator'
);
$self
->operator(
$op
)
if
$op
;
}
$self
->{
'_operator'
} ||=
''
;
return
$self
->{
'_operator'
};
}
sub
rule2 {
my
(
$self
,
$value
) =
@_
;
$self
->{
'_rule2'
} =
$value
if
defined
$value
;
$self
->{
'_rule2'
} =
$self
->safe_value(
'rule2'
)
unless
defined
$self
->{
'_rule2'
};
return
$self
->{
'_rule2'
};
}
sub
stringify_value {
my
(
$self
,
@args
) =
@_
;
my
$out
=
""
;
return
$out
unless
defined
$self
->rule1;
$out
.=
$self
->rule1->stringify;
return
$out
unless
defined
$self
->rule2;
$out
.=
' '
.
$self
->operator .
' '
.
$self
->rule2->stringify ;
return
$out
;
}
sub
_qualify_value {
return
$_
[1];
}
sub
_initialize {
my
(
$self
,
@args
) =
@_
;
$self
->type(
'boolean'
);
}
1;