Class: Bio::NeXML::Tree

Inherits:
Tree
  • Object
show all
Includes:
Mapper
Defined in:
lib/bio/db/nexml/trees.rb

Overview

An NeXML tree. A tree must have a unique ‘id’. It may optionally take a ‘label’ and a ‘rootedge’. This class inherits from Bio::Tree; naturally its functionality is leveraged here.

Direct Known Subclasses

FloatTree, IntTree, Network

Constant Summary collapse

@@writer =
Bio::NeXML::Writer.new

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mapper

#properties

Constructor Details

#initialize(id = nil, options = {}, &block) ⇒ Tree

Create a new tree.

tree = Bio::NeXML::Tree.new( 'tree1' )
tree = Bio::NeXML::Tree.new( 'tree1', :label => 'A tree' )

nodes = %w|node1 node2 node3|.map{ |n| Bio::NeXML::Node.new( n ) }                
edge1 = Bio::NeXML::Edge.new( 'edge1', :source => nodes[0], :target => nodes[1] )
edge2 = Bio::NeXML::Edge.new( 'edge2', :source => nodes[0], :target => nodes[2] )

tree = Bio::NeXML::Tree.new( 'tree1', :nodes => nodes )
tree = Bio::NeXML::Tree.new do |t|                                        
         t.label = 'A tree'
         t.nodes = nodes
         t.edges = [ edge1, edge2 ]
         # or, t << edge1 << edge2
         # or, t.add_edge( edge1 ); t.add_edge( edge2 )

         root = Bio::NeXML::Node.new( 'root1', :root => true )
         rootedge = Bio::NeXML::RootEdge.new( 're1', :target => root )

         t << root # or, t.add_otu( root )
         t.rootedge = rootedge
       end


233
234
235
236
237
238
# File 'lib/bio/db/nexml/trees.rb', line 233

def initialize( id = nil, options = {}, &block )
  super()
  @id = id
  properties( options ) unless options.empty?
  block.arity < 1 ? instance_eval( &block ) : block.call( self ) if block_given?
end

Instance Attribute Details

#idObject

A file level unique identifier.



194
195
196
# File 'lib/bio/db/nexml/trees.rb', line 194

def id
  @id
end

#labelObject

A human readable description.



197
198
199
# File 'lib/bio/db/nexml/trees.rb', line 197

def label
  @label
end

#rootedgeObject

A rootedge to indicate a time span leading up to the root.



200
201
202
# File 'lib/bio/db/nexml/trees.rb', line 200

def rootedge
  @rootedge
end

Instance Method Details

#<<(object) ⇒ Object

Append a node or an edge to the tree. The method delegates the actuall addition to add_node, add_edge methods.



247
248
249
250
251
252
253
254
255
# File 'lib/bio/db/nexml/trees.rb', line 247

def <<( object )
  case object
  when Node
    add_node( object )
  when Edge
    add_edge( object )
  end
  self
end

#[](id) ⇒ Object

Fetch a node, or an edge by its id.



317
318
319
320
# File 'lib/bio/db/nexml/trees.rb', line 317

def []( id )
  get_node_by_id( id ) ||
    get_edge_by_id( id )
end

#__add_edge__Object

:stopdoc:



267
# File 'lib/bio/db/nexml/trees.rb', line 267

alias __add_edge__ add_edge

#__add_node__Object

:stopdoc:



258
# File 'lib/bio/db/nexml/trees.rb', line 258

alias __add_node__ add_node

#add_edge(edge) ⇒ Object

:startdoc: Add an edge to the tree.



270
271
272
273
# File 'lib/bio/db/nexml/trees.rb', line 270

def add_edge( edge )
  super( edge.source, edge.target, edge )
  __add_edge__( edge )
end

#add_node(node) ⇒ Object

:startdoc: Add a node to the tree.



261
262
263
264
# File 'lib/bio/db/nexml/trees.rb', line 261

def add_node( node )
  super( node )
  __add_node__( node )
end

#add_rootedge(edge) ⇒ Object



275
276
277
# File 'lib/bio/db/nexml/trees.rb', line 275

def add_rootedge( edge )
  @rootedge = edge
end

#ancestors(node, *root) ⇒ Object



414
415
416
417
418
419
420
421
422
423
424
# File 'lib/bio/db/nexml/trees.rb', line 414

def ancestors( node, *root )
  if root.empty?
    raise IndexError, 'can not get parent for unrooted tree' if self.root.empty?
    root = self.root
  end
  ancestor = {}
  root.each do |r|
    ancestor[ r ] = super( node, r )
  end
  ancestor
end

#children(node, *root) ⇒ Object



375
376
377
378
379
380
381
382
383
384
385
386
387
388
# File 'lib/bio/db/nexml/trees.rb', line 375

def children( node, *root )
  if root.empty?
    raise IndexError, 'can not get parent for unrooted tree' if self.root.empty?
    root = self.root
  end
  childrens = {}
  root.each do |r|
    c = adjacent_nodes(node)
    c.delete(parent(node, r)[ r ])
    childrens[ r ] = c
  end

  childrens
end

#create_edge(options = {}) ⇒ Object



185
186
187
# File 'lib/bio/db/nexml/trees.rb', line 185

def create_edge( options = {} )
  raise "This is supposed to be an abstract method"
end

#create_node(options = {}) ⇒ Object



179
180
181
182
183
# File 'lib/bio/db/nexml/trees.rb', line 179

def create_node( options = {} )
  node = Node.new( Bio::NeXML.generate_id( Node ), options )
  self << node
  node        
end

#create_rootedge(options = {}) ⇒ Object



189
190
191
# File 'lib/bio/db/nexml/trees.rb', line 189

def create_rootedge( options = {} )
  raise "This is supposed to be an abstract method"
end

#descendents(node, *root) ⇒ Object



390
391
392
393
394
395
396
397
398
399
400
# File 'lib/bio/db/nexml/trees.rb', line 390

def descendents( node, *root )
  if root.empty?
    raise IndexError, 'can not get parent for unrooted tree' if self.root.empty?
    root = self.root
  end
  descendent = {}
  root.each do |r|
    descendent[ r ] = super( node, r )
  end
  descendent
end

#each_node(&block) ⇒ Object

Iterate over each node. Return an Enumerator if no block is given.



336
# File 'lib/bio/db/nexml/trees.rb', line 336

def each_node( &block ); end

#get_edge_by_id(id) ⇒ Object

Fetch an edge by the given id.



314
# File 'lib/bio/db/nexml/trees.rb', line 314

def get_edge_by_id( id ); end

#get_node_by_id(id) ⇒ Object Also known as: get_node_by_name

Fetch a node by the given id.



307
# File 'lib/bio/db/nexml/trees.rb', line 307

def get_node_by_id( id ); end

#has_edge?(edge) ⇒ Boolean

Returns true if the given edge is a part of self.

Returns:

  • (Boolean)


326
# File 'lib/bio/db/nexml/trees.rb', line 326

def has_edge?( edge ); end

#has_node?(node) ⇒ Boolean

Returns true if the given node is a part of self.

Returns:

  • (Boolean)


323
# File 'lib/bio/db/nexml/trees.rb', line 323

def has_node?( node ); end

#include?(object) ⇒ Boolean Also known as: has?

Returns true if the given node or the edge object is a part of this tree; false otherwise.

Returns:

  • (Boolean)


329
330
331
332
# File 'lib/bio/db/nexml/trees.rb', line 329

def include?( object )
  has_node?( object ) ||
    has_edge?( object )
end

#lowest_common_ancestor(node1, node2, *root) ⇒ Object



402
403
404
405
406
407
408
409
410
411
412
# File 'lib/bio/db/nexml/trees.rb', line 402

def lowest_common_ancestor( node1, node2, *root )
  if root.empty?
    raise IndexError, 'can not get parent for unrooted tree' if self.root.empty?
    root = self.root
  end
  lca = {}
  root.each do |r|
    lca[ r ] = super( node1, node2, r )
  end
  lca
end

#parent(node, *roots) ⇒ Object

Returns the parent of the given node corresponding to each root.



363
364
365
366
367
368
369
370
371
372
373
# File 'lib/bio/db/nexml/trees.rb', line 363

def parent( node, *roots )
  if roots.empty?
    raise IndexError, 'can not get parent for unrooted tree' if self.roots.empty?
    roots = self.roots
  end
  parents = {}
  roots.each do |r|
    parents[ r ] = super( node, r )
  end
  parents
end

#remove_edge(edge) ⇒ Object Also known as: delete_edge

Remove an edge from the tree. Returns the edge deleted. If more than one edge exists between the source and the target, both of them will be removed. Raises IndexError if the edge is not found in the tree.



299
300
301
302
303
# File 'lib/bio/db/nexml/trees.rb', line 299

def remove_edge( edge )
  return unless include?( edge )
  super( edge.source, edge.target )
  __delete_edge__( edge )
end

#remove_node(node) ⇒ Object Also known as: delete_node

Remove a node from the tree. Returns the deleted node. It automatically removes all edges connected to that node. Raises IndexError if the node is not found in the tree.



285
286
287
288
289
# File 'lib/bio/db/nexml/trees.rb', line 285

def remove_node( node )
  return unless include?( node )
  super( node )
  __delete_node__( node )
end

#rootsObject

Returns an array of root nodes.



241
242
243
# File 'lib/bio/db/nexml/trees.rb', line 241

def roots
  nodes.select{ |n| n.root? }
end

#to_xmlObject



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/bio/db/nexml/trees.rb', line 162

def to_xml
  node = @@writer.create_node( "tree", @@writer.attributes( self, :id, :'xsi:type', :label ) )

  self.each_node do |n|
    node << n.to_xml
  end

  rootedge = self.rootedge
  node << rootedge.to_xml if rootedge

  self.each_edge do |edge|
    node << edge.to_xml
  end

  node
end