line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# $Id$ |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# BioPerl module for Bio::SeqFeature::Annotated |
4
|
|
|
|
|
|
|
# |
5
|
|
|
|
|
|
|
# Please direct questions and support issues to |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# Cared for by Allen Day |
8
|
|
|
|
|
|
|
# |
9
|
|
|
|
|
|
|
# Copyright Allen Day |
10
|
|
|
|
|
|
|
# |
11
|
|
|
|
|
|
|
# You may distribute this module under the same terms as perl itself |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
# POD documentation - main docs before the code |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 NAME |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated - PLEASE PUT SOMETHING HERE |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 SYNOPSIS |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
# none yet, complain to authors |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 DESCRIPTION |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
None yet, complain to authors. |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
=head1 Implemented Interfaces |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
This class implements the following interfaces. |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
=over 4 |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=item Bio::SeqFeatureI |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
Note that this includes implementing Bio::RangeI. |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=item Bio::AnnotatableI |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
=item Bio::FeatureHolderI |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
Features held by a feature are essentially sub-features. |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=back |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=head1 FEEDBACK |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
=head2 Mailing Lists |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
User feedback is an integral part of the evolution of this and other |
50
|
|
|
|
|
|
|
Bioperl modules. Send your comments and suggestions preferably to one |
51
|
|
|
|
|
|
|
of the Bioperl mailing lists. Your participation is much appreciated. |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
bioperl-l@bioperl.org - General discussion |
54
|
|
|
|
|
|
|
http://bioperl.org/wiki/Mailing_lists - About the mailing lists |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=head2 Support |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Please direct usage questions or support issues to the mailing list: |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
I |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
rather than to the module maintainer directly. Many experienced and |
63
|
|
|
|
|
|
|
reponsive experts will be able look at the problem and quickly |
64
|
|
|
|
|
|
|
address it. Please include a thorough description of the problem |
65
|
|
|
|
|
|
|
with code and data examples if at all possible. |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
=head2 Reporting Bugs |
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
Report bugs to the Bioperl bug tracking system to help us keep track |
70
|
|
|
|
|
|
|
the bugs and their resolution. Bug reports can be submitted via |
71
|
|
|
|
|
|
|
the web: |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
http://bugzilla.open-bio.org/ |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
=head1 AUTHOR - Allen Day |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
Allen Day Eallenday at ucla.eduE |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=head1 APPENDIX |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
The rest of the documentation details each of the object |
82
|
|
|
|
|
|
|
methods. Internal methods are usually preceded with a _ |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=cut |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
package Bio::SeqFeature::Annotated; |
88
|
|
|
|
|
|
|
BEGIN { |
89
|
3
|
|
|
3
|
|
100
|
$Bio::SeqFeature::Annotated::AUTHORITY = 'cpan:BIOPERLML'; |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
$Bio::SeqFeature::Annotated::VERSION = '1.6.905'; |
92
|
3
|
|
|
3
|
|
15
|
use strict; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
55
|
|
93
|
|
|
|
|
|
|
|
94
|
3
|
|
|
3
|
|
883
|
use Bio::Annotation::Collection; |
|
3
|
|
|
|
|
8904
|
|
|
3
|
|
|
|
|
96
|
|
95
|
3
|
|
|
3
|
|
378
|
use Bio::Annotation::OntologyTerm; |
|
3
|
|
|
|
|
15267
|
|
|
3
|
|
|
|
|
64
|
|
96
|
3
|
|
|
3
|
|
267
|
use Bio::Annotation::Target; |
|
3
|
|
|
|
|
3921
|
|
|
3
|
|
|
|
|
66
|
|
97
|
3
|
|
|
3
|
|
925
|
use Bio::LocatableSeq; |
|
3
|
|
|
|
|
71930
|
|
|
3
|
|
|
|
|
105
|
|
98
|
3
|
|
|
3
|
|
33
|
use Bio::Location::Simple; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
77
|
|
99
|
3
|
|
|
3
|
|
13
|
use Bio::Ontology::OntologyStore; |
|
3
|
|
|
|
|
14
|
|
|
3
|
|
|
|
|
73
|
|
100
|
3
|
|
|
3
|
|
1437
|
use Bio::Tools::GFF; |
|
3
|
|
|
|
|
59629
|
|
|
3
|
|
|
|
|
126
|
|
101
|
3
|
|
|
3
|
|
1079
|
use Bio::SeqFeature::AnnotationAdaptor; |
|
3
|
|
|
|
|
2858
|
|
|
3
|
|
|
|
|
78
|
|
102
|
3
|
|
|
3
|
|
19
|
use Data::Dumper; |
|
3
|
|
|
|
|
6
|
|
|
3
|
|
|
|
|
164
|
|
103
|
3
|
|
|
3
|
|
793
|
use URI::Escape; |
|
3
|
|
|
|
|
3837
|
|
|
3
|
|
|
|
|
171
|
|
104
|
|
|
|
|
|
|
|
105
|
3
|
|
|
|
|
978
|
use base qw(Bio::Root::Root |
106
|
|
|
|
|
|
|
Bio::SeqFeature::TypedSeqFeatureI |
107
|
|
|
|
|
|
|
Bio::AnnotatableI |
108
|
3
|
|
|
3
|
|
21
|
Bio::FeatureHolderI); |
|
3
|
|
|
|
|
5
|
|
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
our %tagclass = ( |
111
|
|
|
|
|
|
|
comment => 'Bio::Annotation::Comment', |
112
|
|
|
|
|
|
|
dblink => 'Bio::Annotation::DBLink', |
113
|
|
|
|
|
|
|
description => 'Bio::Annotation::SimpleValue', |
114
|
|
|
|
|
|
|
gene_name => 'Bio::Annotation::SimpleValue', |
115
|
|
|
|
|
|
|
ontology_term => 'Bio::Annotation::OntologyTerm', |
116
|
|
|
|
|
|
|
reference => 'Bio::Annotation::Reference', |
117
|
|
|
|
|
|
|
__DEFAULT__ => 'Bio::Annotation::SimpleValue', |
118
|
|
|
|
|
|
|
); |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
our %tag2text = ( |
121
|
|
|
|
|
|
|
'Bio::Annotation::Comment' => 'text', |
122
|
|
|
|
|
|
|
'Bio::Annotation::DBLink' => 'primary_id', |
123
|
|
|
|
|
|
|
'Bio::Annotation::SimpleValue' => 'value', |
124
|
|
|
|
|
|
|
'Bio::Annotation::SimpleValue' => 'value', |
125
|
|
|
|
|
|
|
'Bio::Annotation::OntologyTerm' => 'name', |
126
|
|
|
|
|
|
|
'Bio::Annotation::Reference' => 'title', |
127
|
|
|
|
|
|
|
__DEFAULT__ => 'value', |
128
|
|
|
|
|
|
|
); |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
###################################### |
131
|
|
|
|
|
|
|
#get_SeqFeatures |
132
|
|
|
|
|
|
|
#display_name |
133
|
|
|
|
|
|
|
#primary_tag |
134
|
|
|
|
|
|
|
#source_tag x with warning |
135
|
|
|
|
|
|
|
#has_tag |
136
|
|
|
|
|
|
|
#get_tag_values |
137
|
|
|
|
|
|
|
#get_tagset_values |
138
|
|
|
|
|
|
|
#get_all_tags |
139
|
|
|
|
|
|
|
#attach_seq |
140
|
|
|
|
|
|
|
#seq x |
141
|
|
|
|
|
|
|
#entire_seq x |
142
|
|
|
|
|
|
|
#seq_id |
143
|
|
|
|
|
|
|
#gff_string |
144
|
|
|
|
|
|
|
#_static_gff_handler |
145
|
|
|
|
|
|
|
#start x |
146
|
|
|
|
|
|
|
#end x |
147
|
|
|
|
|
|
|
#strand x |
148
|
|
|
|
|
|
|
#location |
149
|
|
|
|
|
|
|
#primary_id |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
=head1 PREAMBLE |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
Okay, where to start... |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
The original idea for this class appears to lump all SeqFeatureI data |
156
|
|
|
|
|
|
|
(primary_tag, source_tag, etc) into AnnotationI objects into an |
157
|
|
|
|
|
|
|
Bio::Annotation::Collection. The type is then checked against SOFA. |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
There have been several requests to have type checking be optionally run. |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
Bio::FeatureHolderI::create_hierarchy_from_ParentIDs |
162
|
|
|
|
|
|
|
Bio::FeatureHolderI::feature_count |
163
|
|
|
|
|
|
|
Bio::FeatureHolderI::get_all_SeqFeatures |
164
|
|
|
|
|
|
|
Bio::FeatureHolderI::set_ParentIDs_from_hierarchy |
165
|
|
|
|
|
|
|
Bio::RangeI::contains |
166
|
|
|
|
|
|
|
Bio::RangeI::disconnected_ranges |
167
|
|
|
|
|
|
|
Bio::RangeI::equals |
168
|
|
|
|
|
|
|
Bio::RangeI::intersection |
169
|
|
|
|
|
|
|
Bio::RangeI::offsetStranded |
170
|
|
|
|
|
|
|
Bio::RangeI::overlap_extent |
171
|
|
|
|
|
|
|
Bio::RangeI::overlaps |
172
|
|
|
|
|
|
|
Bio::RangeI::subtract |
173
|
|
|
|
|
|
|
Bio::RangeI::union |
174
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::Dumper |
175
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::MAX_TYPE_CACHE_MEMBERS |
176
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::add_Annotation |
177
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::add_SeqFeature |
178
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::add_tag_value |
179
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::add_target |
180
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::annotation |
181
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::attach_seq |
182
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::display_name |
183
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::each_target |
184
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::end |
185
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::entire_seq |
186
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::frame |
187
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::from_feature |
188
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::get_Annotations |
189
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::get_SeqFeatures |
190
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::get_all_tags |
191
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::get_tag_values |
192
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::get_tagset_values |
193
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::has_tag |
194
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::length |
195
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::location |
196
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::name |
197
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::new |
198
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::phase |
199
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::primary_tag |
200
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::remove_Annotations |
201
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::remove_SeqFeatures |
202
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::remove_tag |
203
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::score |
204
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::seq |
205
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::seq_id |
206
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::source |
207
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::source_tag |
208
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::start |
209
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::strand |
210
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::type |
211
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::uri_escape |
212
|
|
|
|
|
|
|
Bio::SeqFeature::Annotated::uri_unescape |
213
|
|
|
|
|
|
|
Bio::SeqFeature::TypedSeqFeatureI::croak |
214
|
|
|
|
|
|
|
Bio::SeqFeature::TypedSeqFeatureI::ontology_term |
215
|
|
|
|
|
|
|
Bio::SeqFeatureI::generate_unique_persistent_id |
216
|
|
|
|
|
|
|
Bio::SeqFeatureI::gff_string |
217
|
|
|
|
|
|
|
Bio::SeqFeatureI::primary_id |
218
|
|
|
|
|
|
|
Bio::SeqFeatureI::spliced_seq |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
=cut |
221
|
|
|
|
|
|
|
|
222
|
|
|
|
|
|
|
sub new { |
223
|
59
|
|
|
59
|
1
|
131
|
my ( $caller, @args) = @_; |
224
|
59
|
|
|
|
|
260
|
my ($self) = $caller->SUPER::new(@args); |
225
|
|
|
|
|
|
|
|
226
|
59
|
|
|
|
|
643
|
$self->_initialize(@args); |
227
|
|
|
|
|
|
|
|
228
|
59
|
|
|
|
|
137
|
return $self; |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub _initialize { |
232
|
59
|
|
|
59
|
|
130
|
my ($self,@args) = @_; |
233
|
59
|
|
|
|
|
314
|
my ($start, $end, $strand, $frame, $phase, $score, |
234
|
|
|
|
|
|
|
$name, $annot, $location, |
235
|
|
|
|
|
|
|
$display_name, # deprecate |
236
|
|
|
|
|
|
|
$seq_id, $type,$source,$feature |
237
|
|
|
|
|
|
|
) = |
238
|
|
|
|
|
|
|
$self->_rearrange([qw(START |
239
|
|
|
|
|
|
|
END |
240
|
|
|
|
|
|
|
STRAND |
241
|
|
|
|
|
|
|
FRAME |
242
|
|
|
|
|
|
|
PHASE |
243
|
|
|
|
|
|
|
SCORE |
244
|
|
|
|
|
|
|
NAME |
245
|
|
|
|
|
|
|
ANNOTATION |
246
|
|
|
|
|
|
|
LOCATION |
247
|
|
|
|
|
|
|
DISPLAY_NAME |
248
|
|
|
|
|
|
|
SEQ_ID |
249
|
|
|
|
|
|
|
TYPE |
250
|
|
|
|
|
|
|
SOURCE |
251
|
|
|
|
|
|
|
FEATURE |
252
|
|
|
|
|
|
|
)], @args); |
253
|
59
|
100
|
|
|
|
452
|
defined $start && $self->start($start); |
254
|
59
|
100
|
|
|
|
140
|
defined $end && $self->end($end); |
255
|
59
|
100
|
|
|
|
152
|
defined $strand && $self->strand($strand); |
256
|
59
|
50
|
|
|
|
137
|
defined $frame && $self->frame($frame); |
257
|
59
|
50
|
|
|
|
108
|
defined $phase && $self->phase($phase); |
258
|
59
|
50
|
|
|
|
121
|
defined $score && $self->score($score); |
259
|
59
|
50
|
33
|
|
|
236
|
defined $source && ref($source) ? $self->source($source) : $self->source_tag($source); |
260
|
59
|
50
|
33
|
|
|
877
|
defined $type && ref($type) ? $self->type($type) : $self->primary_tag($type); |
261
|
59
|
50
|
|
|
|
124
|
defined $location && $self->location($location); |
262
|
59
|
50
|
|
|
|
109
|
defined $annot && $self->annotation($annot); |
263
|
59
|
50
|
|
|
|
112
|
defined $feature && $self->from_feature($feature); |
264
|
|
|
|
|
|
|
|
265
|
59
|
50
|
33
|
|
|
124
|
if( defined($display_name) && defined($name) ){ |
266
|
0
|
|
|
|
|
0
|
$self->throw('Cannot define (-id and -seq_id) or (-name and -display_name) attributes'); |
267
|
|
|
|
|
|
|
} |
268
|
59
|
50
|
|
|
|
105
|
defined $seq_id && $self->seq_id($seq_id); |
269
|
59
|
50
|
0
|
|
|
227
|
defined ($name || $display_name) && $self->name($name || $display_name); |
|
|
|
33
|
|
|
|
|
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=head1 ATTRIBUTE ACCESSORS FOR Bio::SeqFeature::Annotated |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
=cut |
275
|
|
|
|
|
|
|
|
276
|
|
|
|
|
|
|
=head2 from_feature |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
Usage: $obj->from_feature($myfeature); |
279
|
|
|
|
|
|
|
Desc : initialize this object with the contents of another feature |
280
|
|
|
|
|
|
|
object. Useful for converting objects like |
281
|
|
|
|
|
|
|
L to this class |
282
|
|
|
|
|
|
|
Ret : nothing meaningful |
283
|
|
|
|
|
|
|
Args : a single object of some other feature type, |
284
|
|
|
|
|
|
|
Side Effects: throws error on failure |
285
|
|
|
|
|
|
|
Example: |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=cut |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
sub from_feature { |
290
|
0
|
|
|
0
|
1
|
0
|
my ($self,$feat,%opts) = @_; |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
# should deal with any SeqFeatureI implementation (i.e. we don't want to |
293
|
|
|
|
|
|
|
# automatically force a OO-heavy implementation on all classes) |
294
|
0
|
0
|
0
|
|
|
0
|
ref($feat) && ($feat->isa('Bio::SeqFeatureI')) |
295
|
|
|
|
|
|
|
or $self->throw('invalid arguments to from_feature'); |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
#TODO: add overrides in opts for these values, so people don't have to screw up their feature object |
298
|
|
|
|
|
|
|
#if they don't want to |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
### set most of the data |
301
|
0
|
|
|
|
|
0
|
foreach my $fieldname (qw/ start end strand frame score location seq_id source_tag primary_tag/) { |
302
|
|
|
|
|
|
|
#no strict 'refs'; #using symbolic refs, yes, but using them for methods is allowed now |
303
|
0
|
|
|
|
|
0
|
$self->$fieldname( $feat->$fieldname ); |
304
|
|
|
|
|
|
|
} |
305
|
|
|
|
|
|
|
|
306
|
|
|
|
|
|
|
# now pick up the annotations/tags of the other feature |
307
|
|
|
|
|
|
|
# We'll use AnnotationAdaptor to convert everything over |
308
|
|
|
|
|
|
|
|
309
|
0
|
|
|
|
|
0
|
my %no_copy = map {$_ => 1} qw/seq_id source type frame phase score/; |
|
0
|
|
|
|
|
0
|
|
310
|
0
|
|
|
|
|
0
|
my $adaptor = Bio::SeqFeature::AnnotationAdaptor->new(-feature => $feat); |
311
|
0
|
|
|
|
|
0
|
for my $key ( $adaptor->get_all_annotation_keys() ) { |
312
|
0
|
0
|
|
|
|
0
|
next if $no_copy{$key}; |
313
|
0
|
|
|
|
|
0
|
my @values = $adaptor->get_Annotations($key); |
314
|
0
|
|
|
|
|
0
|
@values = _aggregate_scalar_annotations(\%opts,$key,@values); |
315
|
0
|
|
|
|
|
0
|
foreach my $val (@values) { |
316
|
0
|
|
|
|
|
0
|
$self->add_Annotation($key,$val) |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
} |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
#given a key and its values, make the values into |
321
|
|
|
|
|
|
|
#Bio::Annotation::\w+ objects |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub _aggregate_scalar_annotations { |
324
|
0
|
|
|
0
|
|
0
|
my ($opts,$key,@values) = @_; |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
#anything that's not an object, make it a SimpleValue |
327
|
0
|
0
|
|
|
|
0
|
@values = map { ref($_) ? $_ : Bio::Annotation::SimpleValue->new(-value => $_) } @values; |
|
0
|
|
|
|
|
0
|
|
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
#try to make Target objects |
330
|
0
|
0
|
0
|
|
|
0
|
if($key eq 'Target' && (@values == 3 || @values == 4) |
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
|
|
0
|
0
|
|
|
|
|
331
|
0
|
|
|
|
|
0
|
&& @values == grep {$_->isa('Bio::Annotation::SimpleValue')} @values |
332
|
|
|
|
|
|
|
) { |
333
|
0
|
|
|
|
|
0
|
@values = map {$_->value} @values; |
|
0
|
|
|
|
|
0
|
|
334
|
|
|
|
|
|
|
#make a strand if it doesn't have one, enforcing start <= end |
335
|
0
|
0
|
|
|
|
0
|
if(@values == 3) { |
336
|
0
|
0
|
|
|
|
0
|
if($values[1] <= $values[2]) { |
337
|
0
|
|
|
|
|
0
|
$values[3] = '+'; |
338
|
|
|
|
|
|
|
} else { |
339
|
0
|
|
|
|
|
0
|
@values[1,2] = @values[2,1]; |
340
|
0
|
|
|
|
|
0
|
$values[3] = '-'; |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
} |
343
|
0
|
|
|
|
|
0
|
return ( Bio::Annotation::Target->new( -target_id => $values[0], |
344
|
|
|
|
|
|
|
-start => $values[1], |
345
|
|
|
|
|
|
|
-end => $values[2], |
346
|
|
|
|
|
|
|
-strand => $values[3], |
347
|
|
|
|
|
|
|
) |
348
|
|
|
|
|
|
|
); |
349
|
|
|
|
|
|
|
} |
350
|
|
|
|
|
|
|
#try to make DBLink objects |
351
|
|
|
|
|
|
|
elsif($key eq 'dblink' || $key eq 'Dbxref') { |
352
|
|
|
|
|
|
|
return map { |
353
|
0
|
0
|
|
|
|
0
|
if( /:/ ) { #convert to a DBLink if it has a colon in it |
|
0
|
|
|
|
|
0
|
|
354
|
0
|
|
|
|
|
0
|
my ($db,$id) = split /:/,$_->value; |
355
|
0
|
|
|
|
|
0
|
Bio::Annotation::DBLink->new( -database => $db, |
356
|
|
|
|
|
|
|
-primary_id => $id, |
357
|
|
|
|
|
|
|
); |
358
|
|
|
|
|
|
|
} else { #otherwise leave as a SimpleValue |
359
|
0
|
|
|
|
|
0
|
$_ |
360
|
|
|
|
|
|
|
} |
361
|
|
|
|
|
|
|
} @values; |
362
|
|
|
|
|
|
|
} |
363
|
|
|
|
|
|
|
#make OntologyTerm objects |
364
|
|
|
|
|
|
|
elsif($key eq 'Ontology_term') { |
365
|
0
|
|
|
|
|
0
|
return map { Bio::Annotation::OntologyTerm->new(-identifier => $_->value) } @values |
|
0
|
|
|
|
|
0
|
|
366
|
|
|
|
|
|
|
} |
367
|
|
|
|
|
|
|
#make Comment objects |
368
|
|
|
|
|
|
|
elsif($key eq 'comment') { |
369
|
0
|
|
|
|
|
0
|
return map { Bio::Annotation::Comment->new( -text => $_->value ) } @values; |
|
0
|
|
|
|
|
0
|
|
370
|
|
|
|
|
|
|
} |
371
|
|
|
|
|
|
|
|
372
|
0
|
|
|
|
|
0
|
return @values; |
373
|
|
|
|
|
|
|
} |
374
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
|
376
|
|
|
|
|
|
|
=head2 seq_id() |
377
|
|
|
|
|
|
|
|
378
|
|
|
|
|
|
|
Usage : $obj->seq_id($newval) |
379
|
|
|
|
|
|
|
Function: holds a string corresponding to the unique |
380
|
|
|
|
|
|
|
seq_id of the sequence underlying the feature |
381
|
|
|
|
|
|
|
(e.g. database accession or primary key). |
382
|
|
|
|
|
|
|
Returns : string representing the seq_id. |
383
|
|
|
|
|
|
|
Args : on set, some string or a Bio::Annotation::SimpleValue object. |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
=cut |
386
|
|
|
|
|
|
|
|
387
|
|
|
|
|
|
|
sub seq_id { |
388
|
69
|
|
|
69
|
1
|
5607
|
my($self,$val) = @_; |
389
|
69
|
100
|
|
|
|
176
|
if (defined($val)) { |
390
|
59
|
|
|
|
|
96
|
my $term = undef; |
391
|
59
|
50
|
0
|
|
|
119
|
if (!ref($val)) { |
|
|
0
|
|
|
|
|
|
392
|
59
|
|
|
|
|
199
|
$term = Bio::Annotation::SimpleValue->new(-value => uri_unescape($val)); |
393
|
|
|
|
|
|
|
} elsif (ref($val) && $val->isa('Bio::Annotation::SimpleValue')) { |
394
|
0
|
|
|
|
|
0
|
$term = $val; |
395
|
|
|
|
|
|
|
} |
396
|
59
|
50
|
33
|
|
|
4047
|
if (!defined($term) || ($term->value =~ /^>/)) { |
397
|
0
|
|
|
|
|
0
|
$self->throw('give seq_id() a scalar or Bio::Annotation::SimpleValue object, not '.$val); |
398
|
|
|
|
|
|
|
} |
399
|
59
|
|
|
|
|
503
|
$self->remove_Annotations('seq_id'); |
400
|
59
|
|
|
|
|
1092
|
$self->add_Annotation('seq_id', $term); |
401
|
|
|
|
|
|
|
} |
402
|
|
|
|
|
|
|
|
403
|
69
|
50
|
|
|
|
2291
|
$self->seq_id('.') unless $self->get_Annotations('seq_id'); # make sure we always have something |
404
|
|
|
|
|
|
|
|
405
|
69
|
|
|
|
|
140
|
return ($self->get_Annotations('seq_id'))[0]->value; |
406
|
|
|
|
|
|
|
} |
407
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
=head2 name() |
409
|
|
|
|
|
|
|
|
410
|
|
|
|
|
|
|
Usage : $obj->name($newval) |
411
|
|
|
|
|
|
|
Function: human-readable name for the feature. |
412
|
|
|
|
|
|
|
Returns : value of name (a scalar) |
413
|
|
|
|
|
|
|
Args : on set, new value (a scalar or undef, optional) |
414
|
|
|
|
|
|
|
|
415
|
|
|
|
|
|
|
=cut |
416
|
|
|
|
|
|
|
|
417
|
|
|
|
|
|
|
sub name { |
418
|
0
|
|
|
0
|
1
|
0
|
my($self,$val) = @_; |
419
|
0
|
0
|
|
|
|
0
|
$self->{'name'} = $val if defined($val); |
420
|
0
|
|
|
|
|
0
|
return $self->{'name'}; |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
|
423
|
|
|
|
|
|
|
=head2 type() |
424
|
|
|
|
|
|
|
|
425
|
|
|
|
|
|
|
Usage : $obj->type($newval) |
426
|
|
|
|
|
|
|
Function: a SOFA type for the feature. |
427
|
|
|
|
|
|
|
Returns : Bio::Annotation::OntologyTerm object representing the type. |
428
|
|
|
|
|
|
|
NB: to get a string, use primary_tag(). |
429
|
|
|
|
|
|
|
Args : on set, Bio::Annotation::OntologyTerm object. |
430
|
|
|
|
|
|
|
NB: to set a string (SOFA name or identifier), use primary_tag() |
431
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
=cut |
433
|
|
|
|
|
|
|
|
434
|
3
|
|
|
3
|
|
3302
|
use constant MAX_TYPE_CACHE_MEMBERS => 20; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
6230
|
|
435
|
|
|
|
|
|
|
sub type { |
436
|
155
|
|
|
155
|
1
|
280
|
my($self,$val) = @_; |
437
|
155
|
100
|
|
|
|
315
|
if(defined($val)){ |
438
|
58
|
|
|
|
|
93
|
my $term = undef; |
439
|
|
|
|
|
|
|
|
440
|
58
|
50
|
33
|
|
|
313
|
if(!ref($val)){ |
|
|
50
|
|
|
|
|
|
441
|
0
|
|
|
|
|
0
|
$self->throw("give type() a Bio::Annotation::OntologyTerm object, not a string"); |
442
|
|
|
|
|
|
|
} |
443
|
|
|
|
|
|
|
elsif(ref($val) && $val->isa('Bio::Annotation::OntologyTerm')){ |
444
|
58
|
|
|
|
|
89
|
$term = $val; |
445
|
|
|
|
|
|
|
} |
446
|
|
|
|
|
|
|
else { |
447
|
|
|
|
|
|
|
#we have the wrong type of object |
448
|
0
|
|
|
|
|
0
|
$self->throw('give type() a SOFA term name, identifier, or Bio::Annotation::OntologyTerm object, not '.$val); |
449
|
|
|
|
|
|
|
} |
450
|
58
|
|
|
|
|
149
|
$self->remove_Annotations('type'); |
451
|
58
|
|
|
|
|
1049
|
$self->add_Annotation('type',$term); |
452
|
|
|
|
|
|
|
} |
453
|
|
|
|
|
|
|
|
454
|
155
|
|
|
|
|
2412
|
return $self->get_Annotations('type'); |
455
|
|
|
|
|
|
|
} |
456
|
|
|
|
|
|
|
|
457
|
|
|
|
|
|
|
=head2 source() |
458
|
|
|
|
|
|
|
|
459
|
|
|
|
|
|
|
Usage : $obj->source($newval) |
460
|
|
|
|
|
|
|
Function: holds the source of the feature. |
461
|
|
|
|
|
|
|
Returns : a Bio::Annotation::SimpleValue representing the source. |
462
|
|
|
|
|
|
|
NB: to get a string, use source_tag() |
463
|
|
|
|
|
|
|
Args : on set, a Bio::Annotation::SimpleValue object. |
464
|
|
|
|
|
|
|
NB: to set a string, use source_tag() |
465
|
|
|
|
|
|
|
|
466
|
|
|
|
|
|
|
=cut |
467
|
|
|
|
|
|
|
|
468
|
|
|
|
|
|
|
sub source { |
469
|
240
|
|
|
240
|
1
|
4096
|
my($self,$val) = @_; |
470
|
|
|
|
|
|
|
|
471
|
240
|
100
|
|
|
|
429
|
if (defined($val)) { |
472
|
116
|
|
|
|
|
160
|
my $term; |
473
|
116
|
50
|
33
|
|
|
630
|
if (!ref($val)) { |
|
|
50
|
|
|
|
|
|
474
|
0
|
|
|
|
|
0
|
$self->throw("give source() a Bio::Annotation::SimpleValue object, not a string"); |
475
|
|
|
|
|
|
|
#$term = Bio::Annotation::SimpleValue->new(-value => uri_unescape($val)); |
476
|
|
|
|
|
|
|
} elsif (ref($val) && $val->isa('Bio::Annotation::SimpleValue')) { |
477
|
116
|
|
|
|
|
178
|
$term = $val; |
478
|
|
|
|
|
|
|
} else { |
479
|
0
|
|
|
|
|
0
|
$self->throw('give source() a scalar or Bio::Annotation::SimpleValue object, not '.$val); |
480
|
|
|
|
|
|
|
} |
481
|
116
|
|
|
|
|
279
|
$self->remove_Annotations('source'); |
482
|
116
|
|
|
|
|
3637
|
$self->add_Annotation('source', $term); |
483
|
|
|
|
|
|
|
} |
484
|
|
|
|
|
|
|
|
485
|
240
|
100
|
|
|
|
4825
|
unless ($self->get_Annotations('source')) { |
486
|
59
|
|
|
|
|
235
|
$self->source(Bio::Annotation::SimpleValue->new(-value => '.')); |
487
|
|
|
|
|
|
|
} |
488
|
240
|
|
|
|
|
427
|
return $self->get_Annotations('source'); |
489
|
|
|
|
|
|
|
} |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
=head2 score() |
492
|
|
|
|
|
|
|
|
493
|
|
|
|
|
|
|
Usage : $score = $feat->score() |
494
|
|
|
|
|
|
|
$feat->score($score) |
495
|
|
|
|
|
|
|
Function: holds a value corresponding to the score of the feature. |
496
|
|
|
|
|
|
|
Returns : a string representing the score. |
497
|
|
|
|
|
|
|
Args : on set, a scalar or a Bio::Annotation::SimpleValue object. |
498
|
|
|
|
|
|
|
|
499
|
|
|
|
|
|
|
=cut |
500
|
|
|
|
|
|
|
|
501
|
|
|
|
|
|
|
sub score { |
502
|
66
|
|
|
66
|
1
|
5061
|
my $self = shift; |
503
|
66
|
|
|
|
|
93
|
my $val = shift; |
504
|
|
|
|
|
|
|
|
505
|
66
|
100
|
|
|
|
159
|
if(defined($val)){ |
506
|
58
|
|
|
|
|
78
|
my $term = undef; |
507
|
58
|
50
|
0
|
|
|
133
|
if (!ref($val)) { |
|
|
0
|
|
|
|
|
|
508
|
58
|
|
|
|
|
165
|
$term = Bio::Annotation::SimpleValue->new(-value => $val); |
509
|
|
|
|
|
|
|
} elsif (ref($val) && $val->isa('Bio::Annotation::SimpleValue')) { |
510
|
0
|
|
|
|
|
0
|
$term = $val; |
511
|
|
|
|
|
|
|
} |
512
|
|
|
|
|
|
|
|
513
|
58
|
50
|
33
|
|
|
3351
|
if ($term->value ne '.' && |
|
|
|
66
|
|
|
|
|
514
|
|
|
|
|
|
|
(!defined($term) || ($term->value !~ /^[+-]?\d+\.?\d*(e-\d+)?/))) { |
515
|
0
|
|
|
|
|
0
|
$self->throw("'$val' is not a valid score"); |
516
|
|
|
|
|
|
|
} |
517
|
58
|
|
|
|
|
521
|
$self->remove_Annotations('score'); |
518
|
58
|
|
|
|
|
1112
|
$self->add_Annotation('score', $term); |
519
|
|
|
|
|
|
|
} |
520
|
|
|
|
|
|
|
|
521
|
66
|
100
|
|
|
|
2279
|
$self->score('.') unless scalar($self->get_Annotations('score')); # make sure we always have something |
522
|
|
|
|
|
|
|
|
523
|
66
|
|
|
|
|
137
|
return ($self->get_Annotations('score'))[0]->display_text; |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
|
526
|
|
|
|
|
|
|
=head2 phase() |
527
|
|
|
|
|
|
|
|
528
|
|
|
|
|
|
|
Usage : $phase = $feat->phase() |
529
|
|
|
|
|
|
|
$feat->phase($phase) |
530
|
|
|
|
|
|
|
Function: get/set on phase information |
531
|
|
|
|
|
|
|
Returns : a string 0,1,2,'.' |
532
|
|
|
|
|
|
|
Args : on set, one of 0,1,2,'.' or a Bio::Annotation::SimpleValue |
533
|
|
|
|
|
|
|
object holding one of 0,1,2,'.' as its value. |
534
|
|
|
|
|
|
|
|
535
|
|
|
|
|
|
|
=cut |
536
|
|
|
|
|
|
|
|
537
|
|
|
|
|
|
|
sub phase { |
538
|
57
|
|
|
57
|
1
|
79
|
my $self = shift; |
539
|
57
|
|
|
|
|
96
|
my $val = shift; |
540
|
|
|
|
|
|
|
|
541
|
57
|
50
|
|
|
|
124
|
if(defined($val)){ |
542
|
57
|
|
|
|
|
78
|
my $term = undef; |
543
|
57
|
50
|
0
|
|
|
112
|
if (!ref($val)) { |
|
|
0
|
|
|
|
|
|
544
|
57
|
|
|
|
|
155
|
$term = Bio::Annotation::SimpleValue->new(-value => $val); |
545
|
|
|
|
|
|
|
} elsif (ref($val) && $val->isa('Bio::Annotation::SimpleValue')) { |
546
|
0
|
|
|
|
|
0
|
$term = $val; |
547
|
|
|
|
|
|
|
} |
548
|
57
|
50
|
33
|
|
|
3388
|
if (!defined($term) || ($term->value !~ /^[0-2.]$/)) { |
549
|
0
|
|
|
|
|
0
|
$self->throw("'$val' is not a valid phase"); |
550
|
|
|
|
|
|
|
} |
551
|
57
|
|
|
|
|
529
|
$self->remove_Annotations('phase'); |
552
|
57
|
|
|
|
|
1047
|
$self->add_Annotation('phase', $term); |
553
|
|
|
|
|
|
|
} |
554
|
|
|
|
|
|
|
|
555
|
57
|
50
|
|
|
|
2217
|
$self->phase('.') unless $self->get_Annotations('phase'); # make sure we always have something |
556
|
|
|
|
|
|
|
|
557
|
57
|
|
|
|
|
108
|
return ($self->get_Annotations('phase'))[0]->value; |
558
|
|
|
|
|
|
|
} |
559
|
|
|
|
|
|
|
|
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
=head2 frame() |
562
|
|
|
|
|
|
|
|
563
|
|
|
|
|
|
|
Usage : $frame = $feat->frame() |
564
|
|
|
|
|
|
|
$feat->frame($phase) |
565
|
|
|
|
|
|
|
Function: get/set on phase information |
566
|
|
|
|
|
|
|
Returns : a string 0,1,2,'.' |
567
|
|
|
|
|
|
|
Args : on set, one of 0,1,2,'.' or a Bio::Annotation::SimpleValue |
568
|
|
|
|
|
|
|
object holding one of 0,1,2,'.' as its value. |
569
|
|
|
|
|
|
|
|
570
|
|
|
|
|
|
|
=cut |
571
|
|
|
|
|
|
|
|
572
|
|
|
|
|
|
|
sub frame { |
573
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
574
|
0
|
|
|
|
|
0
|
my $val = shift; |
575
|
|
|
|
|
|
|
|
576
|
0
|
0
|
|
|
|
0
|
if(defined($val)){ |
577
|
0
|
|
|
|
|
0
|
my $term = undef; |
578
|
0
|
0
|
0
|
|
|
0
|
if (!ref($val)) { |
|
|
0
|
|
|
|
|
|
579
|
0
|
|
|
|
|
0
|
$term = Bio::Annotation::SimpleValue->new(-value => $val); |
580
|
|
|
|
|
|
|
} elsif (ref($val) && $val->isa('Bio::Annotation::SimpleValue')) { |
581
|
0
|
|
|
|
|
0
|
$term = $val; |
582
|
|
|
|
|
|
|
} |
583
|
0
|
0
|
0
|
|
|
0
|
if (!defined($term) || ($term->value !~ /^[0-2.]$/)) { |
584
|
0
|
|
|
|
|
0
|
$self->throw("'$val' is not a valid frame"); |
585
|
|
|
|
|
|
|
} |
586
|
0
|
|
|
|
|
0
|
$self->remove_Annotations('frame'); |
587
|
0
|
|
|
|
|
0
|
$self->add_Annotation('frame', $term); |
588
|
|
|
|
|
|
|
} |
589
|
|
|
|
|
|
|
|
590
|
0
|
0
|
|
|
|
0
|
$self->frame('.') unless $self->get_Annotations('frame'); # make sure we always have something |
591
|
|
|
|
|
|
|
|
592
|
0
|
|
|
|
|
0
|
return ($self->get_Annotations('frame'))[0]->value; |
593
|
|
|
|
|
|
|
} |
594
|
|
|
|
|
|
|
|
595
|
|
|
|
|
|
|
############################################################ |
596
|
|
|
|
|
|
|
|
597
|
|
|
|
|
|
|
=head1 SHORTCUT METHODS TO ACCESS Bio::AnnotatableI INTERFACE METHODS |
598
|
|
|
|
|
|
|
|
599
|
|
|
|
|
|
|
=cut |
600
|
|
|
|
|
|
|
|
601
|
|
|
|
|
|
|
=head2 add_Annotation() |
602
|
|
|
|
|
|
|
|
603
|
|
|
|
|
|
|
Usage : |
604
|
|
|
|
|
|
|
Function: $obj->add_Annotation() is a shortcut to $obj->annotation->add_Annotation |
605
|
|
|
|
|
|
|
Returns : |
606
|
|
|
|
|
|
|
Args : |
607
|
|
|
|
|
|
|
|
608
|
|
|
|
|
|
|
=cut |
609
|
|
|
|
|
|
|
|
610
|
|
|
|
|
|
|
sub add_Annotation { |
611
|
507
|
|
|
507
|
1
|
948
|
my ($self,@args) = @_; |
612
|
507
|
|
|
|
|
788
|
return $self->annotation->add_Annotation(@args); |
613
|
|
|
|
|
|
|
} |
614
|
|
|
|
|
|
|
|
615
|
|
|
|
|
|
|
=head2 remove_Annotations() |
616
|
|
|
|
|
|
|
|
617
|
|
|
|
|
|
|
Usage : |
618
|
|
|
|
|
|
|
Function: $obj->remove_Annotations() is a shortcut to $obj->annotation->remove_Annotations |
619
|
|
|
|
|
|
|
Returns : |
620
|
|
|
|
|
|
|
Args : |
621
|
|
|
|
|
|
|
|
622
|
|
|
|
|
|
|
=cut |
623
|
|
|
|
|
|
|
|
624
|
|
|
|
|
|
|
sub remove_Annotations { |
625
|
348
|
|
|
348
|
1
|
616
|
my ($self,@args) = @_; |
626
|
348
|
|
|
|
|
581
|
return $self->annotation->remove_Annotations(@args); |
627
|
|
|
|
|
|
|
} |
628
|
|
|
|
|
|
|
|
629
|
|
|
|
|
|
|
############################################################ |
630
|
|
|
|
|
|
|
|
631
|
|
|
|
|
|
|
=head1 INTERFACE METHODS FOR Bio::SeqFeatureI |
632
|
|
|
|
|
|
|
|
633
|
|
|
|
|
|
|
Note that no methods are deprecated. Any SeqFeatureI methods must return |
634
|
|
|
|
|
|
|
strings (no objects). |
635
|
|
|
|
|
|
|
|
636
|
|
|
|
|
|
|
=cut |
637
|
|
|
|
|
|
|
|
638
|
|
|
|
|
|
|
=head2 display_name() |
639
|
|
|
|
|
|
|
|
640
|
|
|
|
|
|
|
=cut |
641
|
|
|
|
|
|
|
|
642
|
|
|
|
|
|
|
sub display_name { |
643
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
644
|
0
|
|
|
|
|
0
|
return $self->name(@_); |
645
|
|
|
|
|
|
|
} |
646
|
|
|
|
|
|
|
|
647
|
|
|
|
|
|
|
=head2 primary_tag() |
648
|
|
|
|
|
|
|
|
649
|
|
|
|
|
|
|
=cut |
650
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
sub primary_tag { |
652
|
97
|
|
|
97
|
1
|
13279
|
my $self = shift; |
653
|
97
|
100
|
|
|
|
237
|
if (@_) { |
654
|
59
|
|
|
|
|
86
|
my $val = shift; |
655
|
59
|
|
|
|
|
75
|
my $term; |
656
|
59
|
50
|
33
|
|
|
232
|
if(!ref($val) && $val){ |
657
|
|
|
|
|
|
|
#we have a plain text annotation coming in. try to map it to SOFA. |
658
|
|
|
|
|
|
|
|
659
|
0
|
|
|
|
|
0
|
our %__type_cache; #a little cache of plaintext types we've already seen |
660
|
|
|
|
|
|
|
|
661
|
|
|
|
|
|
|
#clear our cache if it gets too big |
662
|
0
|
0
|
|
|
|
0
|
if(scalar(keys %__type_cache) > MAX_TYPE_CACHE_MEMBERS) { |
663
|
0
|
|
|
|
|
0
|
%__type_cache = (); |
664
|
|
|
|
|
|
|
} |
665
|
|
|
|
|
|
|
|
666
|
|
|
|
|
|
|
#set $term to either a cached value, or look up a new one, throwing |
667
|
|
|
|
|
|
|
#up if not found |
668
|
0
|
|
|
|
|
0
|
my $anntext = $val; |
669
|
0
|
0
|
|
|
|
0
|
if ($__type_cache{$anntext}) { |
670
|
0
|
|
|
|
|
0
|
$term = $__type_cache{$anntext}; |
671
|
|
|
|
|
|
|
} else { |
672
|
0
|
|
|
|
|
0
|
my $sofa = Bio::Ontology::OntologyStore->get_instance->get_ontology('Sequence Ontology OBO'); |
673
|
0
|
0
|
|
|
|
0
|
my ($soterm) = $anntext =~ /^\D+:\d+$/ #does it look like an ident? |
674
|
|
|
|
|
|
|
? ($sofa->find_terms(-identifier => $anntext))[0] #yes, lookup by ident |
675
|
|
|
|
|
|
|
: ($sofa->find_terms(-name => $anntext))[0]; #no, lookup by name |
676
|
|
|
|
|
|
|
#throw if it's not in SOFA |
677
|
0
|
0
|
|
|
|
0
|
unless($soterm){ |
678
|
0
|
|
|
|
|
0
|
$self->throw("couldn't find a SOFA term matching type '$val'."); |
679
|
|
|
|
|
|
|
} |
680
|
0
|
|
|
|
|
0
|
my $newterm = Bio::Annotation::OntologyTerm->new; |
681
|
0
|
|
|
|
|
0
|
$newterm->term($soterm); |
682
|
0
|
|
|
|
|
0
|
$term = $newterm; |
683
|
|
|
|
|
|
|
} |
684
|
|
|
|
|
|
|
|
685
|
0
|
|
|
|
|
0
|
$self->type($term); |
686
|
|
|
|
|
|
|
} |
687
|
|
|
|
|
|
|
} |
688
|
|
|
|
|
|
|
|
689
|
97
|
|
100
|
|
|
227
|
my $t = $self->type() || return; |
690
|
38
|
|
|
|
|
102
|
return $t->name; |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
|
693
|
|
|
|
|
|
|
=head2 source_tag() |
694
|
|
|
|
|
|
|
|
695
|
|
|
|
|
|
|
=cut |
696
|
|
|
|
|
|
|
|
697
|
|
|
|
|
|
|
sub source_tag { |
698
|
124
|
|
|
124
|
1
|
5373
|
my $self = shift; |
699
|
124
|
100
|
|
|
|
270
|
if (@_) { |
700
|
116
|
|
|
|
|
172
|
my $val = shift; |
701
|
116
|
100
|
66
|
|
|
389
|
if(!ref($val) && $val){ |
702
|
57
|
|
|
|
|
126
|
my $term = Bio::Annotation::SimpleValue->new(-value => uri_unescape($val)); |
703
|
57
|
|
|
|
|
3591
|
$self->source($term); |
704
|
|
|
|
|
|
|
} |
705
|
|
|
|
|
|
|
} |
706
|
124
|
|
50
|
|
|
251
|
my $t = $self->source() || return; |
707
|
124
|
|
|
|
|
271
|
return $t->display_text; |
708
|
|
|
|
|
|
|
} |
709
|
|
|
|
|
|
|
|
710
|
|
|
|
|
|
|
|
711
|
|
|
|
|
|
|
=head2 attach_seq() |
712
|
|
|
|
|
|
|
|
713
|
|
|
|
|
|
|
Usage : $sf->attach_seq($seq) |
714
|
|
|
|
|
|
|
Function: Attaches a Bio::Seq object to this feature. This |
715
|
|
|
|
|
|
|
Bio::Seq object is for the *entire* sequence: ie |
716
|
|
|
|
|
|
|
from 1 to 10000 |
717
|
|
|
|
|
|
|
Returns : TRUE on success |
718
|
|
|
|
|
|
|
Args : a Bio::PrimarySeqI compliant object |
719
|
|
|
|
|
|
|
|
720
|
|
|
|
|
|
|
=cut |
721
|
|
|
|
|
|
|
|
722
|
|
|
|
|
|
|
sub attach_seq { |
723
|
0
|
|
|
0
|
1
|
0
|
my ($self, $seq) = @_; |
724
|
|
|
|
|
|
|
|
725
|
0
|
0
|
0
|
|
|
0
|
if ( ! ($seq && ref($seq) && $seq->isa("Bio::PrimarySeqI")) ) { |
|
|
|
0
|
|
|
|
|
726
|
0
|
|
|
|
|
0
|
$self->throw("Must attach Bio::PrimarySeqI objects to SeqFeatures"); |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
|
729
|
0
|
|
|
|
|
0
|
$self->{'seq'} = $seq; |
730
|
|
|
|
|
|
|
|
731
|
|
|
|
|
|
|
# attach to sub features if they want it |
732
|
0
|
|
|
|
|
0
|
foreach ( $self->get_SeqFeatures() ) { |
733
|
0
|
|
|
|
|
0
|
$_->attach_seq($seq); |
734
|
|
|
|
|
|
|
} |
735
|
0
|
|
|
|
|
0
|
return 1; |
736
|
|
|
|
|
|
|
} |
737
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
=head2 seq() |
739
|
|
|
|
|
|
|
|
740
|
|
|
|
|
|
|
Usage : $tseq = $sf->seq() |
741
|
|
|
|
|
|
|
Function: returns a truncated version of seq() with bounds matching this feature |
742
|
|
|
|
|
|
|
Returns : sub seq (a Bio::PrimarySeqI compliant object) on attached sequence |
743
|
|
|
|
|
|
|
bounded by start & end, or undef if there is no sequence attached |
744
|
|
|
|
|
|
|
Args : none |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
=cut |
747
|
|
|
|
|
|
|
|
748
|
|
|
|
|
|
|
sub seq { |
749
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
750
|
|
|
|
|
|
|
|
751
|
0
|
0
|
|
|
|
0
|
return unless defined($self->entire_seq()); |
752
|
|
|
|
|
|
|
|
753
|
0
|
|
|
|
|
0
|
my $seq = $self->entire_seq->trunc($self->start(), $self->end()); |
754
|
|
|
|
|
|
|
|
755
|
0
|
0
|
0
|
|
|
0
|
if ( defined $self->strand && $self->strand == -1 ) { |
756
|
0
|
|
|
|
|
0
|
$seq = $seq->revcom; |
757
|
|
|
|
|
|
|
} |
758
|
|
|
|
|
|
|
|
759
|
0
|
|
|
|
|
0
|
return $seq; |
760
|
|
|
|
|
|
|
} |
761
|
|
|
|
|
|
|
|
762
|
|
|
|
|
|
|
=head2 entire_seq() |
763
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
Usage : $whole_seq = $sf->entire_seq() |
765
|
|
|
|
|
|
|
Function: gives the entire sequence that this seqfeature is attached to |
766
|
|
|
|
|
|
|
Returns : a Bio::PrimarySeqI compliant object, or undef if there is no |
767
|
|
|
|
|
|
|
sequence attached |
768
|
|
|
|
|
|
|
Args : none |
769
|
|
|
|
|
|
|
|
770
|
|
|
|
|
|
|
=cut |
771
|
|
|
|
|
|
|
|
772
|
|
|
|
|
|
|
sub entire_seq { |
773
|
0
|
|
|
0
|
1
|
0
|
return shift->{'seq'}; |
774
|
|
|
|
|
|
|
} |
775
|
|
|
|
|
|
|
|
776
|
|
|
|
|
|
|
############################################################ |
777
|
|
|
|
|
|
|
|
778
|
|
|
|
|
|
|
=head1 INTERFACE METHODS FOR Bio::RangeI |
779
|
|
|
|
|
|
|
|
780
|
|
|
|
|
|
|
as inherited via Bio::SeqFeatureI |
781
|
|
|
|
|
|
|
|
782
|
|
|
|
|
|
|
=cut |
783
|
|
|
|
|
|
|
|
784
|
|
|
|
|
|
|
=head2 length() |
785
|
|
|
|
|
|
|
|
786
|
|
|
|
|
|
|
Usage : $feature->length() |
787
|
|
|
|
|
|
|
Function: Get the feature length computed as $feat->end - $feat->start + 1 |
788
|
|
|
|
|
|
|
Returns : integer |
789
|
|
|
|
|
|
|
Args : none |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
=cut |
792
|
|
|
|
|
|
|
|
793
|
|
|
|
|
|
|
sub length { |
794
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
795
|
0
|
|
|
|
|
0
|
return $self->end() - $self->start() + 1; |
796
|
|
|
|
|
|
|
} |
797
|
|
|
|
|
|
|
|
798
|
|
|
|
|
|
|
=head2 start() |
799
|
|
|
|
|
|
|
|
800
|
|
|
|
|
|
|
Usage : $obj->start($newval) |
801
|
|
|
|
|
|
|
Function: Get/set on the start coordinate of the feature |
802
|
|
|
|
|
|
|
Returns : integer |
803
|
|
|
|
|
|
|
Args : on set, new value (a scalar or undef, optional) |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
=cut |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
sub start { |
808
|
164
|
|
|
164
|
1
|
6395
|
my ($self,$value) = @_; |
809
|
164
|
|
|
|
|
301
|
return $self->location->start($value); |
810
|
|
|
|
|
|
|
} |
811
|
|
|
|
|
|
|
|
812
|
|
|
|
|
|
|
=head2 end() |
813
|
|
|
|
|
|
|
|
814
|
|
|
|
|
|
|
Usage : $obj->end($newval) |
815
|
|
|
|
|
|
|
Function: Get/set on the end coordinate of the feature |
816
|
|
|
|
|
|
|
Returns : integer |
817
|
|
|
|
|
|
|
Args : on set, new value (a scalar or undef, optional) |
818
|
|
|
|
|
|
|
|
819
|
|
|
|
|
|
|
=cut |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
sub end { |
822
|
164
|
|
|
164
|
1
|
7356
|
my ($self,$value) = @_; |
823
|
164
|
|
|
|
|
288
|
return $self->location->end($value); |
824
|
|
|
|
|
|
|
} |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
=head2 strand() |
827
|
|
|
|
|
|
|
|
828
|
|
|
|
|
|
|
Usage : $strand = $feat->strand($newval) |
829
|
|
|
|
|
|
|
Function: get/set on strand information, being 1,-1 or 0 |
830
|
|
|
|
|
|
|
Returns : -1,1 or 0 |
831
|
|
|
|
|
|
|
Args : on set, new value (a scalar or undef, optional) |
832
|
|
|
|
|
|
|
|
833
|
|
|
|
|
|
|
=cut |
834
|
|
|
|
|
|
|
|
835
|
|
|
|
|
|
|
sub strand { |
836
|
67
|
|
|
67
|
1
|
5144
|
my $self = shift; |
837
|
67
|
|
|
|
|
122
|
return $self->location->strand(@_); |
838
|
|
|
|
|
|
|
} |
839
|
|
|
|
|
|
|
|
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
############################################################ |
842
|
|
|
|
|
|
|
|
843
|
|
|
|
|
|
|
=head1 INTERFACE METHODS FOR Bio::FeatureHolderI |
844
|
|
|
|
|
|
|
|
845
|
|
|
|
|
|
|
This includes methods for retrieving, adding, and removing |
846
|
|
|
|
|
|
|
features. Since this is already a feature, features held by this |
847
|
|
|
|
|
|
|
feature holder are essentially sub-features. |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
=cut |
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
=head2 get_SeqFeatures |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
Usage : @feats = $feat->get_SeqFeatures(); |
854
|
|
|
|
|
|
|
Function: Returns an array of Bio::SeqFeatureI objects |
855
|
|
|
|
|
|
|
Returns : An array |
856
|
|
|
|
|
|
|
Args : none |
857
|
|
|
|
|
|
|
|
858
|
|
|
|
|
|
|
=cut |
859
|
|
|
|
|
|
|
|
860
|
|
|
|
|
|
|
sub get_SeqFeatures { |
861
|
6
|
100
|
|
6
|
1
|
4002
|
return @{ shift->{'sub_array'} || []}; |
|
6
|
|
|
|
|
48
|
|
862
|
|
|
|
|
|
|
} |
863
|
|
|
|
|
|
|
|
864
|
|
|
|
|
|
|
=head2 add_SeqFeature() |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
Usage : $feat->add_SeqFeature($subfeat); |
867
|
|
|
|
|
|
|
$feat->add_SeqFeature($subfeat,'EXPAND') |
868
|
|
|
|
|
|
|
Function: adds a SeqFeature into the subSeqFeature array. |
869
|
|
|
|
|
|
|
with no 'EXPAND' qualifer, subfeat will be tested |
870
|
|
|
|
|
|
|
as to whether it lies inside the parent, and throw |
871
|
|
|
|
|
|
|
an exception if not. |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
If EXPAND is used, the parent''s start/end/strand will |
874
|
|
|
|
|
|
|
be adjusted so that it grows to accommodate the new |
875
|
|
|
|
|
|
|
subFeature |
876
|
|
|
|
|
|
|
Example : |
877
|
|
|
|
|
|
|
Returns : nothing |
878
|
|
|
|
|
|
|
Args : a Bio::SeqFeatureI object |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
=cut |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
sub add_SeqFeature { |
883
|
24
|
|
|
24
|
1
|
49
|
my ($self,$val, $expand) = @_; |
884
|
|
|
|
|
|
|
|
885
|
24
|
50
|
|
|
|
46
|
return unless $val; |
886
|
|
|
|
|
|
|
|
887
|
24
|
50
|
33
|
|
|
133
|
if ((!ref($val)) || !$val->isa('Bio::SeqFeatureI') ) { |
888
|
0
|
0
|
|
|
|
0
|
$self->throw((ref($val) ? ref($val) : $val) |
889
|
|
|
|
|
|
|
." does not implement Bio::SeqFeatureI."); |
890
|
|
|
|
|
|
|
} |
891
|
|
|
|
|
|
|
|
892
|
24
|
50
|
33
|
|
|
68
|
if($expand && ($expand eq 'EXPAND')) { |
893
|
0
|
|
|
|
|
0
|
$self->_expand_region($val); |
894
|
|
|
|
|
|
|
} else { |
895
|
24
|
50
|
|
|
|
127
|
if ( !$self->contains($val) ) { |
896
|
0
|
|
|
|
|
0
|
$self->warn("$val is not contained within parent feature, and expansion is not valid, ignoring."); |
897
|
0
|
|
|
|
|
0
|
return; |
898
|
|
|
|
|
|
|
} |
899
|
|
|
|
|
|
|
} |
900
|
|
|
|
|
|
|
|
901
|
24
|
|
|
|
|
404
|
push(@{$self->{'sub_array'}},$val); |
|
24
|
|
|
|
|
103
|
|
902
|
|
|
|
|
|
|
} |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
=head2 remove_SeqFeatures() |
905
|
|
|
|
|
|
|
|
906
|
|
|
|
|
|
|
Usage : $obj->remove_SeqFeatures |
907
|
|
|
|
|
|
|
Function: Removes all sub SeqFeatures. If you want to remove only a subset, |
908
|
|
|
|
|
|
|
remove that subset from the returned array, and add back the rest. |
909
|
|
|
|
|
|
|
Returns : The array of Bio::SeqFeatureI implementing sub-features that was |
910
|
|
|
|
|
|
|
deleted from this feature. |
911
|
|
|
|
|
|
|
Args : none |
912
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
=cut |
914
|
|
|
|
|
|
|
|
915
|
|
|
|
|
|
|
sub remove_SeqFeatures { |
916
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
917
|
|
|
|
|
|
|
|
918
|
0
|
0
|
|
|
|
0
|
my @subfeats = @{$self->{'sub_array'} || []}; |
|
0
|
|
|
|
|
0
|
|
919
|
0
|
|
|
|
|
0
|
$self->{'sub_array'} = []; # zap the array. |
920
|
0
|
|
|
|
|
0
|
return @subfeats; |
921
|
|
|
|
|
|
|
} |
922
|
|
|
|
|
|
|
|
923
|
|
|
|
|
|
|
############################################################ |
924
|
|
|
|
|
|
|
|
925
|
|
|
|
|
|
|
=head1 INTERFACE METHODS FOR Bio::AnnotatableI |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
=cut |
928
|
|
|
|
|
|
|
|
929
|
|
|
|
|
|
|
=head2 annotation() |
930
|
|
|
|
|
|
|
|
931
|
|
|
|
|
|
|
Usage : $obj->annotation($annot_obj) |
932
|
|
|
|
|
|
|
Function: Get/set the annotation collection object for annotating this |
933
|
|
|
|
|
|
|
feature. |
934
|
|
|
|
|
|
|
Returns : A Bio::AnnotationCollectionI object |
935
|
|
|
|
|
|
|
Args : newvalue (optional) |
936
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
=cut |
938
|
|
|
|
|
|
|
|
939
|
|
|
|
|
|
|
sub annotation { |
940
|
1946
|
|
|
1946
|
1
|
2730
|
my ($obj,$value) = @_; |
941
|
|
|
|
|
|
|
|
942
|
|
|
|
|
|
|
# we are smart if someone references the object and there hasn't been |
943
|
|
|
|
|
|
|
# one set yet |
944
|
1946
|
100
|
66
|
|
|
5896
|
if(defined $value || ! defined $obj->{'annotation'} ) { |
945
|
59
|
50
|
|
|
|
267
|
$value = Bio::Annotation::Collection->new() unless ( defined $value ); |
946
|
59
|
|
|
|
|
3192
|
$obj->{'annotation'} = $value; |
947
|
|
|
|
|
|
|
} |
948
|
1946
|
|
|
|
|
4382
|
return $obj->{'annotation'}; |
949
|
|
|
|
|
|
|
} |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
############################################################ |
952
|
|
|
|
|
|
|
|
953
|
|
|
|
|
|
|
=head2 location() |
954
|
|
|
|
|
|
|
|
955
|
|
|
|
|
|
|
Usage : my $location = $seqfeature->location() |
956
|
|
|
|
|
|
|
Function: returns a location object suitable for identifying location |
957
|
|
|
|
|
|
|
of feature on sequence or parent feature |
958
|
|
|
|
|
|
|
Returns : Bio::LocationI object |
959
|
|
|
|
|
|
|
Args : [optional] Bio::LocationI object to set the value to. |
960
|
|
|
|
|
|
|
|
961
|
|
|
|
|
|
|
=cut |
962
|
|
|
|
|
|
|
|
963
|
|
|
|
|
|
|
sub location { |
964
|
395
|
|
|
395
|
1
|
579
|
my($self, $value ) = @_; |
965
|
|
|
|
|
|
|
|
966
|
395
|
50
|
|
|
|
974
|
if (defined($value)) { |
|
|
100
|
|
|
|
|
|
967
|
0
|
0
|
0
|
|
|
0
|
unless (ref($value) and $value->isa('Bio::LocationI')) { |
968
|
0
|
|
|
|
|
0
|
$self->throw("object $value pretends to be a location but ". |
969
|
|
|
|
|
|
|
"does not implement Bio::LocationI"); |
970
|
|
|
|
|
|
|
} |
971
|
0
|
|
|
|
|
0
|
$self->{'location'} = $value; |
972
|
|
|
|
|
|
|
} |
973
|
|
|
|
|
|
|
elsif (! $self->{'location'}) { |
974
|
|
|
|
|
|
|
# guarantees a real location object is returned every time |
975
|
59
|
|
|
|
|
233
|
$self->{'location'} = Bio::Location::Simple->new(); |
976
|
|
|
|
|
|
|
} |
977
|
395
|
|
|
|
|
3850
|
return $self->{'location'}; |
978
|
|
|
|
|
|
|
} |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
=head2 add_target() |
981
|
|
|
|
|
|
|
|
982
|
|
|
|
|
|
|
Usage : $seqfeature->add_target(Bio::LocatableSeq->new(...)); |
983
|
|
|
|
|
|
|
Function: adds a target location on another reference sequence for this feature |
984
|
|
|
|
|
|
|
Returns : true on success |
985
|
|
|
|
|
|
|
Args : a Bio::LocatableSeq object |
986
|
|
|
|
|
|
|
|
987
|
|
|
|
|
|
|
=cut |
988
|
|
|
|
|
|
|
|
989
|
|
|
|
|
|
|
sub add_target { |
990
|
0
|
|
|
0
|
1
|
0
|
my ($self,$seq) = @_; |
991
|
0
|
0
|
0
|
|
|
0
|
$self->throw("$seq is not a Bio::LocatableSeq, bailing out") unless ref($seq) and seq->isa('Bio::LocatableSeq'); |
992
|
0
|
|
|
|
|
0
|
push @{ $self->{'targets'} }, $seq; |
|
0
|
|
|
|
|
0
|
|
993
|
0
|
|
|
|
|
0
|
return $seq; |
994
|
|
|
|
|
|
|
} |
995
|
|
|
|
|
|
|
|
996
|
|
|
|
|
|
|
=head2 each_target() |
997
|
|
|
|
|
|
|
|
998
|
|
|
|
|
|
|
Usage : @targets = $seqfeature->each_target(); |
999
|
|
|
|
|
|
|
Function: Returns a list of Bio::LocatableSeqs which are the locations of this object. |
1000
|
|
|
|
|
|
|
To obtain the "primary" location, see L. |
1001
|
|
|
|
|
|
|
Returns : a list of 0..N Bio::LocatableSeq objects |
1002
|
|
|
|
|
|
|
Args : none |
1003
|
|
|
|
|
|
|
|
1004
|
|
|
|
|
|
|
=cut |
1005
|
|
|
|
|
|
|
|
1006
|
|
|
|
|
|
|
sub each_target { |
1007
|
0
|
|
|
0
|
1
|
0
|
my ($self) = @_; |
1008
|
0
|
0
|
|
|
|
0
|
return $self->{'targets'} ? @{ $self->{'targets'} } : (); |
|
0
|
|
|
|
|
0
|
|
1009
|
|
|
|
|
|
|
} |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
=head2 _expand_region |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
Title : _expand_region |
1014
|
|
|
|
|
|
|
Usage : $self->_expand_region($feature); |
1015
|
|
|
|
|
|
|
Function: Expand the total region covered by this feature to |
1016
|
|
|
|
|
|
|
accomodate for the given feature. |
1017
|
|
|
|
|
|
|
|
1018
|
|
|
|
|
|
|
May be called whenever any kind of subfeature is added to this |
1019
|
|
|
|
|
|
|
feature. add_SeqFeature() already does this. |
1020
|
|
|
|
|
|
|
Returns : |
1021
|
|
|
|
|
|
|
Args : A Bio::SeqFeatureI implementing object. |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
=cut |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
sub _expand_region { |
1026
|
0
|
|
|
0
|
|
0
|
my ($self, $feat) = @_; |
1027
|
0
|
0
|
|
|
|
0
|
if(! $feat->isa('Bio::SeqFeatureI')) { |
1028
|
0
|
|
|
|
|
0
|
$self->warn("$feat does not implement Bio::SeqFeatureI"); |
1029
|
|
|
|
|
|
|
} |
1030
|
|
|
|
|
|
|
# if this doesn't have start/end set - forget it! |
1031
|
0
|
0
|
0
|
|
|
0
|
if((! defined($self->start())) && (! defined $self->end())) { |
1032
|
0
|
|
|
|
|
0
|
$self->start($feat->start()); |
1033
|
0
|
|
|
|
|
0
|
$self->end($feat->end()); |
1034
|
0
|
0
|
|
|
|
0
|
$self->strand($feat->strand) unless defined($self->strand()); |
1035
|
|
|
|
|
|
|
# $self->strand($feat->strand) unless $self->strand(); |
1036
|
|
|
|
|
|
|
} else { |
1037
|
0
|
|
|
|
|
0
|
my $range = $self->union($feat); |
1038
|
0
|
|
|
|
|
0
|
$self->start($range->start); |
1039
|
0
|
|
|
|
|
0
|
$self->end($range->end); |
1040
|
0
|
|
|
|
|
0
|
$self->strand($range->strand); |
1041
|
|
|
|
|
|
|
} |
1042
|
|
|
|
|
|
|
} |
1043
|
|
|
|
|
|
|
|
1044
|
|
|
|
|
|
|
=head2 get_Annotations |
1045
|
|
|
|
|
|
|
|
1046
|
|
|
|
|
|
|
Usage : my $parent = $obj->get_Annotations('Parent'); |
1047
|
|
|
|
|
|
|
my @parents = $obj->get_Annotations('Parent'); |
1048
|
|
|
|
|
|
|
Function: a wrapper around Bio::Annotation::Collection::get_Annotations(). |
1049
|
|
|
|
|
|
|
Returns : returns annotations as |
1050
|
|
|
|
|
|
|
Bio::Annotation::Collection::get_Annotations() does, but |
1051
|
|
|
|
|
|
|
additionally returns a single scalar in scalar context |
1052
|
|
|
|
|
|
|
instead of list context so that if an annotation tag |
1053
|
|
|
|
|
|
|
contains only a single value, you can do: |
1054
|
|
|
|
|
|
|
|
1055
|
|
|
|
|
|
|
$parent = $feature->get_Annotations('Parent'); |
1056
|
|
|
|
|
|
|
|
1057
|
|
|
|
|
|
|
instead of: |
1058
|
|
|
|
|
|
|
|
1059
|
|
|
|
|
|
|
($parent) = ($feature->get_Annotations('Parent'))[0]; |
1060
|
|
|
|
|
|
|
|
1061
|
|
|
|
|
|
|
if the 'Parent' tag has multiple values and is called in a |
1062
|
|
|
|
|
|
|
scalar context, the number of annotations is returned. |
1063
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
Args : an annotation tag name. |
1065
|
|
|
|
|
|
|
|
1066
|
|
|
|
|
|
|
=cut |
1067
|
|
|
|
|
|
|
|
1068
|
|
|
|
|
|
|
sub get_Annotations { |
1069
|
1079
|
|
|
1079
|
1
|
1467
|
my $self = shift; |
1070
|
|
|
|
|
|
|
|
1071
|
1079
|
|
|
|
|
1644
|
my @annotations = $self->annotation->get_Annotations(@_); |
1072
|
|
|
|
|
|
|
|
1073
|
1079
|
100
|
|
|
|
29295
|
if(wantarray){ |
|
|
100
|
|
|
|
|
|
1074
|
222
|
|
|
|
|
568
|
return @annotations; |
1075
|
|
|
|
|
|
|
} elsif(scalar(@annotations) == 1){ |
1076
|
714
|
|
|
|
|
1787
|
return $annotations[0]; |
1077
|
|
|
|
|
|
|
} else { |
1078
|
143
|
|
|
|
|
368
|
return scalar(@annotations); |
1079
|
|
|
|
|
|
|
} |
1080
|
|
|
|
|
|
|
} |
1081
|
|
|
|
|
|
|
|
1082
|
|
|
|
|
|
|
=head1 Bio::SeqFeatureI implemented methods |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
These are specialized implementations of SeqFeatureI methods which call the |
1085
|
|
|
|
|
|
|
internal Bio::Annotation::AnnotationCollection object. Just prior to the 1.5 |
1086
|
|
|
|
|
|
|
release the below methods were moved from Bio::SeqFeatureI to Bio::AnnotatableI, |
1087
|
|
|
|
|
|
|
and having Bio::SeqFeatureI inherit Bio::AnnotatableI. This behavior forced all |
1088
|
|
|
|
|
|
|
Bio::SeqFeatureI-implementing classes to use Bio::AnnotationI objects for any |
1089
|
|
|
|
|
|
|
data. It is the consensus of the core developers that this be rolled back in |
1090
|
|
|
|
|
|
|
favor of a more flexible approach by rolling back the above changes and making |
1091
|
|
|
|
|
|
|
this class Bio::AnnotatableI. The SeqFeatureI tag-related methods are |
1092
|
|
|
|
|
|
|
reimplemented in order to approximate the same behavior as before. |
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
The methods below allow mapping of the "get_tag_values()"-style annotation |
1095
|
|
|
|
|
|
|
access to Bio::AnnotationCollectionI. These need not be implemented in a |
1096
|
|
|
|
|
|
|
Bio::AnnotationCollectionI compliant class, as they are built on top of the |
1097
|
|
|
|
|
|
|
methods. For usage, see Bio::SeqFeatureI. |
1098
|
|
|
|
|
|
|
|
1099
|
|
|
|
|
|
|
=cut |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
=head2 has_tag |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
=cut |
1104
|
|
|
|
|
|
|
|
1105
|
|
|
|
|
|
|
sub has_tag { |
1106
|
0
|
|
|
0
|
1
|
0
|
my ($self,$tag) = @_; |
1107
|
0
|
|
|
|
|
0
|
return scalar($self->annotation->get_Annotations($tag)); |
1108
|
|
|
|
|
|
|
} |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
=head2 add_tag_value |
1111
|
|
|
|
|
|
|
|
1112
|
|
|
|
|
|
|
=cut |
1113
|
|
|
|
|
|
|
|
1114
|
|
|
|
|
|
|
sub add_tag_value { |
1115
|
0
|
|
|
0
|
1
|
0
|
my ($self,$tag,@vals) = @_; |
1116
|
|
|
|
|
|
|
|
1117
|
0
|
|
|
|
|
0
|
foreach my $val (@vals){ |
1118
|
0
|
|
0
|
|
|
0
|
my $class = $tagclass{$tag} || $tagclass{__DEFAULT__}; |
1119
|
0
|
|
|
|
|
0
|
my $slot = $tag2text{$class}; |
1120
|
|
|
|
|
|
|
|
1121
|
0
|
|
|
|
|
0
|
my $a = $class->new(); |
1122
|
0
|
|
|
|
|
0
|
$a->$slot($val); |
1123
|
|
|
|
|
|
|
|
1124
|
0
|
|
|
|
|
0
|
$self->annotation->add_Annotation($tag,$a); |
1125
|
|
|
|
|
|
|
} |
1126
|
|
|
|
|
|
|
|
1127
|
0
|
|
|
|
|
0
|
return 1; |
1128
|
|
|
|
|
|
|
} |
1129
|
|
|
|
|
|
|
|
1130
|
|
|
|
|
|
|
=head2 get_tag_values |
1131
|
|
|
|
|
|
|
|
1132
|
|
|
|
|
|
|
Usage : @annotations = $obj->get_tag_values($tag) |
1133
|
|
|
|
|
|
|
Function: returns annotations corresponding to $tag |
1134
|
|
|
|
|
|
|
Returns : a list of scalars |
1135
|
|
|
|
|
|
|
Args : tag name |
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
=cut |
1138
|
|
|
|
|
|
|
|
1139
|
|
|
|
|
|
|
sub get_tag_values { |
1140
|
1
|
|
|
1
|
1
|
503
|
my ($self,$tag) = @_; |
1141
|
1
|
50
|
33
|
|
|
9
|
if(!$tagclass{$tag} && $self->annotation->get_Annotations($tag)){ |
1142
|
|
|
|
|
|
|
#new tag, haven't seen it yet but it exists. add to registry |
1143
|
1
|
|
|
|
|
26
|
my($proto) = $self->annotation->get_Annotations($tag); |
1144
|
|
|
|
|
|
|
# we can only register if there's a method known for obtaining the value |
1145
|
1
|
50
|
|
|
|
21
|
if (exists($tag2text{ref($proto)})) { |
1146
|
1
|
|
|
|
|
4
|
$tagclass{$tag} = ref($proto); |
1147
|
|
|
|
|
|
|
} |
1148
|
|
|
|
|
|
|
} |
1149
|
|
|
|
|
|
|
|
1150
|
1
|
|
33
|
|
|
4
|
my $slot = $tag2text{ $tagclass{$tag} || $tagclass{__DEFAULT__} }; |
1151
|
|
|
|
|
|
|
|
1152
|
1
|
|
|
|
|
3
|
return map { $_->$slot } $self->annotation->get_Annotations($tag); |
|
1
|
|
|
|
|
20
|
|
1153
|
|
|
|
|
|
|
} |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
=head2 get_tagset_values |
1156
|
|
|
|
|
|
|
|
1157
|
|
|
|
|
|
|
Usage : @annotations = $obj->get_tagset_values($tag1,$tag2) |
1158
|
|
|
|
|
|
|
Function: returns annotations corresponding to a list of tags. |
1159
|
|
|
|
|
|
|
this is a convenience method equivalent to multiple calls |
1160
|
|
|
|
|
|
|
to get_tag_values with each tag in the list. |
1161
|
|
|
|
|
|
|
Returns : a list of Bio::AnnotationI objects. |
1162
|
|
|
|
|
|
|
Args : a list of tag names |
1163
|
|
|
|
|
|
|
|
1164
|
|
|
|
|
|
|
=cut |
1165
|
|
|
|
|
|
|
|
1166
|
|
|
|
|
|
|
sub get_tagset_values { |
1167
|
8
|
|
|
8
|
1
|
7680
|
my ($self,@tags) = @_; |
1168
|
8
|
|
|
|
|
24
|
my @r = (); |
1169
|
8
|
|
|
|
|
24
|
foreach my $tag (@tags){ |
1170
|
8
|
|
33
|
|
|
72
|
my $slot = $tag2text{ $tagclass{$tag} || $tagclass{__DEFAULT__} }; |
1171
|
8
|
|
|
|
|
30
|
push @r, map { $_->$slot } $self->annotation->get_Annotations($tag); |
|
4
|
|
|
|
|
156
|
|
1172
|
|
|
|
|
|
|
} |
1173
|
8
|
|
|
|
|
104
|
return @r; |
1174
|
|
|
|
|
|
|
} |
1175
|
|
|
|
|
|
|
|
1176
|
|
|
|
|
|
|
=head2 get_all_tags |
1177
|
|
|
|
|
|
|
|
1178
|
|
|
|
|
|
|
Usage : @tags = $obj->get_all_tags() |
1179
|
|
|
|
|
|
|
Function: returns a list of annotation tag names. |
1180
|
|
|
|
|
|
|
Returns : a list of tag names |
1181
|
|
|
|
|
|
|
Args : none |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
=cut |
1184
|
|
|
|
|
|
|
|
1185
|
|
|
|
|
|
|
sub get_all_tags { |
1186
|
0
|
|
|
0
|
1
|
|
my ($self,@args) = @_; |
1187
|
0
|
|
|
|
|
|
return $self->annotation->get_all_annotation_keys(@args); |
1188
|
|
|
|
|
|
|
} |
1189
|
|
|
|
|
|
|
|
1190
|
|
|
|
|
|
|
=head2 remove_tag |
1191
|
|
|
|
|
|
|
|
1192
|
|
|
|
|
|
|
Usage : See remove_Annotations(). |
1193
|
|
|
|
|
|
|
Function: |
1194
|
|
|
|
|
|
|
Returns : |
1195
|
|
|
|
|
|
|
Args : |
1196
|
|
|
|
|
|
|
Note : Contrary to what the name suggests, this method removes |
1197
|
|
|
|
|
|
|
all annotations corresponding to $tag, not just a |
1198
|
|
|
|
|
|
|
single anntoation. |
1199
|
|
|
|
|
|
|
|
1200
|
|
|
|
|
|
|
=cut |
1201
|
|
|
|
|
|
|
|
1202
|
|
|
|
|
|
|
sub remove_tag { |
1203
|
0
|
|
|
0
|
1
|
|
my ($self,@args) = @_; |
1204
|
0
|
|
|
|
|
|
return $self->annotation->remove_Annotations(@args); |
1205
|
|
|
|
|
|
|
} |
1206
|
|
|
|
|
|
|
|
1207
|
|
|
|
|
|
|
1; |