2 # BioPerl module for Bio::Ontology::OBOEngine
4 # POD documentation - main docs before the code
8 Bio::Ontology::OBOEngine - An Ontology Engine for OBO style flat file
9 format from the Gene Ontology Consortium
13 use Bio::Ontology::OBOEngine;
15 my $parser = Bio::Ontology::OBOEngine->new
16 ( -file => "gene_ontology.obo" );
18 my $engine = $parser->parse();
22 Needs Graph.pm from CPAN.
24 This module replaces SimpleGOEngine.pm, which is deprecated.
30 User feedback is an integral part of the evolution of this and other
31 Bioperl modules. Send your comments and suggestions preferably to the
32 Bioperl mailing lists Your participation is much appreciated.
34 bioperl-l@bioperl.org - General discussion
35 http://bioperl.org/wiki/Mailing_lists - About the mailing lists
39 Please direct usage questions or support issues to the mailing list:
41 I<bioperl-l@bioperl.org>
43 rather than to the module maintainer directly. Many experienced and
44 reponsive experts will be able look at the problem and quickly
45 address it. Please include a thorough description of the problem
46 with code and data examples if at all possible.
50 Report bugs to the Bioperl bug tracking system to help us keep track
51 the bugs and their resolution. Bug reports can be submitted via
54 https://github.com/bioperl/bioperl-live/issues
60 Email: s-merchant@northwestern.edu
64 Northwestern University
65 Center for Genetic Medicine (CGM), dictyBase
72 Hilmar Lapp, hlapp at gmx.net
73 Chris Mungall, cjm at fruitfly.org
77 The rest of the documentation details each of the object
78 methods. Internal methods are usually preceded with a _
82 package Bio
::Ontology
::OBOEngine
;
84 use Bio
::Ontology
::SimpleGOEngine
::GraphAdaptor
;
87 use Bio
::Ontology
::RelationshipType
;
88 use Bio
::Ontology
::RelationshipFactory
;
91 use constant TRUE
=> 1;
92 use constant FALSE
=> 0;
93 use constant IS_A
=> "IS_A";
94 use constant PART_OF
=> "PART_OF";
95 use constant RELATED_TO
=> "RELATED_TO";
96 use constant TERM
=> "TERM";
97 use constant TYPE
=> "TYPE";
98 use constant ONTOLOGY
=> "ONTOLOGY";
99 use constant REGULATES
=> "REGULATES";
100 use constant POSITIVELY_REGULATES
=> "POSITIVELY_REGULATES";
101 use constant NEGATIVELY_REGULATES
=> "NEGATIVELY_REGULATES";
104 use base
qw(Bio::Root::Root Bio::Ontology::OntologyEngineI);
111 Usage : $engine = Bio::Ontology::OBOEngine->new()
112 Function: Creates a new OBOEngine
113 Returns : A new OBOEngine object
119 my( $class, @args ) = @_;
121 my $self = $class->SUPER::new
( @args );
133 Usage : $engine->init();
134 Function: Initializes this Engine.
143 $self->{ "_is_a_relationship" } = Bio
::Ontology
::RelationshipType
->get_instance( IS_A
);
144 $self->{ "_part_of_relationship" } = Bio
::Ontology
::RelationshipType
->get_instance( PART_OF
);
145 $self->{ "_related_to_relationship" } = Bio
::Ontology
::RelationshipType
->get_instance( RELATED_TO
);
147 $self->{'_regulates_relationship'} = Bio
::Ontology
::RelationshipType
->get_instance(REGULATES
);
148 $self->{'_positively_regulate'} = Bio
::Ontology
::RelationshipType
->get_instance(POSITIVELY_REGULATES
);
149 $self->{'_negatively_regulate'} = Bio
::Ontology
::RelationshipType
->get_instance(NEGATIVELY_REGULATES
);
152 $self->graph( Bio
::Ontology
::SimpleGOEngine
::GraphAdaptor
->new() ); # NG 05-02-16
154 # set defaults for the factories
155 $self->relationship_factory(Bio
::Ontology
::RelationshipFactory
->new(
156 -type
=> "Bio::Ontology::Relationship"));
162 =head2 is_a_relationship
164 Title : is_a_relationship()
165 Usage : $IS_A = $engine->is_a_relationship();
166 Function: Returns a Bio::Ontology::RelationshipType object for "is-a"
168 Returns : Bio::Ontology::RelationshipType set to "IS_A"
173 sub is_a_relationship
{
174 my ( $self, $value ) = @_;
176 if ( defined $value ) {
177 $self->throw( "Attempted to change immutable field" );
180 return $self->{ "_is_a_relationship" };
181 } # is_a_relationship
185 =head2 part_of_relationship
187 Title : part_of_relationship()
188 Usage : $PART_OF = $engine->part_of_relationship();
189 Function: Returns a Bio::Ontology::RelationshipType object for "part-of"
191 Returns : Bio::Ontology::RelationshipType set to "PART_OF"
196 sub part_of_relationship
{
197 my ( $self, $value ) = @_;
199 if ( defined $value ) {
200 $self->throw( "Attempted to change immutable field" );
203 return $self->{ "_part_of_relationship" };
204 } # part_of_relationship
207 =head2 related_to_relationship
209 Title : related_to_relationship()
210 Usage : $RELATED_TO = $engine->related_to_relationship();
211 Function: Returns a Bio::Ontology::RelationshipType object for "related-to"
213 Returns : Bio::Ontology::RelationshipType set to "RELATED_TO"
218 sub related_to_relationship
{
219 my ( $self, $value ) = @_;
221 if ( defined $value ) {
222 $self->throw( "Attempted to change immutable field" );
225 return $self->{ "_related_to_relationship" };
226 } # related_to_relationship
228 =head2 regulates_relationship
230 Title : regulates_relationship()
231 Usage : $REGULATES = $engine->regulates_relationship();
232 Function: Returns a Bio::Ontology::RelationshipType object for "regulates"
234 Returns : Bio::Ontology::RelationshipType set to "REGULATES"
239 sub regulates_relationship
{
240 my ( $self, $value ) = @_;
242 if ( defined $value ) {
243 $self->throw( "Attempted to change immutable field" );
246 return $self->{ "_regulates_relationship" };
247 } # is_a_relationship
249 =head2 positively_regulates_relationship
251 Title : positively_regulates_relationship()
252 Usage : $REGULATES = $engine->positively_regulates_relationship();
253 Function: Returns a Bio::Ontology::RelationshipType object for "positively_regulates"
255 Returns : Bio::Ontology::RelationshipType set to "POSITIVELY_REGULATES"
260 sub positively_regulates_relationship
{
261 my ( $self, $value ) = @_;
263 if ( defined $value ) {
264 $self->throw( "Attempted to change immutable field" );
267 return $self->{ "_positively_regulate" };
270 =head2 negatively_regulates_relationship
272 Title : negatively_regulates_relationship()
273 Usage : $REGULATES = $engine->negatively_regulates_relationship();
274 Function: Returns a Bio::Ontology::RelationshipType object for "negatively_regulates"
276 Returns : Bio::Ontology::RelationshipType set to "POSITIVELY_REGULATES"
281 sub negatively_regulates_relationship
{
282 my ( $self, $value ) = @_;
284 if ( defined $value ) {
285 $self->throw( "Attempted to change immutable field" );
288 return $self->{ "_negatively_regulate" };
295 Usage : $engine->add_term( $term_obj );
296 Function: Adds a Bio::Ontology::TermI to this engine
297 Returns : true if the term was added and false otherwise (e.g., if the
298 term already existed in the ontology engine)
299 Args : Bio::Ontology::TermI`
304 my ( $self, $term ) = @_;
306 return FALSE
if $self->has_term( $term );
308 my $goid = $self->_get_id($term);
310 $self->graph()->add_vertex( $goid );
311 $self->graph()->set_vertex_attribute( $goid, TERM
, $term ); # NG 05-02-16
321 Usage : $engine->has_term( $term );
322 Function: Checks whether this engine contains a particular term
323 Returns : true or false
324 Args : Bio::Ontology::TermI
326 Term identifier (e.g. "GO:0012345")
331 my ( $self, $term ) = @_;
332 $term = $self->_get_id( $term );
333 if ( $self->graph()->has_vertex( $term ) ) {
343 =head2 add_relationship_type
345 Title : add_relationship_type
346 Usage : $engine->add_relationship_type( $type_name, $ont );
347 Function: Adds a new relationship type to the engine. Use
348 get_relationship_type($type_name) to retrieve.
349 Returns : true if successfully added, false otherwise
350 Args : relationship type name to add (scalar)
351 ontology to which to assign the relationship type
355 sub add_relationship_type
{
356 my ($self,@args) = @_;
359 my $type_name = $args[0];
361 $self->{ "_extra_relationship_types" }{$type_name} = Bio
::Ontology
::RelationshipType
->get_instance($type_name,$ont);
362 #warn Dumper($self->{"_extra_relationship_types"}{$type_name});
369 =head2 get_relationship_type
371 Title : get_relationship_type
372 Usage : $engine->get_relationship_type( $type_name );
373 Function: Gets a Bio::Ontology::RelationshipI object corresponding
375 Returns : a Bio::Ontology::RelationshipI object
380 sub get_relationship_type
{
381 my ($self,$type_name) = @_;
382 return $self->{ "_extra_relationship_types" }{$type_name};
385 =head2 add_relationship
387 Title : add_relationship
388 Usage : $engine->add_relationship( $relationship );
389 $engine->add_relatioship( $subject_term, $predicate_term,
390 $object_term, $ontology );
391 $engine->add_relatioship( $subject_id, $predicate_id,
392 $object_id, $ontology);
393 Function: Adds a relationship to this engine
394 Returns : true if successfully added, false otherwise
395 Args : The relationship in one of three ways:
397 a) subject (or child) term id, Bio::Ontology::TermI
398 (rel.type), object (or parent) term id, ontology
402 b) subject Bio::Ontology::TermI, predicate
403 Bio::Ontology::TermI (rel.type), object
404 Bio::Ontology::TermI, ontology
408 c) Bio::Ontology::RelationshipI-compliant object
412 # term objs or term ids
413 sub add_relationship
{
414 my ( $self, $child, $type, $parent, $ont ) = @_;
416 if ( scalar( @_ ) == 2 ) {
417 $self->_check_class( $child, "Bio::Ontology::RelationshipI" );
418 $type = $child->predicate_term();
419 $parent = $child->object_term();
420 $ont = $child->ontology();
421 $child = $child->subject_term();
425 $self->_check_class( $type, "Bio::Ontology::TermI" );
427 my $parentid = $self->_get_id( $parent );
428 my $childid = $self->_get_id( $child );
430 my $g = $self->graph();
432 $self->add_term($child) unless $g->has_vertex( $childid );
433 $self->add_term($parent) unless $g->has_vertex( $parentid );
435 # This prevents multi graphs.
436 if ( $g->has_edge( $parentid, $childid ) ) {
440 $g->add_edge( $parentid, $childid );
441 $g->set_edge_attribute( $parentid, $childid, TYPE
, $type ); # NG 05-02-16
442 $g->set_edge_attribute( $parentid, $childid, ONTOLOGY
, $ont ); # NG 05-02-16
451 =head2 get_relationships
454 Title : get_relationships
455 Usage : $engine->get_relationships( $term );
456 Function: Returns all relationships of a term, or all relationships in
457 the graph if no term is specified.
458 Returns : Relationship
465 sub get_relationships
{
466 my ( $self, $term ) = @_;
468 my $g = $self->graph();
470 # obtain the ID if term provided
473 $termid = $self->_get_id( $term );
474 # check for presence in the graph
475 if ( ! $g->has_vertex( $termid ) ) {
476 $self->throw( "no term with identifier \"$termid\" in ontology" );
480 # now build the relationships
481 my $relfact = $self->relationship_factory();
482 # we'll build the relationships from edges
484 my @edges = $termid ?
$g->edges_at( $termid ) : $g->edges(); # NG 05-02-13
486 my ( $startid, $endid ) = @
{ shift @edges }; # NG 05-02-16
487 my $rel = $relfact->create_object
488 (-subject_term
=> $self->get_terms($endid),
489 -object_term
=> $self->get_terms($startid),
490 -predicate_term
=> $g->get_edge_attribute($startid, $endid, TYPE
),
491 -ontology
=> $g->get_edge_attribute($startid, $endid, ONTOLOGY
));
498 } # get_relationships
500 =head2 get_all_relationships
503 Title : get_all_relationships
504 Usage : @rels = $engine->get_all_relationships();
505 Function: Returns all relationships in the graph.
506 Returns : Relationship
511 sub get_all_relationships
{
512 return shift->get_relationships(@_);
513 } # get_all_relationships
517 =head2 get_predicate_terms
519 Title : get_predicate_terms
520 Usage : $engine->get_predicate_terms();
521 Function: Returns the types of relationships this engine contains
522 Returns : Bio::Ontology::RelationshipType
527 sub get_predicate_terms
{
531 $self->is_a_relationship(),
532 $self->part_of_relationship(),
533 $self->related_to_relationship(),
534 $self->regulates_relationship(),
535 $self->positively_regulates_relationship(),
536 $self->negatively_regulates_relationship(),
539 foreach my $termname (keys %{$self->{ "_extra_relationship_types" }}){
540 push @a, $self->{ "_extra_relationship_types" }{ $termname };
544 } # get_predicate_terms
549 =head2 get_child_terms
551 Title : get_child_terms
552 Usage : $engine->get_child_terms( $term_obj, @rel_types );
553 $engine->get_child_terms( $term_id, @rel_types );
554 Function: Returns the children of this term
555 Returns : Bio::Ontology::TermI
556 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType
558 term id, Bio::Ontology::RelationshipType
560 if NO Bio::Ontology::RelationshipType is indicated: children
561 of ALL types are returned
565 sub get_child_terms
{
566 my ( $self, $term, @types ) = @_;
568 return $self->_get_child_parent_terms_helper( $term, TRUE
, @types );
573 =head2 get_descendant_terms
575 Title : get_descendant_terms
576 Usage : $engine->get_descendant_terms( $term_obj, @rel_types );
577 $engine->get_descendant_terms( $term_id, @rel_types );
578 Function: Returns the descendants of this term
579 Returns : Bio::Ontology::TermI
580 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType
582 term id, Bio::Ontology::RelationshipType
584 if NO Bio::Ontology::RelationshipType is indicated:
585 descendants of ALL types are returned
589 sub get_descendant_terms
{
590 my ( $self, $term, @types ) = @_;
595 $term = $self->_get_id( $term );
597 if ( ! $self->graph()->has_vertex( $term ) ) {
598 $self->throw( "Ontology does not contain a term with an identifier of \"$term\"" );
601 $self->_get_descendant_terms_helper( $term, \
%ids, \
@types );
603 while( ( my $id ) = each ( %ids ) ) {
607 return $self->get_terms( @ids );
609 } # get_descendant_terms
612 =head2 get_parent_terms
614 Title : get_parent_terms
615 Usage : $engine->get_parent_terms( $term_obj, @rel_types );
616 $engine->get_parent_terms( $term_id, @rel_types );
617 Function: Returns the parents of this term
618 Returns : Bio::Ontology::TermI
619 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType
621 term id, Bio::Ontology::RelationshipType
623 if NO Bio::Ontology::RelationshipType is indicated:
624 parents of ALL types are returned
628 sub get_parent_terms
{
629 my ( $self, $term, @types ) = @_;
631 return $self->_get_child_parent_terms_helper( $term, FALSE
, @types );
637 =head2 get_ancestor_terms
639 Title : get_ancestor_terms
640 Usage : $engine->get_ancestor_terms( $term_obj, @rel_types );
641 $engine->get_ancestor_terms( $term_id, @rel_types );
642 Function: Returns the ancestors of this term
643 Returns : Bio::Ontology::TermI
644 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType
646 term id, Bio::Ontology::RelationshipType
648 if NO Bio::Ontology::RelationshipType is indicated:
649 ancestors of ALL types are returned
653 sub get_ancestor_terms
{
654 my ( $self, $term, @types ) = @_;
659 $term = $self->_get_id( $term );
661 if ( ! $self->graph()->has_vertex( $term ) ) {
662 $self->throw( "Ontology does not contain a term with an identifier of \"$term\"" );
665 $self->_get_ancestor_terms_helper( $term, \
%ids, \
@types );
667 while( ( my $id ) = each ( %ids ) ) {
671 return $self->get_terms( @ids );
673 } # get_ancestor_terms
679 =head2 get_leaf_terms
681 Title : get_leaf_terms
682 Usage : $engine->get_leaf_terms();
683 Function: Returns the leaf terms
684 Returns : Bio::Ontology::TermI
692 my @a = $self->graph()->sink_vertices();
694 return $self->get_terms( @a );
700 =head2 get_root_terms()
702 Title : get_root_terms
703 Usage : $engine->get_root_terms();
704 Function: Returns the root terms
705 Returns : Bio::Ontology::TermI
714 my @a = $self->graph()->source_vertices();
716 return $self->get_terms( @a );
724 Usage : @terms = $engine->get_terms( "GO:1234567", "GO:2234567" );
725 Function: Returns term objects with given identifiers
726 Returns : Bio::Ontology::TermI, or the term corresponding to the
727 first identifier if called in scalar context
733 my ( $self, @ids ) = @_;
737 foreach my $id ( @ids ) {
738 if ( $self->graph()->has_vertex( $id ) ) {
739 push( @terms, $self->graph()->get_vertex_attribute( $id, TERM
) ); # NG 05-02-16
743 return wantarray ?
@terms : shift(@terms);
750 Title : get_all_terms
751 Usage : $engine->get_all_terms();
752 Function: Returns all terms in this engine
753 Returns : Bio::Ontology::TermI
761 return( $self->get_terms( $self->graph()->vertices() ) );
769 Usage : ($term) = $oe->find_terms(-identifier => "SO:0000263");
770 Function: Find term instances matching queries for their attributes.
772 This implementation can efficiently resolve queries by
776 Returns : an array of zero or more Bio::Ontology::TermI objects
777 Args : Named parameters. The following parameters should be recognized
778 by any implementations:
780 -identifier query by the given identifier
781 -name query by the given name
786 my ($self,@args) = @_;
789 my ($id,$name) = $self->_rearrange([qw(IDENTIFIER NAME)],@args);
792 @terms = $self->get_terms($id);
794 @terms = $self->get_all_terms();
797 @terms = grep { $_->name() eq $name; } @terms;
803 =head2 find_identically_named_terms
805 Title : find_identically_named_terms
806 Usage : ($term) = $oe->find_identically_named_terms($term0);
807 Function: Find term instances where names match the query term
810 Returns : an array of zero or more Bio::Ontology::TermI objects
811 Args : a Bio::Ontology::TermI object
815 sub find_identically_named_terms
{
816 my ($self,$qterm) = @_;
817 $self->throw("Argument doesn't implement Bio::Ontology::TermI. " . "Bummer." )
818 unless defined $qterm and $qterm->isa("Bio::Ontology::TermI");
822 foreach my $term ($self->get_all_terms) {
823 $matching_terms{$term->identifier} = $term and next
824 if $term->name eq $qterm->name;
826 return values %matching_terms;
830 =head2 find_identical_terms
832 Title : find_identical_terms
833 Usage : ($term) = $oe->find_identical_terms($term0);
834 Function: Find term instances where name or synonym
835 matches the query exactly
837 Returns : an array of zero or more Bio::Ontology::TermI objects
838 Args : a Bio::Ontology::TermI object
842 sub find_identical_terms
{
843 my ($self,$qterm) = @_;
844 $self->throw("Argument doesn't implement Bio::Ontology::TermI. " . "Bummer." )
845 unless defined $qterm and $qterm->isa("Bio::Ontology::TermI");
849 foreach my $qstring ($qterm->name, $qterm->each_synonym) {
850 foreach my $term ($self->get_all_terms) {
851 foreach my $string ( $term->name, $term->each_synonym() ) {
852 $matching_terms{$term->identifier} = $term and next
853 if $string eq $qstring;
857 return values %matching_terms;
860 =head2 find_similar_terms
862 Title : find_similar_terms
863 Usage : ($term) = $oe->find_similar_terms($term0);
864 Function: Find term instances where name or synonym, or part of one,
867 Returns : an array of zero or more Bio::Ontology::TermI objects
868 Args : a Bio::Ontology::TermI object
872 sub find_similar_terms
{
873 my ($self,$qterm) = @_;
874 $self->throw("Argument doesn't implement Bio::Ontology::TermI. " . "Bummer." )
875 unless defined $qterm and $qterm->isa("Bio::Ontology::TermI");
879 foreach my $qstring ($qterm->name, $qterm->each_synonym) {
880 foreach my $term ($self->get_all_terms) {
882 foreach my $string ( $term->name, $term->each_synonym() ) {
883 $matching_terms{$term->identifier} = $term and next
884 if $string =~ /\Q$qstring\E/ or $qstring =~ /\Q$string\E/;
888 return values %matching_terms;
892 =head2 relationship_factory
894 Title : relationship_factory
895 Usage : $fact = $obj->relationship_factory()
896 Function: Get/set the object factory to be used when relationship
897 objects are created by the implementation on-the-fly.
900 Returns : value of relationship_factory (a Bio::Factory::ObjectFactoryI
902 Args : on set, a Bio::Factory::ObjectFactoryI compliant object
906 sub relationship_factory
{
909 return $self->{'relationship_factory'} = shift if @_;
910 return $self->{'relationship_factory'};
916 Usage : $fact = $obj->term_factory()
917 Function: Get/set the object factory to be used when term objects are
918 created by the implementation on-the-fly.
920 Note that this ontology engine implementation does not
921 create term objects on the fly, and therefore setting this
922 attribute is meaningless.
925 Returns : value of term_factory (a Bio::Factory::ObjectFactoryI
927 Args : on set, a Bio::Factory::ObjectFactoryI compliant object
935 $self->warn("setting term factory, but ".ref($self).
936 " does not create terms on-the-fly");
937 return $self->{'term_factory'} = shift;
939 return $self->{'term_factory'};
945 Usage : $engine->graph();
946 Function: Returns the Graph this engine is based on
953 my ( $self, $value ) = @_;
955 if ( defined $value ) {
956 $self->_check_class( $value, 'Bio::Ontology::SimpleGOEngine::GraphAdaptor' ); # NG 05-02-16
957 $self->{ "_graph" } = $value;
960 return $self->{ "_graph" };
966 # Checks the correct format of a GOBO-formatted id
967 # Gets the id out of a term or id string
969 my ( $self, $term ) = @_;
974 # use TermI standard API
975 $self->throw( "Object doesn't implement Bio::Ontology::TermI" )
976 unless $term->isa("Bio::Ontology::TermI");
977 $id = $term->identifier();
979 # if there is no ID, we need to fake one from ontology name and name
980 # in order to achieve uniqueness
982 $id = $term->ontology->name() if $term->ontology();
983 $id = $id ?
$id . '|' : '';
984 $id .= $term->name();
988 # if $term->isa("Bio::Ontology::GOterm")||($id =~ /^[A-Z_]{1,8}:\d{1,}$/);
989 return $id if $term->isa("Bio::Ontology::OBOterm") || ( $id =~ /^\w+:\w+$/ );
991 # prefix with something if only numbers
992 # if($id =~ /^\d+$/) {
993 # $self->warn(ref($self).": identifier [$id] is only numbers - ".
994 # "prefixing with 'GO:'");
995 # return "GO:" . $id;
997 # we shouldn't have gotten here if it's at least a remotely decent ID
998 $self->throw( ref($self) . ": non-standard identifier '$id'\n" )
1004 # Helper for getting children and parent terms
1005 sub _get_child_parent_terms_helper
{
1006 my ( $self, $term, $do_get_child_terms, @types ) = @_;
1008 foreach my $type ( @types ) {
1009 $self->_check_class( $type, "Bio::Ontology::TermI" );
1012 my @relative_terms = ();
1014 $term = $self->_get_id( $term );
1015 if ( ! $self->graph()->has_vertex( $term ) ) {
1016 $self->throw( "Ontology does not contain a term with an identifier of \"$term\"" );
1019 my @all_relative_terms = ();
1020 if ( $do_get_child_terms ) {
1021 @all_relative_terms = $self->graph()->successors( $term );
1024 @all_relative_terms = $self->graph()->predecessors( $term );
1027 foreach my $relative ( @all_relative_terms ) {
1028 if ( scalar( @types ) > 0 ) {
1029 foreach my $type ( @types ) {
1031 if ( $do_get_child_terms ) {
1032 $relative_type = $self->graph()->get_edge_attribute ($term, $relative, TYPE
); # NG 05-02-16
1035 $relative_type = $self->graph()->get_edge_attribute ($relative, $term, TYPE
); # NG 05-02-16
1037 if ( $relative_type->equals( $type ) ) {
1038 push( @relative_terms, $relative );
1043 push( @relative_terms, $relative );
1047 return $self->get_terms( @relative_terms );
1053 sub _get_descendant_terms_helper
{
1054 my ( $self, $term, $ids_ref, $types_ref ) = @_;
1056 my @child_terms = $self->get_child_terms( $term, @
$types_ref );
1058 if ( scalar( @child_terms ) < 1 ) {
1062 foreach my $child_term ( @child_terms ) {
1063 my $child_term_id = $self->_get_id($child_term->identifier());
1064 $ids_ref->{ $child_term_id } = 0;
1065 $self->_get_descendant_terms_helper( $child_term_id, $ids_ref, $types_ref );
1068 } # _get_descendant_terms_helper
1072 sub _get_ancestor_terms_helper
{
1073 my ( $self, $term, $ids_ref, $types_ref ) = @_;
1075 my @parent_terms = $self->get_parent_terms( $term, @
$types_ref );
1077 if ( scalar( @parent_terms ) < 1 ) {
1081 foreach my $parent_term ( @parent_terms ) {
1082 my $parent_term_id = $self->_get_id($parent_term->identifier());
1083 $ids_ref->{ $parent_term_id } = 0;
1084 $self->_get_ancestor_terms_helper( $parent_term_id, $ids_ref, $types_ref );
1087 } # get_ancestor_terms_helper
1090 my ( $self, $value, $expected_class ) = @_;
1092 if ( ! defined( $value ) ) {
1093 $self->throw( "Found [undef] where [$expected_class] expected" );
1095 elsif ( ! ref( $value ) ) {
1096 $self->throw( "Found [scalar] where [$expected_class] expected" );
1098 elsif ( ! $value->isa( $expected_class ) ) {
1099 $self->throw( "Found [" . ref( $value ) . "] where [$expected_class] expected" );
1104 #################################################################
1106 #################################################################
1108 *get_relationship_types
= \
&get_predicate_terms
;