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