| 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; |