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

Uploaded
author mahtabm
date Thu, 11 Apr 2013 02:01:53 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/variant_effect_predictor/Bio/SeqFeature/AnnotationAdaptor.pm	Thu Apr 11 02:01:53 2013 -0400
@@ -0,0 +1,440 @@
+# $Id: AnnotationAdaptor.pm,v 1.4 2002/11/11 18:16:31 lapp Exp $
+#
+# BioPerl module for Bio::SeqFeature::AnnotationAdaptor
+#
+# Cared for by Hilmar Lapp <hlapp at gmx.net>
+#
+# Copyright Hilmar Lapp
+#
+# You may distribute this module under the same terms as perl itself
+
+#
+# (c) Hilmar Lapp, hlapp at gmx.net, 2002.
+# (c) GNF, Genomics Institute of the Novartis Research Foundation, 2002.
+#
+# You may distribute this module under the same terms as perl itself.
+# Refer to the Perl Artistic License (see the license accompanying this
+# software package, or see http://www.perl.com/language/misc/Artistic.html)
+# for the terms under which you may use, modify, and redistribute this module.
+# 
+# THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
+# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+#
+
+# POD documentation - main docs before the code
+
+=head1 NAME
+
+Bio::SeqFeature::AnnotationAdaptor - integrates SeqFeatureIs annotation
+
+=head1 SYNOPSIS
+
+   use Bio::SeqFeature::Generic;
+   use Bio::SeqFeature::AnnotationAdaptor;
+
+   # obtain a SeqFeatureI implementing object somehow
+   my $feat = Bio::SeqFeature::Generic->new(-start => 10, -end => 20);
+
+   # add tag/value annotation
+   $feat->add_tag_value("mytag", "value of tag mytag");
+   $feat->add_tag_value("mytag", "another value of tag mytag");
+
+   # Bio::SeqFeature::Generic also provides annotation(), which returns a
+   # Bio::AnnotationCollectionI compliant object
+   $feat->annotation->add_Annotation("dbxref", $dblink);
+
+   # to integrate tag/value annotation with AnnotationCollectionI
+   # annotation, use this adaptor, which also implements 
+   # Bio::AnnotationCollectionI
+   my $anncoll = Bio::SeqFeature::AnnotationAdaptor(-feature => $feat);
+
+   # this will now return tag/value pairs as 
+   # Bio::Annotation::SimpleValue objects
+   my @anns = $anncoll->get_Annotations("mytag");
+   # other added before annotation is available too
+   my @dblinks = $anncoll->get_Annotations("dbxref");
+
+   # also supports transparent adding of tag/value pairs in 
+   # Bio::AnnotationI flavor
+   my $tagval = Bio::Annotation::SimpleValue->new(-value => "some value",
+                                                  -tagname => "some tag");
+   $anncoll->add_Annotation($tagval);
+   # this is now also available from the feature's tag/value system
+   my @vals = $feat->each_tag_value("some tag");
+
+=head1 DESCRIPTION
+
+L<Bio::SeqFeatureI> defines light-weight annotation of features
+through tag/value pairs. Conversely, L<Bio::AnnotationCollectionI>
+together with L<Bio::AnnotationI> defines an annotation bag, which is
+better typed, but more heavy-weight because it contains every single
+piece of annotation as objects. The frequently used base
+implementation of Bio::SeqFeatureI, Bio::SeqFeature::Generic, defines
+an additional slot for AnnotationCollectionI-compliant annotation.
+
+This adaptor provides a L<Bio::AnnotationCollectionI> compliant,
+unified, and integrated view on the annotation of L<Bio::SeqFeatureI>
+objects, including tag/value pairs, and annotation through the
+annotation() method, if the object supports it. Code using this
+adaptor does not need to worry about the different ways of possibly
+annotating a SeqFeatureI object, but can instead assume that it
+strictly follows the AnnotationCollectionI scheme. The price to pay is
+that retrieving and adding annotation will always use objects instead
+of light-weight tag/value pairs.
+
+In other words, this adaptor allows us to keep the best of both
+worlds. If you create tens of thousands of feature objects, and your
+only annotation is tag/value pairs, you are best off using the
+features' native tag/value system. If you create a smaller number of
+features, but with rich and typed annotation mixed with tag/value
+pairs, this adaptor may be for you. Since its implementation is by
+double-composition, you only need to create one instance of the
+adaptor. In order to transparently annotate a feature object, set the
+feature using the feature() method. Every annotation you add will be
+added to the feature object, and hence will not be lost when you set
+feature() to the next object.
+
+=head1 FEEDBACK
+
+=head2 Mailing Lists
+
+User feedback is an integral part of the evolution of this and other
+Bioperl modules. Send your comments and suggestions preferably to
+the Bioperl mailing list.  Your participation is much appreciated.
+
+  bioperl-l@bioperl.org              - General discussion
+  http://bioperl.org/MailList.shtml  - About the mailing lists
+
+=head2 Reporting Bugs
+
+Report bugs to the Bioperl bug tracking system to help us keep track
+of the bugs and their resolution. Bug reports can be submitted via
+email or the web:
+
+  bioperl-bugs@bioperl.org
+  http://bugzilla.bioperl.org/
+
+=head1 AUTHOR - Hilmar Lapp
+
+Email hlapp at gmx.net
+
+Describe contact details here
+
+=head1 CONTRIBUTORS
+
+Additional contributors names and emails here
+
+=head1 APPENDIX
+
+The rest of the documentation details each of the object methods.
+Internal methods are usually preceded with a _
+
+=cut
+
+
+# Let the code begin...
+
+
+package Bio::SeqFeature::AnnotationAdaptor;
+use vars qw(@ISA);
+use strict;
+
+# Object preamble - inherits from Bio::Root::Root
+
+use Bio::Root::Root;
+use Bio::AnnotatableI;
+use Bio::AnnotationCollectionI;
+use Bio::Annotation::SimpleValue;
+
+@ISA = qw(Bio::Root::Root Bio::AnnotationCollectionI Bio::AnnotatableI);
+
+=head2 new
+
+ Title   : new
+ Usage   : my $obj = new Bio::SeqFeature::AnnotationAdaptor();
+ Function: Builds a new Bio::SeqFeature::AnnotationAdaptor object 
+ Returns : an instance of Bio::SeqFeature::AnnotationAdaptor
+ Args    : Named parameters
+            -feature    the Bio::SeqFeatureI implementing object to adapt
+                        (mandatory to be passed here, or set via feature()
+                        before calling other methods)
+            -annotation the Bio::AnnotationCollectionI implementing object
+                        for storing richer annotation (this will default to
+                        the $feature->annotation() if it supports it)
+            -tagvalue_factory the object factory to use for creating tag/value
+                        pair representing objects
+
+
+=cut
+
+sub new {
+    my($class,@args) = @_;
+    
+    my $self = $class->SUPER::new(@args);
+    
+    my ($feat,$anncoll,$fact) =
+	$self->_rearrange([qw(FEATURE
+			      ANNOTATION
+			      TAGVALUE_FACTORY)], @args);
+    
+    $self->feature($feat) if $feat;
+    $self->annotation($anncoll) if $feat;
+    $self->tagvalue_object_factory($fact) if $fact;
+
+    return $self;
+}
+
+=head2 feature
+
+ Title   : feature
+ Usage   : $obj->feature($newval)
+ Function: Get/set the feature that this object adapts to an
+           AnnotationCollectionI.
+ Example : 
+ Returns : value of feature (a Bio::SeqFeatureI compliant object)
+ Args    : new value (a Bio::SeqFeatureI compliant object, optional)
+
+
+=cut
+
+sub feature{
+    my ($self,$value) = @_;
+    if( defined $value) {
+	$self->{'feature'} = $value;
+    }
+    return $self->{'feature'};
+}
+
+=head2 annotation
+
+ Title   : annotation
+ Usage   : $obj->annotation($newval)
+ Function: Get/set the AnnotationCollectionI implementing object used by
+           this adaptor to store additional annotation that cannot be stored
+           by the SeqFeatureI itself.
+
+           If requested before having been set, the value will default to the
+           annotation object of the feature if it has one.
+ Example : 
+ Returns : value of annotation (a Bio::AnnotationCollectionI compliant object)
+ Args    : new value (a Bio::AnnotationCollectionI compliant object, optional)
+
+
+=cut
+
+sub annotation{
+    my ($self,$value) = @_;
+
+    if( defined $value) {
+	$self->{'annotation'} = $value;
+    }
+    if((! exists($self->{'annotation'})) &&
+       $self->feature()->can('annotation')) {
+	return $self->feature()->annotation();
+    }
+    return $self->{'annotation'};
+}
+
+=head1 AnnotationCollectionI implementing methods
+
+=cut
+
+=head2 get_all_annotation_keys
+
+ Title   : get_all_annotation_keys
+ Usage   : $ac->get_all_annotation_keys()
+ Function: gives back a list of annotation keys, which are simple text strings
+ Returns : list of strings
+ Args    : none
+
+=cut
+
+sub get_all_annotation_keys{
+    my ($self) = @_;
+    my @keys = ();
+    
+    # get the tags from the feature object
+    push(@keys, $self->feature()->all_tags());
+    # ask the annotation implementation in addition, while avoiding duplicates
+    if($self->annotation()) {
+	push(@keys,
+	     grep { ! $self->feature->has_tag($_); }
+	          $self->annotation()->get_all_annotation_keys());
+    }
+    # done
+    return @keys;
+}
+
+
+=head2 get_Annotations
+
+ Title   : get_Annotations
+ Usage   : my @annotations = $collection->get_Annotations('key')
+ Function: Retrieves all the Bio::AnnotationI objects for a specific key
+ Returns : list of Bio::AnnotationI - empty if no objects stored for a key
+ Args    : string which is key for annotations
+
+=cut
+
+sub get_Annotations{
+    my ($self, $key) = @_;
+    my @anns = ();
+
+    # if the feature has tag/value pair for this key as the tag
+    if($self->feature()->has_tag($key)) {
+	my $fact = $self->tagvalue_object_factory();
+	# add each tag/value pair as a SimpleValue object
+	foreach my $val ($self->feature()->each_tag_value($key)) {
+	    my $ann;
+	    if($fact) {
+		$ann = $fact->create_object(-value => $val, -tagname => $key);
+	    } else {
+		$ann = Bio::Annotation::SimpleValue->new(-value => $val,
+							 -tagname => $key);
+	    }
+	    push(@anns, $ann);
+	}
+    }
+    # add what is in the annotation implementation if any
+    if($self->annotation()) {
+	push(@anns, $self->annotation->get_Annotations($key));
+    }
+    # done
+    return @anns;
+}
+
+=head2 get_num_of_annotations
+
+ Title   : get_num_of_annotations
+ Usage   : my $count = $collection->get_num_of_annotations()
+ Function: Returns the count of all annotations stored in this collection 
+ Returns : integer
+ Args    : none
+
+
+=cut
+
+sub get_num_of_annotations{
+    my ($self) = @_;
+
+    # first, count the number of tags on the feature
+    my $num_anns = 0;
+    foreach ($self->feature()->all_tags()) {
+	$num_anns += $self->feature()->each_tag_value($_);
+    }
+    # add from the annotation implementation if any
+    if($self->annotation()) {
+	$num_anns += $self->annotation()->get_num_of_annotations();
+    }
+    # done
+    return $num_anns;
+}
+
+=head1 Implementation specific functions - to allow adding
+
+=cut
+
+=head2 add_Annotation
+
+ Title   : add_Annotation
+ Usage   : $self->add_Annotation('reference',$object);
+           $self->add_Annotation($object,'Bio::MyInterface::DiseaseI');
+           $self->add_Annotation($object);
+           $self->add_Annotation('disease',$object,'Bio::MyInterface::DiseaseI');
+ Function: Adds an annotation for a specific key.
+
+           If the key is omitted, the object to be added must provide a value
+           via its tagname().
+
+           If the archetype is provided, this and future objects added under
+           that tag have to comply with the archetype and will be rejected
+           otherwise.
+
+           This implementation will add all Bio::Annotation::SimpleValue
+           objects to the adapted features as tag/value pairs. Caveat: this
+           may potentially result in information loss if a derived object
+           is supplied.
+
+ Returns : none
+ Args    : annotation key ('disease', 'dblink', ...)
+           object to store (must be Bio::AnnotationI compliant)
+           [optional] object archetype to map future storage of object 
+                      of these types to
+
+=cut
+
+sub add_Annotation{
+    my ($self,$key,$object,$archetype) = @_;
+   
+    # if there's no key we use the tagname() as key
+    if(ref($key) && $key->isa("Bio::AnnotationI") &&
+       (! ($object && ref($object)))) {
+	$archetype = $object if $object;
+	$object = $key;
+	$key = $object->tagname();
+	$key = $key->name() if $key && ref($key); # OntologyTermI
+	$self->throw("Annotation object must have a tagname if key omitted")
+	    unless $key;
+    }
+    
+    if( !defined $object ) {
+	$self->throw("Must have at least key and object in add_Annotation");
+    }
+    
+    if( ! (ref($object) && $object->isa("Bio::AnnotationI")) ) {
+	$self->throw("object must be a Bio::AnnotationI compliant object, otherwise we wont add it!");
+    }
+    
+    # ready to add -- if it's a SimpleValue, we add to the feature's tags,
+    # otherwise we'll add to the annotation collection implementation
+
+    if($object->isa("Bio::Annotation::SimpleValue") &&
+       $self->feature()->can('add_tag_value')) {
+	return $self->feature()->add_tag_value($key, $object->value());
+    } else {
+	my $anncoll = $self->annotation();
+	if(! $anncoll) {
+	    $anncoll = Bio::Annotation::Collection->new();
+	    $self->annotation($anncoll);
+	}
+	if($anncoll->can('add_Annotation')) {
+	    return $anncoll->add_Annotation($key,$object,$archetype);
+	}
+	$self->throw("Annotation implementation does not allow adding!");
+    }
+}
+
+=head1 Additional methods
+
+=cut
+
+=head2 tagvalue_object_factory
+
+ Title   : tagvalue_object_factory
+ Usage   : $obj->tagval_object_factory($newval)
+ Function: Get/set the object factory to use for creating objects that
+           represent tag/value pairs (e.g.,
+           Bio::Annotation::SimpleValue).
+
+           The object to be created is expected to follow
+           Bio::Annotation::SimpleValue in terms of supported
+           arguments at creation time, and the methods.
+
+ Example : 
+ Returns : A Bio::Factory::ObjectFactoryI compliant object
+ Args    : new value (a Bio::Factory::ObjectFactoryI compliant object, 
+           optional)
+
+
+=cut
+
+sub tagvalue_object_factory{
+    my ($self,$value) = @_;
+    if( defined $value) {
+	$self->{'tagval_object_factory'} = $value;
+    }
+    return $self->{'tagval_object_factory'};
+}
+
+1;