line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Bio::Phylo::Matrices::Datatype; |
2
|
16
|
|
|
16
|
|
96
|
use strict; |
|
16
|
|
|
|
|
32
|
|
|
16
|
|
|
|
|
455
|
|
3
|
16
|
|
|
16
|
|
73
|
use base 'Bio::Phylo::NeXML::Writable'; |
|
16
|
|
|
|
|
34
|
|
|
16
|
|
|
|
|
1683
|
|
4
|
16
|
|
|
16
|
|
106
|
use Bio::Phylo::Factory; |
|
16
|
|
|
|
|
30
|
|
|
16
|
|
|
|
|
105
|
|
5
|
16
|
|
|
16
|
|
70
|
use Bio::Phylo::Util::Exceptions 'throw'; |
|
16
|
|
|
|
|
30
|
|
|
16
|
|
|
|
|
698
|
|
6
|
16
|
|
|
16
|
|
89
|
use Bio::Phylo::Util::CONSTANT qw'_DOMCREATOR_ _DATATYPE_ /looks_like/'; |
|
16
|
|
|
|
|
37
|
|
|
16
|
|
|
|
|
5727
|
|
7
|
|
|
|
|
|
|
{ |
8
|
|
|
|
|
|
|
my $logger = __PACKAGE__->get_logger; |
9
|
|
|
|
|
|
|
my $fac = Bio::Phylo::Factory->new(); |
10
|
|
|
|
|
|
|
my @fields = \( my ( %lookup, %missing, %gap, %meta ) ); |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=head1 NAME |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
Bio::Phylo::Matrices::Datatype - Validator of character state data |
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
=head1 SYNOPSIS |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# No direct usage |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
=head1 DESCRIPTION |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
This is a superclass for objects that validate character data. Objects that |
23
|
|
|
|
|
|
|
inherit from this class (typically those in the |
24
|
|
|
|
|
|
|
Bio::Phylo::Matrices::Datatype::* namespace) can check strings and arrays of |
25
|
|
|
|
|
|
|
character data for invalid symbols, and split and join strings and arrays |
26
|
|
|
|
|
|
|
in a way appropriate for the type (on whitespace for continuous data, |
27
|
|
|
|
|
|
|
on single characters for categorical data). |
28
|
|
|
|
|
|
|
L objects and L |
29
|
|
|
|
|
|
|
internally delegate validation of their contents to these datatype objects; |
30
|
|
|
|
|
|
|
there is no normal usage in which you'd have to deal with datatype objects |
31
|
|
|
|
|
|
|
directly. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head1 METHODS |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=head2 CONSTRUCTOR |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=over |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=item new() |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
Datatype constructor. |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
Type : Constructor |
44
|
|
|
|
|
|
|
Title : new |
45
|
|
|
|
|
|
|
Usage : No direct usage, is called by TypeSafeData classes; |
46
|
|
|
|
|
|
|
Function: Instantiates a Datatype object |
47
|
|
|
|
|
|
|
Returns : a Bio::Phylo::Matrices::Datatype child class |
48
|
|
|
|
|
|
|
Args : $type (optional, one of continuous, custom, dna, |
49
|
|
|
|
|
|
|
mixed, protein, restriction, rna, standard) |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=cut |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub new : Constructor { |
54
|
837
|
|
|
837
|
1
|
1310
|
my $class = shift; |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# constructor called with type string |
57
|
837
|
100
|
|
|
|
1972
|
if ( $class eq __PACKAGE__ ) { |
58
|
787
|
|
|
|
|
1909
|
my $type = ucfirst( lc(shift) ); |
59
|
787
|
50
|
|
|
|
1671
|
if ( not $type ) { |
60
|
0
|
|
|
|
|
0
|
throw 'BadArgs' => "No subtype specified!"; |
61
|
|
|
|
|
|
|
} |
62
|
787
|
100
|
|
|
|
1630
|
if ( $type eq 'Nucleotide' ) { |
63
|
1
|
|
|
|
|
6
|
$logger->warn("'nucleotide' datatype requested, using 'dna'"); |
64
|
1
|
|
|
|
|
2
|
$type = 'Dna'; |
65
|
|
|
|
|
|
|
} |
66
|
787
|
|
|
|
|
2108
|
return looks_like_class( __PACKAGE__ . '::' . $type ) |
67
|
|
|
|
|
|
|
->SUPER::new(@_); |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
# constructor called from type subclass |
71
|
|
|
|
|
|
|
else { |
72
|
50
|
|
|
|
|
130
|
my %args = looks_like_hash @_; |
73
|
|
|
|
|
|
|
{ |
74
|
16
|
|
|
16
|
|
115
|
no strict 'refs'; |
|
16
|
|
|
|
|
34
|
|
|
16
|
|
|
|
|
1761
|
|
|
0
|
|
|
|
|
0
|
|
75
|
50
|
|
|
|
|
137
|
$args{'-lookup'} = ${"${class}::LOOKUP"} |
76
|
50
|
50
|
|
|
|
64
|
if ${"${class}::LOOKUP"}; |
|
50
|
|
|
|
|
193
|
|
77
|
50
|
|
|
|
|
113
|
$args{'-missing'} = ${"${class}::MISSING"} |
78
|
50
|
50
|
|
|
|
67
|
if ${"${class}::MISSING"}; |
|
50
|
|
|
|
|
149
|
|
79
|
50
|
100
|
|
|
|
72
|
$args{'-gap'} = ${"${class}::GAP"} if ${"${class}::GAP"}; |
|
10
|
|
|
|
|
27
|
|
|
50
|
|
|
|
|
148
|
|
80
|
16
|
|
|
16
|
|
106
|
use strict; |
|
16
|
|
|
|
|
41
|
|
|
16
|
|
|
|
|
936
|
|
81
|
|
|
|
|
|
|
} |
82
|
50
|
|
|
|
|
69
|
return $class->SUPER::new(%args); |
|
50
|
|
|
|
|
162
|
|
83
|
|
|
|
|
|
|
} |
84
|
16
|
|
|
16
|
|
87
|
} |
|
16
|
|
|
|
|
33
|
|
|
16
|
|
|
|
|
98
|
|
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=back |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head2 MUTATORS |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=over |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
=item set_lookup() |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
Sets state lookup table. |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
Type : Mutator |
97
|
|
|
|
|
|
|
Title : set_lookup |
98
|
|
|
|
|
|
|
Usage : $obj->set_lookup($hashref); |
99
|
|
|
|
|
|
|
Function: Sets the state lookup table. |
100
|
|
|
|
|
|
|
Returns : Modified object. |
101
|
|
|
|
|
|
|
Args : Argument must be a hash |
102
|
|
|
|
|
|
|
reference that maps allowed |
103
|
|
|
|
|
|
|
single character symbols |
104
|
|
|
|
|
|
|
(including ambiguity symbols) |
105
|
|
|
|
|
|
|
onto the equivalent set of |
106
|
|
|
|
|
|
|
non-ambiguous symbols |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=cut |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub set_lookup : Clonable { |
111
|
756
|
|
|
756
|
1
|
1217
|
my ( $self, $lookup ) = @_; |
112
|
756
|
|
|
|
|
1531
|
my $id = $self->get_id; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# we have a value |
115
|
756
|
50
|
|
|
|
1352
|
if ( defined $lookup ) { |
116
|
756
|
50
|
|
|
|
1505
|
if ( looks_like_instance $lookup, 'HASH' ) { |
117
|
756
|
|
|
|
|
1507
|
$lookup{$id} = $lookup; |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
else { |
120
|
0
|
|
|
|
|
0
|
throw 'BadArgs' => "lookup must be a hash reference"; |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# no value, so must be a reset |
125
|
|
|
|
|
|
|
else { |
126
|
0
|
|
|
|
|
0
|
$lookup{$id} = $self->get_lookup; |
127
|
|
|
|
|
|
|
} |
128
|
756
|
|
|
|
|
1274
|
return $self; |
129
|
16
|
|
|
16
|
|
4376
|
} |
|
16
|
|
|
|
|
38
|
|
|
16
|
|
|
|
|
66
|
|
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=item set_missing() |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
Sets missing data symbol. |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
Type : Mutator |
136
|
|
|
|
|
|
|
Title : set_missing |
137
|
|
|
|
|
|
|
Usage : $obj->set_missing('?'); |
138
|
|
|
|
|
|
|
Function: Sets the symbol for missing data |
139
|
|
|
|
|
|
|
Returns : Modified object. |
140
|
|
|
|
|
|
|
Args : Argument must be a single |
141
|
|
|
|
|
|
|
character, default is '?' |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
=cut |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
sub set_missing : Clonable { |
146
|
109
|
|
|
109
|
1
|
197
|
my ( $self, $missing ) = @_; |
147
|
109
|
|
|
|
|
210
|
my $id = $self->get_id; |
148
|
109
|
50
|
|
|
|
254
|
if ( $missing ne $self->get_gap ) { |
149
|
109
|
|
|
|
|
201
|
$missing{$id} = $missing; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
else { |
152
|
0
|
|
|
|
|
0
|
throw 'BadArgs' => |
153
|
|
|
|
|
|
|
"Missing character '$missing' already in use as gap character"; |
154
|
|
|
|
|
|
|
} |
155
|
109
|
|
|
|
|
232
|
return $self; |
156
|
16
|
|
|
16
|
|
3597
|
} |
|
16
|
|
|
|
|
43
|
|
|
16
|
|
|
|
|
68
|
|
157
|
|
|
|
|
|
|
|
158
|
|
|
|
|
|
|
=item set_gap() |
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
Sets gap symbol. |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
Type : Mutator |
163
|
|
|
|
|
|
|
Title : set_gap |
164
|
|
|
|
|
|
|
Usage : $obj->set_gap('-'); |
165
|
|
|
|
|
|
|
Function: Sets the symbol for gaps |
166
|
|
|
|
|
|
|
Returns : Modified object. |
167
|
|
|
|
|
|
|
Args : Argument must be a single |
168
|
|
|
|
|
|
|
character, default is '-' |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=cut |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
sub set_gap : Clonable { |
173
|
69
|
|
|
69
|
1
|
136
|
my ( $self, $gap ) = @_; |
174
|
69
|
50
|
|
|
|
183
|
if ( not $gap eq $self->get_missing ) { |
175
|
69
|
|
|
|
|
199
|
$gap{ $self->get_id } = $gap; |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
else { |
178
|
0
|
|
|
|
|
0
|
throw 'BadArgs' => |
179
|
|
|
|
|
|
|
"Gap character '$gap' already in use as missing character"; |
180
|
|
|
|
|
|
|
} |
181
|
69
|
|
|
|
|
161
|
return $self; |
182
|
16
|
|
|
16
|
|
3847
|
} |
|
16
|
|
|
|
|
38
|
|
|
16
|
|
|
|
|
69
|
|
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=item set_metas_for_states() |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Assigns all metadata annotations for all state symbols |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
Type : Mutator |
189
|
|
|
|
|
|
|
Title : set_metas_for_states |
190
|
|
|
|
|
|
|
Usage : $obj->set_metas_for_states({ $state => [ $m1, $m2 ] }); |
191
|
|
|
|
|
|
|
Function: Assigns all metadata annotations for all state symbols |
192
|
|
|
|
|
|
|
Returns : Modified object. |
193
|
|
|
|
|
|
|
Args : A hash reference of state symbols with metadata arrays |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=cut |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
sub set_metas_for_states : Clonable { |
198
|
50
|
|
|
50
|
1
|
79
|
my ( $self, $metas ) = @_; |
199
|
50
|
|
|
|
|
110
|
$meta{$self->get_id} = $metas; |
200
|
50
|
|
|
|
|
109
|
return $self; |
201
|
16
|
|
|
16
|
|
3202
|
} |
|
16
|
|
|
|
|
37
|
|
|
16
|
|
|
|
|
56
|
|
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item add_meta_for_state() |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
Adds a metadata annotation for a state symbol |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
Type : Mutator |
208
|
|
|
|
|
|
|
Title : add_meta_for_state |
209
|
|
|
|
|
|
|
Usage : $obj->add_meta_for_state($meta,$state); |
210
|
|
|
|
|
|
|
Function: Adds a metadata annotation for a state symbol |
211
|
|
|
|
|
|
|
Returns : Modified object. |
212
|
|
|
|
|
|
|
Args : A Bio::Phylo::NeXML::Meta object and a state symbol |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=cut |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub add_meta_for_state { |
217
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $meta, $state ) = @_; |
218
|
0
|
0
|
|
|
|
0
|
if ( my $lookup = $self->get_lookup ) { |
219
|
0
|
0
|
|
|
|
0
|
if ( exists $lookup->{$state} ) { |
220
|
0
|
|
|
|
|
0
|
my $id = $self->get_id; |
221
|
0
|
0
|
|
|
|
0
|
$meta{$id} = {} if not $meta{$id}; |
222
|
0
|
0
|
|
|
|
0
|
$meta{$id}->{$state} = [] if not $meta{$id}->{$state}; |
223
|
0
|
|
|
|
|
0
|
push @{ $meta{$id}->{$state} }, $meta; |
|
0
|
|
|
|
|
0
|
|
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
else { |
226
|
0
|
|
|
|
|
0
|
$logger->warn( |
227
|
|
|
|
|
|
|
"State '$state' is unknown, can't add annotation"); |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
else { |
231
|
0
|
|
|
|
|
0
|
$logger->warn( |
232
|
|
|
|
|
|
|
"This data type has no categorical states to annotate"); |
233
|
|
|
|
|
|
|
} |
234
|
0
|
|
|
|
|
0
|
return $self; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
=item remove_meta_for_state() |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
Removes a metadata annotation for a state symbol |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
Type : Mutator |
242
|
|
|
|
|
|
|
Title : remove_meta_for_state |
243
|
|
|
|
|
|
|
Usage : $obj->remove_meta_for_state($meta,$state); |
244
|
|
|
|
|
|
|
Function: Removes a metadata annotation for a state symbol |
245
|
|
|
|
|
|
|
Returns : Modified object. |
246
|
|
|
|
|
|
|
Args : A Bio::Phylo::NeXML::Meta object and a state symbol |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=cut |
249
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
sub remove_meta_for_state { |
251
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $meta, $state ) = @_; |
252
|
0
|
|
|
|
|
0
|
my $id = $self->get_id; |
253
|
0
|
0
|
0
|
|
|
0
|
if ( $meta{$id} && $meta{$id}->{$state} ) { |
254
|
0
|
|
|
|
|
0
|
my $meta_array = $meta{$id}->{$state}; |
255
|
0
|
|
|
|
|
0
|
my $meta_id = $meta->get_id; |
256
|
0
|
|
|
|
|
0
|
DICT: for my $i ( 0 .. $#{$meta_array} ) { |
|
0
|
|
|
|
|
0
|
|
257
|
0
|
0
|
|
|
|
0
|
if ( $meta_array->[$i]->get_id == $meta_id ) { |
258
|
0
|
|
|
|
|
0
|
splice @{$meta_array}, $i, 1; |
|
0
|
|
|
|
|
0
|
|
259
|
0
|
|
|
|
|
0
|
last DICT; |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
else { |
264
|
0
|
|
|
|
|
0
|
$logger->warn( |
265
|
|
|
|
|
|
|
"There are no annotations to remove for state '$state'"); |
266
|
|
|
|
|
|
|
} |
267
|
0
|
|
|
|
|
0
|
return $self; |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
|
270
|
|
|
|
|
|
|
=back |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=head2 ACCESSORS |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=over |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=item get_type() |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
Gets data type as string. |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
Type : Accessor |
281
|
|
|
|
|
|
|
Title : get_type |
282
|
|
|
|
|
|
|
Usage : my $type = $obj->get_type; |
283
|
|
|
|
|
|
|
Function: Returns the object's datatype |
284
|
|
|
|
|
|
|
Returns : A string |
285
|
|
|
|
|
|
|
Args : None |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=cut |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
sub get_type { |
290
|
824
|
|
|
824
|
1
|
1423
|
my $type = ref shift; |
291
|
824
|
|
|
|
|
3334
|
$type =~ s/.*:://; |
292
|
824
|
|
|
|
|
2432
|
return $type; |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=item get_ids_for_special_symbols() |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
Gets state-to-id mapping for missing and gap symbols |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
Type : Accessor |
300
|
|
|
|
|
|
|
Title : get_ids_for_special_symbols |
301
|
|
|
|
|
|
|
Usage : my %ids = %{ $obj->get_ids_for_special_symbols }; |
302
|
|
|
|
|
|
|
Function: Returns state-to-id mapping |
303
|
|
|
|
|
|
|
Returns : A hash reference, keyed on symbol, with UID values |
304
|
|
|
|
|
|
|
Args : Optional, a boolean: |
305
|
|
|
|
|
|
|
true => prefix state ids with 's' |
306
|
|
|
|
|
|
|
false => keep ids numerical |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
=cut |
309
|
|
|
|
|
|
|
|
310
|
|
|
|
|
|
|
sub get_ids_for_special_symbols { |
311
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
312
|
0
|
|
|
|
|
0
|
my $ids_for_states = $self->get_ids_for_states; |
313
|
0
|
|
|
|
|
0
|
my @indices = sort { $a <=> $b } values %{$ids_for_states}; |
|
0
|
|
|
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
314
|
0
|
|
|
|
|
0
|
my $max_id = $indices[-1]; |
315
|
0
|
|
|
|
|
0
|
my ( $missing, $gap ) = ( $self->get_missing, $self->get_gap ); |
316
|
0
|
|
|
|
|
0
|
my $ids_for_special_symbols = {}; |
317
|
0
|
0
|
|
|
|
0
|
if ( $_[0] ) { |
318
|
0
|
|
|
|
|
0
|
$ids_for_special_symbols->{$gap} = 's' . ++$max_id; |
319
|
0
|
|
|
|
|
0
|
$ids_for_special_symbols->{$missing} = 's' . ++$max_id; |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
else { |
322
|
0
|
|
|
|
|
0
|
$ids_for_special_symbols->{$gap} = ++$max_id; |
323
|
0
|
|
|
|
|
0
|
$ids_for_special_symbols->{$missing} = ++$max_id; |
324
|
|
|
|
|
|
|
} |
325
|
0
|
|
|
|
|
0
|
return $ids_for_special_symbols; |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
=item get_ids_for_states() |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
Gets state-to-id mapping |
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
Type : Accessor |
333
|
|
|
|
|
|
|
Title : get_ids_for_states |
334
|
|
|
|
|
|
|
Usage : my %ids = %{ $obj->get_ids_for_states }; |
335
|
|
|
|
|
|
|
Function: Returns state-to-id mapping |
336
|
|
|
|
|
|
|
Returns : A hash reference, keyed on symbol, with UID values |
337
|
|
|
|
|
|
|
Args : Optional, a boolean: |
338
|
|
|
|
|
|
|
true => prefix state ids with 's' |
339
|
|
|
|
|
|
|
false => keep ids numerical |
340
|
|
|
|
|
|
|
Note : This returns a mapping to alphanumeric states; special |
341
|
|
|
|
|
|
|
symbols (for missing data and gaps) are handled separately |
342
|
|
|
|
|
|
|
|
343
|
|
|
|
|
|
|
=cut |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
sub get_ids_for_states { |
346
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
347
|
0
|
|
|
|
|
0
|
$logger->debug("getting ids for state set $self"); |
348
|
0
|
0
|
|
|
|
0
|
if ( my $lookup = $self->get_lookup ) { |
349
|
0
|
|
|
|
|
0
|
my $ids_for_states = {}; |
350
|
0
|
|
|
|
|
0
|
my ( @symbols, %tmp_cats, $i ); |
351
|
|
|
|
|
|
|
|
352
|
|
|
|
|
|
|
# build a list of state symbols: what properties will this |
353
|
|
|
|
|
|
|
# list have? Symbols will be present in order of the |
354
|
|
|
|
|
|
|
# size of the state set to which they belong; within |
355
|
|
|
|
|
|
|
# each of these ranks, the symbols will be in lexical |
356
|
|
|
|
|
|
|
# order. |
357
|
0
|
|
0
|
|
|
0
|
push( @{ $tmp_cats{ @{ $lookup->{$_} } } ||= [] }, $_ ) |
|
0
|
|
|
|
|
0
|
|
358
|
0
|
|
|
|
|
0
|
for grep /^\d+|[a-zA-Z]/, keys %{$lookup}; |
|
0
|
|
|
|
|
0
|
|
359
|
0
|
|
|
|
|
0
|
push( @symbols, sort { $a cmp $b } @{ $tmp_cats{$_} } ) |
|
0
|
|
|
|
|
0
|
|
360
|
0
|
|
|
|
|
0
|
for sort { $a <=> $b } keys %tmp_cats; |
|
0
|
|
|
|
|
0
|
|
361
|
|
|
|
|
|
|
$ids_for_states->{$_} = ( $_[0] ? 's' : '' ) . ( ++$i ) |
362
|
0
|
0
|
|
|
|
0
|
for (@symbols); |
363
|
0
|
|
|
|
|
0
|
return $ids_for_states; |
364
|
|
|
|
|
|
|
} |
365
|
0
|
|
|
|
|
0
|
return {}; |
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
|
368
|
|
|
|
|
|
|
=item get_states_for_symbol() |
369
|
|
|
|
|
|
|
|
370
|
|
|
|
|
|
|
Gets set of fundamental states for an ambiguity symbol |
371
|
|
|
|
|
|
|
|
372
|
|
|
|
|
|
|
Type : Accessor |
373
|
|
|
|
|
|
|
Title : get_states_for_symbol |
374
|
|
|
|
|
|
|
Usage : my @states = @{ $obj->get_states_for_symbol('N') }; |
375
|
|
|
|
|
|
|
Function: Returns the set of states for an ambiguity symbol |
376
|
|
|
|
|
|
|
Returns : An array ref of symbols |
377
|
|
|
|
|
|
|
Args : An ambiguity symbol |
378
|
|
|
|
|
|
|
Comments: If supplied argument is a fundamental state, an array |
379
|
|
|
|
|
|
|
ref with just that state is returned, e.g. 'A' returns |
380
|
|
|
|
|
|
|
['A'] for DNA and RNA |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
=cut |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
sub get_states_for_symbol { |
385
|
82250
|
|
|
82250
|
1
|
109417
|
my ( $self, $symbol ) = @_; |
386
|
82250
|
|
|
|
|
87773
|
my @states; |
387
|
82250
|
50
|
|
|
|
107963
|
if ( my $lookup = $self->get_lookup ) { |
388
|
82250
|
50
|
|
|
|
167968
|
if ( my $map = $lookup->{uc $symbol} ) { |
389
|
82250
|
|
|
|
|
95115
|
@states = @{ $map }; |
|
82250
|
|
|
|
|
125337
|
|
390
|
|
|
|
|
|
|
} |
391
|
|
|
|
|
|
|
} |
392
|
82250
|
|
|
|
|
174110
|
return \@states; |
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=item get_symbol_for_states() |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
Gets ambiguity symbol for a set of states |
398
|
|
|
|
|
|
|
|
399
|
|
|
|
|
|
|
Type : Accessor |
400
|
|
|
|
|
|
|
Title : get_symbol_for_states |
401
|
|
|
|
|
|
|
Usage : my $state = $obj->get_symbol_for_states('A','C'); |
402
|
|
|
|
|
|
|
Function: Returns the ambiguity symbol for a set of states |
403
|
|
|
|
|
|
|
Returns : A symbol (SCALAR) |
404
|
|
|
|
|
|
|
Args : A set of symbols |
405
|
|
|
|
|
|
|
Comments: If no symbol exists in the lookup |
406
|
|
|
|
|
|
|
table for the given set of states, |
407
|
|
|
|
|
|
|
a new - numerical - one is created |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
=cut |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
sub get_symbol_for_states { |
412
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
413
|
0
|
|
|
|
|
0
|
my @syms = @_; |
414
|
0
|
|
|
|
|
0
|
my $lookup = $self->get_lookup; |
415
|
0
|
0
|
|
|
|
0
|
if ($lookup) { |
416
|
0
|
|
|
|
|
0
|
my @lookup_syms = keys %{$lookup}; |
|
0
|
|
|
|
|
0
|
|
417
|
0
|
|
|
|
|
0
|
SYM: for my $sym (@lookup_syms) { |
418
|
0
|
|
|
|
|
0
|
my @states = @{ $lookup->{$sym} }; |
|
0
|
|
|
|
|
0
|
|
419
|
0
|
0
|
|
|
|
0
|
if ( scalar @syms == scalar @states ) { |
420
|
0
|
|
|
|
|
0
|
my $seen_all = 0; |
421
|
0
|
|
|
|
|
0
|
for my $i ( 0 .. $#syms ) { |
422
|
0
|
|
|
|
|
0
|
my $seen = 0; |
423
|
0
|
|
|
|
|
0
|
for my $j ( 0 .. $#states ) { |
424
|
0
|
0
|
|
|
|
0
|
if ( $syms[$i] eq $states[$j] ) { |
425
|
0
|
|
|
|
|
0
|
$seen++; |
426
|
0
|
|
|
|
|
0
|
$seen_all++; |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
} |
429
|
0
|
0
|
|
|
|
0
|
next SYM if not $seen; |
430
|
|
|
|
|
|
|
} |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
# found existing symbol |
433
|
0
|
0
|
|
|
|
0
|
return $sym if $seen_all == scalar @syms; |
434
|
|
|
|
|
|
|
} |
435
|
|
|
|
|
|
|
} |
436
|
|
|
|
|
|
|
|
437
|
|
|
|
|
|
|
# create new symbol |
438
|
0
|
|
|
|
|
0
|
my $sym; |
439
|
0
|
0
|
|
|
|
0
|
if ( $self->get_type !~ /standard/i ) { |
440
|
0
|
|
|
|
|
0
|
my $sym = 0; |
441
|
0
|
|
|
|
|
0
|
while ( exists $lookup->{$sym} ) { |
442
|
0
|
|
|
|
|
0
|
$sym++; |
443
|
|
|
|
|
|
|
} |
444
|
|
|
|
|
|
|
} |
445
|
|
|
|
|
|
|
else { |
446
|
0
|
|
|
|
|
0
|
LETTER: for my $char ( 'A' .. 'Z' ) { |
447
|
0
|
0
|
|
|
|
0
|
if ( not exists $lookup->{$char} ) { |
448
|
0
|
|
|
|
|
0
|
$sym = $char; |
449
|
0
|
|
|
|
|
0
|
last LETTER; |
450
|
|
|
|
|
|
|
} |
451
|
|
|
|
|
|
|
} |
452
|
|
|
|
|
|
|
} |
453
|
0
|
|
|
|
|
0
|
$lookup->{$sym} = \@syms; |
454
|
0
|
|
|
|
|
0
|
$self->set_lookup($lookup); |
455
|
0
|
|
|
|
|
0
|
return $sym; |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
else { |
458
|
0
|
|
|
|
|
0
|
$logger->info("No lookup table!"); |
459
|
0
|
|
|
|
|
0
|
return; |
460
|
|
|
|
|
|
|
} |
461
|
|
|
|
|
|
|
} |
462
|
|
|
|
|
|
|
|
463
|
|
|
|
|
|
|
=item get_lookup() |
464
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
Gets state lookup table. |
466
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
Type : Accessor |
468
|
|
|
|
|
|
|
Title : get_lookup |
469
|
|
|
|
|
|
|
Usage : my $lookup = $obj->get_lookup; |
470
|
|
|
|
|
|
|
Function: Returns the object's lookup hash |
471
|
|
|
|
|
|
|
Returns : A hash reference |
472
|
|
|
|
|
|
|
Args : None |
473
|
|
|
|
|
|
|
|
474
|
|
|
|
|
|
|
=cut |
475
|
|
|
|
|
|
|
|
476
|
|
|
|
|
|
|
sub get_lookup { |
477
|
83130
|
|
|
83130
|
1
|
96692
|
my $self = shift; |
478
|
83130
|
|
|
|
|
122717
|
my $id = $self->get_id; |
479
|
83130
|
100
|
|
|
|
126763
|
if ( exists $lookup{$id} ) { |
480
|
82476
|
|
|
|
|
147256
|
return $lookup{$id}; |
481
|
|
|
|
|
|
|
} |
482
|
|
|
|
|
|
|
else { |
483
|
654
|
|
|
|
|
877
|
my $class = __PACKAGE__; |
484
|
654
|
|
|
|
|
1293
|
$class .= '::' . $self->get_type; |
485
|
654
|
|
|
|
|
2598
|
$logger->debug("datatype class is $class"); |
486
|
654
|
50
|
|
|
|
1613
|
if ( looks_like_class $class ) { |
487
|
654
|
|
|
|
|
984
|
my $lookup; |
488
|
|
|
|
|
|
|
{ |
489
|
16
|
|
|
16
|
|
18301
|
no strict 'refs'; |
|
16
|
|
|
|
|
38
|
|
|
16
|
|
|
|
|
611
|
|
|
0
|
|
|
|
|
0
|
|
490
|
654
|
|
|
|
|
828
|
$lookup = ${ $class . '::LOOKUP' }; |
|
654
|
|
|
|
|
2153
|
|
491
|
16
|
|
|
16
|
|
85
|
use strict; |
|
16
|
|
|
|
|
33
|
|
|
16
|
|
|
|
|
13076
|
|
492
|
|
|
|
|
|
|
} |
493
|
654
|
|
|
|
|
814
|
$self->set_lookup($lookup); |
|
654
|
|
|
|
|
2014
|
|
494
|
654
|
|
|
|
|
1568
|
return $lookup; |
495
|
|
|
|
|
|
|
} |
496
|
|
|
|
|
|
|
} |
497
|
|
|
|
|
|
|
} |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=item get_missing() |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
Gets missing data symbol. |
502
|
|
|
|
|
|
|
|
503
|
|
|
|
|
|
|
Type : Accessor |
504
|
|
|
|
|
|
|
Title : get_missing |
505
|
|
|
|
|
|
|
Usage : my $missing = $obj->get_missing; |
506
|
|
|
|
|
|
|
Function: Returns the object's missing data symbol |
507
|
|
|
|
|
|
|
Returns : A string |
508
|
|
|
|
|
|
|
Args : None |
509
|
|
|
|
|
|
|
|
510
|
|
|
|
|
|
|
=cut |
511
|
|
|
|
|
|
|
|
512
|
|
|
|
|
|
|
sub get_missing { |
513
|
1643
|
|
|
1643
|
1
|
2210
|
my $self = shift; |
514
|
1643
|
|
|
|
|
3075
|
my $missing = $missing{ $self->get_id }; |
515
|
1643
|
100
|
|
|
|
4719
|
return defined $missing ? $missing : '?'; |
516
|
|
|
|
|
|
|
} |
517
|
|
|
|
|
|
|
|
518
|
|
|
|
|
|
|
=item get_gap() |
519
|
|
|
|
|
|
|
|
520
|
|
|
|
|
|
|
Gets gap symbol. |
521
|
|
|
|
|
|
|
|
522
|
|
|
|
|
|
|
Type : Accessor |
523
|
|
|
|
|
|
|
Title : get_gap |
524
|
|
|
|
|
|
|
Usage : my $gap = $obj->get_gap; |
525
|
|
|
|
|
|
|
Function: Returns the object's gap symbol |
526
|
|
|
|
|
|
|
Returns : A string |
527
|
|
|
|
|
|
|
Args : None |
528
|
|
|
|
|
|
|
|
529
|
|
|
|
|
|
|
=cut |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
sub get_gap { |
532
|
950
|
|
|
950
|
1
|
1378
|
my $self = shift; |
533
|
950
|
|
|
|
|
1700
|
my $gap = $gap{ $self->get_id }; |
534
|
950
|
100
|
|
|
|
2055
|
return defined $gap ? $gap : '-'; |
535
|
|
|
|
|
|
|
} |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
=item get_meta_for_state() |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
Gets metadata annotations (if any) for the provided state symbol |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
Type : Accessor |
542
|
|
|
|
|
|
|
Title : get_meta_for_state |
543
|
|
|
|
|
|
|
Usage : my @meta = @{ $obj->get_meta_for_state }; |
544
|
|
|
|
|
|
|
Function: Gets metadata annotations for a state symbol |
545
|
|
|
|
|
|
|
Returns : An array reference of Bio::Phylo::NeXML::Meta objects |
546
|
|
|
|
|
|
|
Args : A state symbol |
547
|
|
|
|
|
|
|
|
548
|
|
|
|
|
|
|
=cut |
549
|
|
|
|
|
|
|
|
550
|
|
|
|
|
|
|
sub get_meta_for_state { |
551
|
0
|
|
|
0
|
1
|
0
|
my ( $self, $state ) = @_; |
552
|
0
|
|
|
|
|
0
|
my $id = $self->get_id; |
553
|
0
|
0
|
0
|
|
|
0
|
if ( $meta{$id} && $meta{$id}->{$state} ) { |
554
|
0
|
|
|
|
|
0
|
return $meta{$id}->{$state}; |
555
|
|
|
|
|
|
|
} |
556
|
0
|
|
|
|
|
0
|
return []; |
557
|
|
|
|
|
|
|
} |
558
|
|
|
|
|
|
|
|
559
|
|
|
|
|
|
|
=item get_metas_for_states() |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
Gets metadata annotations (if any) for all state symbols |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
Type : Accessor |
564
|
|
|
|
|
|
|
Title : get_metas_for_states |
565
|
|
|
|
|
|
|
Usage : my @meta = @{ $obj->get_metas_for_states }; |
566
|
|
|
|
|
|
|
Function: Gets metadata annotations for state symbols |
567
|
|
|
|
|
|
|
Returns : An array reference of Bio::Phylo::NeXML::Meta objects |
568
|
|
|
|
|
|
|
Args : None |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
=cut |
571
|
|
|
|
|
|
|
|
572
|
50
|
|
|
50
|
1
|
110
|
sub get_metas_for_states { $meta{shift->get_id} } |
573
|
|
|
|
|
|
|
|
574
|
|
|
|
|
|
|
=back |
575
|
|
|
|
|
|
|
|
576
|
|
|
|
|
|
|
=head2 TESTS |
577
|
|
|
|
|
|
|
|
578
|
|
|
|
|
|
|
=over |
579
|
|
|
|
|
|
|
|
580
|
|
|
|
|
|
|
=item is_ambiguous() |
581
|
|
|
|
|
|
|
|
582
|
|
|
|
|
|
|
Tests whether the supplied state symbol represents an ambiguous (polymorphic |
583
|
|
|
|
|
|
|
or uncertain) state. For example, for the most commonly-used alphabet for |
584
|
|
|
|
|
|
|
DNA states, the symbol 'N' represents complete uncertainty, the actual state |
585
|
|
|
|
|
|
|
could be any of 'A', 'C', 'G' or 'T', and so this method would return a true |
586
|
|
|
|
|
|
|
value. |
587
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
Type : Test |
589
|
|
|
|
|
|
|
Title : is_ambiguous |
590
|
|
|
|
|
|
|
Usage : if ( $obj->is_ambiguous('N') ) { |
591
|
|
|
|
|
|
|
# do something |
592
|
|
|
|
|
|
|
} |
593
|
|
|
|
|
|
|
Function: Returns true if argument is an ambiguous state symbol |
594
|
|
|
|
|
|
|
Returns : BOOLEAN |
595
|
|
|
|
|
|
|
Args : A state symbol |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=cut |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
sub is_ambiguous { |
600
|
65
|
|
|
65
|
1
|
115
|
my ( $self, $symbol ) = @_; |
601
|
65
|
100
|
|
|
|
105
|
if ( my $lookup = $self->get_lookup ) { |
602
|
50
|
|
|
|
|
74
|
my $mapping = $lookup->{uc $symbol}; |
603
|
50
|
100
|
66
|
|
|
121
|
if ( $mapping and ref $mapping eq 'ARRAY' ) { |
604
|
39
|
|
|
|
|
44
|
return scalar(@{$mapping}) > 1; |
|
39
|
|
|
|
|
90
|
|
605
|
|
|
|
|
|
|
} |
606
|
|
|
|
|
|
|
} |
607
|
26
|
|
|
|
|
56
|
return 0; |
608
|
|
|
|
|
|
|
} |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
=item is_valid() |
611
|
|
|
|
|
|
|
|
612
|
|
|
|
|
|
|
Validates argument. |
613
|
|
|
|
|
|
|
|
614
|
|
|
|
|
|
|
Type : Test |
615
|
|
|
|
|
|
|
Title : is_valid |
616
|
|
|
|
|
|
|
Usage : if ( $obj->is_valid($datum) ) { |
617
|
|
|
|
|
|
|
# do something |
618
|
|
|
|
|
|
|
} |
619
|
|
|
|
|
|
|
Function: Returns true if $datum only contains valid characters |
620
|
|
|
|
|
|
|
Returns : BOOLEAN |
621
|
|
|
|
|
|
|
Args : A Bio::Phylo::Matrices::Datum object |
622
|
|
|
|
|
|
|
|
623
|
|
|
|
|
|
|
=cut |
624
|
|
|
|
|
|
|
|
625
|
|
|
|
|
|
|
sub is_valid { |
626
|
1451
|
|
|
1451
|
1
|
2288
|
my $self = shift; |
627
|
1451
|
|
|
|
|
1964
|
my @data; |
628
|
1451
|
|
|
|
|
2777
|
ARG: for my $arg (@_) { |
629
|
1451
|
50
|
|
|
|
6325
|
if ( ref $arg eq 'ARRAY' ) { |
|
|
100
|
|
|
|
|
|
630
|
0
|
|
|
|
|
0
|
push @data, @{$arg}; |
|
0
|
|
|
|
|
0
|
|
631
|
|
|
|
|
|
|
} |
632
|
|
|
|
|
|
|
elsif ( UNIVERSAL::can( $arg, 'get_char' ) ) { |
633
|
743
|
|
|
|
|
1731
|
push @data, $arg->get_char; |
634
|
|
|
|
|
|
|
} |
635
|
|
|
|
|
|
|
else { |
636
|
708
|
50
|
|
|
|
1999
|
if ( length($arg) > 1 ) { |
637
|
0
|
|
|
|
|
0
|
push @data, @{ $self->split($arg) }; |
|
0
|
|
|
|
|
0
|
|
638
|
|
|
|
|
|
|
} |
639
|
|
|
|
|
|
|
else { |
640
|
708
|
|
|
|
|
10466
|
@data = @_; |
641
|
708
|
|
|
|
|
1378
|
last ARG; |
642
|
|
|
|
|
|
|
} |
643
|
|
|
|
|
|
|
} |
644
|
|
|
|
|
|
|
} |
645
|
1451
|
100
|
|
|
|
4189
|
return 1 if not @data; |
646
|
712
|
|
|
|
|
1701
|
my $lookup = $self->get_lookup; |
647
|
712
|
|
|
|
|
1439
|
my @symbols = ( $self->get_missing, $self->get_gap, keys %{$lookup} ); |
|
712
|
|
|
|
|
3005
|
|
648
|
712
|
|
|
|
|
1557
|
my %symbols = map { $_ => 1 } grep { defined $_ } @symbols; |
|
12480
|
|
|
|
|
18786
|
|
|
12480
|
|
|
|
|
16983
|
|
649
|
712
|
|
|
|
|
1910
|
CHAR_CHECK: for my $char (@data) { |
650
|
82978
|
50
|
|
|
|
113794
|
next CHAR_CHECK if not defined $char; |
651
|
82978
|
100
|
|
|
|
138608
|
next CHAR_CHECK if $symbols{ uc $char }; |
652
|
8
|
|
|
|
|
63
|
return 0; |
653
|
|
|
|
|
|
|
} |
654
|
704
|
|
|
|
|
10950
|
return 1; |
655
|
|
|
|
|
|
|
} |
656
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
=item is_same() |
658
|
|
|
|
|
|
|
|
659
|
|
|
|
|
|
|
Compares data type objects. |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
Type : Test |
662
|
|
|
|
|
|
|
Title : is_same |
663
|
|
|
|
|
|
|
Usage : if ( $obj->is_same($obj1) ) { |
664
|
|
|
|
|
|
|
# do something |
665
|
|
|
|
|
|
|
} |
666
|
|
|
|
|
|
|
Function: Returns true if $obj1 contains the same validation rules |
667
|
|
|
|
|
|
|
Returns : BOOLEAN |
668
|
|
|
|
|
|
|
Args : A Bio::Phylo::Matrices::Datatype::* object |
669
|
|
|
|
|
|
|
|
670
|
|
|
|
|
|
|
=cut |
671
|
|
|
|
|
|
|
|
672
|
|
|
|
|
|
|
sub is_same { |
673
|
119
|
|
|
119
|
1
|
252
|
my ( $self, $model ) = @_; |
674
|
119
|
|
|
|
|
535
|
$logger->info("Comparing datatype '$self' to '$model'"); |
675
|
119
|
100
|
|
|
|
281
|
return 1 if $self->get_id == $model->get_id; |
676
|
34
|
50
|
|
|
|
81
|
return 0 if $self->get_type ne $model->get_type; |
677
|
|
|
|
|
|
|
|
678
|
|
|
|
|
|
|
# check strings |
679
|
34
|
|
|
|
|
79
|
for my $prop (qw(get_type get_missing get_gap)) { |
680
|
102
|
|
|
|
|
229
|
my ( $self_prop, $model_prop ) = ( $self->$prop, $model->$prop ); |
681
|
102
|
50
|
33
|
|
|
445
|
return 0 |
|
|
|
33
|
|
|
|
|
682
|
|
|
|
|
|
|
if defined $self_prop |
683
|
|
|
|
|
|
|
&& defined $model_prop |
684
|
|
|
|
|
|
|
&& $self_prop ne $model_prop; |
685
|
|
|
|
|
|
|
} |
686
|
34
|
|
|
|
|
90
|
my ( $s_lookup, $m_lookup ) = ( $self->get_lookup, $model->get_lookup ); |
687
|
|
|
|
|
|
|
|
688
|
|
|
|
|
|
|
# one has lookup, other hasn't |
689
|
34
|
50
|
33
|
|
|
141
|
if ( $s_lookup && !$m_lookup ) { |
690
|
0
|
|
|
|
|
0
|
return 0; |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
# both don't have lookup -> are continuous |
694
|
34
|
0
|
33
|
|
|
89
|
if ( !$s_lookup && !$m_lookup ) { |
695
|
0
|
|
|
|
|
0
|
return 1; |
696
|
|
|
|
|
|
|
} |
697
|
|
|
|
|
|
|
|
698
|
|
|
|
|
|
|
# get keys |
699
|
34
|
|
|
|
|
47
|
my @s_keys = keys %{$s_lookup}; |
|
34
|
|
|
|
|
140
|
|
700
|
34
|
|
|
|
|
61
|
my @m_keys = keys %{$m_lookup}; |
|
34
|
|
|
|
|
96
|
|
701
|
|
|
|
|
|
|
|
702
|
|
|
|
|
|
|
# different number of keys |
703
|
34
|
50
|
|
|
|
90
|
if ( scalar(@s_keys) != scalar(@m_keys) ) { |
704
|
0
|
|
|
|
|
0
|
return 0; |
705
|
|
|
|
|
|
|
} |
706
|
|
|
|
|
|
|
|
707
|
|
|
|
|
|
|
# compare keys |
708
|
34
|
|
|
|
|
71
|
for my $key (@s_keys) { |
709
|
448
|
50
|
|
|
|
694
|
if ( not exists $m_lookup->{$key} ) { |
710
|
0
|
|
|
|
|
0
|
return 0; |
711
|
|
|
|
|
|
|
} |
712
|
|
|
|
|
|
|
else { |
713
|
|
|
|
|
|
|
|
714
|
|
|
|
|
|
|
# compare values |
715
|
448
|
|
|
|
|
799
|
my ( %s_vals, %m_vals ); |
716
|
448
|
|
|
|
|
0
|
my ( @s_vals, @m_vals ); |
717
|
448
|
|
|
|
|
493
|
@s_vals = @{ $s_lookup->{$key} }; |
|
448
|
|
|
|
|
761
|
|
718
|
448
|
|
|
|
|
553
|
@m_vals = @{ $m_lookup->{$key} }; |
|
448
|
|
|
|
|
629
|
|
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
# different number of vals |
721
|
448
|
50
|
|
|
|
774
|
if ( scalar(@m_vals) != scalar(@s_vals) ) { |
722
|
0
|
|
|
|
|
0
|
return 0; |
723
|
|
|
|
|
|
|
} |
724
|
|
|
|
|
|
|
|
725
|
|
|
|
|
|
|
# make hashes to compare on vals |
726
|
448
|
|
|
|
|
611
|
%s_vals = map { $_ => 1 } @s_vals; |
|
808
|
|
|
|
|
1383
|
|
727
|
448
|
|
|
|
|
616
|
%m_vals = map { $_ => 1 } @m_vals; |
|
808
|
|
|
|
|
1191
|
|
728
|
448
|
|
|
|
|
789
|
for my $val ( keys %s_vals ) { |
729
|
808
|
50
|
|
|
|
1693
|
return 0 if not exists $m_vals{$val}; |
730
|
|
|
|
|
|
|
} |
731
|
|
|
|
|
|
|
} |
732
|
|
|
|
|
|
|
} |
733
|
34
|
|
|
|
|
149
|
return 1; |
734
|
|
|
|
|
|
|
} |
735
|
|
|
|
|
|
|
|
736
|
|
|
|
|
|
|
=back |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=head2 UTILITY METHODS |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
=over |
741
|
|
|
|
|
|
|
|
742
|
|
|
|
|
|
|
=item split() |
743
|
|
|
|
|
|
|
|
744
|
|
|
|
|
|
|
Splits argument string of characters following appropriate rules. |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
Type : Utility method |
747
|
|
|
|
|
|
|
Title : split |
748
|
|
|
|
|
|
|
Usage : $obj->split($string) |
749
|
|
|
|
|
|
|
Function: Splits $string into characters |
750
|
|
|
|
|
|
|
Returns : An array reference of characters |
751
|
|
|
|
|
|
|
Args : A string |
752
|
|
|
|
|
|
|
|
753
|
|
|
|
|
|
|
=cut |
754
|
|
|
|
|
|
|
|
755
|
|
|
|
|
|
|
sub split { |
756
|
1237
|
|
|
1237
|
1
|
2218
|
my ( $self, $string ) = @_; |
757
|
1237
|
|
|
|
|
69875
|
my @array = CORE::split( /\s*/, $string ); |
758
|
1237
|
|
|
|
|
17598
|
return \@array; |
759
|
|
|
|
|
|
|
} |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
=item join() |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
Joins argument array ref of characters following appropriate rules. |
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
Type : Utility method |
766
|
|
|
|
|
|
|
Title : join |
767
|
|
|
|
|
|
|
Usage : $obj->join($arrayref) |
768
|
|
|
|
|
|
|
Function: Joins $arrayref into a string |
769
|
|
|
|
|
|
|
Returns : A string |
770
|
|
|
|
|
|
|
Args : An array reference |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
=cut |
773
|
|
|
|
|
|
|
|
774
|
|
|
|
|
|
|
sub join { |
775
|
40
|
|
|
40
|
1
|
62
|
my ( $self, $array ) = @_; |
776
|
40
|
|
|
|
|
50
|
return CORE::join( '', @{$array} ); |
|
40
|
|
|
|
|
175
|
|
777
|
|
|
|
|
|
|
} |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
sub _cleanup : Destructor { |
780
|
1672
|
|
|
1672
|
|
2416
|
my $self = shift; |
781
|
1672
|
|
|
|
|
5954
|
$logger->debug("cleaning up '$self'"); |
782
|
1672
|
|
|
|
|
3408
|
my $id = $self->get_id; |
783
|
1672
|
|
|
|
|
2793
|
for my $field (@fields) { |
784
|
6688
|
|
|
|
|
10444
|
delete $field->{$id}; |
785
|
|
|
|
|
|
|
} |
786
|
16
|
|
|
16
|
|
119
|
} |
|
16
|
|
|
|
|
36
|
|
|
16
|
|
|
|
|
86
|
|
787
|
|
|
|
|
|
|
|
788
|
|
|
|
|
|
|
=back |
789
|
|
|
|
|
|
|
|
790
|
|
|
|
|
|
|
=head2 SERIALIZERS |
791
|
|
|
|
|
|
|
|
792
|
|
|
|
|
|
|
=over |
793
|
|
|
|
|
|
|
|
794
|
|
|
|
|
|
|
=item to_xml() |
795
|
|
|
|
|
|
|
|
796
|
|
|
|
|
|
|
Writes data type definitions to xml |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
Type : Serializer |
799
|
|
|
|
|
|
|
Title : to_xml |
800
|
|
|
|
|
|
|
Usage : my $xml = $obj->to_xml |
801
|
|
|
|
|
|
|
Function: Writes data type definitions to xml |
802
|
|
|
|
|
|
|
Returns : An xml string representation of data type definition |
803
|
|
|
|
|
|
|
Args : None |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
=cut |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
sub to_xml { |
808
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
809
|
0
|
|
|
|
|
0
|
$logger->debug("writing $self to xml"); |
810
|
0
|
|
|
|
|
0
|
my $xml = ''; |
811
|
0
|
|
0
|
|
|
0
|
my $normalized = $_[0] || {}; |
812
|
0
|
|
|
|
|
0
|
my $polymorphism = $_[1]; |
813
|
0
|
0
|
|
|
|
0
|
if ( my $lookup = $self->get_lookup ) { |
814
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $self->get_xml_tag; |
815
|
0
|
|
|
|
|
0
|
$logger->debug($xml); |
816
|
0
|
|
|
|
|
0
|
my $id_for_state = $self->get_ids_for_states(1); |
817
|
|
|
|
|
|
|
my @states = sort { |
818
|
0
|
|
|
|
|
0
|
my ( $m, $n ); |
819
|
0
|
|
|
|
|
0
|
($m) = $id_for_state->{$a} =~ /([0-9]+)/; |
820
|
0
|
|
|
|
|
0
|
($n) = $id_for_state->{$b} =~ /([0-9]+)/; |
821
|
0
|
|
|
|
|
0
|
$m <=> $n |
822
|
0
|
|
|
|
|
0
|
} keys %{$id_for_state}; |
|
0
|
|
|
|
|
0
|
|
823
|
0
|
|
|
|
|
0
|
for my $state (@states) { |
824
|
0
|
|
|
|
|
0
|
$xml .= |
825
|
|
|
|
|
|
|
$self->_state_to_xml( $state, $id_for_state, $lookup, |
826
|
|
|
|
|
|
|
$normalized, $polymorphism ); |
827
|
|
|
|
|
|
|
} |
828
|
0
|
|
|
|
|
0
|
my ( $missing, $gap ) = ( $self->get_missing, $self->get_gap ); |
829
|
0
|
|
|
|
|
0
|
my $special = $self->get_ids_for_special_symbols; |
830
|
0
|
0
|
|
|
|
0
|
if ( %{$special} ) { |
|
0
|
|
|
|
|
0
|
|
831
|
0
|
|
|
|
|
0
|
my $uss = |
832
|
|
|
|
|
|
|
$fac->create_xmlwritable( '-tag' => 'uncertain_state_set' ); |
833
|
0
|
|
|
|
|
0
|
my $mbr = $fac->create_xmlwritable( |
834
|
|
|
|
|
|
|
'-tag' => 'member', |
835
|
|
|
|
|
|
|
'-identifiable' => 0 |
836
|
|
|
|
|
|
|
); |
837
|
|
|
|
|
|
|
$uss->set_attributes( |
838
|
0
|
|
|
|
|
0
|
'id' => "s" . $special->{$gap}, |
839
|
|
|
|
|
|
|
'symbol' => '-' |
840
|
|
|
|
|
|
|
); |
841
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $uss->get_xml_tag(1); |
842
|
|
|
|
|
|
|
$uss->set_attributes( |
843
|
0
|
|
|
|
|
0
|
'id' => "s" . $special->{$missing}, |
844
|
|
|
|
|
|
|
'symbol' => '?' |
845
|
|
|
|
|
|
|
); |
846
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $uss->get_xml_tag(); |
847
|
0
|
|
|
|
|
0
|
for (@states) { |
848
|
0
|
|
|
|
|
0
|
$mbr->set_attributes( 'state' => $id_for_state->{$_} ); |
849
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $mbr->get_xml_tag(1); |
850
|
|
|
|
|
|
|
} |
851
|
0
|
|
|
|
|
0
|
$mbr->set_attributes( 'state' => "s" . $special->{$gap} ); |
852
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $mbr->get_xml_tag(1); |
853
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $uss->get_tag . ">"; |
854
|
|
|
|
|
|
|
} |
855
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $self->get_tag . ">"; |
856
|
|
|
|
|
|
|
} |
857
|
0
|
|
|
|
|
0
|
return $xml; |
858
|
|
|
|
|
|
|
} |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
sub _state_to_xml { |
861
|
0
|
|
|
0
|
|
0
|
my ( $self, $state, $id_for_state, $lookup, $normalized, $polymorphism ) |
862
|
|
|
|
|
|
|
= @_; |
863
|
0
|
|
|
|
|
0
|
my $state_id = $id_for_state->{$state}; |
864
|
0
|
|
|
|
|
0
|
my @mapping = @{ $lookup->{$state} }; |
|
0
|
|
|
|
|
0
|
|
865
|
|
|
|
|
|
|
my $symbol = |
866
|
0
|
0
|
|
|
|
0
|
exists $normalized->{$state} ? $normalized->{$state} : $state; |
867
|
0
|
|
|
|
|
0
|
my $xml = ''; |
868
|
0
|
|
|
|
|
0
|
my $unambiguous = scalar @mapping <= 1; |
869
|
0
|
0
|
|
|
|
0
|
my $tag = |
|
|
0
|
|
|
|
|
|
870
|
|
|
|
|
|
|
$unambiguous ? 'state' |
871
|
|
|
|
|
|
|
: $polymorphism ? 'polymorphic_state_set' |
872
|
|
|
|
|
|
|
: 'uncertain_state_set'; |
873
|
0
|
|
|
|
|
0
|
my $elt = $fac->create_xmlwritable( |
874
|
|
|
|
|
|
|
'-tag' => $tag, |
875
|
|
|
|
|
|
|
'-xml_id' => $state_id, |
876
|
|
|
|
|
|
|
'-attributes' => { 'symbol' => $symbol } |
877
|
|
|
|
|
|
|
); |
878
|
0
|
|
|
|
|
0
|
$elt->add_meta($_) for @{ $self->get_meta_for_state($state) }; |
|
0
|
|
|
|
|
0
|
|
879
|
|
|
|
|
|
|
|
880
|
0
|
0
|
|
|
|
0
|
if ($unambiguous) { |
881
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $elt->get_xml_tag(1); |
882
|
|
|
|
|
|
|
} |
883
|
|
|
|
|
|
|
else { |
884
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $elt->get_xml_tag(); |
885
|
0
|
|
|
|
|
0
|
for (@mapping) { |
886
|
|
|
|
|
|
|
$xml .= $fac->create_xmlwritable( |
887
|
|
|
|
|
|
|
'-tag' => 'member', |
888
|
|
|
|
|
|
|
'-identifiable' => 0, |
889
|
0
|
|
|
|
|
0
|
'-attributes' => { 'state' => $id_for_state->{$_} } |
890
|
|
|
|
|
|
|
)->get_xml_tag(1); |
891
|
|
|
|
|
|
|
} |
892
|
0
|
|
|
|
|
0
|
$xml .= "\n" . $elt->get_tag . ">"; |
893
|
|
|
|
|
|
|
} |
894
|
0
|
|
|
|
|
0
|
return $xml; |
895
|
|
|
|
|
|
|
} |
896
|
|
|
|
|
|
|
|
897
|
|
|
|
|
|
|
=item to_dom() |
898
|
|
|
|
|
|
|
|
899
|
|
|
|
|
|
|
Analog to to_xml. |
900
|
|
|
|
|
|
|
|
901
|
|
|
|
|
|
|
Type : Serializer |
902
|
|
|
|
|
|
|
Title : to_dom |
903
|
|
|
|
|
|
|
Usage : $type->to_dom |
904
|
|
|
|
|
|
|
Function: Generates a DOM subtree from the invocant |
905
|
|
|
|
|
|
|
and its contained objects |
906
|
|
|
|
|
|
|
Returns : an ::Element object |
907
|
|
|
|
|
|
|
Args : none |
908
|
|
|
|
|
|
|
|
909
|
|
|
|
|
|
|
=cut |
910
|
|
|
|
|
|
|
|
911
|
|
|
|
|
|
|
sub to_dom { |
912
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
913
|
0
|
|
|
|
|
0
|
my $dom = $_[0]; |
914
|
0
|
|
|
|
|
0
|
my @args = @_; |
915
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
# handle dom factory object... |
917
|
0
|
0
|
0
|
|
|
0
|
if ( looks_like_instance( $dom, 'SCALAR' ) |
918
|
|
|
|
|
|
|
&& $dom->_type == _DOMCREATOR_ ) |
919
|
|
|
|
|
|
|
{ |
920
|
0
|
|
|
|
|
0
|
splice( @args, 0, 1 ); |
921
|
|
|
|
|
|
|
} |
922
|
|
|
|
|
|
|
else { |
923
|
0
|
|
|
|
|
0
|
$dom = $Bio::Phylo::NeXML::DOM::DOM; |
924
|
0
|
0
|
|
|
|
0
|
unless ($dom) { |
925
|
0
|
|
|
|
|
0
|
throw 'BadArgs' => 'DOM factory object not provided'; |
926
|
|
|
|
|
|
|
} |
927
|
|
|
|
|
|
|
} |
928
|
0
|
|
|
|
|
0
|
my $elt; |
929
|
0
|
|
0
|
|
|
0
|
my $normalized = $args[0] || {}; |
930
|
0
|
|
|
|
|
0
|
my $polymorphism = $args[1]; |
931
|
0
|
0
|
|
|
|
0
|
if ( my $lookup = $self->get_lookup ) { |
932
|
0
|
|
|
|
|
0
|
$elt = $self->get_dom_elt($dom); |
933
|
0
|
|
|
|
|
0
|
my $id_for_state = $self->get_ids_for_states; |
934
|
|
|
|
|
|
|
my @states = sort { |
935
|
0
|
|
|
|
|
0
|
my ( $m, $n ); |
936
|
0
|
|
|
|
|
0
|
($m) = $id_for_state->{$a} =~ /([0-9]+)/; |
937
|
0
|
|
|
|
|
0
|
($n) = $id_for_state->{$b} =~ /([0-9]+)/; |
938
|
0
|
|
|
|
|
0
|
$m <=> $n |
939
|
0
|
|
|
|
|
0
|
} keys %{$id_for_state}; |
|
0
|
|
|
|
|
0
|
|
940
|
0
|
|
|
|
|
0
|
keys %{$id_for_state}; |
|
0
|
|
|
|
|
0
|
|
941
|
0
|
|
|
|
|
0
|
my $max_id = 0; |
942
|
0
|
|
|
|
|
0
|
for my $state (@states) { |
943
|
0
|
|
|
|
|
0
|
my $state_id = $id_for_state->{$state}; |
944
|
0
|
|
|
|
|
0
|
$id_for_state->{$state} = 's' . $state_id; |
945
|
0
|
|
|
|
|
0
|
$max_id = $state_id; |
946
|
|
|
|
|
|
|
} |
947
|
0
|
|
|
|
|
0
|
for my $state (@states) { |
948
|
0
|
|
|
|
|
0
|
$elt->set_child( |
949
|
|
|
|
|
|
|
$self->_state_to_dom( |
950
|
|
|
|
|
|
|
$dom, $state, $id_for_state, |
951
|
|
|
|
|
|
|
$lookup, $normalized, $polymorphism |
952
|
|
|
|
|
|
|
) |
953
|
|
|
|
|
|
|
); |
954
|
|
|
|
|
|
|
} |
955
|
0
|
|
|
|
|
0
|
my ( $missing, $gap ) = ( $self->get_missing, $self->get_gap ); |
956
|
0
|
|
|
|
|
0
|
my $special = $self->get_ids_for_special_symbols; |
957
|
0
|
0
|
|
|
|
0
|
if ( %{$special} ) { |
|
0
|
|
|
|
|
0
|
|
958
|
0
|
|
|
|
|
0
|
my $uss; |
959
|
0
|
|
|
|
|
0
|
$uss = $dom->create_element( '-tag' => 'uncertain_state_set' ); |
960
|
0
|
|
|
|
|
0
|
$uss->set_attributes( 'id' => 's' . $special->{$gap} ); |
961
|
0
|
|
|
|
|
0
|
$uss->set_attributes( 'symbol' => '-' ); |
962
|
0
|
|
|
|
|
0
|
$elt->set_child($uss); |
963
|
0
|
|
|
|
|
0
|
$uss = $dom->create_element( '-tag' => 'uncertain_state_set' ); |
964
|
0
|
|
|
|
|
0
|
$uss->set_attributes( 'id' => 's' . $special->{$missing} ); |
965
|
0
|
|
|
|
|
0
|
$uss->set_attributes( 'symbol' => '?' ); |
966
|
0
|
|
|
|
|
0
|
my $mbr; |
967
|
|
|
|
|
|
|
|
968
|
0
|
|
|
|
|
0
|
for (@states) { |
969
|
0
|
|
|
|
|
0
|
$mbr = $dom->create_element( '-tag' => 'member' ); |
970
|
0
|
|
|
|
|
0
|
$mbr->set_attributes( 'state' => $id_for_state->{$_} ); |
971
|
0
|
|
|
|
|
0
|
$uss->set_child($mbr); |
972
|
|
|
|
|
|
|
} |
973
|
0
|
|
|
|
|
0
|
$mbr = $dom->create_element( '-tag' => 'member' ); |
974
|
0
|
|
|
|
|
0
|
$mbr->set_attributes( 'state' => 's' . $special->{$gap} ); |
975
|
0
|
|
|
|
|
0
|
$uss->set_child($mbr); |
976
|
0
|
|
|
|
|
0
|
$elt->set_child($uss); |
977
|
|
|
|
|
|
|
} |
978
|
|
|
|
|
|
|
} |
979
|
0
|
|
|
|
|
0
|
return $elt; |
980
|
|
|
|
|
|
|
} |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
sub _state_to_dom { |
983
|
0
|
|
|
0
|
|
0
|
my ( $self, $dom, $state, $id_for_state, $lookup, $normalized, |
984
|
|
|
|
|
|
|
$polymorphism ) |
985
|
|
|
|
|
|
|
= @_; |
986
|
0
|
|
|
|
|
0
|
my $state_id = $id_for_state->{$state}; |
987
|
0
|
|
|
|
|
0
|
my @mapping = @{ $lookup->{$state} }; |
|
0
|
|
|
|
|
0
|
|
988
|
|
|
|
|
|
|
my $symbol = |
989
|
0
|
0
|
|
|
|
0
|
exists $normalized->{$state} ? $normalized->{$state} : $state; |
990
|
0
|
|
|
|
|
0
|
my $elt; |
991
|
|
|
|
|
|
|
|
992
|
|
|
|
|
|
|
# has ambiguity mappings |
993
|
0
|
0
|
|
|
|
0
|
if ( scalar @mapping > 1 ) { |
994
|
0
|
0
|
|
|
|
0
|
my $tag = |
995
|
|
|
|
|
|
|
$polymorphism ? 'polymorphic_state_set' : 'uncertain_state_set'; |
996
|
0
|
|
|
|
|
0
|
$elt = $dom->create_element( '-tag' => $tag ); |
997
|
0
|
|
|
|
|
0
|
$elt->set_attributes( 'id' => $state_id ); |
998
|
0
|
|
|
|
|
0
|
$elt->set_attributes( 'symbol' => $symbol ); |
999
|
0
|
|
|
|
|
0
|
for my $map (@mapping) { |
1000
|
0
|
|
|
|
|
0
|
my $mbr = $dom->create_element( '-tag' => 'member' ); |
1001
|
0
|
|
|
|
|
0
|
$mbr->set_attributes( 'state' => $id_for_state->{$map} ); |
1002
|
0
|
|
|
|
|
0
|
$elt->set_child($mbr); |
1003
|
|
|
|
|
|
|
} |
1004
|
|
|
|
|
|
|
} |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
# no ambiguity |
1007
|
|
|
|
|
|
|
else { |
1008
|
0
|
|
|
|
|
0
|
$elt = $dom->create_element( '-tag' => 'state' ); |
1009
|
0
|
|
|
|
|
0
|
$elt->set_attributes( 'id' => $state_id ); |
1010
|
0
|
|
|
|
|
0
|
$elt->set_attributes( 'symbol' => $symbol ); |
1011
|
|
|
|
|
|
|
} |
1012
|
0
|
|
|
|
|
0
|
return $elt; |
1013
|
|
|
|
|
|
|
} |
1014
|
50
|
|
|
50
|
|
142
|
sub _tag { 'states' } |
1015
|
50
|
|
|
50
|
|
112
|
sub _type { _DATATYPE_ } |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
=back |
1018
|
|
|
|
|
|
|
|
1019
|
|
|
|
|
|
|
=cut |
1020
|
|
|
|
|
|
|
|
1021
|
|
|
|
|
|
|
# podinherit_insert_token |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
=head1 SEE ALSO |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
There is a mailing list at L |
1026
|
|
|
|
|
|
|
for any user or developer questions and discussions. |
1027
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
=over |
1029
|
|
|
|
|
|
|
|
1030
|
|
|
|
|
|
|
=item L |
1031
|
|
|
|
|
|
|
|
1032
|
|
|
|
|
|
|
This object inherits from L, so the methods defined |
1033
|
|
|
|
|
|
|
therein are also applicable to L objects. |
1034
|
|
|
|
|
|
|
|
1035
|
|
|
|
|
|
|
=item L |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
Also see the manual: L and L. |
1038
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
=back |
1040
|
|
|
|
|
|
|
|
1041
|
|
|
|
|
|
|
=head1 CITATION |
1042
|
|
|
|
|
|
|
|
1043
|
|
|
|
|
|
|
If you use Bio::Phylo in published research, please cite it: |
1044
|
|
|
|
|
|
|
|
1045
|
|
|
|
|
|
|
B, B, B, B |
1046
|
|
|
|
|
|
|
and B, 2011. Bio::Phylo - phyloinformatic analysis using Perl. |
1047
|
|
|
|
|
|
|
I B<12>:63. |
1048
|
|
|
|
|
|
|
L |
1049
|
|
|
|
|
|
|
|
1050
|
|
|
|
|
|
|
=cut |
1051
|
|
|
|
|
|
|
|
1052
|
|
|
|
|
|
|
} |
1053
|
|
|
|
|
|
|
1; |