bug 2549; fixed small bug in Bio::Taxon which doesn't catch -common_name
[bioperl-live.git] / Bio / TreeIO / cluster.pm
blobb62de9673ea7dd3a006df6eb2e676532bbfa58e4
1 # $Id$
3 # BioPerl module for Bio::TreeIO::cluster
5 # Contributed by Guillaume Rousse <Guillaume-dot-Rousse-at-inria-dot-fr>
7 # Copyright INRIA
9 # You may distribute this module under the same terms as perl itself
11 # POD documentation - main docs before the code
13 =head1 NAME
15 Bio::TreeIO::cluster - A TreeIO driver module for parsing Algorithm::Cluster::treecluster() output
17 =head1 SYNOPSIS
19 # do not use this module directly
20 use Bio::TreeIO;
21 use Algorithm::Cluster;
22 my ($result, $linkdist) = Algorithm::Cluster::treecluster(
23 distances => $matrix
25 my $treeio = Bio::TreeIO->new(
26 -format => 'cluster',
27 -result => $result,
28 -linkdist => $linkdist,
29 -labels => $labels
31 my $tree = $treeio->next_tree;
33 =head1 DESCRIPTION
35 This is a driver module for parsing Algorithm::Cluster::treecluster() output.
37 =head1 FEEDBACK
39 =head2 Mailing Lists
41 User feedback is an integral part of the evolution of this and other
42 Bioperl modules. Send your comments and suggestions preferably to
43 the Bioperl mailing list. Your participation is much appreciated.
45 bioperl-l@bioperl.org - General discussion
46 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
48 =head2 Reporting Bugs
50 Report bugs to the Bioperl bug tracking system to help us keep track
51 of the bugs and their resolution. Bug reports can be submitted via
52 the web:
54 http://bugzilla.open-bio.org/
56 =head1 AUTHOR - Guillaume Rousse
58 Email Guillaume-dot-Rousse-at-inria-dot-fr
60 =head1 CONTRIBUTORS
62 Jason Stajich - jason-at-bioperl-dot-org
64 =head1 APPENDIX
66 The rest of the documentation details each of the object methods.
67 Internal methods are usually preceded with a _
69 =cut
72 # Let the code begin...
75 package Bio::TreeIO::cluster;
76 use strict;
78 use Bio::Event::EventGeneratorI;
79 use IO::String;
81 use base qw(Bio::TreeIO);
83 =head2 new
85 Title : new
86 Usage : my $obj = Bio::TreeIO::cluster->new();
87 Function: Builds a new Bio::TreeIO::cluster object for reading Algorithm::Cluster::treecluster output
88 Returns : Bio::TreeIO::cluster
89 Args :-result => Algorithm::Cluster result
90 -linkdist => distance between links
91 -labels => node labels
93 =cut
95 sub _initialize {
96 my $self = shift;
97 ($self->{_result},$self->{_linkdist},
98 $self->{_labels}) = $self->_rearrange([qw
99 (RESULT LINKDIST LABELS)],
100 @_);
101 $self->SUPER::_initialize(@_);
104 =head2 next_tree
106 Title : next_tree
107 Usage : my $tree = $treeio->next_tree
108 Function: Gets the next tree in the stream
109 Returns : Bio::Tree::TreeI
110 Args : none
113 =cut
115 sub next_tree {
116 my ($self) = @_;
117 if( ! $self->{_result} ){
118 $self->warn("Must provide value 'result' and 'linkdist' and 'labels' when initializing a TreeIO::cluster object");
119 return;
121 $self->_eventHandler->start_document();
123 # build tree from the root
124 $self->_eventHandler->start_element({Name => 'tree'});
125 $self->_recurse(-1, 0);
126 $self->_recurse(-1, 1);
127 $self->_eventHandler->end_element({Name => 'tree'});
129 return $self->_eventHandler->end_document;
132 sub _recurse {
133 my ($self, $line, $column) = @_;
135 my $id = $self->{_result}->[$line]->[$column];
136 if ($id >= 0) {
137 # leaf
138 $self->debug("leaf $id\n");
139 $self->debug("distance $self->{_linkdist}->[$line]\n");
140 $self->debug("label $self->{_labels}->[$id]\n");
141 $self->_eventHandler->start_element({Name => 'node'});
142 $self->_eventHandler->start_element({Name => 'branch_length'});
143 $self->_eventHandler->characters($self->{_linkdist}->[$line]);
144 $self->_eventHandler->end_element({Name => 'branch_length'});
145 $self->_eventHandler->start_element({Name => 'id'});
146 $self->_eventHandler->characters($self->{_labels}->[$id]);
147 $self->_eventHandler->end_element({Name => 'id'});
148 $self->_eventHandler->start_element({Name => 'leaf'});
149 $self->_eventHandler->characters(1);
150 $self->_eventHandler->end_element({Name => 'leaf'});
151 $self->_eventHandler->end_element({Name => 'node'});
152 } else {
153 # internal node
154 $self->debug("internal node $id\n");
155 $self->debug("distance $self->{_linkdist}->[$line]\n");
156 $self->_eventHandler->start_element({Name => 'node'});
157 $self->_eventHandler->start_element({Name => 'branch_length'});
158 $self->_eventHandler->characters($self->{_linkdist}->[$line]);
159 $self->_eventHandler->end_element({Name => 'branch_length'});
160 $self->_eventHandler->start_element({Name => 'leaf'});
161 $self->_eventHandler->characters(0);
162 $self->_eventHandler->end_element({Name => 'leaf'});
163 $self->_eventHandler->start_element({Name => 'tree'});
164 my $child_id = - ($id + 1);
165 $self->_recurse($child_id, 0);
166 $self->_recurse($child_id, 1);
167 $self->_eventHandler->end_element({Name => 'tree'});
168 $self->_eventHandler->end_element({Name => 'node'});
173 =head2 write_tree
175 Title : write_tree
176 Usage :
177 Function: Sorry not possible with this format
178 Returns : none
179 Args : none
182 =cut
184 sub write_tree{
185 $_[0]->throw("Sorry the format 'cluster' can only be used as an input format");