File Coverage

blib/lib/Bio/Phylo/Unparsers/Figtree.pm
Criterion Covered Total %
statement 49 51 96.0
branch 6 10 60.0
condition n/a
subroutine 9 9 100.0
pod n/a
total 64 70 91.4


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