BioPerl
view release on metacpan or search on metacpan
Bio/PhyloNetwork/Factory.pm view on Meta::CPAN
If the parameter -numhybrids=E<gt>$numhybrids is given, then the generated
networks will have at most $numhybrids hybrid nodes. Note that, necessarily,
$numhybrids E<lt> $numleaves.
If the parameter -recurse=E<gt>1 is given, then all networks with number of hybrid
nodes less or equal to $numhybrids will be given; otherwise only those with
exactly $numhybrids hybrid nodes.
=cut
sub new {
my ($pkg,@args)=@_;
my $self=$pkg->SUPER::new(@args);
my ($leavesR,$numleaves,$numhybrids,$recurse)=
$self->_rearrange([qw(LEAVES
NUMLEAVES
NUMHYBRIDS
RECURSE)],@args);
my @leaves;
if ((! defined $leavesR) && (defined $numleaves)) {
@leaves=map {"l$_"} (1..$numleaves);
$leavesR=\@leaves;
}
if (! defined $leavesR) {
$self->throw("No leaves set neither numleaves given");
}
@leaves=@$leavesR;
$self->{leaves}=$leavesR;
$numleaves=@leaves;
$self->{numleaves}=$numleaves;
$recurse ||= 0;
if (! defined $numhybrids) {
$numhybrids=$numleaves-1;
$recurse=1;
}
$self->{recurse}=$recurse;
$self->{numhybrids}=$numhybrids;
if ($numhybrids ==0) {
return Bio::PhyloNetwork::TreeFactory->new(-leaves=>\@leaves);
}
my $parent;
if ($numhybrids > 1) {
$parent=new($pkg,'-leaves'=>\@leaves,
'-numhybrids'=>($numhybrids-1),
'-recurse'=>($recurse));
}
else {
$parent=Bio::PhyloNetwork::TreeFactory->new(-leaves=>\@leaves);
}
$self->{parent}=$parent;
my $oldnet=$parent->next_network();
$self->{oldnet}=$oldnet;
$self->update();
$self->{found}=[];
bless($self,$pkg);
}
sub update {
my ($self)=@_;
my @candidates=$self->{oldnet}->edges();
$self->{candidates}=\@candidates;
$self->{numcandidates}=(scalar @candidates);
$self->{index1}=-$self->{recurse};
$self->{index2}=0;
}
=head2 next_network
Title : next_network
Usage : my $net=$factory->next_network()
Function: returns a network
Returns : Bio::PhyloNetwork
Args : none
=cut
sub next_network {
my ($self)=@_;
my $numleaves=$self->{numleaves};
my $numhybrids=$self->{numhybrids};
START:
if ($self->{index1}==-1) {
$self->{index1}++;
return $self->{oldnet};
}
if ($self->{index1} >= $self->{numcandidates}) {
$self->{index2}++;
$self->{index1}=0;
}
if ($self->{index2} >= $self->{numcandidates}) {
my $oldnet=$self->{parent}->next_network();
if (! $oldnet) {
return 0;
}
$self->{oldnet}=$oldnet;
$self->update();
goto START;
}
if ((scalar $self->{oldnet}->hybrid_nodes())< $self->{numhybrids}-1) {
$self->{candidates}=[];
$self->{numcandidates}=0;
goto START;
}
my $u1=$self->{candidates}->[$self->{index1}]->[0];
my $v1=$self->{candidates}->[$self->{index1}]->[1];
my $u2=$self->{candidates}->[$self->{index2}]->[0];
my $v2=$self->{candidates}->[$self->{index2}]->[1];
my $lbl=$self->{numhybrids};
if ($self->{oldnet}->is_attackable($u1,$v1,$u2,$v2)) {
my $net=Bio::PhyloNetwork->new(-graph=>$self->{oldnet}->graph);
$net->do_attack($u1,$v1,$u2,$v2,$lbl);
$self->{index1}++;
my @found=@{$self->{found}};
foreach my $netant (@found) {
if ($net->is_mu_isomorphic($netant) ) {
goto START;
}
( run in 0.897 second using v1.01-cache-2.11-cpan-39bf76dae61 )