2 # Module for Bio::PhyloNetwork::Factory
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Gabriel Cardona <gabriel(dot)cardona(at)uib(dot)es>
8 # Copyright Gabriel Cardona
10 # You may distribute this module under the same terms as perl itself
12 # POD documentation - main docs before the code
16 Bio::PhyloNetwork::Factory - Module to sequentially generate
24 use Bio::PhyloNetwork;
25 use Bio::PhyloNetwork::Factory;
27 # Will generate sequentially all the 4059 binary tree-child phylogenetic
28 # networks with 4 leaves
30 my $factory=Bio::PhyloNetwork::Factory->new(-numleaves=>4);
34 while (my $net=$factory->next_network()) {
36 print "".(scalar @nets).": ".$net->eNewick()."\n";
41 Sequentially builds a (binary tree-child) phylogenetic network each time
42 next_network is called.
46 Gabriel Cardona, gabriel(dot)cardona(at)uib(dot)es
54 The rest of the documentation details each of the object methods.
58 package Bio
::PhyloNetwork
::Factory
;
63 use base
qw(Bio::Root::Root);
65 use Bio
::PhyloNetwork
;
66 use Bio
::PhyloNetwork
::TreeFactory
;
71 Usage : my $factory = new Bio::PhyloNetwork::Factory();
72 Function: Creates a new Bio::PhyloNetwork::Factory
73 Returns : Bio::PhyloNetwork::RandomFactory
74 Args : -numleaves => integer
76 -leaves => reference to an array (of leaves names)
77 -numhybrids => integer [default = numleaves -1]
78 -recurse => boolean [optional]
80 Returns a Bio::PhyloNetwork::Factory object. Such an object will
81 sequentially create binary tree-child phylogenetic networks
82 each time next_network is called.
84 If the parameter -leaves=E<gt>\@leaves is given, then the set of leaves of
85 these networks will be @leaves. If it is given the parameter
86 -numleaves=E<gt>$numleaves, then the set of leaves will be "l1"..."l$numleaves".
88 If the parameter -numhybrids=E<gt>$numhybrids is given, then the generated
89 networks will have at most $numhybrids hybrid nodes. Note that, necessarily,
90 $numhybrids E<lt> $numleaves.
92 If the parameter -recurse=E<gt>1 is given, then all networks with number of hybrid
93 nodes less or equal to $numhybrids will be given; otherwise only those with
94 exactly $numhybrids hybrid nodes.
101 my $self=$pkg->SUPER::new
(@args);
103 my ($leavesR,$numleaves,$numhybrids,$recurse)=
104 $self->_rearrange([qw(LEAVES
109 if ((! defined $leavesR) && (defined $numleaves)) {
110 @leaves=map {"l$_"} (1..$numleaves);
113 if (! defined $leavesR) {
114 $self->throw("No leaves set neither numleaves given");
117 $self->{leaves
}=$leavesR;
119 $self->{numleaves
}=$numleaves;
122 if (! defined $numhybrids) {
123 $numhybrids=$numleaves-1;
126 $self->{recurse
}=$recurse;
127 $self->{numhybrids
}=$numhybrids;
128 if ($numhybrids ==0) {
129 return Bio
::PhyloNetwork
::TreeFactory
->new(-leaves
=>\
@leaves);
132 if ($numhybrids > 1) {
133 $parent=new
($pkg,'-leaves'=>\
@leaves,
134 '-numhybrids'=>($numhybrids-1),
135 '-recurse'=>($recurse));
138 $parent=Bio
::PhyloNetwork
::TreeFactory
->new(-leaves
=>\
@leaves);
140 $self->{parent
}=$parent;
141 my $oldnet=$parent->next_network();
142 $self->{oldnet
}=$oldnet;
151 my @candidates=$self->{oldnet
}->edges();
152 $self->{candidates
}=\
@candidates;
153 $self->{numcandidates
}=(scalar @candidates);
154 $self->{index1
}=-$self->{recurse
};
161 Usage : my $net=$factory->next_network()
162 Function: returns a network
163 Returns : Bio::PhyloNetwork
170 my $numleaves=$self->{numleaves
};
171 my $numhybrids=$self->{numhybrids
};
173 if ($self->{index1
}==-1) {
175 return $self->{oldnet
};
177 if ($self->{index1
} >= $self->{numcandidates
}) {
181 if ($self->{index2
} >= $self->{numcandidates
}) {
182 my $oldnet=$self->{parent
}->next_network();
186 $self->{oldnet
}=$oldnet;
190 if ((scalar $self->{oldnet
}->hybrid_nodes())< $self->{numhybrids
}-1) {
191 $self->{candidates
}=[];
192 $self->{numcandidates
}=0;
195 my $u1=$self->{candidates
}->[$self->{index1
}]->[0];
196 my $v1=$self->{candidates
}->[$self->{index1
}]->[1];
197 my $u2=$self->{candidates
}->[$self->{index2
}]->[0];
198 my $v2=$self->{candidates
}->[$self->{index2
}]->[1];
199 my $lbl=$self->{numhybrids
};
200 if ($self->{oldnet
}->is_attackable($u1,$v1,$u2,$v2)) {
201 my $net=Bio
::PhyloNetwork
->new(-graph
=>$self->{oldnet
}->graph);
202 $net->do_attack($u1,$v1,$u2,$v2,$lbl);
204 my @found=@
{$self->{found
}};
205 foreach my $netant (@found) {
206 if ($net->is_mu_isomorphic($netant) ) {
211 $self->{found
}=\
@found;