Mercurial > repos > mahtabm > ensembl
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; |