3 # BioPerl module for Bio::Ontology::Ontology
5 # Cared for by Hilmar Lapp <hlapp at gmx.net>
7 # Copyright Hilmar Lapp
9 # You may distribute this module under the same terms as perl itself
12 # (c) Hilmar Lapp, hlapp at gmx.net, 2003.
13 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2003.
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.
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.
25 # POD documentation - main docs before the code
29 Bio::Ontology::Ontology - standard implementation of an Ontology
33 use Bio::Ontology::Ontology;
34 use Bio::Ontology::Term;
36 # create ontology object
37 my $ont = Bio::Ontology::Ontology->new(-name => "OBF");
39 # add terms, relationships ...
40 my $bp = Bio::Ontology::Term->new(-identifier => '02', -name => "Bioperl");
41 my $obf = Bio::Ontology::Term->new(-identifier => '01', -name => "OBF");
42 my $partof = Bio::Ontology::RelationshipType->get_instance("PART_OF");
45 $ont->add_relationship($bp, $obf, $partof);
48 my @terms = $ont->get_root_terms(); # "OBF"
49 my @desc = $ont->get_descendant_terms($terms[0], $partof); # "Bioperl"
50 # ... see methods for other ways to query
52 # for advanced users, you can re-use the query engine outside of an
53 # ontology to let one instance manage multiple ontologies
54 my $ont2 = Bio::Ontology::Ontology->new(-name => "Foundations",
55 -engine => $ont->engine());
60 This is a no-frills implementation of L<Bio::Ontology::OntologyI>.
62 The query functions are implemented by delegation to an
63 OntologyEngineI implementation.
69 User feedback is an integral part of the evolution of this and other
70 Bioperl modules. Send your comments and suggestions preferably to
71 the Bioperl mailing list. Your participation is much appreciated.
73 bioperl-l@bioperl.org - General discussion
74 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
78 Report bugs to the Bioperl bug tracking system to help us keep track
79 of the bugs and their resolution. Bug reports can be submitted via
82 http://bugzilla.open-bio.org/
84 =head1 AUTHOR - Hilmar Lapp
86 Email hlapp at gmx.net
90 The rest of the documentation details each of the object methods.
91 Internal methods are usually preceded with a _
96 # Let the code begin...
99 package Bio
::Ontology
::Ontology
;
102 # Object preamble - inherits from Bio::Root::Root
104 #use Bio::Ontology::SimpleOntologyEngine; # loaded dynamically now!
106 use base
qw(Bio::Root::Root Bio::Ontology::OntologyI Bio::AnnotatableI);
111 Usage : my $obj = Bio::Ontology::Ontology->new();
112 Function: Builds a new Bio::Ontology::Ontology object
113 Returns : an instance of Bio::Ontology::Ontology
114 Args : any number of named arguments. The following names will be
115 recognized by this module:
117 -name the name of the ontology
118 -authority the name of the authority for the ontology
119 -identifier an identifier for the ontology, if any
120 -engine the Bio::Ontology::OntologyEngineI
121 implementation that this instance should use;
122 default is Bio::Ontology::SimpleOntologyEngine
124 See the corresponding get/set methods for further documentation
125 on individual properties.
130 my($class,@args) = @_;
132 my $self = $class->SUPER::new
(@args);
133 my ($name,$auth,$def,$id,$engine) =
134 $self->_rearrange([qw(NAME
141 defined($name) && $self->name($name);
142 defined($auth) && $self->authority($auth);
143 defined($def) && $self->definition($def);
144 defined($id) && $self->identifier($id);
145 defined($engine) && $self->engine($engine);
150 =head1 Methods from L<Bio::Ontology::OntologyI>
157 Usage : $obj->name($newval)
158 Function: Get/set the name of the ontology.
160 Returns : value of name (a scalar)
161 Args : on set, new value (a scalar or undef, optional)
169 return $self->{'name'} = shift if @_;
170 return $self->{'name'};
176 Usage : $obj->authority($newval)
177 Function: Get/set the authority for this ontology, for instance the
178 DNS base for the organization granting the name of the
179 ontology and identifiers for the terms.
181 This attribute is optional and should not generally
182 expected by applications to have been set. It is here to
183 follow the rules for namespaces, which ontologies serve as
187 Returns : value of authority (a scalar)
188 Args : on set, new value (a scalar or undef, optional)
196 return $self->{'authority'} = shift if @_;
197 return $self->{'authority'};
203 Usage : $obj->definition($newval)
204 Function: Get/set a descriptive definition of the ontology.
206 Returns : value of definition (a scalar)
207 Args : on set, new value (a scalar or undef, optional)
215 return $self->{'definition'} = shift if @_;
216 return $self->{'definition'};
222 Usage : $id = $obj->identifier()
223 Function: Get an identifier for this ontology.
225 This is primarily intended for look-up purposes. The value
226 is not modifiable and is determined automatically by the
227 implementation. Also, the identifier's uniqueness will only
228 hold within the scope of a particular application's run
229 time since it is derived from a memory location.
232 Returns : value of identifier (a scalar)
242 $self->throw("cannot modify identifier for ".ref($self))
243 if exists($self->{'identifier'});
245 $self->{'identifier'} = $id if $id;
247 if(! exists($self->{'identifier'})) {
248 ($self->{'identifier'}) = "$self" =~ /(0x[0-9a-fA-F]+)/;
250 return $self->{'identifier'};
257 Function: Release any resources this ontology may occupy. In order
258 to efficiently release unused memory or file handles, you
259 should call this method once you are finished with an
263 Returns : TRUE on success and FALSE otherwise
272 # if it is in the ontology store, remove it from there
273 my $store = Bio
::Ontology
::OntologyStore
->get_instance();
274 $store->remove_ontology($self);
275 # essentially we need to dis-associate from the engine here
276 $self->engine(undef);
280 =head1 Implementation-specific public methods
287 Usage : $engine = $obj->engine()
288 Function: Get/set the ontology engine to which all the query methods
291 Returns : an object implementing Bio::Ontology::OntologyEngineI
292 Args : on set, new value (an object implementing
293 Bio::Ontology::OntologyEngineI, or undef)
295 See L<Bio::Ontology::OntologyEngineI>.
306 $engine->isa("Bio::Ontology::OntologyEngineI")))) {
307 $self->throw("object of class ".ref($engine)." does not implement".
308 " Bio::Ontology::OntologyEngineI. Bummer!");
310 $self->{'engine'} = $engine;
311 } elsif (! exists($self->{'engine'})) {
312 # instantiate on demand
314 # this introduces a dependency on Graph.pm, so load dynamically
315 require Bio
::Ontology
::SimpleOntologyEngine
;
318 $self->throw("failed to load SimpleOntologyEngine, possibly "
319 ."Graph.pm is not installed; either install or supply "
320 ."another OntologyEngineI implementation:\n"
323 $self->{'engine'} = Bio
::Ontology
::SimpleOntologyEngine
->new();
325 return $self->{'engine'};
328 =head1 Methods defined in L<Bio::Ontology::OntologyEngineI>
335 Usage : add_term(TermI term): TermI
336 Function: Adds TermI object to the ontology engine term store
338 If the ontology property of the term object was not set,
339 this implementation will set it to itself upon adding the
342 Example : $oe->add_term($term)
343 Returns : its argument.
344 Args : object of class TermI.
353 # set ontology if not set already
354 $term->ontology($self) if $term && (! $term->ontology());
355 return $self->engine->add_term($term,@_);
358 =head2 add_relationship
360 Title : add_relationship
361 Usage : add_relationship(RelationshipI relationship): RelationshipI
362 add_relatioship(TermI subject, TermI predicate, TermI object)
363 Function: Adds a relationship object to the ontology engine.
365 Returns : Its argument.
366 Args : A RelationshipI object.
371 sub add_relationship
{
375 if($rel && $rel->isa("Bio::Ontology::TermI")) {
376 # we need to construct the relationship object on the fly
377 my ($predicate,$object) = @_;
378 $rel = Bio
::Ontology
::Relationship
->new(
379 -subject_term
=> $rel,
380 -object_term
=> $object,
381 -predicate_term
=> $predicate,
385 # set ontology if not set already
386 $rel->ontology($self) unless $rel->ontology();
387 return $self->engine->add_relationship($rel);
390 =head2 get_relationship_type
392 Title : get_relationship_type
393 Usage : get_relationship_type(scalar): RelationshipTypeI
394 Function: Get a relationshiptype object from the ontology engine.
396 Returns : A RelationshipTypeI object.
397 Args : The name (scalar) of the RelationshipTypeI object desired.
402 sub get_relationship_type
{
404 return $self->engine->get_relationship_type(@_);
407 =head2 get_relationships
409 Title : get_relationships
410 Usage : get_relationships(TermI term): RelationshipI[]
411 Function: Retrieves all relationship objects in the ontology, or all
412 relationships of a given term.
414 Returns : Array of Bio::Ontology::RelationshipI objects
415 Args : Optionally, a Bio::Ontology::TermI compliant object
420 sub get_relationships
{
424 # we don't need to filter in this case
425 return $self->engine->get_relationships($term);
427 # else we need to filter by ontology
428 return grep { my $ont = $_->ontology;
429 # the first condition is a superset of the second, but
430 # we add it here for efficiency reasons, as many times
431 # it will short-cut to true and is supposedly faster than
433 ($ont == $self) || ($ont->name eq $self->name);
434 } $self->engine->get_relationships(@_);
437 =head2 get_predicate_terms
439 Title : get_predicate_terms
440 Usage : get_predicate_terms(): TermI
441 Function: Retrieves all relationship types.
443 Returns : Array of TermI objects
449 sub get_predicate_terms
{
452 return grep { $_->ontology->name eq $self->name;
453 } $self->engine->get_predicate_terms(@_);
456 =head2 get_child_terms
458 Title : get_child_terms
459 Usage : get_child_terms(TermI term, TermI predicate_terms): TermI
460 Function: Retrieves all child terms of a given term, that satisfy a
461 relationship among those that are specified in the second
462 argument or undef otherwise. get_child_terms is a special
463 case of get_descendant_terms, limiting the search to the
466 Note that a returned term may possibly be in another
467 ontology than this one, because the underlying engine may
468 manage multiple ontologies and the relationships of terms
469 between them. If you only want descendants within this
470 ontology, you need to filter the returned array.
473 Returns : Array of TermI objects.
474 Args : First argument is the term of interest, second is the list
475 of relationship type terms.
481 return shift->engine->get_child_terms(@_);
484 =head2 get_descendant_terms
486 Title : get_descendant_terms
487 Usage : get_descendant_terms(TermI term, TermI rel_types): TermI
488 Function: Retrieves all descendant terms of a given term, that
489 satisfy a relationship among those that are specified in
490 the second argument or undef otherwise.
492 Note that a returned term may possibly be in another
493 ontology than this one, because the underlying engine may
494 manage multiple ontologies and the relationships of terms
495 between them. If you only want descendants within this
496 ontology, you need to filter the returned array.
499 Returns : Array of TermI objects.
500 Args : First argument is the term of interest, second is the list
501 of relationship type terms.
506 sub get_descendant_terms
{
507 return shift->engine->get_descendant_terms(@_);
510 =head2 get_parent_terms
512 Title : get_parent_terms
513 Usage : get_parent_terms(TermI term, TermI predicate_terms): TermI
514 Function: Retrieves all parent terms of a given term, that satisfy a
515 relationship among those that are specified in the second
516 argument or undef otherwise. get_parent_terms is a special
517 case of get_ancestor_terms, limiting the search to the
520 Note that a returned term may possibly be in another
521 ontology than this one, because the underlying engine may
522 manage multiple ontologies and the relationships of terms
523 between them. If you only want descendants within this
524 ontology, you need to filter the returned array.
527 Returns : Array of TermI objects.
528 Args : First argument is the term of interest, second is the list
529 of relationship type terms.
534 sub get_parent_terms
{
535 return shift->engine->get_parent_terms(@_);
538 =head2 get_ancestor_terms
540 Title : get_ancestor_terms
541 Usage : get_ancestor_terms(TermI term, TermI predicate_terms): TermI
542 Function: Retrieves all ancestor terms of a given term, that satisfy
543 a relationship among those that are specified in the second
544 argument or undef otherwise.
546 Note that a returned term may possibly be in another
547 ontology than this one, because the underlying engine may
548 manage multiple ontologies and the relationships of terms
549 between them. If you only want descendants within this
550 ontology, you need to filter the returned array.
553 Returns : Array of TermI objects.
554 Args : First argument is the term of interest, second is the list
555 of relationship type terms.
560 sub get_ancestor_terms
{
561 return shift->engine->get_ancestor_terms(@_);
564 =head2 get_leaf_terms
566 Title : get_leaf_terms
567 Usage : get_leaf_terms(): TermI
568 Function: Retrieves all leaf terms from the ontology. Leaf term is a
569 term w/o descendants.
571 Example : @leaf_terms = $obj->get_leaf_terms()
572 Returns : Array of TermI objects.
579 return grep { my $ont = $_->ontology;
580 # the first condition is a superset of the second, but
581 # we add it here for efficiency reasons, as many times
582 # it will short-cut to true and is supposedly faster than
584 ($ont == $self) || ($ont->name eq $self->name);
585 } $self->engine->get_leaf_terms(@_);
588 =head2 get_root_terms()
590 Title : get_root_terms
591 Usage : get_root_terms(): TermI
592 Function: Retrieves all root terms from the ontology. Root term is a
595 Example : @root_terms = $obj->get_root_terms()
596 Returns : Array of TermI objects.
603 return grep { my $ont = $_->ontology;
604 # the first condition is a superset of the second, but
605 # we add it here for efficiency reasons, as many times
606 # it will short-cut to true and is supposedly faster than
608 ($ont == $self) || ($ont->name eq $self->name);
609 } $self->engine->get_root_terms(@_);
614 Title : get_all_terms
615 Usage : get_all_terms: TermI
616 Function: Retrieves all terms from the ontology.
618 We do not mandate an order here in which the terms are
619 returned. In fact, the default implementation will return
620 them in unpredictable order.
622 Example : @terms = $obj->get_all_terms()
623 Returns : Array of TermI objects.
630 return grep { my $ont = $_->ontology;
631 # the first condition is a superset of the second, but
632 # we add it here for efficiency reasons, as many times
633 # it will short-cut to true and is supposedly faster than
635 ($ont == $self) || ($ont->name eq $self->name);
636 } $self->engine->get_all_terms(@_);
642 Usage : ($term) = $oe->find_terms(-identifier => "SO:0000263");
643 Function: Find term instances matching queries for their attributes.
645 An implementation may not support querying for arbitrary
646 attributes, but can generally be expected to accept
647 -identifier and -name as queries. If both are provided,
648 they are implicitly intersected.
651 Returns : an array of zero or more Bio::Ontology::TermI objects
652 Args : Named parameters. The following parameters should be recognized
653 by any implementations:
655 -identifier query by the given identifier
656 -name query by the given name
662 return grep { $_->ontology->name eq $self->name;
663 } $self->engine->find_terms(@_);
666 =head2 find_identical_terms
668 Title : find_identical_terms
669 Usage : ($term) = $oe->find_identical_terms($term0);
670 Function: Find term instances where name or synonym
671 matches the query exactly
673 Returns : an array of zero or more Bio::Ontology::TermI objects
674 Args : a Bio::Ontology::TermI object
678 sub find_identical_terms
{
680 return grep { $_->ontology->name eq $self->name;
681 } $self->engine->find_identical_terms(@_);
685 =head2 find_similar_terms
687 Title : find_similar_terms
688 Usage : ($term) = $oe->find_similar_terms($term0);
689 Function: Find term instances where name or synonym, or part of one,
692 Returns : an array of zero or more Bio::Ontology::TermI objects
693 Args : a Bio::Ontology::TermI object
697 sub find_similar_terms
{
699 return grep { $_->ontology->name eq $self->name;
700 } $self->engine->find_similar_terms(@_);
703 =head2 find_identically_named_terms
705 Title : find_identically_named_terms
706 Usage : ($term) = $oe->find_identically_named_terms($term0);
707 Function: Find term instances where names match the query term
710 Returns : an array of zero or more Bio::Ontology::TermI objects
711 Args : a Bio::Ontology::TermI object
715 sub find_identically_named_terms
{
717 return grep { $_->ontology->name eq $self->name
718 } $self->engine->find_identically_named_terms(@_);
721 =head1 Factory for relationships and terms
725 =head2 relationship_factory
727 Title : relationship_factory
728 Usage : $fact = $obj->relationship_factory()
729 Function: Get (and set, if the engine supports it) the object
730 factory to be used when relationship objects are created by
731 the implementation on-the-fly.
734 Returns : value of relationship_factory (a Bio::Factory::ObjectFactoryI
740 sub relationship_factory
{
741 return shift->engine->relationship_factory(@_);
747 Usage : $fact = $obj->term_factory()
748 Function: Get (and set, if the engine supports it) the object
749 factory to be used when term objects are created by
750 the implementation on-the-fly.
753 Returns : value of term_factory (a Bio::Factory::ObjectFactoryI
760 return shift->engine->term_factory(@_);
767 Usage : $annos = $obj->annotation()
768 Function: Get/Set the Bio::Annotation::Collection object
769 The collection contains Bio::Annotation::SimpleValue
770 objects to store header information like the version
771 and date present in the header section of an Ontology
775 Returns : value of annotation (a Bio::Annotation::Collection
777 Args : A Bio::Annotation::Collection object (Optional)
783 $self->{'annotation'} = shift if @_;
784 return $self->{'annotation'};
788 #################################################################
790 #################################################################
792 *get_relationship_types
= \
&get_predicate_terms
;