Bio::DB::TFBS namespace has been moved to its own distribution named after itself
[bioperl-live.git] / Bio / Ontology / Ontology.pm
blobf4a7512f7f2e4a6c1fe69c992dd50af7bd741e73
2 # BioPerl module for Bio::Ontology::Ontology
4 # Please direct questions and support issues to <bioperl-l@bioperl.org>
6 # Cared for by Hilmar Lapp <hlapp at gmx.net>
8 # Copyright Hilmar Lapp
10 # You may distribute this module under the same terms as perl itself
13 # (c) Hilmar Lapp, hlapp at gmx.net, 2003.
14 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2003.
16 # You may distribute this module under the same terms as perl itself.
17 # Refer to the Perl Artistic License (see the license accompanying this
18 # software package, or see http://www.perl.com/language/misc/Artistic.html)
19 # for the terms under which you may use, modify, and redistribute this module.
21 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
22 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
23 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 # POD documentation - main docs before the code
28 =head1 NAME
30 Bio::Ontology::Ontology - standard implementation of an Ontology
32 =head1 SYNOPSIS
34 use Bio::Ontology::Ontology;
35 use Bio::Ontology::Term;
37 # create ontology object
38 my $ont = Bio::Ontology::Ontology->new(-name => "OBF");
40 # add terms, relationships ...
41 my $bp = Bio::Ontology::Term->new(-identifier => '02', -name => "Bioperl");
42 my $obf = Bio::Ontology::Term->new(-identifier => '01', -name => "OBF");
43 my $partof = Bio::Ontology::RelationshipType->get_instance("PART_OF");
44 $ont->add_term($bp);
45 $ont->add_term($obf);
46 $ont->add_relationship($bp, $obf, $partof);
48 # then query
49 my @terms = $ont->get_root_terms(); # "OBF"
50 my @desc = $ont->get_descendant_terms($terms[0], $partof); # "Bioperl"
51 # ... see methods for other ways to query
53 # for advanced users, you can re-use the query engine outside of an
54 # ontology to let one instance manage multiple ontologies
55 my $ont2 = Bio::Ontology::Ontology->new(-name => "Foundations",
56 -engine => $ont->engine());
59 =head1 DESCRIPTION
61 This is a no-frills implementation of L<Bio::Ontology::OntologyI>.
63 The query functions are implemented by delegation to an
64 OntologyEngineI implementation.
66 =head1 FEEDBACK
68 =head2 Mailing Lists
70 User feedback is an integral part of the evolution of this and other
71 Bioperl modules. Send your comments and suggestions preferably to
72 the Bioperl mailing list. Your participation is much appreciated.
74 bioperl-l@bioperl.org - General discussion
75 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
77 =head2 Support
79 Please direct usage questions or support issues to the mailing list:
81 I<bioperl-l@bioperl.org>
83 rather than to the module maintainer directly. Many experienced and
84 reponsive experts will be able look at the problem and quickly
85 address it. Please include a thorough description of the problem
86 with code and data examples if at all possible.
88 =head2 Reporting Bugs
90 Report bugs to the Bioperl bug tracking system to help us keep track
91 of the bugs and their resolution. Bug reports can be submitted via
92 the web:
94 https://github.com/bioperl/bioperl-live/issues
96 =head1 AUTHOR - Hilmar Lapp
98 Email hlapp at gmx.net
100 =head1 APPENDIX
102 The rest of the documentation details each of the object methods.
103 Internal methods are usually preceded with a _
105 =cut
108 # Let the code begin...
111 package Bio::Ontology::Ontology;
112 use strict;
114 # Object preamble - inherits from Bio::Root::Root
116 #use Bio::Ontology::SimpleOntologyEngine; # loaded dynamically now!
118 use base qw(Bio::Root::Root Bio::Ontology::OntologyI Bio::AnnotatableI);
120 =head2 new
122 Title : new
123 Usage : my $obj = Bio::Ontology::Ontology->new();
124 Function: Builds a new Bio::Ontology::Ontology object
125 Returns : an instance of Bio::Ontology::Ontology
126 Args : any number of named arguments. The following names will be
127 recognized by this module:
129 -name the name of the ontology
130 -authority the name of the authority for the ontology
131 -identifier an identifier for the ontology, if any
132 -engine the Bio::Ontology::OntologyEngineI
133 implementation that this instance should use;
134 default is Bio::Ontology::SimpleOntologyEngine
136 See the corresponding get/set methods for further documentation
137 on individual properties.
139 =cut
141 sub new {
142 my($class,@args) = @_;
144 my $self = $class->SUPER::new(@args);
145 my ($name,$auth,$def,$id,$engine) =
146 $self->_rearrange([qw(NAME
147 AUTHORITY
148 DEFINITION
149 IDENTIFIER
150 ENGINE)
152 @args);
153 defined($name) && $self->name($name);
154 defined($auth) && $self->authority($auth);
155 defined($def) && $self->definition($def);
156 defined($id) && $self->identifier($id);
157 defined($engine) && $self->engine($engine);
159 return $self;
162 =head1 Methods from L<Bio::Ontology::OntologyI>
164 =cut
166 =head2 name
168 Title : name
169 Usage : $obj->name($newval)
170 Function: Get/set the name of the ontology.
171 Example :
172 Returns : value of name (a scalar)
173 Args : on set, new value (a scalar or undef, optional)
176 =cut
178 sub name{
179 my $self = shift;
181 return $self->{'name'} = shift if @_;
182 return $self->{'name'};
185 =head2 authority
187 Title : authority
188 Usage : $obj->authority($newval)
189 Function: Get/set the authority for this ontology, for instance the
190 DNS base for the organization granting the name of the
191 ontology and identifiers for the terms.
193 This attribute is optional and should not generally
194 expected by applications to have been set. It is here to
195 follow the rules for namespaces, which ontologies serve as
196 for terms.
198 Example :
199 Returns : value of authority (a scalar)
200 Args : on set, new value (a scalar or undef, optional)
203 =cut
205 sub authority{
206 my $self = shift;
208 return $self->{'authority'} = shift if @_;
209 return $self->{'authority'};
212 =head2 definition
214 Title : definition
215 Usage : $obj->definition($newval)
216 Function: Get/set a descriptive definition of the ontology.
217 Example :
218 Returns : value of definition (a scalar)
219 Args : on set, new value (a scalar or undef, optional)
222 =cut
224 sub definition{
225 my $self = shift;
227 return $self->{'definition'} = shift if @_;
228 return $self->{'definition'};
231 =head2 identifier
233 Title : identifier
234 Usage : $id = $obj->identifier()
235 Function: Get an identifier for this ontology.
237 This is primarily intended for look-up purposes. The value
238 is not modifiable and is determined automatically by the
239 implementation. Also, the identifier's uniqueness will only
240 hold within the scope of a particular application's run
241 time since it is derived from a memory location.
243 Example :
244 Returns : value of identifier (a scalar)
245 Args :
248 =cut
250 sub identifier{
251 my $self = shift;
253 if(@_) {
254 $self->throw("cannot modify identifier for ".ref($self))
255 if exists($self->{'identifier'});
256 my $id = shift;
257 $self->{'identifier'} = $id if $id;
259 if(! exists($self->{'identifier'})) {
260 ($self->{'identifier'}) = "$self" =~ /(0x[0-9a-fA-F]+)/;
262 return $self->{'identifier'};
265 =head2 close
267 Title : close
268 Usage :
269 Function: Release any resources this ontology may occupy. In order
270 to efficiently release unused memory or file handles, you
271 should call this method once you are finished with an
272 ontology.
274 Example :
275 Returns : TRUE on success and FALSE otherwise
276 Args : none
279 =cut
281 sub close{
282 my $self = shift;
284 # if it is in the ontology store, remove it from there
285 my $store = Bio::Ontology::OntologyStore->get_instance();
286 $store->remove_ontology($self);
287 # essentially we need to dis-associate from the engine here
288 $self->engine(undef);
289 return 1;
292 =head1 Implementation-specific public methods
294 =cut
296 =head2 engine
298 Title : engine
299 Usage : $engine = $obj->engine()
300 Function: Get/set the ontology engine to which all the query methods
301 delegate.
302 Example :
303 Returns : an object implementing Bio::Ontology::OntologyEngineI
304 Args : on set, new value (an object implementing
305 Bio::Ontology::OntologyEngineI, or undef)
307 See L<Bio::Ontology::OntologyEngineI>.
309 =cut
311 sub engine{
312 my $self = shift;
314 if (@_) {
315 my $engine = shift;
316 if($engine &&
317 (! (ref($engine) &&
318 $engine->isa("Bio::Ontology::OntologyEngineI")))) {
319 $self->throw("object of class ".ref($engine)." does not implement".
320 " Bio::Ontology::OntologyEngineI. Bummer!");
322 $self->{'engine'} = $engine;
323 } elsif (! exists($self->{'engine'})) {
324 # instantiate on demand
325 eval {
326 # this introduces a dependency on Graph.pm, so load dynamically
327 require Bio::Ontology::SimpleOntologyEngine;
329 if ($@) {
330 $self->throw("failed to load SimpleOntologyEngine, possibly "
331 ."Graph.pm is not installed; either install or supply "
332 ."another OntologyEngineI implementation:\n"
333 .$@);
335 $self->{'engine'} = Bio::Ontology::SimpleOntologyEngine->new();
337 return $self->{'engine'};
340 =head1 Methods defined in L<Bio::Ontology::OntologyEngineI>
342 =cut
344 =head2 add_term
346 Title : add_term
347 Usage : add_term(TermI term): TermI
348 Function: Adds TermI object to the ontology engine term store
350 If the ontology property of the term object was not set,
351 this implementation will set it to itself upon adding the
352 term.
354 Example : $oe->add_term($term)
355 Returns : its argument.
356 Args : object of class TermI.
359 =cut
361 sub add_term{
362 my $self = shift;
363 my $term = shift;
365 # set ontology if not set already
366 $term->ontology($self) if $term && (! $term->ontology());
367 return $self->engine->add_term($term,@_);
370 =head2 add_relationship
372 Title : add_relationship
373 Usage : add_relationship(RelationshipI relationship): RelationshipI
374 add_relatioship(TermI subject, TermI predicate, TermI object)
375 Function: Adds a relationship object to the ontology engine.
376 Example :
377 Returns : Its argument.
378 Args : A RelationshipI object.
381 =cut
383 sub add_relationship {
384 my $self = shift;
385 my $rel = shift;
387 if($rel && $rel->isa("Bio::Ontology::TermI")) {
388 # we need to construct the relationship object on the fly
389 my ($predicate,$object) = @_;
390 $rel = Bio::Ontology::Relationship->new(
391 -subject_term => $rel,
392 -object_term => $object,
393 -predicate_term => $predicate,
394 -ontology => $self,
397 # set ontology if not set already
398 $rel->ontology($self) unless $rel->ontology();
399 return $self->engine->add_relationship($rel);
402 =head2 get_relationship_type
404 Title : get_relationship_type
405 Usage : get_relationship_type(scalar): RelationshipTypeI
406 Function: Get a relationshiptype object from the ontology engine.
407 Example :
408 Returns : A RelationshipTypeI object.
409 Args : The name (scalar) of the RelationshipTypeI object desired.
412 =cut
414 sub get_relationship_type{
415 my $self = shift;
416 return $self->engine->get_relationship_type(@_);
419 =head2 get_relationships
421 Title : get_relationships
422 Usage : get_relationships(TermI term): RelationshipI[]
423 Function: Retrieves all relationship objects in the ontology, or all
424 relationships of a given term.
425 Example :
426 Returns : Array of Bio::Ontology::RelationshipI objects
427 Args : Optionally, a Bio::Ontology::TermI compliant object
430 =cut
432 sub get_relationships {
433 my $self = shift;
434 my $term = shift;
435 if($term) {
436 # we don't need to filter in this case
437 return $self->engine->get_relationships($term);
439 # else we need to filter by ontology
440 return grep { my $ont = $_->ontology;
441 # the first condition is a superset of the second, but
442 # we add it here for efficiency reasons, as many times
443 # it will short-cut to true and is supposedly faster than
444 # string comparison
445 ($ont == $self) || ($ont->name eq $self->name);
446 } $self->engine->get_relationships(@_);
449 =head2 get_predicate_terms
451 Title : get_predicate_terms
452 Usage : get_predicate_terms(): TermI
453 Function: Retrieves all relationship types.
454 Example :
455 Returns : Array of TermI objects
456 Args :
459 =cut
461 sub get_predicate_terms{
462 my $self = shift;
464 # skipped Bio::Ontology::Relationship w/o defined Ontology (bug 2573)
465 return grep { $_->ontology && ($_->ontology->name eq $self->name)
466 } $self->engine->get_predicate_terms(@_);
469 =head2 get_child_terms
471 Title : get_child_terms
472 Usage : get_child_terms(TermI term, TermI predicate_terms): TermI
473 Function: Retrieves all child terms of a given term, that satisfy a
474 relationship among those that are specified in the second
475 argument or undef otherwise. get_child_terms is a special
476 case of get_descendant_terms, limiting the search to the
477 direct descendants.
479 Note that a returned term may possibly be in another
480 ontology than this one, because the underlying engine may
481 manage multiple ontologies and the relationships of terms
482 between them. If you only want descendants within this
483 ontology, you need to filter the returned array.
485 Example :
486 Returns : Array of TermI objects.
487 Args : First argument is the term of interest, second is the list
488 of relationship type terms.
491 =cut
493 sub get_child_terms{
494 return shift->engine->get_child_terms(@_);
497 =head2 get_descendant_terms
499 Title : get_descendant_terms
500 Usage : get_descendant_terms(TermI term, TermI rel_types): TermI
501 Function: Retrieves all descendant terms of a given term, that
502 satisfy a relationship among those that are specified in
503 the second argument or undef otherwise.
505 Note that a returned term may possibly be in another
506 ontology than this one, because the underlying engine may
507 manage multiple ontologies and the relationships of terms
508 between them. If you only want descendants within this
509 ontology, you need to filter the returned array.
511 Example :
512 Returns : Array of TermI objects.
513 Args : First argument is the term of interest, second is the list
514 of relationship type terms.
517 =cut
519 sub get_descendant_terms{
520 return shift->engine->get_descendant_terms(@_);
523 =head2 get_parent_terms
525 Title : get_parent_terms
526 Usage : get_parent_terms(TermI term, TermI predicate_terms): TermI
527 Function: Retrieves all parent terms of a given term, that satisfy a
528 relationship among those that are specified in the second
529 argument or undef otherwise. get_parent_terms is a special
530 case of get_ancestor_terms, limiting the search to the
531 direct ancestors.
533 Note that a returned term may possibly be in another
534 ontology than this one, because the underlying engine may
535 manage multiple ontologies and the relationships of terms
536 between them. If you only want descendants within this
537 ontology, you need to filter the returned array.
539 Example :
540 Returns : Array of TermI objects.
541 Args : First argument is the term of interest, second is the list
542 of relationship type terms.
545 =cut
547 sub get_parent_terms{
548 return shift->engine->get_parent_terms(@_);
551 =head2 get_ancestor_terms
553 Title : get_ancestor_terms
554 Usage : get_ancestor_terms(TermI term, TermI predicate_terms): TermI
555 Function: Retrieves all ancestor terms of a given term, that satisfy
556 a relationship among those that are specified in the second
557 argument or undef otherwise.
559 Note that a returned term may possibly be in another
560 ontology than this one, because the underlying engine may
561 manage multiple ontologies and the relationships of terms
562 between them. If you only want descendants within this
563 ontology, you need to filter the returned array.
565 Example :
566 Returns : Array of TermI objects.
567 Args : First argument is the term of interest, second is the list
568 of relationship type terms.
571 =cut
573 sub get_ancestor_terms{
574 return shift->engine->get_ancestor_terms(@_);
577 =head2 get_leaf_terms
579 Title : get_leaf_terms
580 Usage : get_leaf_terms(): TermI
581 Function: Retrieves all leaf terms from the ontology. Leaf term is a
582 term w/o descendants.
584 Example : @leaf_terms = $obj->get_leaf_terms()
585 Returns : Array of TermI objects.
586 Args :
588 =cut
590 sub get_leaf_terms{
591 my $self = shift;
592 return grep { my $ont = $_->ontology;
593 # the first condition is a superset of the second, but
594 # we add it here for efficiency reasons, as many times
595 # it will short-cut to true and is supposedly faster than
596 # string comparison
597 ($ont == $self) || ($ont->name eq $self->name);
598 } $self->engine->get_leaf_terms(@_);
601 =head2 get_root_terms()
603 Title : get_root_terms
604 Usage : get_root_terms(): TermI
605 Function: Retrieves all root terms from the ontology. Root term is a
606 term w/o parents.
608 Example : @root_terms = $obj->get_root_terms()
609 Returns : Array of TermI objects.
610 Args :
612 =cut
614 sub get_root_terms{
615 my $self = shift;
616 return grep { my $ont = $_->ontology;
617 # the first condition is a superset of the second, but
618 # we add it here for efficiency reasons, as many times
619 # it will short-cut to true and is supposedly faster than
620 # string comparison
621 ($ont == $self) || ($ont->name eq $self->name);
622 } $self->engine->get_root_terms(@_);
625 =head2 get_all_terms
627 Title : get_all_terms
628 Usage : get_all_terms: TermI
629 Function: Retrieves all terms from the ontology.
631 We do not mandate an order here in which the terms are
632 returned. In fact, the default implementation will return
633 them in unpredictable order.
635 Example : @terms = $obj->get_all_terms()
636 Returns : Array of TermI objects.
637 Args :
639 =cut
641 sub get_all_terms{
642 my $self = shift;
643 return grep { my $ont = $_->ontology;
644 # the first condition is a superset of the second, but
645 # we add it here for efficiency reasons, as many times
646 # it will short-cut to true and is supposedly faster than
647 # string comparison
648 ($ont == $self) || ($ont->name eq $self->name);
649 } $self->engine->get_all_terms(@_);
652 =head2 find_terms
654 Title : find_terms
655 Usage : ($term) = $oe->find_terms(-identifier => "SO:0000263");
656 Function: Find term instances matching queries for their attributes.
658 An implementation may not support querying for arbitrary
659 attributes, but can generally be expected to accept
660 -identifier and -name as queries. If both are provided,
661 they are implicitly intersected.
663 Example :
664 Returns : an array of zero or more Bio::Ontology::TermI objects
665 Args : Named parameters. The following parameters should be recognized
666 by any implementations:
668 -identifier query by the given identifier
669 -name query by the given name
671 =cut
673 sub find_terms{
674 my $self = shift;
675 return grep { $_->ontology->name eq $self->name;
676 } $self->engine->find_terms(@_);
679 =head2 find_identical_terms
681 Title : find_identical_terms
682 Usage : ($term) = $oe->find_identical_terms($term0);
683 Function: Find term instances where name or synonym
684 matches the query exactly
685 Example :
686 Returns : an array of zero or more Bio::Ontology::TermI objects
687 Args : a Bio::Ontology::TermI object
689 =cut
691 sub find_identical_terms{
692 my $self = shift;
693 return grep { $_->ontology->name eq $self->name;
694 } $self->engine->find_identical_terms(@_);
698 =head2 find_similar_terms
700 Title : find_similar_terms
701 Usage : ($term) = $oe->find_similar_terms($term0);
702 Function: Find term instances where name or synonym, or part of one,
703 matches the query.
704 Example :
705 Returns : an array of zero or more Bio::Ontology::TermI objects
706 Args : a Bio::Ontology::TermI object
708 =cut
710 sub find_similar_terms{
711 my $self = shift;
712 return grep { $_->ontology->name eq $self->name;
713 } $self->engine->find_similar_terms(@_);
716 =head2 find_identically_named_terms
718 Title : find_identically_named_terms
719 Usage : ($term) = $oe->find_identically_named_terms($term0);
720 Function: Find term instances where names match the query term
721 name exactly
722 Example :
723 Returns : an array of zero or more Bio::Ontology::TermI objects
724 Args : a Bio::Ontology::TermI object
726 =cut
728 sub find_identically_named_terms{
729 my $self = shift;
730 return grep { $_->ontology->name eq $self->name
731 } $self->engine->find_identically_named_terms(@_);
734 =head1 Factory for relationships and terms
736 =cut
738 =head2 relationship_factory
740 Title : relationship_factory
741 Usage : $fact = $obj->relationship_factory()
742 Function: Get (and set, if the engine supports it) the object
743 factory to be used when relationship objects are created by
744 the implementation on-the-fly.
746 Example :
747 Returns : value of relationship_factory (a Bio::Factory::ObjectFactoryI
748 compliant object)
749 Args :
751 =cut
753 sub relationship_factory{
754 return shift->engine->relationship_factory(@_);
757 =head2 term_factory
759 Title : term_factory
760 Usage : $fact = $obj->term_factory()
761 Function: Get (and set, if the engine supports it) the object
762 factory to be used when term objects are created by
763 the implementation on-the-fly.
765 Example :
766 Returns : value of term_factory (a Bio::Factory::ObjectFactoryI
767 compliant object)
768 Args :
770 =cut
772 sub term_factory{
773 return shift->engine->term_factory(@_);
777 =head2 annotation
779 Title : annotation
780 Usage : $annos = $obj->annotation()
781 Function: Get/Set the Bio::Annotation::Collection object
782 The collection contains Bio::Annotation::SimpleValue
783 objects to store header information like the version
784 and date present in the header section of an Ontology
785 file.
787 Example :
788 Returns : value of annotation (a Bio::Annotation::Collection
789 compliant object)
790 Args : A Bio::Annotation::Collection object (Optional)
792 =cut
794 sub annotation{
795 my $self = shift;
796 $self->{'annotation'} = shift if @_;
797 return $self->{'annotation'};
801 #################################################################
802 # aliases
803 #################################################################
805 *get_relationship_types = \&get_predicate_terms;