Mercurial > repos > mahtabm > ensembl
diff variant_effect_predictor/Bio/Annotation/Collection.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/Annotation/Collection.pm Thu Apr 11 02:01:53 2013 -0400 @@ -0,0 +1,687 @@ +# $Id: Collection.pm,v 1.16 2002/11/22 22:48:25 birney Exp $ + +# +# BioPerl module for Bio::Annotation::Collection.pm +# +# Cared for by Ewan Birney <birney@ebi.ac.uk> +# +# Copyright Ewan Birney +# +# You may distribute this module under the same terms as perl itself + +# POD documentation - main docs before the code + +=head1 NAME + +Bio::Annotation::Collection - Default Perl implementation of AnnotationCollectionI + +=head1 SYNOPSIS + + # get an AnnotationCollectionI somehow, eg + + $ac = $seq->annotation(); + + foreach $key ( $ac->get_all_annotation_keys() ) { + @values = $ac->get_Annotations($key); + foreach $value ( @values ) { + # value is an Bio::AnnotationI, and defines a "as_text" method + print "Annotation ",$key," stringified value ",$value->as_text,"\n"; + + # also defined hash_tree method, which allows data orientated + # access into this object + $hash = $value->hash_tree(); + } + } + +=head1 DESCRIPTION + +Bioperl implementation for Bio::AnnotationCollecitonI + +=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 one +of the Bioperl mailing lists. Your participation is much appreciated. + + bioperl-l@bioperl.org - General discussion + http://bio.perl.org/MailList.html - About the mailing lists + +=head2 Reporting Bugs + +Report bugs to the Bioperl bug tracking system to help us keep track +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 - Ewan Birney + +Email birney@ebi.ac.uk + +=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::Annotation::Collection; + +use vars qw(@ISA); +use strict; + +# Object preamble - inherits from Bio::Root::Root + +use Bio::AnnotationCollectionI; +use Bio::AnnotationI; +use Bio::Root::Root; +use Bio::Annotation::TypeManager; +use Bio::Annotation::SimpleValue; + + +@ISA = qw(Bio::Root::Root Bio::AnnotationCollectionI Bio::AnnotationI); + + +=head2 new + + Title : new + Usage : $coll = Bio::Annotation::Collection->new() + Function: Makes a new Annotation::Collection object. + Returns : Bio::Annotation::Collection + Args : none + +=cut + +sub new{ + my ($class,@args) = @_; + + my $self = $class->SUPER::new(@args); + + $self->{'_annotation'} = {}; + $self->_typemap(Bio::Annotation::TypeManager->new()); + + return $self; +} + + +=head1 L<Bio::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) = @_; + return keys %{$self->{'_annotation'}}; +} + +=head2 get_Annotations + + Title : get_Annotations + Usage : my @annotations = $collection->get_Annotations('key') + Function: Retrieves all the Bio::AnnotationI objects for one or more + specific key(s). + + If no key is given, returns all annotation objects. + + The returned objects will have their tagname() attribute set to + the key under which they were attached, unless the tagname was + already set. + + Returns : list of Bio::AnnotationI - empty if no objects stored for a key + Args : keys (list of strings) for annotations (optional) + +=cut + +sub get_Annotations{ + my ($self,@keys) = @_; + + my @anns = (); + @keys = $self->get_all_annotation_keys() unless @keys; + foreach my $key (@keys) { + if(exists($self->{'_annotation'}->{$key})) { + push(@anns, + map { + $_->tagname($key) if ! $_->tagname(); $_; + } @{$self->{'_annotation'}->{$key}}); + } + } + return @anns; +} + +=head2 get_all_Annotations + + Title : get_all_Annotations + Usage : + Function: Similar to get_Annotations, but traverses and flattens nested + annotation collections. This means that collections in the + tree will be replaced by their components. + + Keys will not be passed on to nested collections. I.e., if the + tag name of a nested collection matches the key, it will be + flattened in its entirety. + + Hence, for un-nested annotation collections this will be identical + to get_Annotations. + Example : + Returns : an array of L<Bio::AnnotationI> compliant objects + Args : keys (list of strings) for annotations (optional) + + +=cut + +sub get_all_Annotations{ + my ($self,@keys) = @_; + + return map { + $_->isa("Bio::AnnotationCollectionI") ? + $_->get_all_Annotations() : $_; + } $self->get_Annotations(@keys); +} + +=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) = @_; + my $count = 0; + map { $count += scalar @$_ } values %{$self->{'_annotation'}}; + return $count; +} + +=head1 Implementation specific functions - mainly for 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. + + 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 ) { + $self->throw("Must add an object. Use Bio::Annotation::{Comment,SimpleValue,OntologyTerm} for simple text additions"); + } + + if( !$object->isa("Bio::AnnotationI") ) { + $self->throw("object must be AnnotationI compliant, otherwise we wont add it!"); + } + + # ok, now we are ready! If we don't have an archetype, set it + # from the type of the object + + if( !defined $archetype ) { + $archetype = ref $object; + } + + # check typemap, storing if needed. + my $stored_map = $self->_typemap->type_for_key($key); + + if( defined $stored_map ) { + # check validity, irregardless of archetype. A little cheeky + # this means isa stuff is executed correctly + + if( !$self->_typemap()->is_valid($key,$object) ) { + $self->throw("Object $object was not valid with key $key. If you were adding new keys in, perhaps you want to make use of the archetype method to allow registration to a more basic type"); + } + } else { + $self->_typemap->_add_type_map($key,$archetype); + } + + # we are ok to store + + if( !defined $self->{'_annotation'}->{$key} ) { + $self->{'_annotation'}->{$key} = []; + } + + push(@{$self->{'_annotation'}->{$key}},$object); + + return 1; +} + +=head2 remove_Annotations + + Title : remove_Annotations + Usage : + Function: Remove the annotations for the specified key from this collection. + Example : + Returns : an array Bio::AnnotationI compliant objects which were stored + under the given key(s) + Args : the key(s) (tag name(s), one or more strings) for which to + remove annotations (optional; if none given, flushes all + annotations) + + +=cut + +sub remove_Annotations{ + my ($self, @keys) = @_; + + @keys = $self->get_all_annotation_keys() unless @keys; + my @anns = $self->get_Annotations(@keys); + # flush + foreach (@keys) { + delete $self->{'_annotation'}->{$_}; + } + return @anns; +} + +=head2 flatten_Annotations + + Title : flatten_Annotations + Usage : + Function: Flattens part or all of the annotations in this collection. + + This is a convenience method for getting the flattened + annotation for the given keys, removing the annotation for + those keys, and adding back the flattened array. + + This should not change anything for un-nested collections. + Example : + Returns : an array Bio::AnnotationI compliant objects which were stored + under the given key(s) + Args : list of keys (strings) the annotation for which to flatten, + defaults to all keys if not given + + +=cut + +sub flatten_Annotations{ + my ($self,@keys) = @_; + + my @anns = $self->get_all_Annotations(@keys); + my @origanns = $self->remove_Annotations(@keys); + foreach (@anns) { + $self->add_Annotation($_); + } + return @origanns; +} + +=head1 Bio::AnnotationI methods implementations + + This is to allow nested annotation: you can a collection as an + annotation object to an annotation collection. + +=cut + +=head2 as_text + + Title : as_text + Usage : + Function: See L<Bio::AnnotationI> + Example : + Returns : a string + Args : none + + +=cut + +sub as_text{ + my $self = shift; + + my $txt = "Collection consisting of "; + my @texts = (); + foreach my $ann ($self->get_Annotations()) { + push(@texts, $ann->as_text()); + } + if(@texts) { + $txt .= join(", ", map { '['.$_.']'; } @texts); + } else { + $txt .= "no elements"; + } + return $txt; +} + +=head2 hash_tree + + Title : hash_tree + Usage : + Function: See L<Bio::AnnotationI> + Example : + Returns : a hash reference + Args : none + + +=cut + +sub hash_tree{ + my $self = shift; + my $tree = {}; + + foreach my $key ($self->get_all_annotation_keys()) { + # all contained objects will support hash_tree() + # (they are AnnotationIs) + $tree->{$key} = [$self->get_Annotations($key)]; + } + return $tree; +} + +=head2 tagname + + Title : tagname + Usage : $obj->tagname($newval) + Function: Get/set the tagname for this annotation value. + + Setting this is optional. If set, it obviates the need to + provide a tag to Bio::AnnotationCollectionI when adding + this object. When obtaining an AnnotationI object from the + collection, the collection will set the value to the tag + under which it was stored unless the object has a tag + stored already. + + Example : + Returns : value of tagname (a scalar) + Args : new value (a scalar, optional) + + +=cut + +sub tagname{ + my $self = shift; + + return $self->{'tagname'} = shift if @_; + return $self->{'tagname'}; +} + + +=head1 Backward compatible functions + +Functions put in for backward compatibility with old +Bio::Annotation.pm stuff + +=cut + +=head2 description + + Title : description + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub description{ + my ($self,$value) = @_; + + $self->deprecated("Using old style annotation call on new Annotation::Collection object"); + + if( defined $value ) { + my $val = Bio::Annotation::SimpleValue->new(); + $val->value($value); + $self->add_Annotation('description',$val); + } + + my ($desc) = $self->get_Annotations('description'); + + # If no description tag exists, do not attempt to call value on undef: + return $desc ? $desc->value : undef; +} + + +=head2 add_gene_name + + Title : add_gene_name + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub add_gene_name{ + my ($self,$value) = @_; + + $self->deprecated("Old style add_gene_name called on new style Annotation::Collection"); + + my $val = Bio::Annotation::SimpleValue->new(); + $val->value($value); + $self->add_Annotation('gene_name',$val); +} + +=head2 each_gene_name + + Title : each_gene_name + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub each_gene_name{ + my ($self) = @_; + + $self->deprecated("Old style each_gene_name called on new style Annotation::Collection"); + + my @out; + my @gene = $self->get_Annotations('gene_name'); + + foreach my $g ( @gene ) { + push(@out,$g->value); + } + + return @out; +} + +=head2 add_Reference + + Title : add_Reference + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub add_Reference{ + my ($self, @values) = @_; + + $self->deprecated("add_Reference (old style Annotation) on new style Annotation::Collection"); + + # Allow multiple (or no) references to be passed, as per old method + foreach my $value (@values) { + $self->add_Annotation('reference',$value); + } +} + +=head2 each_Reference + + Title : each_Reference + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub each_Reference{ + my ($self) = @_; + + $self->deprecated("each_Reference (old style Annotation) on new style Annotation::Collection"); + + return $self->get_Annotations('reference'); +} + + +=head2 add_Comment + + Title : add_Comment + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub add_Comment{ + my ($self,$value) = @_; + + $self->deprecated("add_Comment (old style Annotation) on new style Annotation::Collection"); + + $self->add_Annotation('comment',$value); + +} + +=head2 each_Comment + + Title : each_Comment + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub each_Comment{ + my ($self) = @_; + + $self->deprecated("each_Comment (old style Annotation) on new style Annotation::Collection"); + + return $self->get_Annotations('comment'); +} + + + +=head2 add_DBLink + + Title : add_DBLink + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub add_DBLink{ + my ($self,$value) = @_; + + $self->deprecated("add_DBLink (old style Annotation) on new style Annotation::Collection"); + + $self->add_Annotation('dblink',$value); + +} + +=head2 each_DBLink + + Title : each_DBLink + Usage : + Function: + Example : + Returns : + Args : + + +=cut + +sub each_DBLink{ + my ($self) = @_; + + $self->deprecated("each_DBLink (old style Annotation) on new style Annotation::Collection - use get_Annotations('dblink')"); + + return $self->get_Annotations('dblink'); +} + + + +=head1 Implementation management functions + +=cut + +=head2 _typemap + + Title : _typemap + Usage : $obj->_typemap($newval) + Function: + Example : + Returns : value of _typemap + Args : newvalue (optional) + + +=cut + +sub _typemap{ + my ($self,$value) = @_; + if( defined $value) { + $self->{'_typemap'} = $value; + } + return $self->{'_typemap'}; + +} + +1;