tag fourth (and hopefully last) alpha
[bioperl-live.git] / branch-1-6 / Bio / PhyloNetwork / TreeFactoryX.pm
blob3be002859cc38c4ec365dc8124a3758171cf0101
1 # $Id$
3 # Module for Bio::PhyloNetwork::TreeFactoryX
5 # Please direct questions and support issues to <bioperl-l@bioperl.org>
7 # Cared for by Gabriel Cardona <gabriel(dot)cardona(at)uib(dot)es>
9 # Copyright Gabriel Cardona
11 # You may distribute this module under the same terms as perl itself
13 # POD documentation - main docs before the code
15 =head1 NAME
17 Bio::PhyloNetwork::TreeFactoryX - Module to sequentially generate
18 Phylogenetic Trees
20 =head1 SYNOPSIS
22 use strict;
23 use warnings;
25 use Bio::PhyloNetwork;
26 use Bio::PhyloNetwork::TreeFactory;
28 # Will generate sequentially all the 15 binary phylogetic
29 # trees with 4 leaves
31 my $factory=Bio::PhyloNetwork::TreeFactory->new(-numleaves=>4);
33 my @nets;
35 while (my $net=$factory->next_network()) {
36 push @nets,$net;
37 print "".(scalar @nets).": ".$net->eNewick()."\n";
40 =head1 DESCRIPTION
42 Sequentially builds a (binary) phylogenetic tree each time
43 next_network is called.
45 =head1 AUTHOR
47 Gabriel Cardona, gabriel(dot)cardona(at)uib(dot)es
49 =head1 SEE ALSO
51 L<Bio::PhyloNetwork>
53 =head1 APPENDIX
55 The rest of the documentation details each of the object methods.
57 =cut
59 package Bio::PhyloNetwork::TreeFactoryX;
61 use strict;
62 use warnings;
64 use base qw(Bio::Root::Root);
66 use Bio::PhyloNetwork;
68 =head2 new
70 Title : new
71 Usage : my $factory = new Bio::PhyloNetwork::TreeFactory();
72 Function: Creates a new Bio::PhyloNetwork::TreeFactory
73 Returns : Bio::PhyloNetwork::RandomFactory
74 Args : -numleaves => integer
76 -leaves => reference to an array (of leaves names)
78 Returns a Bio::PhyloNetwork::TreeFactory object. Such an object will
79 sequentially create binary phylogenetic trees
80 each time next_network is called.
82 If the parameter -leaves=E<gt>\@leaves is given, then the set of leaves of
83 these networks will be @leaves. If it is given the parameter
84 -numleaves=E<gt>$numleaves, then the set of leaves will be "l1"..."l$numleaves".
86 =cut
88 sub new {
89 my ($pkg,@args)=@_;
91 my $self=$pkg->SUPER::new(@args);
93 my ($leavesR,$numleaves,$numhybrids)=
94 $self->_rearrange([qw(LEAVES
95 NUMLEAVES
96 NUMHYBRIDS)],@args);
98 my @leaves;
99 if ((! defined $leavesR) && (defined $numleaves)) {
100 @leaves=map {"l$_"} (1..$numleaves);
101 $leavesR=\@leaves;
103 if (! defined $leavesR) {
104 $self->throw("No leaves set neither numleaves given");
106 @leaves=@$leavesR;
107 $self->{leaves}=$leavesR;
109 $numleaves=@leaves;
110 $self->{numleaves}=$numleaves;
111 if ($numleaves > 2) {
112 my @leavesparent=@leaves;
113 my $newleaf=pop @leavesparent;
114 $self->{newleaf}=$newleaf;
115 $self->{parent}=
116 new($pkg,-leaves=>\@leavesparent);
117 my $oldnet=$self->{parent}->next_network_new();
118 $self->{oldnet}=$oldnet;
119 my @candidates=$oldnet->nodes();
120 $self->{candidates}=\@candidates;
122 $self->{index}=0;
123 $self->{found}=[];
124 $self->{thrown}=0;
125 bless($self,$pkg);
128 =head2 next_network
130 Title : next_network
131 Usage : my $net=$factory->next_network()
132 Function: returns a tree
133 Returns : Bio::PhyloNetwork
134 Args : none
136 =cut
138 sub next_network_new {
139 my ($self)=@_;
141 my $n=$self->{numleaves};
142 if ($self->{numleaves} == 2) {
143 if ($self->{index} == 0) {
144 my $graph=Graph::Directed->new();
145 $graph->add_edges("t0",$self->{leaves}->[0],"t0",$self->{leaves}->[1]);
146 my $net=Bio::PhyloNetwork->new(-graph=>$graph);
147 $self->{index}++;
148 $self->{found}=[$net];
149 return $net;
151 else {
152 return 0;
155 else {
156 if ($self->{index} == (scalar @{$self->{candidates}})) {
157 my $oldnet=$self->{parent}->next_network_new();
158 if (! $oldnet) {
159 return 0;
161 $self->{oldnet}=$oldnet;
162 my @candidates=$oldnet->nodes();
163 $self->{candidates}=\@candidates;
164 $self->{index}=0;
166 my $graph=$self->{oldnet}->{graph}->copy();
167 my $u=$self->{candidates}->[$self->{index}];
168 foreach my $w ($graph->predecessors($u)) {
169 $graph->delete_edge($w,$u);
170 $graph->add_edge($w,"t$n");
172 $graph->add_edge("t$n",$u);
173 $graph->add_edge("t$n",$self->{newleaf});
174 my $net=Bio::PhyloNetwork->new(-graph=>$graph);
175 $self->{index}++;
176 my @found=@{$self->{found}};
177 push @found,$net;
178 $self->{found}=\@found;
179 return $net;
183 sub next_network_repeated {
184 my ($self)=@_;
186 return 0 if ($self->{thrown} >= (scalar @{$self->{found}}));
187 $self->{thrown}=$self->{thrown}+1;
188 return $self->{found}->[$self->{thrown}-1];
191 sub next_network {
192 my ($self)=@_;
193 return $self->next_network_new();