bug 2549; fixed small bug in Bio::Taxon which doesn't catch -common_name
[bioperl-live.git] / Bio / Ontology / SimpleOntologyEngine.pm
blob2c5998402302df8f9662252c15f3bd6bcba96e15
1 # $Id$
3 # BioPerl module for Bio::Ontology::SimpleOntologyEngine
5 # Cared for by Peter Dimitrov <dimitrov@gnf.org>
7 # Copyright Peter Dimitrov
8 # (c) Peter Dimitrov, dimitrov@gnf.org, 2002.
9 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2002.
11 # You may distribute this module under the same terms as perl itself.
12 # Refer to the Perl Artistic License (see the license accompanying this
13 # software package, or see http://www.perl.com/language/misc/Artistic.html)
14 # for the terms under which you may use, modify, and redistribute this module.
16 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
17 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
18 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 # POD documentation - main docs before the code
22 =head1 NAME
24 Bio::Ontology::SimpleOntologyEngine - Implementation of OntologyEngineI interface
26 =head1 SYNOPSIS
28 my $soe = Bio::Ontology::SimpleOntologyEngine->new;
30 =head1 DESCRIPTION
32 This is a "simple" implementation of Bio::Ontology::OntologyEngineI.
34 =head1 FEEDBACK
36 =head2 Mailing Lists
38 User feedback is an integral part of the evolution of this and other
39 Bioperl modules. Send your comments and suggestions preferably to
40 the Bioperl mailing list. Your participation is much appreciated.
42 bioperl-l@bioperl.org - General discussion
43 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
45 =head2 Reporting Bugs
47 Report bugs to the Bioperl bug tracking system to help us keep track
48 of the bugs and their resolution. Bug reports can be submitted via
49 the web:
51 http://bugzilla.open-bio.org/
53 =head1 AUTHOR - Peter Dimitrov
55 Email dimitrov@gnf.org
57 =head1 CONTRIBUTORS
59 Hilmar Lapp, hlapp at gmx.net
61 =head1 APPENDIX
63 The rest of the documentation details each of the object methods.
64 Internal methods are usually preceded with a _
66 =cut
69 # Let the code begin...
72 package Bio::Ontology::SimpleOntologyEngine;
73 use strict;
74 use Carp;
75 use Bio::Ontology::RelationshipFactory;
76 use Data::Dumper;
78 use base qw(Bio::Root::Root Bio::Ontology::OntologyEngineI);
80 =head2 new
82 Title : new
83 Usage : $soe = Bio::Ontology::SimpleOntologyEngine->new;
84 Function: Initializes the ontology engine.
85 Example : $soe = Bio::Ontology::SimpleOntologyEngine->new;
86 Returns : Object of class SimpleOntologyEngine.
87 Args :
89 =cut
91 sub new{
92 my ($class, @args) = @_;
93 my $self = $class->SUPER::new(@args);
94 # my %param = @args;
96 $self->_term_store( {} );
97 $self->_relationship_store( {} );
98 $self->_inverted_relationship_store( {} );
99 $self->_relationship_type_store( {} );
100 $self->_instantiated_terms_store( {} );
102 # set defaults for the factories
103 $self->relationship_factory(Bio::Ontology::RelationshipFactory->new(
104 -type => "Bio::Ontology::Relationship"));
105 return $self;
108 =head2 _instantiated_terms_store
110 Title : _instantiated_terms_store
111 Usage : $obj->_instantiated_terms_store($newval)
112 Function:
113 Example :
114 Returns : hash
115 Args : empty hash
117 =cut
119 sub _instantiated_terms_store{
120 my ($self, $value) = @_;
122 if( defined $value) {
123 $self->{'_instantiated_terms_store'} = $value;
125 return $self->{'_instantiated_terms_store'};
128 =head2 mark_instantiated
130 Title : mark_instantiated
131 Usage : $self->mark_instantiated(TermI terms): TermI
132 Function: Marks TermI objects as fully instantiated,
133 allowing for proper counting of the number of terms in the term store.
134 The TermI objects has to be already stored in the term store in order
135 to be marked.
136 Example : $self->mark_instantiated($term);
137 Returns : its argument or throws an exception if a term is not
138 in the term store.
139 Args : array of objects of class TermI.
141 =cut
143 sub mark_instantiated{
144 my ($self, @terms) = @_;
146 foreach my $term (@terms) {
147 $self->throw( "term ".$term->identifier." not in the term store\n" )
148 if !defined $self->_term_store->{$term->identifier};
149 $self->_instantiated_terms_store->{$term->identifier} = 1;
152 return @terms;
155 =head2 mark_uninstantiated
157 Title : mark_uninstantiated
158 Usage : $self->mark_uninstantiated(TermI terms): TermI
159 Function: Marks TermI objects as not fully instantiated,
160 Example : $self->mark_uninstantiated($term);
161 Returns : its argument or throws an exception if a term is not
162 in the term store(if the term is not marked it does nothing).
163 Args : array of objects of class TermI.
165 =cut
167 sub mark_uninstantiated{
168 my ($self, @terms) = @_;
170 foreach my $term (@terms) {
171 $self->throw( "term ".$term->identifier." not in the term store\n" )
172 if !defined $self->_term_store->{$term->identifier};
173 delete $self->_instantiated_terms_store->{$term->identifier}
174 if defined $self->_instantiated_terms_store->{$term->identifier};
177 return @terms;
180 =head2 _term_store
182 Title : term_store
183 Usage : $obj->_term_store($newval)
184 Function:
185 Example :
186 Returns : reference to an array of Bio::Ontology::TermI objects
187 Args : reference to an array of Bio::Ontology::TermI objects
189 =cut
191 sub _term_store{
192 my ($self, $value) = @_;
194 if( defined $value) {
195 if ( defined $self->{'_term_store'}) {
196 $self->throw("_term_store already defined\n");
198 else {
199 $self->{'_term_store'} = $value;
203 return $self->{'_term_store'};
206 =head2 add_term
208 Title : add_term
209 Usage : add_term(TermI term): TermI
210 Function: Adds TermI object to the ontology engine term store.
211 Marks the term fully instantiated by default.
212 Example : $soe->add_term($term)
213 Returns : its argument.
214 Args : object of class TermI.
216 =cut
218 sub add_term{
219 my ($self, $term) = @_;
220 my $term_store = $self->_term_store;
222 if ( defined $term_store -> {$term->identifier}) {
223 $self->throw( "term ".$term->identifier." already defined\n" );
225 else {
226 $term_store->{$term->identifier} = $term;
227 $self->_instantiated_terms_store->{$term->identifier} = 1;
230 return $term;
233 =head2 get_term_by_identifier
235 Title : get_term_by_identifier
236 Usage : get_term_by_identifier(String id): TermI
237 Function: Retrieves terms from the term store by their identifier
238 field, or an empty list if not there.
239 Example : $term = $soe->get_term_by_identifier("IPR000001");
240 Returns : An array of zero or more Bio::Ontology::TermI objects.
241 Args : An array of identifier strings
243 =cut
245 sub get_term_by_identifier{
246 my ($self, @ids) = @_;
247 my @ans = ();
249 foreach my $id (@ids) {
250 my $term = $self->_term_store->{$id};
251 push @ans, $term if defined $term;
254 return @ans;
257 =head2 _get_number_rels
259 Title : get_number_rels
260 Usage :
261 Function:
262 Example :
263 Returns :
264 Args :
266 =cut
268 sub _get_number_rels{
269 my ($self) = @_;
270 my $num_rels = 0;
272 foreach my $entry ($self->_relationship_store) {
273 $num_rels += scalar keys %$entry;
275 return $num_rels;
278 =head2 _get_number_terms
280 Title : _get_number_terms
281 Usage :
282 Function:
283 Example :
284 Returns :
285 Args :
287 =cut
289 sub _get_number_terms{
290 my ($self) = @_;
292 return scalar $self->_filter_unmarked( values %{$self->_term_store} );
296 =head2 _relationship_store
298 Title : _storerelationship_store
299 Usage : $obj->relationship_store($newval)
300 Function:
301 Example :
302 Returns : reference to an array of Bio::Ontology::TermI objects
303 Args : reference to an array of Bio::Ontology::TermI objects
305 =cut
307 sub _relationship_store{
308 my ($self, $value) = @_;
310 if( defined $value) {
311 if ( defined $self->{'_relationship_store'}) {
312 $self->throw("_relationship_store already defined\n");
314 else {
315 $self->{'_relationship_store'} = $value;
319 return $self->{'_relationship_store'};
322 =head2 _inverted_relationship_store
324 Title : _inverted_relationship_store
325 Usage :
326 Function:
327 Example :
328 Returns : reference to an array of Bio::Ontology::TermI objects
329 Args : reference to an array of Bio::Ontology::TermI objects
331 =cut
333 sub _inverted_relationship_store{
334 my ($self, $value) = @_;
336 if( defined $value) {
337 if ( defined $self->{'_inverted_relationship_store'}) {
338 $self->throw("_inverted_relationship_store already defined\n");
340 else {
341 $self->{'_inverted_relationship_store'} = $value;
345 return $self->{'_inverted_relationship_store'};
348 =head2 _relationship_type_store
350 Title : _relationship_type_store
351 Usage : $obj->_relationship_type_store($newval)
352 Function:
353 Example :
354 Returns : reference to an array of Bio::Ontology::RelationshipType objects
355 Args : reference to an array of Bio::Ontology::RelationshipType objects
357 =cut
359 sub _relationship_type_store{
360 my ($self, $value) = @_;
362 if( defined $value) {
363 if ( defined $self->{'_relationship_type_store'}) {
364 $self->throw("_relationship_type_store already defined\n");
366 else {
367 $self->{'_relationship_type_store'} = $value;
371 return $self->{'_relationship_type_store'};
374 =head2 _add_relationship_simple
376 Title : _add_relationship_simple
377 Usage :
378 Function:
379 Example :
380 Returns :
381 Args :
383 =cut
385 sub _add_relationship_simple{
386 my ($self, $store, $rel, $inverted) = @_;
387 my $parent_id;
388 my $child_id;
390 if ($inverted) {
391 $parent_id = $rel->subject_term->identifier;
392 $child_id = $rel->object_term->identifier;
394 else {
395 $parent_id = $rel->object_term->identifier;
396 $child_id = $rel->subject_term->identifier;
398 if(defined $store->{$parent_id} && (defined $store->{$parent_id}->{$child_id}) &&
399 ($store->{$parent_id}->{$child_id}->name != $rel->predicate_term->name)){
400 $self->throw("relationship ".Dumper($rel->predicate_term).
401 " between ".$parent_id." and ".$child_id.
402 " already defined as ".
403 Dumper($store->{$parent_id}->{$child_id})."\n");
405 else {
406 $store->{$parent_id}->{$child_id} = $rel->predicate_term;
410 =head2 add_relationship
412 Title : add_relationship
413 Usage : add_relationship(RelationshipI relationship): RelationshipI
414 Function: Adds a relationship object to the ontology engine.
415 Example :
416 Returns : Its argument.
417 Args : A RelationshipI object.
419 =cut
421 sub add_relationship{
422 my ($self, $rel) = @_;
424 $self->_add_relationship_simple($self->_relationship_store,
425 $rel, 0);
426 $self->_add_relationship_simple($self->_inverted_relationship_store,
427 $rel, 1);
428 $self->_relationship_type_store->{
429 $self->_unique_termid($rel->predicate_term)} = $rel->predicate_term;
431 return $rel;
434 =head2 get_relationships
436 Title : get_relationships
437 Usage : get_relationships(): RelationshipI
438 Function: Retrieves all relationship objects.
439 Example :
440 Returns : Array of RelationshipI objects
441 Args :
443 =cut
445 sub get_relationships{
446 my $self = shift;
447 my $term = shift;
448 my @rels;
449 my $store = $self->_relationship_store;
450 my $relfact = $self->relationship_factory();
452 my @parent_ids = $term ?
453 # if a term is supplied then only get the term's parents
454 (map { $_->identifier(); } $self->get_parent_terms($term)) :
455 # otherwise use all parent ids
456 (keys %{$store});
457 # add the term as a parent too if one is supplied
458 push(@parent_ids,$term->identifier) if $term;
460 foreach my $parent_id (@parent_ids) {
461 my $parent_entry = $store->{$parent_id};
463 # if a term is supplied, add a relationship for the parent to the term
464 # except if the parent is the term itself (we added that one before)
465 if($term && ($parent_id ne $term->identifier())) {
466 my @parent_terms = $self->get_term_by_identifier($parent_id);
467 foreach my $parent_term (@parent_terms) {
468 push(@rels,
469 $relfact->create_object(-object_term => $parent_term,
470 -subject_term => $term,
471 -predicate_term =>
472 $parent_entry->{$term->identifier},
473 -ontology => $term->ontology())
477 } else {
478 # otherwise, i.e., no term supplied, or the parent equals the
479 # supplied term
480 my @parent_terms = $term ?
481 ($term) : $self->get_term_by_identifier($parent_id);
482 foreach my $child_id (keys %$parent_entry) {
483 my $rel_info = $parent_entry->{$child_id};
484 my ($subj_term) = $self->get_term_by_identifier($child_id);
486 foreach my $parent_term (@parent_terms) {
487 push(@rels,
488 $relfact->create_object(-object_term => $parent_term,
489 -subject_term => $subj_term,
490 -predicate_term => $rel_info,
491 -ontology =>$parent_term->ontology
499 return @rels;
502 =head2 get_all_relationships
504 Title : get_all_relationships
505 Usage : get_all_relationships(): RelationshipI
506 Function: Retrieves all relationship objects.
507 Example :
508 Returns : Array of RelationshipI objects
509 Args :
511 =cut
513 sub get_all_relationships{
514 return shift->get_relationships();
517 =head2 get_predicate_terms
519 Title : get_predicate_terms
520 Usage : get_predicate_terms(): TermI
521 Function: Retrives all relationship types stored in the engine
522 Example :
523 Returns : reference to an array of Bio::Ontology::RelationshipType objects
524 Args :
526 =cut
528 sub get_predicate_terms{
529 my ($self) = @_;
531 return values %{$self->_relationship_type_store};
534 =head2 _is_rel_type
536 Title : _is_rel_type
537 Usage :
538 Function:
539 Example :
540 Returns :
541 Args :
543 =cut
545 sub _is_rel_type{
546 my ($self, $term, @rel_types) = @_;
548 foreach my $rel_type (@rel_types) {
549 if($rel_type->identifier || $term->identifier) {
550 return 1 if $rel_type->identifier eq $term->identifier;
551 } else {
552 return 1 if $rel_type->name eq $term->name;
556 return 0;
559 =head2 _typed_traversal
561 Title : _typed_traversal
562 Usage :
563 Function:
564 Example :
565 Returns :
566 Args :
568 =cut
570 sub _typed_traversal{
571 my ($self, $rel_store, $level, $term_id, @rel_types) = @_;
572 return if !defined($rel_store->{$term_id});
573 my %parent_entry = %{$rel_store->{$term_id}};
574 my @children = keys %parent_entry;
576 my @ans;
578 if (@rel_types > 0) {
579 @ans = ();
581 foreach my $child_id (@children) {
582 push @ans, $child_id
583 if $self->_is_rel_type( $rel_store->{$term_id}->{$child_id},
584 @rel_types);
587 else {
588 @ans = @children;
590 if ($level < 1) {
591 my @ans1 = ();
593 foreach my $child_id (@ans) {
594 push @ans1, $self->_typed_traversal($rel_store,
595 $level - 1, $child_id, @rel_types)
596 if defined $rel_store->{$child_id};
598 push @ans, @ans1;
601 return @ans;
604 =head2 get_child_terms
606 Title : get_child_terms
607 Usage : get_child_terms(TermI term, TermI predicate_terms): TermI
608 get_child_terms(TermI term, RelationshipType predicate_terms): TermI
609 Function: Retrieves all child terms of a given term, that satisfy a
610 relationship among those that are specified in the second
611 argument or undef otherwise. get_child_terms is a special
612 case of get_descendant_terms, limiting the search to the
613 direct descendants.
614 Example :
615 Returns : Array of TermI objects.
616 Args : First argument is the term of interest, second is the list of
617 relationship type terms.
619 =cut
621 sub get_child_terms{
622 my ($self, $term, @relationship_types) = @_;
624 $self->throw("must provide TermI compliant object")
625 unless defined($term) && $term->isa("Bio::Ontology::TermI");
627 return $self->_filter_unmarked(
628 $self->get_term_by_identifier(
629 $self->_typed_traversal($self->_relationship_store,
631 $term->identifier,
632 @relationship_types) ) );
635 =head2 get_descendant_terms
637 Title : get_descendant_terms
638 Usage : get_descendant_terms(TermI term, TermI rel_types): TermI
639 get_child_terms(TermI term, RelationshipType predicate_terms): TermI
640 Function: Retrieves all descendant terms of a given term, that
641 satisfy a relationship among those that are specified in
642 the second argument or undef otherwise. Uses
643 _typed_traversal to find all descendants.
645 Example :
646 Returns : Array of TermI objects.
647 Args : First argument is the term of interest, second is the list of
648 relationship type terms.
650 =cut
652 sub get_descendant_terms{
653 my ($self, $term, @relationship_types) = @_;
655 $self->throw("must provide TermI compliant object")
656 unless defined($term) && $term->isa("Bio::Ontology::TermI");
658 return $self->_filter_unmarked(
659 $self->_filter_repeated(
660 $self->get_term_by_identifier(
661 $self->_typed_traversal($self->_relationship_store,
663 $term->identifier,
664 @relationship_types) ) ) );
667 =head2 get_parent_terms
669 Title : get_parent_terms
670 Usage : get_parent_terms(TermI term, TermI predicate_terms): TermI
671 get_child_terms(TermI term, RelationshipType predicate_terms): TermI
672 Function: Retrieves all parent terms of a given term, that satisfy a
673 relationship among those that are specified in the second
674 argument or undef otherwise. get_parent_terms is a special
675 case of get_ancestor_terms, limiting the search to the
676 direct ancestors.
678 Example :
679 Returns : Array of TermI objects.
680 Args : First argument is the term of interest, second is the list of relationship type terms.
682 =cut
684 sub get_parent_terms{
685 my ($self, $term, @relationship_types) = @_;
686 $self->throw("term must be a valid object, not undef") unless defined $term;
688 return $self->_filter_unmarked(
689 $self->get_term_by_identifier(
690 $self->_typed_traversal($self->_inverted_relationship_store,
692 $term->identifier,
693 @relationship_types) ) );
696 =head2 get_ancestor_terms
698 Title : get_ancestor_terms
699 Usage : get_ancestor_terms(TermI term, TermI predicate_terms): TermI
700 get_child_terms(TermI term, RelationshipType predicate_terms): TermI
701 Function: Retrieves all ancestor terms of a given term, that satisfy
702 a relationship among those that are specified in the second
703 argument or undef otherwise. Uses _typed_traversal to find
704 all ancestors.
706 Example :
707 Returns : Array of TermI objects.
708 Args : First argument is the term of interest, second is the list
709 of relationship type terms.
711 =cut
713 sub get_ancestor_terms{
714 my ($self, $term, @relationship_types) = @_;
715 $self->throw("term must be a valid object, not undef") unless defined $term;
717 return $self->_filter_unmarked(
718 $self->_filter_repeated(
719 $self->get_term_by_identifier(
720 $self->_typed_traversal($self->_inverted_relationship_store,
722 $term->identifier,
723 @relationship_types) ) ) );
726 =head2 get_leaf_terms
728 Title : get_leaf_terms
729 Usage : get_leaf_terms(): TermI
730 Function: Retrieves all leaf terms from the ontology. Leaf term is a term w/o descendants.
731 Example : @leaf_terms = $obj->get_leaf_terms()
732 Returns : Array of TermI objects.
733 Args :
735 =cut
737 sub get_leaf_terms{
738 my ($self) = @_;
739 my @leaf_terms;
741 foreach my $term (values %{$self->_term_store}) {
742 push @leaf_terms, $term
743 if !defined $self->_relationship_store->{$term->identifier} &&
744 defined $self->_instantiated_terms_store->{$term->identifier};
747 return @leaf_terms;
750 =head2 get_root_terms
752 Title : get_root_terms
753 Usage : get_root_terms(): TermI
754 Function: Retrieves all root terms from the ontology. Root term is a term w/o descendants.
755 Example : @root_terms = $obj->get_root_terms()
756 Returns : Array of TermI objects.
757 Args :
759 =cut
761 sub get_root_terms{
762 my ($self) = @_;
763 my @root_terms;
765 foreach my $term (values %{$self->_term_store}) {
766 push @root_terms, $term
767 if !defined $self->_inverted_relationship_store->{$term->identifier} &&
768 defined $self->_instantiated_terms_store->{$term->identifier};
771 return @root_terms;
774 =head2 _filter_repeated
776 Title : _filter_repeated
777 Usage : @lst = $self->_filter_repeated(@old_lst);
778 Function: Removes repeated terms
779 Example :
780 Returns : List of unique TermI objects
781 Args : List of TermI objects
783 =cut
785 sub _filter_repeated{
786 my ($self, @args) = @_;
787 my %h;
789 foreach my $element (@args) {
790 $h{$element->identifier} = $element if !defined $h{$element->identifier};
793 return values %h;
796 =head2 get_all_terms
798 Title : get_all_terms
799 Usage : get_all_terms(): TermI
800 Function: Retrieves all terms currently stored in the ontology.
801 Example : @all_terms = $obj->get_all_terms()
802 Returns : Array of TermI objects.
803 Args :
805 =cut
807 sub get_all_terms{
808 my ($self) = @_;
810 return $self->_filter_unmarked( values %{$self->_term_store} );
813 =head2 find_terms
815 Title : find_terms
816 Usage : ($term) = $oe->find_terms(-identifier => "SO:0000263");
817 Function: Find term instances matching queries for their attributes.
819 This implementation can efficiently resolve queries by
820 identifier.
822 Example :
823 Returns : an array of zero or more Bio::Ontology::TermI objects
824 Args : Named parameters. The following parameters should be recognized
825 by any implementations:
827 -identifier query by the given identifier
828 -name query by the given name
830 =cut
832 sub find_terms{
833 my ($self,@args) = @_;
834 my @terms;
836 my ($id,$name) = $self->_rearrange([qw(IDENTIFIER NAME)],@args);
838 if(defined($id)) {
839 @terms = $self->get_term_by_identifier($id);
840 } else {
841 @terms = $self->get_all_terms();
843 if(defined($name)) {
844 @terms = grep { $_->name() eq $name; } @terms;
846 return @terms;
850 =head2 relationship_factory
852 Title : relationship_factory
853 Usage : $fact = $obj->relationship_factory()
854 Function: Get/set the object factory to be used when relationship
855 objects are created by the implementation on-the-fly.
857 Example :
858 Returns : value of relationship_factory (a Bio::Factory::ObjectFactoryI
859 compliant object)
860 Args : on set, a Bio::Factory::ObjectFactoryI compliant object
862 =cut
864 sub relationship_factory{
865 my $self = shift;
867 return $self->{'relationship_factory'} = shift if @_;
868 return $self->{'relationship_factory'};
871 =head2 term_factory
873 Title : term_factory
874 Usage : $fact = $obj->term_factory()
875 Function: Get/set the object factory to be used when term objects are
876 created by the implementation on-the-fly.
878 Note that this ontology engine implementation does not
879 create term objects on the fly, and therefore setting this
880 attribute is meaningless.
882 Example :
883 Returns : value of term_factory (a Bio::Factory::ObjectFactoryI
884 compliant object)
885 Args : on set, a Bio::Factory::ObjectFactoryI compliant object
887 =cut
889 sub term_factory{
890 my $self = shift;
892 if(@_) {
893 $self->warn("setting term factory, but ".ref($self).
894 " does not create terms on-the-fly");
895 return $self->{'term_factory'} = shift;
897 return $self->{'term_factory'};
900 =head2 _filter_unmarked
902 Title : _filter_unmarked
903 Usage : _filter_unmarked(TermI terms): TermI
904 Function: Removes the uninstantiated terms from the list of terms
905 Example :
906 Returns : array of fully instantiated TermI objects
907 Args : array of TermI objects
909 =cut
911 sub _filter_unmarked{
912 my ($self, @terms) = @_;
913 my @filtered_terms = ();
915 if ( scalar(@terms) >= 1) {
916 foreach my $term (@terms) {
917 push @filtered_terms, $term
918 if defined $self->_instantiated_terms_store->{$term->identifier};
922 return @filtered_terms;
925 =head2 remove_term_by_id
927 Title : remove_term_by_id
928 Usage : remove_term_by_id(String id): TermI
929 Function: Removes TermI object from the ontology engine using the
930 string id as an identifier. Current implementation does not
931 enforce consistency of the relationships using that term.
932 Example : $term = $soe->remove_term_by_id($id);
933 Returns : Object of class TermI or undef if not found.
934 Args : The string identifier of a term.
936 =cut
938 sub remove_term_by_id{
939 my ($self, $id) = @_;
941 if ( $self->get_term_by_identifier($id) ) {
942 my $term = $self->{_term_store}->{$id};
943 delete $self->{_term_store}->{$id};
944 return $term;
946 else {
947 $self->warn("Term with id '$id' is not in the term store");
948 return;
952 =head2 to_string
954 Title : to_string
955 Usage : print $sv->to_string();
956 Function: Currently returns formatted string containing the number of
957 terms and number of relationships from the ontology engine.
958 Example : print $sv->to_string();
959 Returns :
960 Args :
962 =cut
964 sub to_string{
965 my ($self) = @_;
966 my $s = "";
968 $s .= "-- # Terms:\n";
969 $s .= scalar($self->get_all_terms)."\n";
970 $s .= "-- # Relationships:\n";
971 $s .= $self->_get_number_rels."\n";
973 return $s;
976 =head2 _unique_termid
978 Title : _unique_termid
979 Usage :
980 Function: Returns a string that can be used as ID using fail-over
981 approaches.
983 If the identifier attribute is not set, it uses the
984 combination of name and ontology name, provided both are
985 set. If they are not, it returns the name alone.
987 Note that this is a private method. Call from inheriting
988 classes but not from outside.
990 Example :
991 Returns : a string
992 Args : a Bio::Ontology::TermI compliant object
994 =cut
996 sub _unique_termid{
997 my $self = shift;
998 my $term = shift;
1000 return $term->identifier() if $term->identifier();
1001 my $id = $term->ontology->name() if $term->ontology();
1002 if($id) {
1003 $id .= '|';
1004 } else {
1005 $id = '';
1007 $id .= $term->name();
1011 #################################################################
1012 # aliases
1013 #################################################################
1015 *get_relationship_types = \&get_predicate_terms;