File Coverage

blib/lib/Bio/Phylo/Unparsers/Figtree.pm
Criterion Covered Total %
statement 46 48 95.8
branch 6 10 60.0
condition n/a
subroutine 8 8 100.0
pod n/a
total 60 66 90.9


line stmt bran cond sub pod time code
1             package Bio::Phylo::Unparsers::Figtree;
2 1     1   8 use strict;
  1         2  
  1         36  
3 1     1   4 use base 'Bio::Phylo::Unparsers::Nexus';
  1         2  
  1         360  
4 1     1   5 use Bio::Phylo::Util::Logger ':levels';
  1         2  
  1         94  
5 1     1   187 use Bio::Phylo::Util::Exceptions 'throw';
  1         2  
  1         41  
6 1     1   6 use Bio::Phylo::Util::CONSTANT qw':objecttypes :namespaces';
  1         105  
  1         225  
7 1     1   7 use Data::Dumper;
  1         2  
  1         365  
8              
9             my $log = Bio::Phylo::Util::Logger->new;
10             my $ns = _NS_FIGTREE_;
11             my $pre = 'fig';
12              
13             =head1 NAME
14              
15             Bio::Phylo::Unparsers::Figtree - Serializer used by Bio::Phylo::IO, no serviceable parts inside
16              
17             =head1 DESCRIPTION
18              
19             This module turns objects into a nexus-formatted string that uses additional
20             syntax for Figtree. It is called by the L<Bio::Phylo::IO> facade, don't call it
21             directly. You can pass the following additional arguments to the unparse call:
22            
23             =begin comment
24              
25             Type : Wrapper
26             Title : _to_string($obj)
27             Usage : $figtree->_to_string($obj);
28             Function: Stringifies an object into
29             a nexus/figtree formatted string.
30             Alias :
31             Returns : SCALAR
32             Args : Bio::Phylo::*
33              
34             =end comment
35              
36             =cut
37              
38             sub _to_string {
39 1     1   3 my $self = shift;
40 1         11 $self->{'FOREST_ARGS'} = {
41             '-nodelabels' => \&_figtree_handler,
42             '-figtree' => 1,
43             };
44 1         4 return $self->SUPER::_to_string(@_);
45             }
46              
47             sub _figtree_handler {
48              
49             # node object, translation table ID, if any
50 35     35   69 my ( $node, $id ) = @_;
51              
52             # fetch Meta objects, filter out the ones that are _NS_FIGTREE_,
53             # turn them into a hash without the fig prefix
54 35         51 my @meta = @{ $node->get_meta };
  35         81  
55 637         1236 my %meta = map { $_->get_predicate_local => $_->get_object }
56 35         91 grep { $_->get_predicate_namespace eq $ns } @meta;
  637         1206  
57 35         193 $log->debug( Dumper(\%meta) );
58            
59             # there can be separate annotations that are _min and _max for
60             # the same variable name stem. We combine these into a range
61             # between curly braces. Also add % percentage symbol for 95%
62             # HPD ranges - the % symbol is disallowed in CURIEs, hence we
63             # have to bring it back here.
64 35         110 my %merged;
65 35         132 KEY: for my $key ( keys %meta ) {
66 637 100       1651 if ( $key =~ /^(.+?)_min$/ ) {
    100          
67 206         376 my $stem = $1;
68 206         303 my $max_key = $stem . '_max';
69 206         366 $stem =~ s/95/95%/;
70 206         646 $merged{$stem} = '{'.$meta{$key}.','.$meta{$max_key}.'}';
71             }
72             elsif ( $key =~ /^(.+?)_max$/ ) {
73 206         325 next KEY;
74             }
75             else {
76 225         282 $key =~ s/95/95%/;
77 225         377 $merged{$key} = $meta{$key};
78             }
79             }
80            
81             # create the concatenated annotation string
82 35         122 my $anno = '[&' . join( ',',map { $_.'='.$merged{$_} } keys %merged ) . ']';
  431         859  
83            
84             # construct the name:
85 35         84 my $name;
86            
87             # case 1 - a translation table index was provided, this now replaces the name
88 35 50       102 if ( defined $id ) {
    0          
89 35         58 $name = $id;
90             }
91            
92             # case 2 - no translation table index, use the node name
93             elsif ( defined $node->get_name ) {
94 0         0 $name = $node->get_name;
95             }
96            
97             # case 3 - use the empty string, to avoid uninitialized warnings.
98             else {
99 0         0 $name = '';
100             }
101            
102             # append the annotation string, if we have it
103 35 50       115 my $annotated = $anno ne '[&]' ? $name . $anno : $name;
104 35         120 $log->debug($annotated);
105 35         243 return $annotated;
106             }
107              
108             # podinherit_insert_token
109              
110             =head1 SEE ALSO
111              
112             There is a mailing list at L<https://groups.google.com/forum/#!forum/bio-phylo>
113             for any user or developer questions and discussions.
114              
115             =over
116              
117             =item L<Bio::Phylo::IO>
118              
119             The nexus serializer is called by the L<Bio::Phylo::IO> object.
120              
121             =item L<Bio::Phylo::Manual>
122              
123             Also see the manual: L<Bio::Phylo::Manual> and L<http://rutgervos.blogspot.com>.
124              
125             =back
126              
127             =head1 CITATION
128              
129             If you use Bio::Phylo in published research, please cite it:
130              
131             B<Rutger A Vos>, B<Jason Caravas>, B<Klaas Hartmann>, B<Mark A Jensen>
132             and B<Chase Miller>, 2011. Bio::Phylo - phyloinformatic analysis using Perl.
133             I<BMC Bioinformatics> B<12>:63.
134             L<http://dx.doi.org/10.1186/1471-2105-12-63>
135              
136             =cut
137              
138             1;