comparison variant_effect_predictor/Bio/SeqFeature/AnnotationAdaptor.pm @ 0:1f6dce3d34e0

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1f6dce3d34e0
1 # $Id: AnnotationAdaptor.pm,v 1.4 2002/11/11 18:16:31 lapp Exp $
2 #
3 # BioPerl module for Bio::SeqFeature::AnnotationAdaptor
4 #
5 # Cared for by Hilmar Lapp <hlapp at gmx.net>
6 #
7 # Copyright Hilmar Lapp
8 #
9 # You may distribute this module under the same terms as perl itself
10
11 #
12 # (c) Hilmar Lapp, hlapp at gmx.net, 2002.
13 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2002.
14 #
15 # You may distribute this module under the same terms as perl itself.
16 # Refer to the Perl Artistic License (see the license accompanying this
17 # software package, or see http://www.perl.com/language/misc/Artistic.html)
18 # for the terms under which you may use, modify, and redistribute this module.
19 #
20 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
21 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
22 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 #
24
25 # POD documentation - main docs before the code
26
27 =head1 NAME
28
29 Bio::SeqFeature::AnnotationAdaptor - integrates SeqFeatureIs annotation
30
31 =head1 SYNOPSIS
32
33 use Bio::SeqFeature::Generic;
34 use Bio::SeqFeature::AnnotationAdaptor;
35
36 # obtain a SeqFeatureI implementing object somehow
37 my $feat = Bio::SeqFeature::Generic->new(-start => 10, -end => 20);
38
39 # add tag/value annotation
40 $feat->add_tag_value("mytag", "value of tag mytag");
41 $feat->add_tag_value("mytag", "another value of tag mytag");
42
43 # Bio::SeqFeature::Generic also provides annotation(), which returns a
44 # Bio::AnnotationCollectionI compliant object
45 $feat->annotation->add_Annotation("dbxref", $dblink);
46
47 # to integrate tag/value annotation with AnnotationCollectionI
48 # annotation, use this adaptor, which also implements
49 # Bio::AnnotationCollectionI
50 my $anncoll = Bio::SeqFeature::AnnotationAdaptor(-feature => $feat);
51
52 # this will now return tag/value pairs as
53 # Bio::Annotation::SimpleValue objects
54 my @anns = $anncoll->get_Annotations("mytag");
55 # other added before annotation is available too
56 my @dblinks = $anncoll->get_Annotations("dbxref");
57
58 # also supports transparent adding of tag/value pairs in
59 # Bio::AnnotationI flavor
60 my $tagval = Bio::Annotation::SimpleValue->new(-value => "some value",
61 -tagname => "some tag");
62 $anncoll->add_Annotation($tagval);
63 # this is now also available from the feature's tag/value system
64 my @vals = $feat->each_tag_value("some tag");
65
66 =head1 DESCRIPTION
67
68 L<Bio::SeqFeatureI> defines light-weight annotation of features
69 through tag/value pairs. Conversely, L<Bio::AnnotationCollectionI>
70 together with L<Bio::AnnotationI> defines an annotation bag, which is
71 better typed, but more heavy-weight because it contains every single
72 piece of annotation as objects. The frequently used base
73 implementation of Bio::SeqFeatureI, Bio::SeqFeature::Generic, defines
74 an additional slot for AnnotationCollectionI-compliant annotation.
75
76 This adaptor provides a L<Bio::AnnotationCollectionI> compliant,
77 unified, and integrated view on the annotation of L<Bio::SeqFeatureI>
78 objects, including tag/value pairs, and annotation through the
79 annotation() method, if the object supports it. Code using this
80 adaptor does not need to worry about the different ways of possibly
81 annotating a SeqFeatureI object, but can instead assume that it
82 strictly follows the AnnotationCollectionI scheme. The price to pay is
83 that retrieving and adding annotation will always use objects instead
84 of light-weight tag/value pairs.
85
86 In other words, this adaptor allows us to keep the best of both
87 worlds. If you create tens of thousands of feature objects, and your
88 only annotation is tag/value pairs, you are best off using the
89 features' native tag/value system. If you create a smaller number of
90 features, but with rich and typed annotation mixed with tag/value
91 pairs, this adaptor may be for you. Since its implementation is by
92 double-composition, you only need to create one instance of the
93 adaptor. In order to transparently annotate a feature object, set the
94 feature using the feature() method. Every annotation you add will be
95 added to the feature object, and hence will not be lost when you set
96 feature() to the next object.
97
98 =head1 FEEDBACK
99
100 =head2 Mailing Lists
101
102 User feedback is an integral part of the evolution of this and other
103 Bioperl modules. Send your comments and suggestions preferably to
104 the Bioperl mailing list. Your participation is much appreciated.
105
106 bioperl-l@bioperl.org - General discussion
107 http://bioperl.org/MailList.shtml - About the mailing lists
108
109 =head2 Reporting Bugs
110
111 Report bugs to the Bioperl bug tracking system to help us keep track
112 of the bugs and their resolution. Bug reports can be submitted via
113 email or the web:
114
115 bioperl-bugs@bioperl.org
116 http://bugzilla.bioperl.org/
117
118 =head1 AUTHOR - Hilmar Lapp
119
120 Email hlapp at gmx.net
121
122 Describe contact details here
123
124 =head1 CONTRIBUTORS
125
126 Additional contributors names and emails here
127
128 =head1 APPENDIX
129
130 The rest of the documentation details each of the object methods.
131 Internal methods are usually preceded with a _
132
133 =cut
134
135
136 # Let the code begin...
137
138
139 package Bio::SeqFeature::AnnotationAdaptor;
140 use vars qw(@ISA);
141 use strict;
142
143 # Object preamble - inherits from Bio::Root::Root
144
145 use Bio::Root::Root;
146 use Bio::AnnotatableI;
147 use Bio::AnnotationCollectionI;
148 use Bio::Annotation::SimpleValue;
149
150 @ISA = qw(Bio::Root::Root Bio::AnnotationCollectionI Bio::AnnotatableI);
151
152 =head2 new
153
154 Title : new
155 Usage : my $obj = new Bio::SeqFeature::AnnotationAdaptor();
156 Function: Builds a new Bio::SeqFeature::AnnotationAdaptor object
157 Returns : an instance of Bio::SeqFeature::AnnotationAdaptor
158 Args : Named parameters
159 -feature the Bio::SeqFeatureI implementing object to adapt
160 (mandatory to be passed here, or set via feature()
161 before calling other methods)
162 -annotation the Bio::AnnotationCollectionI implementing object
163 for storing richer annotation (this will default to
164 the $feature->annotation() if it supports it)
165 -tagvalue_factory the object factory to use for creating tag/value
166 pair representing objects
167
168
169 =cut
170
171 sub new {
172 my($class,@args) = @_;
173
174 my $self = $class->SUPER::new(@args);
175
176 my ($feat,$anncoll,$fact) =
177 $self->_rearrange([qw(FEATURE
178 ANNOTATION
179 TAGVALUE_FACTORY)], @args);
180
181 $self->feature($feat) if $feat;
182 $self->annotation($anncoll) if $feat;
183 $self->tagvalue_object_factory($fact) if $fact;
184
185 return $self;
186 }
187
188 =head2 feature
189
190 Title : feature
191 Usage : $obj->feature($newval)
192 Function: Get/set the feature that this object adapts to an
193 AnnotationCollectionI.
194 Example :
195 Returns : value of feature (a Bio::SeqFeatureI compliant object)
196 Args : new value (a Bio::SeqFeatureI compliant object, optional)
197
198
199 =cut
200
201 sub feature{
202 my ($self,$value) = @_;
203 if( defined $value) {
204 $self->{'feature'} = $value;
205 }
206 return $self->{'feature'};
207 }
208
209 =head2 annotation
210
211 Title : annotation
212 Usage : $obj->annotation($newval)
213 Function: Get/set the AnnotationCollectionI implementing object used by
214 this adaptor to store additional annotation that cannot be stored
215 by the SeqFeatureI itself.
216
217 If requested before having been set, the value will default to the
218 annotation object of the feature if it has one.
219 Example :
220 Returns : value of annotation (a Bio::AnnotationCollectionI compliant object)
221 Args : new value (a Bio::AnnotationCollectionI compliant object, optional)
222
223
224 =cut
225
226 sub annotation{
227 my ($self,$value) = @_;
228
229 if( defined $value) {
230 $self->{'annotation'} = $value;
231 }
232 if((! exists($self->{'annotation'})) &&
233 $self->feature()->can('annotation')) {
234 return $self->feature()->annotation();
235 }
236 return $self->{'annotation'};
237 }
238
239 =head1 AnnotationCollectionI implementing methods
240
241 =cut
242
243 =head2 get_all_annotation_keys
244
245 Title : get_all_annotation_keys
246 Usage : $ac->get_all_annotation_keys()
247 Function: gives back a list of annotation keys, which are simple text strings
248 Returns : list of strings
249 Args : none
250
251 =cut
252
253 sub get_all_annotation_keys{
254 my ($self) = @_;
255 my @keys = ();
256
257 # get the tags from the feature object
258 push(@keys, $self->feature()->all_tags());
259 # ask the annotation implementation in addition, while avoiding duplicates
260 if($self->annotation()) {
261 push(@keys,
262 grep { ! $self->feature->has_tag($_); }
263 $self->annotation()->get_all_annotation_keys());
264 }
265 # done
266 return @keys;
267 }
268
269
270 =head2 get_Annotations
271
272 Title : get_Annotations
273 Usage : my @annotations = $collection->get_Annotations('key')
274 Function: Retrieves all the Bio::AnnotationI objects for a specific key
275 Returns : list of Bio::AnnotationI - empty if no objects stored for a key
276 Args : string which is key for annotations
277
278 =cut
279
280 sub get_Annotations{
281 my ($self, $key) = @_;
282 my @anns = ();
283
284 # if the feature has tag/value pair for this key as the tag
285 if($self->feature()->has_tag($key)) {
286 my $fact = $self->tagvalue_object_factory();
287 # add each tag/value pair as a SimpleValue object
288 foreach my $val ($self->feature()->each_tag_value($key)) {
289 my $ann;
290 if($fact) {
291 $ann = $fact->create_object(-value => $val, -tagname => $key);
292 } else {
293 $ann = Bio::Annotation::SimpleValue->new(-value => $val,
294 -tagname => $key);
295 }
296 push(@anns, $ann);
297 }
298 }
299 # add what is in the annotation implementation if any
300 if($self->annotation()) {
301 push(@anns, $self->annotation->get_Annotations($key));
302 }
303 # done
304 return @anns;
305 }
306
307 =head2 get_num_of_annotations
308
309 Title : get_num_of_annotations
310 Usage : my $count = $collection->get_num_of_annotations()
311 Function: Returns the count of all annotations stored in this collection
312 Returns : integer
313 Args : none
314
315
316 =cut
317
318 sub get_num_of_annotations{
319 my ($self) = @_;
320
321 # first, count the number of tags on the feature
322 my $num_anns = 0;
323 foreach ($self->feature()->all_tags()) {
324 $num_anns += $self->feature()->each_tag_value($_);
325 }
326 # add from the annotation implementation if any
327 if($self->annotation()) {
328 $num_anns += $self->annotation()->get_num_of_annotations();
329 }
330 # done
331 return $num_anns;
332 }
333
334 =head1 Implementation specific functions - to allow adding
335
336 =cut
337
338 =head2 add_Annotation
339
340 Title : add_Annotation
341 Usage : $self->add_Annotation('reference',$object);
342 $self->add_Annotation($object,'Bio::MyInterface::DiseaseI');
343 $self->add_Annotation($object);
344 $self->add_Annotation('disease',$object,'Bio::MyInterface::DiseaseI');
345 Function: Adds an annotation for a specific key.
346
347 If the key is omitted, the object to be added must provide a value
348 via its tagname().
349
350 If the archetype is provided, this and future objects added under
351 that tag have to comply with the archetype and will be rejected
352 otherwise.
353
354 This implementation will add all Bio::Annotation::SimpleValue
355 objects to the adapted features as tag/value pairs. Caveat: this
356 may potentially result in information loss if a derived object
357 is supplied.
358
359 Returns : none
360 Args : annotation key ('disease', 'dblink', ...)
361 object to store (must be Bio::AnnotationI compliant)
362 [optional] object archetype to map future storage of object
363 of these types to
364
365 =cut
366
367 sub add_Annotation{
368 my ($self,$key,$object,$archetype) = @_;
369
370 # if there's no key we use the tagname() as key
371 if(ref($key) && $key->isa("Bio::AnnotationI") &&
372 (! ($object && ref($object)))) {
373 $archetype = $object if $object;
374 $object = $key;
375 $key = $object->tagname();
376 $key = $key->name() if $key && ref($key); # OntologyTermI
377 $self->throw("Annotation object must have a tagname if key omitted")
378 unless $key;
379 }
380
381 if( !defined $object ) {
382 $self->throw("Must have at least key and object in add_Annotation");
383 }
384
385 if( ! (ref($object) && $object->isa("Bio::AnnotationI")) ) {
386 $self->throw("object must be a Bio::AnnotationI compliant object, otherwise we wont add it!");
387 }
388
389 # ready to add -- if it's a SimpleValue, we add to the feature's tags,
390 # otherwise we'll add to the annotation collection implementation
391
392 if($object->isa("Bio::Annotation::SimpleValue") &&
393 $self->feature()->can('add_tag_value')) {
394 return $self->feature()->add_tag_value($key, $object->value());
395 } else {
396 my $anncoll = $self->annotation();
397 if(! $anncoll) {
398 $anncoll = Bio::Annotation::Collection->new();
399 $self->annotation($anncoll);
400 }
401 if($anncoll->can('add_Annotation')) {
402 return $anncoll->add_Annotation($key,$object,$archetype);
403 }
404 $self->throw("Annotation implementation does not allow adding!");
405 }
406 }
407
408 =head1 Additional methods
409
410 =cut
411
412 =head2 tagvalue_object_factory
413
414 Title : tagvalue_object_factory
415 Usage : $obj->tagval_object_factory($newval)
416 Function: Get/set the object factory to use for creating objects that
417 represent tag/value pairs (e.g.,
418 Bio::Annotation::SimpleValue).
419
420 The object to be created is expected to follow
421 Bio::Annotation::SimpleValue in terms of supported
422 arguments at creation time, and the methods.
423
424 Example :
425 Returns : A Bio::Factory::ObjectFactoryI compliant object
426 Args : new value (a Bio::Factory::ObjectFactoryI compliant object,
427 optional)
428
429
430 =cut
431
432 sub tagvalue_object_factory{
433 my ($self,$value) = @_;
434 if( defined $value) {
435 $self->{'tagval_object_factory'} = $value;
436 }
437 return $self->{'tagval_object_factory'};
438 }
439
440 1;