~ubuntu-branches/ubuntu/trusty/bioperl/trusty-proposed

« back to all changes in this revision

Viewing changes to Bio/Tree/TreeFunctionsI.pm

  • Committer: Bazaar Package Importer
  • Author(s): Charles Plessy
  • Date: 2009-03-10 07:19:11 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090310071911-fukqzw54pyb1f0bd
Tags: 1.6.0-2
* Removed patch system (not used):
  - removed instuctions in debian/rules;
  - removed quilt from Build-Depends in debian/control.
* Re-enabled tests:
  - uncommented test command in debian/rules;
  - uncommented previously missing build-dependencies in debian/control.
  - Re-enabled tests and uncommented build-dependencies accordingly.
* Removed libmodule-build-perl and libtest-harness-perl from
  Build-Depends-Indep (provided by perl-modules).
* Better cleaning of empty directories using find -type d -empty -delete
  instead of rmdir in debian/rules (LP: #324001).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# $Id: TreeFunctionsI.pm,v 1.28.2.1 2006/10/02 23:10:37 sendu Exp $
 
1
# $Id: TreeFunctionsI.pm 14904 2008-09-19 16:17:32Z heikki $
2
2
#
3
3
# BioPerl module for Bio::Tree::TreeFunctionsI
4
4
#
5
 
# Cared for by Jason Stajich <jason@bioperl.org>
 
5
# Cared for by Jason Stajich <jason-at-bioperl-dot-org>
6
6
#
7
7
# Copyright Jason Stajich
8
8
#
17
17
=head1 SYNOPSIS
18
18
 
19
19
  use Bio::TreeIO;
20
 
  my $in = new Bio::TreeIO(-format => 'newick', -file => 'tree.tre');
 
20
  my $in = Bio::TreeIO->new(-format => 'newick', -file => 'tree.tre');
21
21
 
22
22
  my $tree = $in->next_tree;
23
23
 
78
78
package Bio::Tree::TreeFunctionsI;
79
79
use strict;
80
80
 
 
81
use UNIVERSAL qw(isa);
 
82
 
81
83
use base qw(Bio::Tree::TreeI);
82
84
 
83
85
=head2 find_node
115
117
 
116
118
   # could actually do this by testing $rootnode->can($type) but
117
119
   # it is possible that a tree is implemeted with different node types
118
 
   # - although it is unlikely that the root node would be richer than the 
 
120
   # - although it is unlikely that the root node would be richer than the
119
121
   # leaf nodes.  Can't handle NHX tags right now
120
 
    
 
122
 
121
123
   my @nodes = grep { $_->can($type) && defined $_->$type() &&
122
124
                     $_->$type() eq $field } $self->get_nodes();
123
125
 
184
186
    else { 
185
187
        $node = $input;
186
188
    }
187
 
    
 
189
 
188
190
    # when dealing with Bio::Taxon objects with databases, the root will always
189
191
    # be the database's root, ignoring this Tree's set root node; prefer the
190
192
    # Tree's idea of root.
191
193
    my $root = $self->get_root_node || '';
192
 
    
 
194
 
193
195
    my @lineage;
194
196
    while ($node) {
195
197
        $node = $node->ancestor || last;
229
231
sub splice {
230
232
    my ($self, @args) = @_;
231
233
    $self->throw("Must supply some arguments") unless @args > 0;
232
 
    
 
234
 
233
235
    my @nodes_to_remove;
234
236
    if (ref($args[0])) {
235
237
        $self->throw("When supplying just a list of Nodes, they must be Bio::Tree::NodeI objects") unless $args[0]->isa('Bio::Tree::NodeI');
243
245
        my $remove_all = 1;
244
246
        while (my ($key, $value) = each %args) {
245
247
            my @values = ref($value) ? @{$value} : ($value);
246
 
            
 
248
 
247
249
            if ($key =~ s/remove_//) {
248
250
                $remove_all = 0;
249
251
                foreach my $value (@values) {
256
258
                }
257
259
            }
258
260
        }
259
 
        
 
261
 
260
262
        if ($remove_all) {
261
263
            if (@keep_nodes == 0) {
262
264
                $self->warn("Requested to remove everything except certain nodes, but those nodes were not found; doing nothing instead");
263
265
                return;
264
266
            }
265
 
            
 
267
 
266
268
            @remove_nodes = $self->get_nodes;
267
269
        }
268
 
        
269
270
        if (@keep_nodes > 0) {
270
271
            my %keep_iids = map { $_->internal_id => 1 } @keep_nodes;
271
272
            foreach my $node (@remove_nodes) {
276
277
            @nodes_to_remove = @remove_nodes;
277
278
        }
278
279
    }
279
 
    
280
280
    # do the splicing
281
281
    #*** the algorithm here hasn't really been thought through and tested much,
282
282
    #    will probably need revising
284
284
    my $reroot = 0;
285
285
    foreach my $node (@nodes_to_remove) {
286
286
        my @descs = $node->each_Descendent;
287
 
        
288
287
        my $ancestor = $node->ancestor;
289
288
        if (! $ancestor && ! $reroot) {
290
289
            # we're going to remove the tree root, so will have to re-root the
294
293
            $node->remove_all_Descendents;
295
294
            next;
296
295
        }
297
 
        
298
296
        if (exists $root_descs{$node->internal_id}) {
299
297
            # well, this one can't be the future root anymore
300
298
            delete $root_descs{$node->internal_id};
301
 
            
302
299
            # but maybe one of this one's descs will become the root
303
300
            foreach my $desc (@descs) {
304
301
                $root_descs{$desc->internal_id} = $desc;
305
302
            }
306
303
        }
307
 
        
308
304
        # make the ancestor of our descendents our own ancestor, and give us
309
305
        # no ancestor of our own to remove us from the tree
310
306
        foreach my $desc (@descs) {
312
308
        }
313
309
        $node->ancestor(undef);
314
310
    }
315
 
    
316
311
    if ($reroot) {
317
312
        my @candidates = values %root_descs;
318
313
        $self->throw("After splicing, there was no tree root!") unless @candidates > 0;
328
323
           get_lca(@nodes);
329
324
 Function: given two or more nodes, returns the lowest common ancestor (aka most
330
325
           recent common ancestor)
331
 
 Returns : node object or undef if there is no commen ancestor
 
326
 Returns : node object or undef if there is no common ancestor
332
327
 Args    : -nodes => arrayref of nodes to test, OR
333
328
           just a list of nodes
334
329
 
345
340
        @nodes = @args;
346
341
    }
347
342
    @nodes >= 2 or $self->throw("At least 2 nodes are required");
348
 
    
349
343
    # We must go root->leaf to get the correct answer to lca (in a world where
350
344
    # internal_id might not be uniquely assigned), but leaf->root is more
351
345
    # forgiving (eg. lineages may not all have the same root, or they may have
354
348
    # I use root->leaf so that we can easily do multiple nodes at once - no
355
349
    # matter what taxa are below the lca, the lca and all its ancestors ought to
356
350
    # be identical.
357
 
    
358
351
    my @paths;
359
352
    foreach my $node (@nodes) {
 
353
        unless(ref($node) && $node->isa('Bio::Tree::NodeI')) {
 
354
            $self->throw("Cannot process get_lca() with a non-NodeI object ($node)\n");
 
355
        }
360
356
        my @path = ($self->get_lineage_nodes($node), $node);
361
357
        push(@paths, \@path);
362
358
    }
363
359
    return unless @paths >= 2;
364
 
    
365
360
    my $lca;
366
361
    LEVEL: while ($paths[0] > 0) {
367
362
        my %node_ids;
375
370
            }
376
371
            $node_ids{$node_id}++;
377
372
        }
378
 
        
379
373
        if (keys %node_ids == 1) {
380
374
            $lca = $node;
381
375
        }
385
379
            last LEVEL;
386
380
        }
387
381
    }
388
 
    
389
382
    # If the tree that we are contains the lca (get_lca could have been called
390
383
    # on an empty tree, since it works with plain Nodes), prefer to return the
391
384
    # node object that belongs to us
393
386
        my $own_lca = $self->find_node(-internal_id => $lca->internal_id);
394
387
        $lca = $own_lca if $own_lca;
395
388
    }
396
 
    
397
389
    return $lca;
398
390
}
399
391
 
431
423
sub merge_lineage {
432
424
    my ($self, $thing) = @_;
433
425
    $self->throw("Must supply an object reference") unless ref($thing);
434
 
    
 
426
 
435
427
    my ($lineage_tree, $lineage_leaf);
436
428
    if ($thing->isa('Bio::Tree::TreeI')) {
437
429
        my @leaves = $thing->get_leaf_nodes;
444
436
        $lineage_tree = $self->new(-node => $thing);
445
437
        $lineage_leaf = $thing;
446
438
    }
447
 
    
448
 
    # get the lca of this node and every leaf of the main tree until we find
449
 
    # the branch that isn't in the main tree yet
450
 
    my ($main_tree_lca, $new_branch_base);
451
 
    foreach my $leaf ($self->get_leaf_nodes) {
452
 
        $main_tree_lca = $self->get_lca($lineage_leaf, $leaf) || ($self->warn("couldn't get the lca of nodes ".$lineage_leaf->id." and ".$leaf->id."!") && next);
453
 
        
454
 
        my $branch_lca = $lineage_tree->find_node(-internal_id => $main_tree_lca->internal_id);
455
 
        ($new_branch_base) = $branch_lca->each_Descendent;
456
 
        if ($new_branch_base) {
457
 
            if ($self->find_node(-internal_id => $new_branch_base->internal_id)) {
458
 
                # this branch is already in the main tree, try again
459
 
                $new_branch_base = undef;
460
 
                next;
461
 
            }
462
 
            else {
463
 
                last;
464
 
            }
465
 
        }
466
 
        else {
467
 
            # the lca is the lineage leaf itself, nothing for us to merge
 
439
 
 
440
    # see if any node in the supplied lineage is in our tree - that will be
 
441
    # our lca and we can merge at the node below
 
442
    my @lineage = ($lineage_leaf, reverse($self->get_lineage_nodes($lineage_leaf)));
 
443
    my $merged = 0;
 
444
    for my $i (0..$#lineage) {
 
445
        my $lca = $self->find_node(-internal_id => $lineage[$i]->internal_id) || next;
 
446
 
 
447
        if ($i == 0) {
 
448
            # the supplied thing to merge is already in the tree, nothing to do
468
449
            return;
469
450
        }
 
451
        # $i is the lca, so the previous node is new to the tree and should
 
452
        # be merged on
 
453
        $lca->add_Descendent($lineage[$i-1]);
 
454
        $merged = 1;
 
455
        last;
470
456
    }
471
 
    $new_branch_base || ($self->warn("couldn't merge the lineage of ".$lineage_leaf->id." with the rest of the tree!\n") && return);
472
 
    $main_tree_lca->add_Descendent($new_branch_base);
 
457
    $merged || ($self->warn("Couldn't merge the lineage of ".$lineage_leaf->id." with the rest of the tree!\n") && return);
473
458
}
474
459
 
475
460
=head2 contract_linear_paths
479
464
 Function: Splices out all nodes in the tree that have an ancestor and only one
480
465
           descendent.
481
466
 Returns : n/a
482
 
 Args    : none
 
467
 Args    : none for normal behaviour, true to dis-regard the ancestor requirment
 
468
           and re-root the tree as necessary
483
469
 
484
470
 For example, if we are the tree $tree:
485
471
 
497
483
     |
498
484
     +---F
499
485
 
 
486
 Instead, $tree->contract_linear_paths(1) would have given:
 
487
 
 
488
 +---E
 
489
 |
 
490
 D
 
491
 |
 
492
 +---F
 
493
 
500
494
=cut
501
495
 
502
496
sub contract_linear_paths {
503
497
    my $self = shift;
 
498
    my $reroot = shift;
504
499
    my @remove;
505
500
    foreach my $node ($self->get_nodes) {
506
501
        if ($node->ancestor && $node->each_Descendent == 1) {
508
503
        }
509
504
    }
510
505
    $self->splice(@remove) if @remove;
 
506
    if ($reroot) {
 
507
        my $root = $self->get_root_node;
 
508
        my @descs = $root->each_Descendent;
 
509
        if (@descs == 1) {
 
510
            my $new_root = shift(@descs);
 
511
            $self->set_root_node($new_root);
 
512
            $new_root->ancestor(undef);
 
513
        }
 
514
    }
 
515
}
 
516
 
 
517
=head2 is_binary
 
518
 
 
519
  Example    : is_binary(); is_binary($node);
 
520
  Description: Finds if the tree or subtree defined by
 
521
               the internal node is a true binary tree
 
522
               without polytomies
 
523
  Returns    : boolean
 
524
  Exceptions : 
 
525
  Args       : Internal node Bio::Tree::NodeI, optional
 
526
 
 
527
 
 
528
=cut
 
529
 
 
530
sub is_binary;
 
531
 
 
532
sub is_binary {
 
533
    my $self = shift;
 
534
    my $node = shift || $self->get_root_node;
 
535
 
 
536
    my $binary = 1;
 
537
    my @descs = $node->each_Descendent;
 
538
    $binary = 0 unless @descs == 2 or @descs == 0;
 
539
    #print "$binary, ", scalar @descs, "\n";
 
540
 
 
541
    # recurse
 
542
    foreach my $desc (@descs) {
 
543
        $binary += $self->is_binary($desc) -1;
 
544
    }
 
545
    $binary = 0 if $binary < 0;
 
546
    return $binary;
 
547
}
 
548
 
 
549
 
 
550
=head2 force_binary
 
551
 
 
552
 Title   : force_binary
 
553
 Usage   : force_binary()
 
554
 Function: Forces the tree into a binary tree, splitting branches arbitrarily
 
555
           and creating extra nodes as necessary, such that all nodes have
 
556
           exactly two or zero descendants.
 
557
 Returns : n/a
 
558
 Args    : none
 
559
 
 
560
 For example, if we are the tree $tree:
 
561
 
 
562
 +---G
 
563
 |
 
564
 +---F
 
565
 |
 
566
 +---E
 
567
 |
 
568
 A
 
569
 |
 
570
 +---D
 
571
 |
 
572
 +---C
 
573
 |
 
574
 +---B
 
575
 
 
576
 (A has 6 descendants B-G)
 
577
 
 
578
 After calling $tree->force_binary(), $tree looks like:
 
579
 
 
580
         +---X
 
581
         |
 
582
     +---X
 
583
     |   |
 
584
     |   +---X
 
585
     |
 
586
 +---X
 
587
 |   |
 
588
 |   |   +---G
 
589
 |   |   |
 
590
 |   +---X
 
591
 |       |
 
592
 |       +---F
 
593
 A
 
594
 |       +---E
 
595
 |       |
 
596
 |   +---X
 
597
 |   |   |
 
598
 |   |   +---D
 
599
 |   |
 
600
 +---X
 
601
     |
 
602
     |   +---C
 
603
     |   |
 
604
     +---X
 
605
         |
 
606
         +---B
 
607
 
 
608
 (Where X are artificially created nodes with ids 'artificial_n', where n is
 
609
 an integer making the id unique within the tree)
 
610
 
 
611
=cut
 
612
 
 
613
sub force_binary {
 
614
    my $self = shift;
 
615
    my $node = shift || $self->get_root_node;
 
616
 
 
617
    my @descs = $node->each_Descendent;
 
618
    if (@descs > 2) {
 
619
        $self->warn("Node ".($node->can('node_name') ? ($node->node_name || $node->id) : $node->id).
 
620
                    " has more than two descendants\n(".
 
621
                    join(", ", map { $node->can('node_name') ? ($node->node_name || $node->id) : $node->id } @descs).
 
622
                    ")\nWill do an arbitrary balanced split");
 
623
        my @working = @descs;
 
624
        # create an even set of artifical nodes on which to later hang the descs
 
625
        my $half = @working / 2;
 
626
        $half++ if $half > int($half);
 
627
        $half = int($half);
 
628
        my @artificials;
 
629
        while ($half > 1) {
 
630
            my @this_level;
 
631
            foreach my $top_node (@artificials || $node) {
 
632
                for (1..2) {
 
633
                    my $art = $top_node->new(-id => "artificial_".++$self->{_art_num});
 
634
                    $top_node->add_Descendent($art);
 
635
                    push(@this_level, $art);
 
636
                }
 
637
            }
 
638
            @artificials = @this_level;
 
639
            $half--;
 
640
        }
 
641
        # attach two descs to each artifical leaf
 
642
        foreach my $art (@artificials) {
 
643
            for (1..2) {
 
644
                my $desc = shift(@working) || $node->new(-id => "artificial_".++$self->{_art_num});
 
645
                $desc->ancestor($art);
 
646
            }
 
647
        }
 
648
    }
 
649
    elsif (@descs == 1) {
 
650
        # ensure that all nodes have 2 descs
 
651
        $node->add_Descendent($node->new(-id => "artificial_".++$self->{_art_num}));
 
652
    }
 
653
    # recurse
 
654
    foreach my $desc (@descs) {
 
655
        $self->force_binary($desc);
 
656
    }
 
657
}
 
658
 
 
659
=head2 simplify_to_leaves_string
 
660
 
 
661
 Title   : simplify_to_leaves_string
 
662
 Usage   : my $leaves_string = $tree->simplify_to_leaves_string()
 
663
 Function: Creates a simple textual representation of the relationship between
 
664
           leaves in self. It forces the tree to be binary, so the result may
 
665
           not strictly correspond to the tree (if the tree wasn't binary), but
 
666
           will be as close as possible. The tree object is not altered. Only
 
667
           leaf node ids are output, in a newick-like format.
 
668
 Returns : string
 
669
 Args    : none
 
670
 
 
671
=cut
 
672
 
 
673
sub simplify_to_leaves_string {
 
674
    my $self = shift;
 
675
 
 
676
    # Before contracting and forcing binary we need to clone self, but Clone.pm
 
677
    # clone() seg faults and fails to make the clone, whilst Storable dclone
 
678
    # needs $self->{_root_cleanup_methods} deleted (code ref) and seg faults at
 
679
    # end of script. Let's make our own clone...
 
680
    my $tree = $self->_clone;
 
681
 
 
682
    $tree->contract_linear_paths(1);
 
683
    $tree->force_binary;
 
684
    foreach my $node ($tree->get_nodes) {
 
685
        my $id = $node->id;
 
686
        $id = ($node->is_Leaf && $id !~ /^artificial/) ? $id : '';
 
687
        $node->id($id);
 
688
    }
 
689
 
 
690
    my %paired;
 
691
    my @data = $self->_simplify_helper($tree->get_root_node, \%paired);
 
692
 
 
693
    return join(',', @data);
 
694
}
 
695
 
 
696
# safe tree clone that doesn't seg fault
 
697
sub _clone {
 
698
    my ($self, $parent, $parent_clone) = @_;
 
699
    $parent ||= $self->get_root_node;
 
700
    $parent_clone ||= $self->_clone_node($parent);
 
701
 
 
702
    foreach my $node ($parent->each_Descendent()) {
 
703
        my $child = $self->_clone_node($node);
 
704
        $child->ancestor($parent_clone);
 
705
        $self->_clone($node, $child);
 
706
    }
 
707
    $parent->ancestor && return;
 
708
 
 
709
    my $tree = $self->new(-root => $parent_clone);
 
710
    return $tree;
 
711
}
 
712
 
 
713
# safe node clone that doesn't seg fault, but deliberately loses ancestors and
 
714
# descendents
 
715
sub _clone_node {
 
716
    my ($self, $node) = @_;
 
717
    my $clone = $node->new;
 
718
 
 
719
    while (my ($key, $val) = each %{$node}) {
 
720
        if ($key eq '_desc' || $key eq '_ancestor') {
 
721
            next;
 
722
        }
 
723
        ${$clone}{$key} = $val;
 
724
    }
 
725
 
 
726
    return $clone;
 
727
}
 
728
 
 
729
# tree string generator for simplify_to_leaves_string, based on
 
730
# Bio::TreeIO::newick::_write_tree_Helper
 
731
sub _simplify_helper {
 
732
    my ($self, $node, $paired) = @_;
 
733
    return () if (!defined $node);
 
734
 
 
735
    my @data = ();
 
736
    foreach my $node ($node->each_Descendent()) {
 
737
        push(@data, $self->_simplify_helper($node, $paired));
 
738
    }
 
739
 
 
740
    my $id = $node->id_output || '';
 
741
    if (@data) {
 
742
        unless (exists ${$paired}{"@data"} || @data == 1)  {
 
743
            $data[0] = "(" . $data[0];
 
744
            $data[-1] .= ")";
 
745
            ${$paired}{"@data"} = 1;
 
746
        }
 
747
    }
 
748
    elsif ($id) {
 
749
        push(@data, $id);
 
750
    }
 
751
 
 
752
    return @data;
511
753
}
512
754
 
513
755
=head2 distance
528
770
        return;
529
771
    }
530
772
    $self->throw("Must provide 2 nodes") unless @{$nodes} == 2;
531
 
    
 
773
 
532
774
    my $lca = $self->get_lca(@{$nodes});
533
775
    unless($lca) { 
534
776
        $self->warn("could not find the lca of supplied nodes; can't find distance either");
535
777
        return;
536
778
    }
537
 
    
 
779
 
538
780
    my $cumul_dist = 0;
539
781
    my $warned = 0;
540
782
    foreach my $current_node (@{$nodes}) {
541
783
        while (1) {
 
784
            last if $current_node eq $lca;
542
785
            if ($current_node->branch_length) {
543
786
                $cumul_dist += $current_node->branch_length;
544
787
            }
546
789
                $self->warn("At least some nodes do not have a branch length, the distance returned could be wrong");
547
790
                $warned = 1;
548
791
            }
549
 
            
 
792
 
550
793
            $current_node = $current_node->ancestor || last;
551
 
            last if $current_node eq $lca;
552
794
        }
553
795
    }
554
 
    
 
796
 
555
797
    return $cumul_dist;
556
798
}
557
799
 
581
823
   if( ref($nodes) !~ /ARRAY/i ) {
582
824
       $self->warn("Must provide a valid array reference for -nodes");
583
825
   }
584
 
   
 
826
 
585
827
   my $clade_root = $self->get_lca(@{$nodes});
586
828
   unless( defined $clade_root ) { 
587
829
       $self->warn("could not find clade root via lca");
588
830
       return;
589
831
   }
590
 
   
 
832
 
591
833
   my $og_ancestor = $outgroup->ancestor;
592
834
   while( defined ($og_ancestor ) ) {
593
835
       if( $og_ancestor->internal_id == $clade_root->internal_id ) {
636
878
   foreach my $n ( @$nodes ) {
637
879
       $nodehash{$n->internal_id} = $n;
638
880
   }
639
 
   
 
881
 
640
882
   my $clade_root = $self->get_lca(-nodes => $nodes );
641
883
   unless( defined $clade_root ) { 
642
884
       $self->warn("could not find clade root via lca");
643
885
       return;
644
886
   }
645
 
   
 
887
 
646
888
   my $og_ancestor = $outgroup->ancestor;
647
889
 
648
890
   # Is this necessary/correct for paraphyly test?
653
895
       }
654
896
       $og_ancestor = $og_ancestor->ancestor;
655
897
   }
656
 
   my $tree = new Bio::Tree::Tree(-root     => $clade_root,
 
898
   my $tree = Bio::Tree::Tree->new(-root     => $clade_root,
657
899
                                  -nodelete => 1);
658
900
 
659
901
   foreach my $n ( $tree->get_nodes() ) { 
683
925
        $self->warn("Must provide a valid Bio::Tree::NodeI when rerooting");
684
926
        return 0;
685
927
    }
686
 
    
 
928
 
687
929
    {
688
 
        my $anc = $new_root->ancestor;  
 
930
        my $anc = $new_root->ancestor;
689
931
        unless( $anc ) {
690
932
            return 0;
691
933
        }
708
950
        $self->warn("Node requested for reroot is already the root node!");
709
951
        return 0;
710
952
    }
711
 
    
 
953
 
712
954
    # reverse the ancestor & children pointers
713
955
    my @path_from_oldroot = ($self->get_lineage_nodes($new_root), $new_root);
714
956
    for (my $i = 0; $i < @path_from_oldroot - 1; $i++) {
737
979
=head2 findnode_by_id
738
980
 
739
981
 Title   : findnode_by_id
740
 
 Usage   : my $node = $tree->find_node_by_id($id);
741
 
 Function: Get a node by its internal id (which should be 
 
982
 Usage   : my $node = $tree->findnode_by_id($id);
 
983
 Function: Get a node by its id (which should be 
742
984
           unique for the tree)
743
985
 Returns : L<Bio::Tree::NodeI>
744
986
 Args    : node id
749
991
 
750
992
sub findnode_by_id {
751
993
    my $tree = shift;
 
994
    $tree->deprecated("use of findnode_by_id() is deprecated; ".
 
995
                      "use find_node() instead");
752
996
    my $id = shift;
753
997
    my $rootnode = $tree->get_root_node;
754
998
    if ( ($rootnode->id) and ($rootnode->id eq $id) ) {
762
1006
    }
763
1007
}
764
1008
 
 
1009
=head2 move_id_to_bootstrap
 
1010
 
 
1011
 Title   : move_id_to_bootstrap
 
1012
 Usage   : $tree->move_id_to_bootstrap
 
1013
 Function: Move internal IDs to bootstrap slot
 
1014
 Returns : undef
 
1015
 Args    : undef
 
1016
 
 
1017
 
 
1018
=cut
 
1019
 
 
1020
sub move_id_to_bootstrap{
 
1021
   my ($tree) = shift;
 
1022
   for my $node ( grep { ! $_->is_Leaf } $tree->get_nodes ) {
 
1023
       $node->bootstrap($node->id);
 
1024
       $node->id('');
 
1025
   }
 
1026
}
 
1027
 
 
1028
 
 
1029
=head2 add_traits
 
1030
 
 
1031
  Example    : $key = $stat->add_traits($tree, $trait_file, 3);
 
1032
  Description: Add traits to a Bio::Tree:Tree nodes
 
1033
               of a tree from a file.
 
1034
  Returns    : trait name
 
1035
  Exceptions : log an error if a node has no value in the file
 
1036
  Caller     : main()
 
1037
 
 
1038
The trait file is a tab-delimied text file and need to have a header
 
1039
line giving names to traits. The first column contains the leaf node
 
1040
ids. Subsequent columns contain different trait value sets. Columns
 
1041
numbering starts from 0. The default trait column is the second
 
1042
(1). The returned hashref has one special key, my_trait_name, that
 
1043
holds the trait name. Single or double quotes are removed.
 
1044
 
 
1045
=cut
 
1046
 
 
1047
sub _read_trait_file {
 
1048
    my $self = shift;
 
1049
    my $file = shift;
 
1050
    my $column = shift || 1;
 
1051
 
 
1052
    my $traits;
 
1053
    open my $TRAIT, "<", $file or $self->("Can't find file $file: $!\n");
 
1054
 
 
1055
    my $first_line = 1;
 
1056
    while (<$TRAIT>) {
 
1057
        if ($first_line) {
 
1058
            $first_line = 0;
 
1059
            s/['"]//g;
 
1060
            my @line = split;
 
1061
            $traits->{'my_trait_name'} = $line[$column];
 
1062
            next;
 
1063
        }
 
1064
        s/['"]//g;
 
1065
        my @line = split;
 
1066
        last unless $line[0];
 
1067
        $traits->{$line[0]} = $line[$column];
 
1068
    }
 
1069
    return $traits;
 
1070
}
 
1071
 
 
1072
 
 
1073
sub add_trait {
 
1074
    my $self = shift;
 
1075
    my $file = shift;
 
1076
    my $column = shift;
 
1077
 
 
1078
    my $traits = $self->_read_trait_file($file, $column); # filename, trait column
 
1079
    my $key = $traits->{'my_trait_name'};
 
1080
    #use YAML; print Dump $traits; exit;
 
1081
    foreach my $node ($self->get_leaf_nodes) {
 
1082
        # strip quotes from the node id
 
1083
        $node->id($1) if $node->id =~ /^['"]+(.*)['"]+$/;
 
1084
        eval {
 
1085
            $node->verbose(2);
 
1086
            $node->add_tag_value($key, $traits->{ $node->id } );
 
1087
        };
 
1088
        $self->throw("ERROR: No trait for node [".
 
1089
                     $node->id. "/".  $node->internal_id. "]")
 
1090
            if $@;
 
1091
    }
 
1092
    return $key;
 
1093
}
 
1094
 
 
1095
 
765
1096
1;