annotate variant_effect_predictor/Bio/EnsEMBL/Compara/NestedSet.pm @ 1:d6778b5d8382 draft default tip

Deleted selected files
author willmclaren
date Fri, 03 Aug 2012 10:05:43 -0400
parents 21066c0abaf5
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1 =head1 NAME
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
2
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
3 NestedSet - DESCRIPTION of Object
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
4
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
5 =head1 SYNOPSIS
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
6
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
7 =head1 DESCRIPTION
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
8
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
9 Abstract superclass to encapsulate the process of storing and manipulating a
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
10 nested-set representation tree. Also implements a 'reference count' system
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
11 based on the ObjectiveC retain/release design.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
12 Designed to be used as the Root class for all Compara 'proxy' classes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
13 (Member, GenomeDB, DnaFrag, NCBITaxon) to allow them to be made into sets and trees.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
14
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
15 =head1 CONTACT
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
16
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
17 Contact Albert Vilella on implementation detail: avilella@ebi.ac.uk
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
18 Contact Jessica Severin on implementation/design detail: jessica@ebi.ac.uk
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
19 Contact Ewan Birney on EnsEMBL in general: birney@sanger.ac.uk
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
20
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
21 =head1 APPENDIX
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
22
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
23 The rest of the documentation details each of the object methods. Internal methods are usually preceded with a _
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
24
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
25 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
26
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
27
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
28
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
29 package Bio::EnsEMBL::Compara::NestedSet;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
30
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
31 use strict;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
32 use warnings;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
33 use Bio::EnsEMBL::Utils::Exception;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
34 use Bio::EnsEMBL::Utils::Argument;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
35
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
36 use Bio::EnsEMBL::Utils::Exception qw(deprecate throw);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
37
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
38 use Bio::TreeIO;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
39 use Bio::EnsEMBL::Compara::Graph::Node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
40 use Bio::EnsEMBL::Compara::Member;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
41 our @ISA = qw(Bio::EnsEMBL::Compara::Graph::Node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
42
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
43 #################################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
44 # Factory methods
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
45 #################################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
46
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
47 sub init {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
48 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
49 $self->SUPER::init;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
50 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
51 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
52
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
53 sub dealloc {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
54 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
55
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
56 #printf("DEALLOC NestedSet refcount:%d ", $self->refcount); $self->print_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
57 #$self->release_children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
58 return $self->SUPER::dealloc;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
59 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
60
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
61 =head2 copy
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
62
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
63 Overview : creates copy of tree starting at this node going down
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
64 Example : my $clone = $self->copy;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
65 Returntype : Bio::EnsEMBL::Compara::NestedSet
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
66 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
67 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
68
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
69 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
70
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
71 sub copy {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
72 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
73
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
74 my $mycopy = $self->SUPER::copy;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
75 bless $mycopy, ref $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
76
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
77 $mycopy->distance_to_parent($self->distance_to_parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
78 $mycopy->left_index($self->left_index);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
79 $mycopy->right_index($self->right_index);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
80
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
81 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
82 $mycopy->add_child($child->copy);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
83 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
84 return $mycopy;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
85 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
86
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
87
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
88 =head2 release_tree
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
89
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
90 Overview : deletes and frees the memory used by this tree
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
91 and all the underlying nodes.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
92 Example : $self->release_tree;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
93 Returntype : undef
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
94 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
95 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
96
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
97 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
98
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
99 sub release_tree {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
100 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
101
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
102 my $child_count = $self->get_child_count;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
103 $self->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
104 $self->cascade_unlink if($child_count);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
105 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
106 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
107
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
108 #################################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
109 # Object variable methods
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
110 #################################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
111
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
112 sub left_index {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
113 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
114 $self->{'_left_index'} = shift if(@_);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
115 $self->{'_left_index'} = 0 unless(defined($self->{'_left_index'}));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
116 return $self->{'_left_index'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
117 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
118
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
119 sub right_index {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
120 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
121 $self->{'_right_index'} = shift if(@_);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
122 $self->{'_right_index'} = 0 unless(defined($self->{'_right_index'}));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
123 return $self->{'_right_index'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
124 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
125
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
126
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
127 #######################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
128 # Set manipulation methods
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
129 #######################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
130
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
131 =head2 add_child
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
132
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
133 Overview : attaches child nestedset node to this nested set
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
134 Arg [1] : Bio::EnsEMBL::Compara::NestedSet $child
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
135 Arg [2] : (opt.) distance between this node and child
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
136 Example : $self->add_child($child);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
137 Returntype : undef
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
138 Exceptions : if child is undef or not a NestedSet subclass
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
139 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
140
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
141 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
142
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
143 sub add_child {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
144 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
145 my $child = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
146 my $dist = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
147
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
148 throw("child not defined")
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
149 unless(defined($child));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
150 throw("arg must be a [Bio::EnsEMBL::Compara::NestedSet] not a [$child]")
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
151 unless($child->isa('Bio::EnsEMBL::Compara::NestedSet'));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
152
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
153 #printf("add_child: parent(%s) <-> child(%s)\n", $self->node_id, $child->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
154
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
155 unless(defined($dist)) { $dist = $child->_distance; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
156
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
157 $child->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
158 #create_link_to_node is a safe method which checks if connection exists
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
159 my $link = $self->create_link_to_node($child);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
160 $child->_set_parent_link($link);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
161 $self->{'_children_loaded'} = 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
162 $link->distance_between($dist);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
163 return $link;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
164 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
165
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
166
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
167 =head2 disavow_parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
168
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
169 Overview : unlink and release self from its parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
170 might cause self to delete if refcount reaches Zero.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
171 Example : $self->disavow_parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
172 Returntype : undef
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
173 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
174
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
175 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
176
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
177 sub disavow_parent {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
178 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
179
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
180 if($self->{'_parent_link'}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
181 my $link = $self->{'_parent_link'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
182 #print("DISAVOW parent : "); $parent->print_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
183 #print(" child : "); $self->print_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
184 $link->dealloc;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
185 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
186 $self->_set_parent_link(undef);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
187 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
188 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
189
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
190
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
191 =head2 release_children
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
192
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
193 Overview : recursive releases all children
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
194 will cause potential deletion of children if refcount reaches Zero.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
195 Example : $self->release_children
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
196 Returntype : $self
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
197 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
198 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
199
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
200 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
201
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
202 sub release_children {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
203 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
204
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
205 # by calling with parent, this preserved the link to the parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
206 # and thus doesn't unlink self
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
207 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
208 $child->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
209 $child->release_children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
210 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
211 #$self->cascade_unlink($self->{'_parent_node'});
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
212 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
213 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
214
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
215
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
216 =head2 parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
217
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
218 Overview : returns the parent NestedSet object for this node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
219 Example : my $my_parent = $object->parent();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
220 Returntype : undef or Bio::EnsEMBL::Compara::NestedSet
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
221 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
222 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
223
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
224 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
225
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
226 sub parent {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
227 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
228 return $self->adaptor->fetch_parent_for_node($self) if defined $self->adaptor;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
229 return $self->{'_parent_link'}->get_neighbor($self) if defined $self->{'_parent_link'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
230 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
231 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
232
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
233
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
234 sub parent_link {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
235 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
236 return $self->{'_parent_link'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
237 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
238
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
239 sub has_parent {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
240 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
241 return 1 if($self->{'_parent_link'} or $self->_parent_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
242 return 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
243 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
244
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
245
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
246 sub has_ancestor {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
247 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
248 my $ancestor = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
249 throw "[$ancestor] must be a Bio::EnsEMBL::Compara::NestedSet object"
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
250 unless ($ancestor and $ancestor->isa("Bio::EnsEMBL::Compara::NestedSet"));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
251 my $node = $self->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
252 while($node) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
253 return 1 if($node->equals($ancestor));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
254 $node = $node->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
255 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
256 return 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
257 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
258
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
259
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
260 =head2 root
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
261
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
262 Overview : returns the root NestedSet object for this node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
263 returns $self if node has no parent (this is the root)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
264 Example : my $root = $object->root();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
265 Description: Returns the root of the tree for this node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
266 with links to all the intermediate nodes. Sister nodes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
267 are not included in the result.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
268 Returntype : undef or Bio::EnsEMBL::Compara::NestedSet
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
269 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
270 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
271
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
272 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
273
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
274 sub root {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
275 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
276
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
277 # Only if we don't have it cached
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
278 # Only if we have left and right and it's not a leaf
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
279 # Only if it's for release clusterset (1 genetrees - 0 genomic align trees)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
280 if (!defined($self->{'_parent_link'}) and $self->adaptor
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
281 and ($self->right_index-$self->left_index)>1
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
282 and (defined $self->{'_parent_id'})
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
283 and (1==$self->{'_parent_id'})
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
284 ) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
285 return $self->adaptor->fetch_root_by_node($self);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
286 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
287
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
288 # Otherwise, go through the step-by-step method
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
289 return $self unless(defined($self->parent));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
290 # return $self if($self->node_id eq $self->parent->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
291 return $self->parent->root;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
292 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
293
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
294 sub subroot {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
295 deprecate('subroot() should not be used and will be removed in release 70.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
296 If you are using it, please contact the dev mailing-list dev@ensembl.org');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
297 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
298
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
299 return undef unless($self->parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
300 return $self unless(defined($self->parent->parent));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
301 return $self->parent->subroot;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
302 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
303
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
304
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
305 =head2 children
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
306
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
307 Overview : returns a list of NestedSet nodes directly under this parent node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
308 Example : my @children = @{$object->children()};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
309 Returntype : array reference of Bio::EnsEMBL::Compara::NestedSet objects (could be empty)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
310 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
311 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
312 Algorithm : new algorithm for fetching children:
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
313 for each link connected to this NestedsSet node, a child is defined if
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
314 old: the link is not my parent_link
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
315 new: the link's neighbors' parent_link is the link
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
316 This allows one (with a carefully coded algorithm) to overlay a tree on top
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
317 of a fully connected graph and use the parent/children methods of NestedSet
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
318 to walk the 'tree' substructure of the graph.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
319 Trees that are really just trees are still trees.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
320
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
321 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
322
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
323 sub children {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
324 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
325 $self->load_children_if_needed;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
326 my @kids;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
327 foreach my $link (@{$self->links}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
328 next unless(defined($link));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
329 my $neighbor = $link->get_neighbor($self);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
330 my $parent_link = $neighbor->parent_link;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
331 next unless($parent_link);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
332 next unless($parent_link eq $link);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
333 push @kids, $neighbor;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
334 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
335 return \@kids;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
336 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
337
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
338 sub each_child {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
339 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
340
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
341 # Return an iterator over the children (most effective when children list is LONG)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
342 my $count = -1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
343 $self->load_children_if_needed;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
344 my @links = @{$self->links};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
345
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
346 return sub {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
347 while ($count < scalar(@links)) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
348 $count++;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
349 my $link = $links[$count];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
350 next unless(defined $link);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
351
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
352 my $neighbor = $link->get_neighbor($self);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
353 next unless($neighbor->parent_link);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
354 next unless($neighbor->parent_link->equals($link));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
355 return $neighbor;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
356 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
357 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
358 };
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
359 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
360
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
361 =head2 sorted_children
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
362
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
363 Overview : returns a sorted list of NestedSet nodes directly under this parent node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
364 sort so that internal nodes<leaves and then on distance
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
365 Example : my @kids = @{$object->ordered_children()};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
366 Returntype : array reference of Bio::EnsEMBL::Compara::NestedSet objects (could be empty)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
367 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
368 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
369
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
370 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
371
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
372 sub sorted_children {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
373 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
374
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
375 my @sortedkids =
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
376 sort { $a->is_leaf <=> $b->is_leaf
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
377 ||
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
378 $a->get_child_count <=> $b->get_child_count
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
379 ||
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
380 $a->distance_to_parent <=> $b->distance_to_parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
381 } @{$self->children;};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
382 return \@sortedkids;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
383 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
384
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
385
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
386 =head2 get_all_nodes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
387
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
388 Arg 1 : hashref $node_hash [used for recursivity, do not use it!]
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
389 Example : my $all_nodes = $root->get_all_nodes();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
390 Description : Returns this and all underlying sub nodes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
391 ReturnType : listref of Bio::EnsEMBL::Compara::NestedSet objects
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
392 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
393 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
394 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
395
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
396 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
397
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
398 sub get_all_nodes {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
399 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
400 my $node_hash = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
401
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
402 my $toplevel = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
403 unless($node_hash) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
404 $node_hash = {};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
405 $toplevel =1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
406 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
407
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
408 $node_hash->{$self->obj_id} = $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
409 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
410 $child->get_all_nodes($node_hash);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
411 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
412
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
413 if ($toplevel) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
414 return [values(%$node_hash)];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
415 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
416 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
417 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
418
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
419
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
420 =head2 get_all_nodes_by_tag_value
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
421
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
422 Arg 1 : tag_name
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
423 Arg 2 : tag_value (optional)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
424 Example : my $all_nodes = $root->get_all_nodes_by_tagvalue('taxon_name'=>'Mamalia');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
425 Description : Returns all underlying nodes that have a tag of the given name, and optionally a value of the given value.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
426 ReturnType : listref of Bio::EnsEMBL::Compara::NestedSet objects
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
427 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
428 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
429 Status :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
430
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
431 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
432
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
433 sub get_all_nodes_by_tag_value {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
434 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
435 my $tag = shift || die( "Need a tag name" );
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
436 my $value = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
437 my @found;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
438 foreach my $node( @{$self->get_all_nodes} ){
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
439 my $tval = $node->get_tagvalue($tag);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
440 if( defined $tval and $value ? $tval eq $value : 1 ){
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
441 push @found, $node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
442 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
443 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
444 return [@found];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
445 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
446
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
447
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
448 =head2 get_all_subnodes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
449
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
450 Arg 1 : hashref $node_hash [used for recursivity, do not use it!]
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
451 Example : my $all_nodes = $root->get_all_nodes();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
452 Description : Returns all underlying sub nodes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
453 ReturnType : listref of Bio::EnsEMBL::Compara::NestedSet objects
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
454 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
455 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
456 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
457
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
458 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
459
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
460 sub get_all_subnodes {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
461 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
462 my $node_hash = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
463
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
464 my $toplevel = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
465 unless($node_hash) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
466 $node_hash = {};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
467 $toplevel =1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
468 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
469
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
470 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
471 $node_hash->{$child->obj_id} = $child;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
472 $child->get_all_subnodes($node_hash);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
473 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
474 return values(%$node_hash) if($toplevel);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
475 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
476 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
477
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
478 =head2 get_all_ancestors
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
479
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
480 Arg 1 :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
481 Example : my @ancestors = @{$node->get_all_ancestors};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
482 Description : Returns all ancestor nodes for a given node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
483 ReturnType : listref of Bio::EnsEMBL::Compara::NestedSet objects
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
484 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
485 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
486 Status :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
487
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
488 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
489
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
490 sub get_all_ancestors {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
491 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
492 my $this = $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
493 my @ancestors;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
494 while( $this = $this->parent ){
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
495 push @ancestors, $this;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
496 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
497 return [@ancestors]
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
498 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
499
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
500 =head2 get_all_adjacent_subtrees
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
501
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
502 Arg 1 :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
503 Example : my @subtrees = @{$node->get_all_adjacent_subtrees};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
504 Description : Returns subtree 'root' nodes where the subtree is adjacent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
505 to this node. Used e.g. by the web code for the 'collapse
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
506 other nodes' action
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
507 ReturnType : listref of Bio::EnsEMBL::Compara::NestedSet objects
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
508 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
509 Caller : EnsEMBL::Web::Component::Gene::ComparaTree
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
510 Status :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
511
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
512 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
513
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
514 sub get_all_adjacent_subtrees {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
515 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
516 my $node_id = $self->node_id;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
517 my @node_path_to_root = ($self, @{$self->get_all_ancestors} );
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
518 my %path_node_ids = map{ $_->node_id => 1 } @node_path_to_root;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
519
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
520 my $this = $self->root; # Start at the root node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
521
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
522 my @adjacent_subtrees;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
523 while( $this ){
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
524 last if $this->node_id == $node_id; # Stop on reaching current node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
525 my $next;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
526 foreach my $child (@{$this->children}){
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
527 next if $child->is_leaf; # Leaves cannot be subtrees
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
528 if( $path_node_ids{$child->node_id} ){ # Ancestor node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
529 $next = $child;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
530 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
531 push @adjacent_subtrees, $child;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
532 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
533 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
534 $this = $next || undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
535 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
536
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
537 return [@adjacent_subtrees]
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
538 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
539
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
540
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
541 =head2 num_leaves
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
542
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
543 Example : my $num_leaves = $node->num_leaves
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
544 Description : Returns the number of leaves underlying the node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
545 ReturnType : integer
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
546 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
547 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
548 Status : At risk (relies on left and right indexes)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
549
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
550 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
551 #'
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
552 sub num_leaves {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
553 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
554
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
555 my $left = $self->left_index;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
556 my $right = $self->right_index;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
557
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
558 return unless( $left && $right );
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
559
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
560 my $num = $right - $left + 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
561 my $num_leaves = ( ($num/2) + 1 ) / 2;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
562
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
563 return $num_leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
564 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
565
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
566
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
567 sub get_child_count {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
568 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
569 $self->load_children_if_needed;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
570 return scalar @{$self->children};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
571 # my $count = $self->link_count;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
572 # $count-- if($self->has_parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
573 # return $count;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
574 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
575
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
576 sub load_children_if_needed {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
577 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
578 if(!defined($self->{'_children_loaded'}) and $self->adaptor) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
579 #define _children_id_hash thereby signally that I've tried to load my children
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
580 $self->{'_children_loaded'} = 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
581 #print("load_children_if_needed : "); $self->print_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
582 $self->adaptor->fetch_all_children_for_node($self);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
583 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
584 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
585
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
586 sub no_autoload_children {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
587 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
588
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
589 return if($self->{'_children_loaded'});
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
590 $self->{'_children_loaded'} = 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
591 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
592
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
593
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
594 =head2 distance_to_parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
595
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
596 Arg [1] : (opt.) <int or double> distance
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
597 Example : my $dist = $object->distance_to_parent();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
598 Example : $object->distance_to_parent(1.618);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
599 Description: Getter/Setter for the distance between this child and its parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
600 Returntype : integer node_id
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
601 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
602 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
603
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
604 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
605
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
606 sub distance_to_parent {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
607 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
608 my $dist = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
609
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
610 if($self->{'_parent_link'}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
611 if(defined($dist)) { $self->{'_parent_link'}->distance_between($dist); }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
612 else { $dist = $self->{'_parent_link'}->distance_between; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
613 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
614 if(defined($dist)) { $self->_distance($dist); }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
615 else { $dist = $self->_distance; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
616 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
617 return $dist;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
618 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
619
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
620 sub _distance {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
621 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
622 $self->{'_distance_to_parent'} = shift if(@_);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
623 $self->{'_distance_to_parent'} = 0.0 unless(defined($self->{'_distance_to_parent'}));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
624 return $self->{'_distance_to_parent'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
625 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
626
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
627 sub distance_to_root {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
628 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
629 my $dist = $self->distance_to_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
630 $dist += $self->parent->distance_to_root if($self->parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
631 return $dist;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
632 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
633
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
634
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
635 =head2 distance_to_ancestor
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
636
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
637 Arg [1] : Bio::EnsEMBL::Compara::NestedSet $ancestor
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
638 Example : my $distance = $this_node->distance_to_ancestor($ancestor);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
639 Description : Calculates the distance in the tree between this node and
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
640 its ancestor $ancestor
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
641 Returntype : float
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
642 Exceptions : throws if $ancestor is not an ancestor of this node.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
643 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
644 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
645
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
646 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
647
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
648 sub distance_to_ancestor {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
649 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
650 my $ancestor = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
651
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
652 if ($ancestor->node_id eq $self->node_id) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
653 return 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
654 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
655 unless (defined $self->parent) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
656 throw("Ancestor not found\n");
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
657 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
658 return $self->distance_to_parent + $self->parent->distance_to_ancestor($ancestor);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
659 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
660
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
661
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
662 =head2 distance_to_node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
663
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
664 Arg [1] : Bio::EnsEMBL::Compara::NestedSet $node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
665 Example : my $distance = $this_node->distance_to_node($other_node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
666 Description : Calculates the distance in the tree between these
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
667 two nodes.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
668 Returntype : float
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
669 Exceptions : returns undef if no ancestor can be found, no distances are
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
670 defined in the tree, etc.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
671 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
672 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
673
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
674 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
675
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
676 sub distance_to_node {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
677 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
678 my $node = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
679
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
680 my $ancestor = $self->find_first_shared_ancestor($node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
681 if (!$ancestor) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
682 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
683 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
684 my $distance = $self->distance_to_ancestor($ancestor);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
685 $distance += $node->distance_to_ancestor($ancestor);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
686
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
687 return $distance;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
688 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
689
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
690
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
691 # Returns a TreeI-compliant object based on this NestedSet.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
692 sub get_TreeI {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
693 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
694 my $newick = $self->newick_format();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
695
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
696 open(my $fake_fh, "+<", \$newick);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
697 my $treein = new Bio::TreeIO(-fh => $fake_fh, -format => 'newick');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
698 my $treeI = $treein->next_tree;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
699 $treein->close;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
700
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
701 return $treeI;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
702 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
703
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
704 sub new_from_newick {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
705 my $class = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
706 my $file = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
707 my $treein = new Bio::TreeIO(-file => $file, -format => 'newick');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
708 my $treeI = $treein->next_tree;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
709 $treein->close;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
710
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
711 return $class->new_from_TreeI($treeI);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
712 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
713
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
714 sub new_from_TreeI {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
715 my $class = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
716 my $treeI = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
717
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
718 my $rootI = $treeI->get_root_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
719 my $node = new $class;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
720
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
721 # Kick off the recursive, parallel node adding.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
722 _add_nodeI_to_node($node,$rootI);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
723
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
724 return $node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
725 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
726
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
727 # Recursive helper for new_from_TreeI.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
728 sub _add_nodeI_to_node {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
729 my $node = shift; # Our node object (Compara)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
730 my $nodeI = shift; # Our nodeI object (BioPerl)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
731
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
732 foreach my $c ($nodeI->each_Descendent) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
733 my $child = ref($node)->new;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
734
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
735 my $name = $c->id || '';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
736 $name =~ s/^\s+//;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
737 $name =~ s/\s+$//;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
738
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
739 # Set name.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
740 $child->name($name);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
741
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
742 # Set branch length.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
743 $node->add_child($child,$c->branch_length);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
744
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
745 # Recurse.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
746 _add_nodeI_to_node($child,$c);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
747 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
748 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
749
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
750 =head2 print_tree
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
751
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
752 Arg [1] : int $scale
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
753 Example : $this_node->print_tree(100);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
754 Description : Prints this tree in ASCII format. The scale is used to define
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
755 the width of the tree in the output
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
756 Returntype : undef
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
757 Exceptions :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
758 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
759 Status : At risk (as the output might change)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
760
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
761 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
762
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
763 sub print_tree {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
764 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
765 my $scale = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
766
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
767 $scale = 100 unless($scale);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
768 $self->_internal_print_tree(undef, 0, $scale);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
769 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
770
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
771 sub string_tree {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
772 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
773 my $scale = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
774 $scale ||= 100;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
775 my $buffer = '';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
776 $self->_internal_string_tree(undef, 0, $scale, \$buffer);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
777 return $buffer;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
778 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
779
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
780 sub _internal_string_tree {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
781 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
782 my $indent = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
783 my $lastone = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
784 my $scale = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
785 my $buffer = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
786
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
787 if(defined($indent)) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
788 $$buffer .= $indent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
789 for(my $i=0; $i<$self->distance_to_parent()*$scale; $i++) { $$buffer .= '-'; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
790 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
791
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
792 $$buffer .= $self->string_node($indent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
793
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
794 if(defined($indent)) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
795 if($lastone) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
796 chop($indent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
797 $indent .= " ";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
798 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
799 for(my $i=0; $i<$self->distance_to_parent()*$scale; $i++) { $indent .= ' '; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
800 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
801 $indent = '' unless(defined($indent));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
802 $indent .= "|";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
803
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
804 my $children = $self->sorted_children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
805 my $count=0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
806 $lastone = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
807 foreach my $child_node (@$children) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
808 $count++;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
809 $lastone = 1 if($count == scalar(@$children));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
810 $child_node->_internal_string_tree($indent,$lastone,$scale,$buffer);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
811 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
812 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
813
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
814 sub _internal_print_tree {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
815 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
816 my $indent = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
817 my $lastone = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
818 my $scale = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
819
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
820 if(defined($indent)) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
821 print($indent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
822 for(my $i=0; $i<$self->distance_to_parent()*$scale; $i++) { print('-'); }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
823 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
824
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
825 $self->print_node($indent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
826
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
827 if(defined($indent)) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
828 if($lastone) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
829 chop($indent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
830 $indent .= " ";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
831 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
832 for(my $i=0; $i<$self->distance_to_parent()*$scale; $i++) { $indent .= ' '; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
833 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
834 $indent = '' unless(defined($indent));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
835 $indent .= "|";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
836
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
837 my $children = $self->sorted_children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
838 my $count=0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
839 $lastone = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
840 foreach my $child_node (@$children) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
841 $count++;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
842 $lastone = 1 if($count == scalar(@$children));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
843 $child_node->_internal_print_tree($indent,$lastone,$scale);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
844 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
845 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
846
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
847
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
848 sub print_node {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
849 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
850 print $self->string_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
851 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
852
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
853 sub string_node {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
854 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
855 my $str = '(';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
856
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
857 my $isdup = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
858 $isdup = 1 if ($self->get_tagvalue('Duplication', 0) > 0 and not $self->get_tagvalue('dubious_duplication', 0));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
859 $isdup = 1 if $self->get_tagvalue('node_type', '') eq 'duplication';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
860
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
861 my $isdub = ($self->get_tagvalue('node_type', '') eq 'dubious');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
862
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
863 if ($isdup) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
864 my $taxon_name = $self->get_tagvalue('taxon_name', '');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
865 if ($taxon_name =~ /\S+\ \S+/) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
866 $str .= "Dup ";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
867 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
868 $str .= "DUP ";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
869 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
870 my $sis = $self->get_tagvalue('duplication_confidence_score', 0) * 100;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
871 $str .= sprintf('SIS=%d ', $sis);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
872 } elsif ($isdub) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
873 $str .= "DD ";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
874 $str .= 'SIS=0 ';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
875 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
876 if($self->has_tag("bootstrap")) { my $bootstrap_value = $self->get_tagvalue("bootstrap"); $str .= "B=$bootstrap_value "; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
877 if($self->has_tag("taxon_name")) { my $taxon_name_value = $self->get_tagvalue("taxon_name"); $str .="T=$taxon_name_value "; }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
878 $str .= sprintf("%s %d,%d)", $self->node_id, $self->left_index, $self->right_index);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
879 $str .= sprintf("%s\n", $self->name || '');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
880 return $str;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
881 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
882
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
883
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
884 =head2 newick_format
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
885
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
886 Arg [1] : string $format_mode
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
887 Example : $this_node->newick_format("full");
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
888 Description : Prints this tree in Newick format. Several modes are
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
889 available: full, display_label_composite, simple, species,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
890 species_short_name, ncbi_taxon, ncbi_name, njtree and phylip
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
891 Returntype : string
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
892 Exceptions :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
893 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
894 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
895
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
896 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
897
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
898 my %ryo_modes = (
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
899 'member_id' => '%{^-m}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
900 'member_id_taxon_id' => '%{-m}%{"_"-x}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
901 'display_label_composite' => '%{-l"_"}%{n}%{"_"-s}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
902 'full_common' => '%{n}%{" "-c.^}%{"."-g}%{"_"-t"_MYA"}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
903 'gene_stable_id_composite' => '%{-i"_"}%{n}%{"_"-s}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
904 'gene_stable_id' => '%{-i}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
905 'ncbi_taxon' => '%{o}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
906 'ncbi_name' => '%{n}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
907 'simple' => '%{^-n}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
908 'full' => '%{n}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
909 'species' => '%{^-S|p}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
910 'species_short_name' => '%{^-s|p}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
911 'otu_id' => '%{-s"|"}%{-l"|"}%{n}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
912 'int_node_id' => '%{-n}%{o-}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
913 'full_web' => '%{n-}%{-n|p}%{"_"-s"_"}%{":"d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
914 'phylip' => '%21{n,}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
915 'njtree' => '%{o}%{-T(is_incomplete)|E"*"}%{-T(is_incomplete,0,*)}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
916 );
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
917
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
918 my $nhx0 = '%{n-_|T(taxon_name)}:%{d}';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
919 my $nhx1 = ':D=%{-E"N"}%{T(node_type,duplication,Y)-}%{T(node_type,dubious,Y)-}%{T(node_type,gene_split,Y)-}%{T(node_type,speciation,N)}%{":B="T(bootstrap)}';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
920 my $nhx2 = ':T=%{-x}%{T(taxon_id)-}';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
921
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
922 my %nhx_ryo_modes_1 = (
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
923 'member_id_taxon_id' => '%{-m}%{o-}_%{-x}%{T(taxon_id)-}:%{d}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
924 'protein_id' => '%{-n}'.$nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
925 'transcript_id' => '%{-r}'.$nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
926 'gene_id' => '%{-i}'.$nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
927 'full' => $nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
928 'full_web' => $nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
929 'display_label' => '%{-L|i}%{"_"-s}'.$nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
930 'display_label_composite' => '%{-L"_"}%{-i}%{"_"-s}'.$nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
931 'treebest_ortho' => '%{-m}%{"_"-x}'.$nhx0,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
932 'simple' => $ryo_modes{'simple'},
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
933 'phylip' => $ryo_modes{'phylip'},
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
934 );
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
935
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
936 my %nhx_ryo_modes_2 = (
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
937 'member_id_taxon_id' => $nhx1.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
938 'protein_id' => $nhx1.'%{":G="-i}'.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
939 'transcript_id' => $nhx1.'%{":G="-i}'.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
940 'gene_id' => $nhx1.'%{":G="-r}'.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
941 'full' => $nhx1.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
942 'full_web' => $nhx1.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
943 'display_label' => $nhx1.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
944 'display_label_composite' => $nhx1.$nhx2,
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
945 'treebest_ortho' => $nhx1.$nhx2.':S=%{-x}%{T(taxon_id)-}',
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
946 );
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
947
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
948
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
949 sub newick_format {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
950 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
951 my $format_mode = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
952
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
953 my $ryo_string;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
954
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
955 if (not defined $format_mode) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
956 $ryo_string = $ryo_modes{'full'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
957
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
958 } elsif ($format_mode eq "ryo") {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
959 $ryo_string = shift @_;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
960
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
961 } elsif (defined $ryo_modes{$format_mode}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
962 $ryo_string = $ryo_modes{$format_mode};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
963
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
964 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
965 throw("Unrecognized format '$format_mode'. Please use 'ryo' to introduce a roll-your-own format string\n");
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
966 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
967 return $self->_internal_newick_format_ryo($ryo_string);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
968 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
969
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
970 sub nhx_format {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
971 my ($self, $format_mode) = @_;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
972 my $ryo_string1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
973 my $ryo_string2;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
974
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
975 if (not defined $format_mode) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
976 $ryo_string1 = $nhx_ryo_modes_1{'protein_id'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
977 $ryo_string2 = $nhx_ryo_modes_2{'protein_id'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
978
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
979 } elsif ($format_mode eq "ryo") {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
980 $ryo_string1 = shift @_;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
981 $ryo_string2 = shift @_;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
982
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
983 } elsif (defined $nhx_ryo_modes_1{$format_mode}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
984 $ryo_string1 = $nhx_ryo_modes_1{$format_mode};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
985 $ryo_string2 = $nhx_ryo_modes_2{$format_mode};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
986
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
987 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
988 throw("Unrecognized format '$format_mode'. Please use 'ryo' to introduce a roll-your-own format string\n");
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
989 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
990 my $fmt = $ryo_string1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
991 $fmt = $ryo_string1.'[&&NHX'.$ryo_string2.']' if defined $ryo_string2;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
992 return $self->_internal_newick_format_ryo($fmt);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
993 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
994
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
995 sub _internal_newick_format_ryo {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
996 my ($self, $ryo_string) = @_;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
997 my $newick_str;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
998 eval {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
999 use Bio::EnsEMBL::Compara::FormatTree;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1000 my $ryo_formatter = Bio::EnsEMBL::Compara::FormatTree->new($ryo_string);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1001 $newick_str = $ryo_formatter->format_newick($self);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1002 };
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1003 if ($@) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1004 throw("Something bad happened while trying to stringify the tree: $@\n");
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1005 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1006 return "$newick_str;";
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1007 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1008
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1009 =head2 newick_simple_format
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1010
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1011 DEPRECATED. Use newick_format("simple") instead
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1012
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1013 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1014
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1015 sub newick_simple_format {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1016 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1017 deprecate('Use newick_format("simple") instead.');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1018 return $self->newick_format('simple');
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1019 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1020
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1021
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1022 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1023 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1024 # Set theory methods
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1025 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1026 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1027
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1028 #sub equals {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1029 # my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1030 # my $other = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1031 # throw("arg must be a [Bio::EnsEMBL::Compara::NestedSet] not a [$other]")
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1032 # unless($other->isa('Bio::EnsEMBL::Compara::NestedSet'));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1033 # return 1 if($self->node_id eq $other->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1034 # foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1035 # return 0 unless($other->has_child($child));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1036 # }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1037 # return 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1038 #}
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1039
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1040 sub has_child {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1041 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1042 my $child = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1043 throw("arg must be a [Bio::EnsEMBL::Compara::NestedSet] not a [$child]")
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1044 unless($child->isa('Bio::EnsEMBL::Compara::NestedSet'));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1045 $self->load_children_if_needed;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1046 my $link = $self->link_for_neighbor($child);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1047 return 0 unless($link);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1048 return 0 if($self->{'_parent_link'} and ($self->{'_parent_link'}->equals($link)));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1049 return 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1050 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1051
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1052 sub is_member_of {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1053 my $A = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1054 my $B = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1055 return 1 if($B->has_child($A));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1056 return 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1057 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1058
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1059 sub is_subset_of {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1060 my $A = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1061 my $B = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1062 foreach my $child (@{$A->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1063 return 0 unless($B->has_child($child));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1064 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1065 return 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1066 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1067
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1068 sub is_leaf {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1069 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1070 return 1 unless($self->get_child_count);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1071 return 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1072 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1073
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1074 sub merge_children {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1075 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1076 my $nset = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1077 throw("arg must be a [Bio::EnsEMBL::Compara::NestedSet] not a [$nset]")
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1078 unless($nset->isa('Bio::EnsEMBL::Compara::NestedSet'));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1079 foreach my $child_node (@{$nset->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1080 $self->add_child($child_node, $child_node->distance_to_parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1081 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1082 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1083 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1084
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1085 sub merge_node_via_shared_ancestor {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1086 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1087 my $node = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1088
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1089 my $node_dup = $self->find_node_by_node_id($node->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1090 if($node_dup) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1091 #warn("trying to merge in a node with already exists\n");
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1092 return $node_dup;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1093 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1094 return undef unless($node->parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1095
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1096 my $ancestor = $self->find_node_by_node_id($node->parent->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1097 if($ancestor) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1098 $ancestor->add_child($node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1099 #print("common ancestor at : "); $ancestor->print_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1100 return $ancestor;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1101 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1102 return $self->merge_node_via_shared_ancestor($node->parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1103 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1104
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1105
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1106 sub extract_subtree_from_leaves {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1107 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1108 my $copy = $self->copy;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1109 my $node_ids = shift; # Array ref of node_ids.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1110 my @keepers = @{$node_ids};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1111 my @all = @{$copy->get_all_nodes};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1112
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1113 # Add all ancestors of kept nodes to the keep list.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1114 my @all_keepers = ();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1115 foreach my $keeper (@keepers) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1116 my $node = $copy->find_node_by_node_id($keeper);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1117 push @all_keepers, $keeper;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1118
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1119 my $parent = $node->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1120 while (defined $parent) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1121 push @all_keepers, $parent->node_id;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1122 $parent = $parent->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1123 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1124 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1125
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1126 my @remove_me = ();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1127 foreach my $node (@all) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1128 push @remove_me, $node unless (grep {$node->node_id == $_} @all_keepers);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1129 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1130 $copy->remove_nodes(\@remove_me);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1131 return $copy;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1132 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1133
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1134
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1135 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1136 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1137 # nested_set manipulations
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1138 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1139 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1140
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1141
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1142 =head2 flatten_tree
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1143
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1144 Overview : Removes all internal nodes and attaches leaves to the tree root, creating
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1145 a "flattened" star tree structure.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1146 Example : $node->flatten_tree();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1147 Returntype : undef or Bio::EnsEMBL::Compara::NestedSet
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1148 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1149 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1150
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1151 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1152
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1153 sub flatten_tree {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1154 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1155
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1156 my $leaves = $self->get_all_leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1157 foreach my $leaf (@{$leaves}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1158 $leaf->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1159 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1160
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1161 $self->release_children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1162 foreach my $leaf (@{$leaves}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1163 $self->add_child($leaf, 0.0);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1164 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1165
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1166 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1167 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1168
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1169 =head2 re_root
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1170
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1171 Overview : rearranges the tree structure so that the root is moved to
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1172 beetween this node and its parent. If the old root was more than
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1173 bifurcated (2 children) a new node is created where it was to hold
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1174 the multiple children that arises from the re-rooting.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1175 The old root is returned.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1176 Example : $node->re_root();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1177 Returntype : undef or Bio::EnsEMBL::Compara::NestedSet
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1178 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1179 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1180
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1181 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1182
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1183 sub re_root {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1184 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1185
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1186 return $self unless($self->parent); #I'm root so just return self
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1187
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1188 my $root = $self->root;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1189 my $tmp_root = new Bio::EnsEMBL::Compara::NestedSet;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1190 $tmp_root->merge_children($root);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1191
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1192 my $parent = $self->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1193 my $dist = $self->distance_to_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1194 $self->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1195
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1196 my $old_root = $parent->_invert_tree_above;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1197 $old_root->minimize_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1198
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1199 $root->add_child($parent, $dist / 2.0);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1200 $root->add_child($self, $dist / 2.0);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1201
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1202 return $root;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1203 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1204
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1205
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1206 sub _invert_tree_above {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1207 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1208 return $self unless($self->parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1209
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1210 my $old_root = $self->parent->_invert_tree_above;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1211 #now my parent has been inverted so it is the new root
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1212
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1213 #flip the direction of the link between myself and my parent
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1214 $self->parent->_set_parent_link($self->{'_parent_link'});
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1215 $self->_set_parent_link(undef);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1216
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1217 #now I'm the new root and the old root might need to be modified
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1218 return $old_root;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1219 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1220
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1221
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1222 sub build_leftright_indexing {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1223 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1224 my $counter = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1225
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1226 $counter = 1 unless($counter);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1227
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1228 $self->left_index($counter++);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1229 foreach my $child_node (@{$self->sorted_children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1230 $counter = $child_node->build_leftright_indexing($counter);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1231 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1232 $self->right_index($counter++);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1233 return $counter;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1234 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1235
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1236
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1237 =head2 remove_nodes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1238
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1239 Arg [1] : arrayref Bio::EnsEMBL::Compara::NestedSet $nodes
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1240 Example : my $ret_tree = $tree->remove_nodes($nodes);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1241 Description : Returns the tree with removed nodes in list. Nodes should be in the tree.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1242 Returntype : Bio::EnsEMBL::Compara::NestedSet object
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1243 Exceptions :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1244 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1245 Status : At risk (behaviour on exceptions could change)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1246
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1247 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1248
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1249 sub remove_nodes {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1250 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1251 my $nodes = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1252
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1253 foreach my $node (@$nodes) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1254 if ($node->is_leaf) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1255 $node->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1256 $self = $self->minimize_tree;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1257 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1258 my $node_children = $node->children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1259 foreach my $child (@$node_children) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1260 $node->parent->add_child($child);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1261 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1262 $node->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1263 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1264 # Delete dangling one-child trees (help memory manager)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1265 if ($self->get_child_count == 1) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1266 my $child = $self->children->[0];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1267 $child->parent->merge_children($child);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1268 $child->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1269 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1270 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1271 # Could be zero if all asked to delete, so return undef instead of
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1272 # fake one-node tree.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1273 if ($self->get_child_count < 2) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1274 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1275 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1276 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1277 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1278 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1279
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1280
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1281 =head2 delete_lineage
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1282
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1283 Arg [1] : Bio::EnsEMBL::Compara::NestedSet $node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1284 Example : $tree->delete_lineage($node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1285 Description : Removes $node from tree. Nodes should be in the tree.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1286 Returntype :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1287 Exceptions :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1288 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1289 Status : At risk (behaviour on exceptions could change)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1290
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1291 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1292
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1293 sub delete_lineage {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1294 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1295 my $del_me = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1296
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1297 throw("arg must be a [Bio::EnsEMBL::Compara::NestedSet] not a [$self]")
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1298 unless ($self->isa('Bio::EnsEMBL::Compara::NestedSet'));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1299
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1300 my $parent = $del_me->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1301 while ($parent) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1302 my $num_children = scalar @{$parent->children};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1303 if ($num_children > 1) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1304 $self->remove_nodes([$del_me]);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1305 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1306 } elsif ($num_children == 1) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1307 $self->remove_nodes([$del_me]);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1308 $del_me = $parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1309 $parent = $del_me->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1310 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1311 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1312 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1313 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1314
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1315 =head2 minimize_tree
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1316
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1317 Arg [1] : -none-
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1318 Example : $leaf->disavow_parent();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1319 $tree = $tree->minimize_tree();
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1320 Description : Returns the tree after removing internal nodes that do not
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1321 represent an multi- or bi-furcation anymore. This is typically
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1322 required after disavowing a node. Please ensure you use the
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1323 object returned by the method and not the original object
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1324 anymore!
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1325 Returntype : Bio::EnsEMBL::Compara::NestedSet object
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1326 Exceptions :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1327 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1328 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1329
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1330 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1331
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1332 sub minimize_tree {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1333 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1334 return $self if($self->is_leaf);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1335
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1336 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1337 $child->minimize_tree;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1338 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1339 return $self->minimize_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1340 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1341
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1342
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1343 sub minimize_node {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1344 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1345
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1346 return $self unless($self->get_child_count() == 1);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1347
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1348 my $child = $self->children->[0];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1349 my $dist = $child->distance_to_parent + $self->distance_to_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1350 if ($self->parent) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1351 $self->parent->add_child($child, $dist);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1352 $self->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1353 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1354 $child->disavow_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1355 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1356 return $child
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1357 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1358
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1359
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1360 sub scale {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1361 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1362 my $scale = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1363
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1364 foreach my $node (@{$self->get_all_nodes}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1365 my $bl = $node->distance_to_parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1366 $bl = 0 unless (defined $bl);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1367 $node->distance_to_parent($bl*$scale);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1368 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1369 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1370 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1371
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1372
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1373 sub scale_max_to {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1374 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1375 my $new_max = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1376
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1377 my $max_dist = $self->max_distance;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1378 my $scale_factor = $new_max / $max_dist;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1379 return $self->scale($scale_factor);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1380 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1381
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1382
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1383
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1384 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1385 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1386 # search methods
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1387 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1388 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1389
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1390 sub find_node_by_name {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1391 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1392 my $name = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1393
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1394 return $self if((defined $self->name) && $name eq $self->name);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1395
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1396 my $children = $self->children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1397 foreach my $child_node (@$children) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1398 my $found = $child_node->find_node_by_name($name);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1399 return $found if(defined($found));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1400 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1401
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1402 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1403 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1404
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1405 sub find_node_by_node_id {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1406 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1407 my $node_id = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1408
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1409 return $self if($node_id eq $self->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1410
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1411 my $children = $self->children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1412 foreach my $child_node (@$children) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1413 my $found = $child_node->find_node_by_node_id($node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1414 return $found if(defined($found));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1415 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1416
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1417 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1418 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1419
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1420 sub find_leaf_by_name {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1421 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1422 my $name = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1423
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1424 return $self if((defined $self->name) and ($name eq $self->name));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1425
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1426 my $leaves = $self->get_all_leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1427 foreach my $leaf (@$leaves) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1428 return $leaf if((defined $leaf->name) and ($name eq $leaf->name));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1429 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1430
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1431 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1432 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1433
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1434 sub find_leaf_by_node_id {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1435 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1436 my $node_id = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1437
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1438 return $self if($node_id eq $self->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1439
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1440 my $leaves = $self->get_all_leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1441 foreach my $leaf (@$leaves) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1442 return $leaf if($node_id eq $leaf->node_id);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1443 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1444
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1445 return undef;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1446 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1447
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1448
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1449 =head2 get_all_sorted_leaves
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1450
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1451 Arg [1] : Bio::EnsEMBL::Compara::NestedSet $top_leaf
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1452 Arg [...] : (optional) Bio::EnsEMBL::Compara::NestedSet $secondary_priority_leaf
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1453 Example : my $sorted_leaves = $object->get_all_sorted_leaves($human_leaf);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1454 Example : my $sorted_leaves = $object->get_all_sorted_leaves($human_leaf, $mouse_leaf);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1455 Description : Sorts the tree such as $top_leaf is the first leave and returns
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1456 all the other leaves in the order defined by the tree.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1457 It is possible to define as many secondary top leaves as you require
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1458 to sort other branches of the tree. The priority to sort the trees
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1459 is defined by the order in which you specify the leaves.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1460 Returntype : listref of Bio::EnsEMBL::Compara::NestedSet (all sorted leaves)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1461 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1462 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1463 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1464
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1465 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1466
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1467 sub get_all_sorted_leaves {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1468 my ($self, @priority_leaves) = @_;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1469
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1470 if (!@priority_leaves) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1471 return $self->get_all_leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1472 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1473
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1474 # Assign priority scores for all parent nodes of the priority leaves
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1475 my $score_by_node;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1476 my $score = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1477 # Loop through all the priority leaves, starting from the last one (lowest score)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1478 while (my $priority_leaf = pop @priority_leaves) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1479 $score++; # Increases the score, next priority leaves (earlier in the argument list) will overwrite the score if needed
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1480 my $this_node = $priority_leaf;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1481 # Loop through all the parent node up to the root of the tree
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1482 do {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1483 $score_by_node->{$this_node} = $score;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1484 $this_node = $this_node->parent;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1485 } while ($this_node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1486 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1487
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1488 my $sorted_leaves = $self->_recursive_get_all_sorted_leaves($score_by_node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1489
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1490 return $sorted_leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1491 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1492
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1493 =head2 _recursive_get_all_sorted_leaves
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1494
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1495 Arg [1] : hashref $score_by_node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1496 Example : my $sorted_leaves = $object->_recursive_get_all_sorted_leaves($score_by_node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1497 Description : Recursive code for the get_all_sorted_leaves() method
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1498 Returntype : listref of Bio::EnsEMBL::Compara::NestedSet (sorted leaves)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1499 Exceptions : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1500 Caller : private
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1501 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1502
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1503 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1504
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1505 sub _recursive_get_all_sorted_leaves {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1506 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1507 my $score_by_node = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1508
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1509 my $sorted_leaves = [];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1510 my $children = $self->children;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1511
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1512 if (@$children == 0) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1513 $sorted_leaves = [$self];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1514 } else {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1515 $children = [sort {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1516 ($score_by_node->{$b} || $score_by_node->{$a}) ? (($score_by_node->{$b} || 0)<=>($score_by_node->{$a} || 0)) : ($a->node_id <=> $b->node_id)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1517 } @$children];
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1518 for (my $i = 0; $i < @$children; $i++) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1519 push(@$sorted_leaves, @{$children->[$i]->_recursive_get_all_sorted_leaves($score_by_node)});
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1520 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1521 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1522
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1523 return $sorted_leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1524 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1525
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1526 =head2 get_all_leaves
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1527
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1528 Title : get_all_leaves
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1529 Usage : my @leaves = @{$tree->get_all_leaves};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1530 Function: searching from the given starting node, searches and creates list
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1531 of all leaves in this subtree and returns by reference
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1532 Example :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1533 Returns : reference to list of NestedSet objects (all leaves)
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1534 Args : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1535
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1536 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1537
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1538 sub get_all_leaves {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1539 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1540
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1541 my $leaves = {};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1542 $self->_recursive_get_all_leaves($leaves);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1543 my @leaf_list = sort {$a->node_id <=> $b->node_id} values(%{$leaves});
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1544 return \@leaf_list;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1545 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1546
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1547 sub _recursive_get_all_leaves {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1548 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1549 my $leaves = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1550
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1551 $leaves->{$self->obj_id} = $self if($self->is_leaf);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1552
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1553 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1554 no warnings 'recursion';
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1555 $child->_recursive_get_all_leaves($leaves);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1556 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1557 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1558
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1559
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1560 sub get_all_leaves_indexed {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1561 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1562 deprecate("Use Bio::EnsEMBL::Compara::DBSQL::GeneTreeNodeAdaptor->fetch_all_leaves_indexed() method instead");
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1563
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1564 my @leaf_list = @{$self->adaptor->fetch_all_leaves_indexed($self)};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1565
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1566 return \@leaf_list;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1567 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1568
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1569 =head2 max_distance
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1570
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1571 Title : max_distance
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1572 Args : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1573 Usage : $tree_node->max_distance;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1574 Function: searching from the given starting node, calculates the maximum distance to a leaf
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1575 Returns : int
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1576
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1577 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1578
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1579 sub max_distance {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1580 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1581
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1582 my $max_distance = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1583
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1584 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1585 my $distance = $child->max_distance;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1586 $max_distance = $distance if($distance>$max_distance);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1587 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1588
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1589 return ($self->distance_to_parent + $max_distance);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1590 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1591
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1592
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1593 =head2 max_depth
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1594
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1595 Title : max_depth
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1596 Args : none
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1597 Usage : $tree_node->max_depth;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1598 Function: searching from the given starting node, calculates the maximum depth to a leaf
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1599 Returns : int
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1600
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1601 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1602
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1603 sub max_depth {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1604 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1605
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1606 my $max_depth = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1607
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1608 foreach my $child (@{$self->children}) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1609 my $depth = $child->max_depth + 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1610 $max_depth=$depth if($depth>$max_depth);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1611 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1612 return $max_depth;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1613 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1614
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1615
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1616 =head2 find_first_shared_ancestor
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1617
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1618 Arg [1] : Bio::EnsEMBL::Compara::NestedSet $node
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1619 Example : my $ancestor = $this_node->find_first_shared_ancestor($other_node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1620 Description : Gets the first common ancestor between this node and the other one.
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1621 Returntype : Bio::EnsEMBL::Compara::NestedSet object
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1622 Exceptions :
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1623 Caller : general
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1624 Status : Stable
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1625
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1626 =cut
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1627
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1628 sub find_first_shared_ancestor {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1629 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1630 my $node = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1631
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1632 return $self if($self->equals($node));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1633 return $node if($self->has_ancestor($node));
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1634 return $self->find_first_shared_ancestor($node->parent);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1635 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1636
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1637
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1638 sub find_first_shared_ancestor_from_leaves {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1639 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1640 my $leaf_list = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1641
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1642 my @leaves = @{$leaf_list};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1643
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1644 my $ancestor = shift @leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1645 while (scalar @leaves > 0) {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1646 my $node = shift @leaves;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1647 $ancestor = $ancestor->find_first_shared_ancestor($node);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1648 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1649 return $ancestor;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1650 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1651
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1652
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1653 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1654 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1655 # developer/adaptor API methods
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1656 #
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1657 ##################################
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1658
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1659
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1660 # used for building tree from a DB fetch, want to restrict users to create trees
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1661 # by only -add_child method
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1662 sub _set_parent_link {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1663 my ($self, $link) = @_;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1664
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1665 $self->{'_parent_id'} = 0;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1666 $self->{'_parent_link'} = $link;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1667 $self->{'_parent_id'} = $link->get_neighbor($self)->node_id if($link);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1668 return $self;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1669 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1670
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1671
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1672 # used for building tree from a DB fetch until all the objects are in memory
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1673 sub _parent_id {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1674 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1675 $self->{'_parent_id'} = shift if(@_);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1676 return $self->{'_parent_id'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1677 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1678
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1679 # used for building tree from a DB fetch until all the objects are in memory
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1680 sub _root_id {
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1681 my $self = shift;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1682 $self->{'_root_id'} = shift if(@_);
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1683 return $self->{'_root_id'};
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1684 }
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1685
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1686 1;
21066c0abaf5 Uploaded
willmclaren
parents:
diff changeset
1687