Mercurial > repos > mahtabm > ensembl
comparison variant_effect_predictor/Bio/Ontology/SimpleGOEngine.pm @ 0:1f6dce3d34e0
Uploaded
| author | mahtabm |
|---|---|
| date | Thu, 11 Apr 2013 02:01:53 -0400 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:1f6dce3d34e0 |
|---|---|
| 1 # $Id: SimpleGOEngine.pm,v 1.3.2.6 2003/06/30 05:04:06 lapp Exp $ | |
| 2 # | |
| 3 # BioPerl module for Bio::Ontology::SimpleGOEngine | |
| 4 # | |
| 5 # Cared for by Christian M. Zmasek <czmasek@gnf.org> or <cmzmasek@yahoo.com> | |
| 6 # | |
| 7 # (c) Christian M. Zmasek, czmasek@gnf.org, 2002. | |
| 8 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2002. | |
| 9 # | |
| 10 # You may distribute this module under the same terms as perl itself. | |
| 11 # Refer to the Perl Artistic License (see the license accompanying this | |
| 12 # software package, or see http://www.perl.com/language/misc/Artistic.html) | |
| 13 # for the terms under which you may use, modify, and redistribute this module. | |
| 14 # | |
| 15 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | |
| 16 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
| 17 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
| 18 # | |
| 19 # You may distribute this module under the same terms as perl itself | |
| 20 | |
| 21 # POD documentation - main docs before the code | |
| 22 | |
| 23 =head1 NAME | |
| 24 | |
| 25 SimpleGOEngine - a Ontology Engine for GO implementing OntologyEngineI | |
| 26 | |
| 27 =head1 SYNOPSIS | |
| 28 | |
| 29 use Bio::Ontology::SimpleGOEngine; | |
| 30 | |
| 31 my $parser = Bio::Ontology::SimpleGOEngine->new | |
| 32 ( -defs_file => "/home/czmasek/GO/GO.defs", | |
| 33 -files => ["/home/czmasek/GO/component.ontology", | |
| 34 "/home/czmasek/GO/function.ontology", | |
| 35 "/home/czmasek/GO/process.ontology"] ); | |
| 36 | |
| 37 my $engine = $parser->parse(); | |
| 38 | |
| 39 my $IS_A = Bio::Ontology::RelationshipType->get_instance( "IS_A" ); | |
| 40 my $PART_OF = Bio::Ontology::RelationshipType->get_instance( "PART_OF" ); | |
| 41 | |
| 42 | |
| 43 =head1 DESCRIPTION | |
| 44 | |
| 45 Needs Graph.pm from CPAN. | |
| 46 | |
| 47 =head1 FEEDBACK | |
| 48 | |
| 49 =head2 Mailing Lists | |
| 50 | |
| 51 User feedback is an integral part of the evolution of this and other | |
| 52 Bioperl modules. Send your comments and suggestions preferably to the | |
| 53 Bioperl mailing lists Your participation is much appreciated. | |
| 54 | |
| 55 bioperl-l@bioperl.org - General discussion | |
| 56 http://bio.perl.org/MailList.html - About the mailing lists | |
| 57 | |
| 58 =head2 Reporting Bugs | |
| 59 | |
| 60 report bugs to the Bioperl bug tracking system to help us keep track | |
| 61 the bugs and their resolution. Bug reports can be submitted via | |
| 62 email or the web: | |
| 63 | |
| 64 bioperl-bugs@bio.perl.org | |
| 65 http://bugzilla.bioperl.org/ | |
| 66 | |
| 67 =head1 AUTHOR | |
| 68 | |
| 69 Christian M. Zmasek | |
| 70 | |
| 71 Email: czmasek@gnf.org or cmzmasek@yahoo.com | |
| 72 | |
| 73 WWW: http://www.genetics.wustl.edu/eddy/people/zmasek/ | |
| 74 | |
| 75 Address: | |
| 76 | |
| 77 Genomics Institute of the Novartis Research Foundation | |
| 78 10675 John Jay Hopkins Drive | |
| 79 San Diego, CA 92121 | |
| 80 | |
| 81 =head1 APPENDIX | |
| 82 | |
| 83 The rest of the documentation details each of the object | |
| 84 methods. Internal methods are usually preceded with a _ | |
| 85 | |
| 86 =cut | |
| 87 | |
| 88 | |
| 89 # Let the code begin... | |
| 90 | |
| 91 | |
| 92 | |
| 93 package Bio::Ontology::SimpleGOEngine; | |
| 94 | |
| 95 use Graph::Directed; | |
| 96 | |
| 97 use vars qw( @ISA ); | |
| 98 use strict; | |
| 99 use Bio::Root::Root; | |
| 100 use Bio::Ontology::RelationshipType; | |
| 101 use Bio::Ontology::RelationshipFactory; | |
| 102 use Bio::Ontology::OntologyEngineI; | |
| 103 | |
| 104 use constant TRUE => 1; | |
| 105 use constant FALSE => 0; | |
| 106 use constant IS_A => "IS_A"; | |
| 107 use constant PART_OF => "PART_OF"; | |
| 108 use constant TERM => "TERM"; | |
| 109 use constant TYPE => "TYPE"; | |
| 110 use constant ONTOLOGY => "ONTOLOGY"; | |
| 111 | |
| 112 @ISA = qw( Bio::Root::Root | |
| 113 Bio::Ontology::OntologyEngineI ); | |
| 114 | |
| 115 | |
| 116 | |
| 117 =head2 new | |
| 118 | |
| 119 Title : new | |
| 120 Usage : $engine = Bio::Ontology::SimpleGOEngine->new() | |
| 121 Function: Creates a new SimpleGOEngine | |
| 122 Returns : A new SimpleGOEngine object | |
| 123 Args : | |
| 124 | |
| 125 =cut | |
| 126 | |
| 127 sub new { | |
| 128 my( $class, @args ) = @_; | |
| 129 | |
| 130 my $self = $class->SUPER::new( @args ); | |
| 131 | |
| 132 $self->init(); | |
| 133 | |
| 134 return $self; | |
| 135 } # new | |
| 136 | |
| 137 | |
| 138 | |
| 139 =head2 init | |
| 140 | |
| 141 Title : init() | |
| 142 Usage : $engine->init(); | |
| 143 Function: Initializes this Engine. | |
| 144 Returns : | |
| 145 Args : | |
| 146 | |
| 147 =cut | |
| 148 | |
| 149 sub init { | |
| 150 my ( $self ) = @_; | |
| 151 | |
| 152 $self->{ "_is_a_relationship" } = Bio::Ontology::RelationshipType->get_instance( IS_A ); | |
| 153 $self->{ "_part_of_relationship" } = Bio::Ontology::RelationshipType->get_instance( PART_OF ); | |
| 154 | |
| 155 $self->graph( Graph::Directed->new() ); | |
| 156 | |
| 157 # set defaults for the factories | |
| 158 $self->relationship_factory(Bio::Ontology::RelationshipFactory->new( | |
| 159 -type => "Bio::Ontology::Relationship")); | |
| 160 | |
| 161 } # init | |
| 162 | |
| 163 | |
| 164 | |
| 165 =head2 is_a_relationship | |
| 166 | |
| 167 Title : is_a_relationship() | |
| 168 Usage : $IS_A = $engine->is_a_relationship(); | |
| 169 Function: Returns a Bio::Ontology::RelationshipType object for "is-a" | |
| 170 relationships | |
| 171 Returns : Bio::Ontology::RelationshipType set to "IS_A" | |
| 172 Args : | |
| 173 | |
| 174 =cut | |
| 175 | |
| 176 sub is_a_relationship { | |
| 177 my ( $self, $value ) = @_; | |
| 178 | |
| 179 if ( defined $value ) { | |
| 180 $self->throw( "Attempted to change immutable field" ); | |
| 181 } | |
| 182 | |
| 183 return $self->{ "_is_a_relationship" }; | |
| 184 } # is_a_relationship | |
| 185 | |
| 186 | |
| 187 | |
| 188 =head2 part_of_relationship | |
| 189 | |
| 190 Title : part_of_relationship() | |
| 191 Usage : $PART_OF = $engine->part_of_relationship(); | |
| 192 Function: Returns a Bio::Ontology::RelationshipType object for "part-of" | |
| 193 relationships | |
| 194 Returns : Bio::Ontology::RelationshipType set to "PART_OF" | |
| 195 Args : | |
| 196 | |
| 197 =cut | |
| 198 | |
| 199 sub part_of_relationship { | |
| 200 my ( $self, $value ) = @_; | |
| 201 | |
| 202 if ( defined $value ) { | |
| 203 $self->throw( "Attempted to change immutable field" ); | |
| 204 } | |
| 205 | |
| 206 return $self->{ "_part_of_relationship" }; | |
| 207 } # part_of_relationship | |
| 208 | |
| 209 | |
| 210 | |
| 211 | |
| 212 =head2 add_term | |
| 213 | |
| 214 Title : add_term | |
| 215 Usage : $engine->add_term( $term_obj ); | |
| 216 Function: Adds a Bio::Ontology::TermI to this engine | |
| 217 Returns : true if the term was added and false otherwise (e.g., if the | |
| 218 term already existed in the ontology engine) | |
| 219 Args : Bio::Ontology::TermI | |
| 220 | |
| 221 | |
| 222 =cut | |
| 223 | |
| 224 sub add_term { | |
| 225 my ( $self, $term ) = @_; | |
| 226 | |
| 227 return FALSE if $self->has_term( $term ); | |
| 228 | |
| 229 my $goid = $self->_get_id($term); | |
| 230 | |
| 231 $self->graph()->add_vertex( $goid ); | |
| 232 $self->graph()->set_attribute( TERM, $goid, $term ); | |
| 233 | |
| 234 return TRUE; | |
| 235 | |
| 236 } # add_term | |
| 237 | |
| 238 | |
| 239 | |
| 240 =head2 has_term | |
| 241 | |
| 242 Title : has_term | |
| 243 Usage : $engine->has_term( $term ); | |
| 244 Function: Checks whether this engine contains a particular term | |
| 245 Returns : true or false | |
| 246 Args : Bio::Ontology::TermI | |
| 247 or | |
| 248 erm identifier (e.g. "GO:0012345") | |
| 249 | |
| 250 | |
| 251 =cut | |
| 252 | |
| 253 sub has_term { | |
| 254 my ( $self, $term ) = @_; | |
| 255 $term = $self->_get_id( $term ); | |
| 256 if ( $self->graph()->has_vertex( $term ) ) { | |
| 257 return TRUE; | |
| 258 } | |
| 259 else { | |
| 260 return FALSE; | |
| 261 } | |
| 262 | |
| 263 } # has_term | |
| 264 | |
| 265 | |
| 266 | |
| 267 =head2 add_relationship | |
| 268 | |
| 269 Title : add_relationship | |
| 270 Usage : $engine->add_relationship( $relationship ); | |
| 271 $engine->add_relatioship( $subject_term, $predicate_term, $object_term, $ontology ); | |
| 272 $engine->add_relatioship( $subject_id, $predicate_id, $object_id, $ontology); | |
| 273 Function: Adds a relationship to this engine | |
| 274 Returns : true if successfully added, false otherwise | |
| 275 Args : term id, Bio::Ontology::TermI (rel.type), term id, ontology | |
| 276 or | |
| 277 Bio::Ontology::TermI, Bio::Ontology::TermI (rel.type), Bio::Ontology::TermI, ontology | |
| 278 or | |
| 279 Bio::Ontology::RelationshipI | |
| 280 | |
| 281 =cut | |
| 282 | |
| 283 # term objs or term ids | |
| 284 sub add_relationship { | |
| 285 my ( $self, $child, $type, $parent, $ont ) = @_; | |
| 286 | |
| 287 if ( scalar( @_ ) == 2 ) { | |
| 288 $self->_check_class( $child, "Bio::Ontology::RelationshipI" ); | |
| 289 $type = $child->predicate_term(); | |
| 290 $parent = $child->object_term(); | |
| 291 $ont = $child->ontology(); | |
| 292 $child = $child->subject_term(); | |
| 293 } | |
| 294 | |
| 295 | |
| 296 $self->_check_class( $type, "Bio::Ontology::TermI" ); | |
| 297 | |
| 298 my $parentid = $self->_get_id( $parent ); | |
| 299 my $childid = $self->_get_id( $child ); | |
| 300 | |
| 301 my $g = $self->graph(); | |
| 302 | |
| 303 $self->add_term($child) unless $g->has_vertex( $childid ); | |
| 304 $self->add_term($parent) unless $g->has_vertex( $parentid ); | |
| 305 | |
| 306 # This prevents multi graphs. | |
| 307 if ( $g->has_edge( $parentid, $childid ) ) { | |
| 308 return FALSE; | |
| 309 } | |
| 310 | |
| 311 $g->add_edge( $parentid, $childid ); | |
| 312 $g->set_attribute( TYPE, $parentid, $childid, $type ); | |
| 313 $g->set_attribute( ONTOLOGY, $parentid, $childid, $ont ); | |
| 314 | |
| 315 return TRUE; | |
| 316 | |
| 317 } # add_relationship | |
| 318 | |
| 319 | |
| 320 | |
| 321 | |
| 322 =head2 get_relationships | |
| 323 | |
| 324 | |
| 325 Title : get_relationships | |
| 326 Usage : $engine->get_relationships( $term ); | |
| 327 Function: Returns all relationships of a term, or all relationships in | |
| 328 the graph if no term is specified. | |
| 329 Returns : Relationship[] | |
| 330 Args : term id | |
| 331 or | |
| 332 Bio::Ontology::TermI | |
| 333 | |
| 334 =cut | |
| 335 | |
| 336 sub get_relationships { | |
| 337 my ( $self, $term ) = @_; | |
| 338 | |
| 339 my $g = $self->graph(); | |
| 340 | |
| 341 # obtain the ID if term provided | |
| 342 my $termid; | |
| 343 if($term) { | |
| 344 $termid = $self->_get_id( $term ); | |
| 345 # check for presence in the graph | |
| 346 if ( ! $g->has_vertex( $termid ) ) { | |
| 347 $self->throw( "no term with identifier \"$termid\" in ontology" ); | |
| 348 } | |
| 349 } | |
| 350 | |
| 351 # now build the relationships | |
| 352 my $relfact = $self->relationship_factory(); | |
| 353 # we'll build the relationships from edges | |
| 354 my @rels = (); | |
| 355 my @edges = $g->edges($termid); | |
| 356 while(@edges) { | |
| 357 my $startid = shift(@edges); | |
| 358 my $endid = shift(@edges); | |
| 359 my $rel = $relfact->create_object( | |
| 360 -subject_term => $self->get_terms($endid), | |
| 361 -object_term => $self->get_terms($startid), | |
| 362 -predicate_term => $g->get_attribute(TYPE, | |
| 363 $startid, $endid), | |
| 364 -ontology => $g->get_attribute(ONTOLOGY, | |
| 365 $startid, $endid)); | |
| 366 push( @rels, $rel ); | |
| 367 } | |
| 368 | |
| 369 return @rels; | |
| 370 | |
| 371 } # get_relationships | |
| 372 | |
| 373 =head2 get_all_relationships | |
| 374 | |
| 375 | |
| 376 Title : get_all_relationships | |
| 377 Usage : @rels = $engine->get_all_relationships(); | |
| 378 Function: Returns all relationships in the graph. | |
| 379 Returns : Relationship[] | |
| 380 Args : | |
| 381 | |
| 382 =cut | |
| 383 | |
| 384 sub get_all_relationships { | |
| 385 return shift->get_relationships(@_); | |
| 386 } # get_all_relationships | |
| 387 | |
| 388 | |
| 389 | |
| 390 =head2 get_predicate_terms | |
| 391 | |
| 392 Title : get_predicate_terms | |
| 393 Usage : $engine->get_predicate_terms(); | |
| 394 Function: Returns the types of relationships this engine contains | |
| 395 Returns : Bio::Ontology::RelationshipType[] | |
| 396 Args : | |
| 397 | |
| 398 | |
| 399 =cut | |
| 400 | |
| 401 sub get_predicate_terms { | |
| 402 my ( $self ) = @_; | |
| 403 | |
| 404 my @a = ( $self->is_a_relationship(), | |
| 405 $self->part_of_relationship() ); | |
| 406 | |
| 407 return @a; | |
| 408 } # get_predicate_terms | |
| 409 | |
| 410 | |
| 411 | |
| 412 | |
| 413 =head2 get_child_terms | |
| 414 | |
| 415 Title : get_child_terms | |
| 416 Usage : $engine->get_child_terms( $term_obj, @rel_types ); | |
| 417 $engine->get_child_terms( $term_id, @rel_types ); | |
| 418 Function: Returns the children of this term | |
| 419 Returns : Bio::Ontology::TermI[] | |
| 420 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType[] | |
| 421 or | |
| 422 term id, Bio::Ontology::RelationshipType[] | |
| 423 | |
| 424 if NO Bio::Ontology::RelationshipType[] is indicated: children | |
| 425 of ALL types are returned | |
| 426 | |
| 427 =cut | |
| 428 | |
| 429 sub get_child_terms { | |
| 430 my ( $self, $term, @types ) = @_; | |
| 431 | |
| 432 return $self->_get_child_parent_terms_helper( $term, TRUE, @types ); | |
| 433 | |
| 434 } # get_child_terms | |
| 435 | |
| 436 | |
| 437 =head2 get_descendant_terms | |
| 438 | |
| 439 Title : get_descendant_terms | |
| 440 Usage : $engine->get_descendant_terms( $term_obj, @rel_types ); | |
| 441 $engine->get_descendant_terms( $term_id, @rel_types ); | |
| 442 Function: Returns the descendants of this term | |
| 443 Returns : Bio::Ontology::TermI[] | |
| 444 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType[] | |
| 445 or | |
| 446 term id, Bio::Ontology::RelationshipType[] | |
| 447 | |
| 448 if NO Bio::Ontology::RelationshipType[] is indicated: descendants | |
| 449 of ALL types are returned | |
| 450 | |
| 451 =cut | |
| 452 | |
| 453 sub get_descendant_terms { | |
| 454 my ( $self, $term, @types ) = @_; | |
| 455 | |
| 456 my %ids = (); | |
| 457 my @ids = (); | |
| 458 | |
| 459 $term = $self->_get_id( $term ); | |
| 460 | |
| 461 if ( ! $self->graph()->has_vertex( $term ) ) { | |
| 462 $self->throw( "Ontology does not contain a term with an identifier of \"$term\"" ); | |
| 463 } | |
| 464 | |
| 465 $self->_get_descendant_terms_helper( $term, \%ids, \@types ); | |
| 466 | |
| 467 while( ( my $id ) = each ( %ids ) ) { | |
| 468 push( @ids, $id ); | |
| 469 } | |
| 470 | |
| 471 return $self->get_terms( @ids ); | |
| 472 | |
| 473 } # get_descendant_terms | |
| 474 | |
| 475 | |
| 476 | |
| 477 | |
| 478 =head2 get_parent_terms | |
| 479 | |
| 480 Title : get_parent_terms | |
| 481 Usage : $engine->get_parent_terms( $term_obj, @rel_types ); | |
| 482 $engine->get_parent_terms( $term_id, @rel_types ); | |
| 483 Function: Returns the parents of this term | |
| 484 Returns : Bio::Ontology::TermI[] | |
| 485 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType[] | |
| 486 or | |
| 487 term id, Bio::Ontology::RelationshipType[] | |
| 488 | |
| 489 if NO Bio::Ontology::RelationshipType[] is indicated: parents | |
| 490 of ALL types are returned | |
| 491 | |
| 492 =cut | |
| 493 | |
| 494 sub get_parent_terms { | |
| 495 my ( $self, $term, @types ) = @_; | |
| 496 | |
| 497 return $self->_get_child_parent_terms_helper( $term, FALSE, @types ); | |
| 498 | |
| 499 } # get_parent_terms | |
| 500 | |
| 501 | |
| 502 | |
| 503 =head2 get_ancestor_terms | |
| 504 | |
| 505 Title : get_ancestor_terms | |
| 506 Usage : $engine->get_ancestor_terms( $term_obj, @rel_types ); | |
| 507 $engine->get_ancestor_terms( $term_id, @rel_types ); | |
| 508 Function: Returns the ancestors of this term | |
| 509 Returns : Bio::Ontology::TermI[] | |
| 510 Args : Bio::Ontology::TermI, Bio::Ontology::RelationshipType[] | |
| 511 or | |
| 512 term id, Bio::Ontology::RelationshipType[] | |
| 513 | |
| 514 if NO Bio::Ontology::RelationshipType[] is indicated: ancestors | |
| 515 of ALL types are returned | |
| 516 | |
| 517 =cut | |
| 518 | |
| 519 sub get_ancestor_terms { | |
| 520 my ( $self, $term, @types ) = @_; | |
| 521 | |
| 522 my %ids = (); | |
| 523 my @ids = (); | |
| 524 | |
| 525 $term = $self->_get_id( $term ); | |
| 526 | |
| 527 if ( ! $self->graph()->has_vertex( $term ) ) { | |
| 528 $self->throw( "Ontology does not contain a term with an identifier of \"$term\"" ); | |
| 529 } | |
| 530 | |
| 531 $self->_get_ancestor_terms_helper( $term, \%ids, \@types ); | |
| 532 | |
| 533 while( ( my $id ) = each ( %ids ) ) { | |
| 534 push( @ids, $id ); | |
| 535 } | |
| 536 | |
| 537 return $self->get_terms( @ids ); | |
| 538 | |
| 539 } # get_ancestor_terms | |
| 540 | |
| 541 | |
| 542 | |
| 543 | |
| 544 | |
| 545 =head2 get_leaf_terms | |
| 546 | |
| 547 Title : get_leaf_terms | |
| 548 Usage : $engine->get_leaf_terms(); | |
| 549 Function: Returns the leaf terms | |
| 550 Returns : Bio::Ontology::TermI[] | |
| 551 Args : | |
| 552 | |
| 553 =cut | |
| 554 | |
| 555 sub get_leaf_terms { | |
| 556 my ( $self ) = @_; | |
| 557 | |
| 558 my @a = $self->graph()->sink_vertices(); | |
| 559 | |
| 560 return $self->get_terms( @a ); | |
| 561 | |
| 562 } | |
| 563 | |
| 564 | |
| 565 | |
| 566 =head2 get_root_terms() | |
| 567 | |
| 568 Title : get_root_terms | |
| 569 Usage : $engine->get_root_terms(); | |
| 570 Function: Returns the root terms | |
| 571 Returns : Bio::Ontology::TermI[] | |
| 572 Args : | |
| 573 | |
| 574 =cut | |
| 575 | |
| 576 sub get_root_terms { | |
| 577 my ( $self ) = @_; | |
| 578 | |
| 579 | |
| 580 my @a = $self->graph()->source_vertices(); | |
| 581 | |
| 582 return $self->get_terms( @a ); | |
| 583 | |
| 584 } | |
| 585 | |
| 586 | |
| 587 =head2 get_terms | |
| 588 | |
| 589 Title : get_terms | |
| 590 Usage : @terms = $engine->get_terms( "GO:1234567", "GO:2234567" ); | |
| 591 Function: Returns term objects with given identifiers | |
| 592 Returns : Bio::Ontology::TermI[], or the term corresponding to the | |
| 593 first identifier if called in scalar context | |
| 594 Args : term ids[] | |
| 595 | |
| 596 | |
| 597 =cut | |
| 598 | |
| 599 sub get_terms { | |
| 600 my ( $self, @ids ) = @_; | |
| 601 | |
| 602 my @terms = (); | |
| 603 | |
| 604 foreach my $id ( @ids ) { | |
| 605 if ( $self->graph()->has_vertex( $id ) ) { | |
| 606 push( @terms, $self->graph()->get_attribute( TERM, $id ) ); | |
| 607 } | |
| 608 } | |
| 609 | |
| 610 return wantarray ? @terms : shift(@terms); | |
| 611 | |
| 612 } # get_terms | |
| 613 | |
| 614 | |
| 615 =head2 get_all_terms | |
| 616 | |
| 617 Title : get_all_terms | |
| 618 Usage : $engine->get_all_terms(); | |
| 619 Function: Returns all terms in this engine | |
| 620 Returns : Bio::Ontology::TermI[] | |
| 621 Args : | |
| 622 | |
| 623 =cut | |
| 624 | |
| 625 sub get_all_terms { | |
| 626 my ( $self ) = @_; | |
| 627 | |
| 628 return( $self->get_terms( $self->graph()->vertices() ) ); | |
| 629 | |
| 630 } # get_all_terms | |
| 631 | |
| 632 | |
| 633 =head2 find_terms | |
| 634 | |
| 635 Title : find_terms | |
| 636 Usage : ($term) = $oe->find_terms(-identifier => "SO:0000263"); | |
| 637 Function: Find term instances matching queries for their attributes. | |
| 638 | |
| 639 This implementation can efficiently resolve queries by | |
| 640 identifier. | |
| 641 | |
| 642 Example : | |
| 643 Returns : an array of zero or more Bio::Ontology::TermI objects | |
| 644 Args : Named parameters. The following parameters should be recognized | |
| 645 by any implementations: | |
| 646 | |
| 647 -identifier query by the given identifier | |
| 648 -name query by the given name | |
| 649 | |
| 650 | |
| 651 =cut | |
| 652 | |
| 653 sub find_terms{ | |
| 654 my ($self,@args) = @_; | |
| 655 my @terms; | |
| 656 | |
| 657 my ($id,$name) = $self->_rearrange([qw(IDENTIFIER NAME)],@args); | |
| 658 | |
| 659 if(defined($id)) { | |
| 660 @terms = $self->get_terms($id); | |
| 661 } else { | |
| 662 @terms = $self->get_all_terms(); | |
| 663 } | |
| 664 if(defined($name)) { | |
| 665 @terms = grep { $_->name() eq $name; } @terms; | |
| 666 } | |
| 667 return @terms; | |
| 668 } | |
| 669 | |
| 670 =head2 relationship_factory | |
| 671 | |
| 672 Title : relationship_factory | |
| 673 Usage : $fact = $obj->relationship_factory() | |
| 674 Function: Get/set the object factory to be used when relationship | |
| 675 objects are created by the implementation on-the-fly. | |
| 676 | |
| 677 Example : | |
| 678 Returns : value of relationship_factory (a Bio::Factory::ObjectFactoryI | |
| 679 compliant object) | |
| 680 Args : on set, a Bio::Factory::ObjectFactoryI compliant object | |
| 681 | |
| 682 | |
| 683 =cut | |
| 684 | |
| 685 sub relationship_factory{ | |
| 686 my $self = shift; | |
| 687 | |
| 688 return $self->{'relationship_factory'} = shift if @_; | |
| 689 return $self->{'relationship_factory'}; | |
| 690 } | |
| 691 | |
| 692 =head2 term_factory | |
| 693 | |
| 694 Title : term_factory | |
| 695 Usage : $fact = $obj->term_factory() | |
| 696 Function: Get/set the object factory to be used when term objects are | |
| 697 created by the implementation on-the-fly. | |
| 698 | |
| 699 Note that this ontology engine implementation does not | |
| 700 create term objects on the fly, and therefore setting this | |
| 701 attribute is meaningless. | |
| 702 | |
| 703 Example : | |
| 704 Returns : value of term_factory (a Bio::Factory::ObjectFactoryI | |
| 705 compliant object) | |
| 706 Args : on set, a Bio::Factory::ObjectFactoryI compliant object | |
| 707 | |
| 708 | |
| 709 =cut | |
| 710 | |
| 711 sub term_factory{ | |
| 712 my $self = shift; | |
| 713 | |
| 714 if(@_) { | |
| 715 $self->warn("setting term factory, but ".ref($self). | |
| 716 " does not create terms on-the-fly"); | |
| 717 return $self->{'term_factory'} = shift; | |
| 718 } | |
| 719 return $self->{'term_factory'}; | |
| 720 } | |
| 721 | |
| 722 =head2 graph | |
| 723 | |
| 724 Title : graph() | |
| 725 Usage : $engine->graph(); | |
| 726 Function: Returns the Graph this engine is based on | |
| 727 Returns : Graph | |
| 728 Args : | |
| 729 | |
| 730 =cut | |
| 731 | |
| 732 sub graph { | |
| 733 my ( $self, $value ) = @_; | |
| 734 | |
| 735 if ( defined $value ) { | |
| 736 $self->_check_class( $value, "Graph::Directed" ); | |
| 737 $self->{ "_graph" } = $value; | |
| 738 } | |
| 739 | |
| 740 return $self->{ "_graph" }; | |
| 741 } # graph | |
| 742 | |
| 743 | |
| 744 | |
| 745 # Internal methods | |
| 746 # ---------------- | |
| 747 | |
| 748 | |
| 749 # Checks the correct format of a GOBO-formatted id | |
| 750 # Gets the id out of a term or id string | |
| 751 sub _get_id { | |
| 752 my ( $self, $term ) = @_; | |
| 753 | |
| 754 if(ref($term)) { | |
| 755 return $term->GO_id() if $term->isa("Bio::Ontology::GOterm"); | |
| 756 # if not a GOterm, use standard API | |
| 757 $self->throw("Object doesn't implement Bio::Ontology::TermI. ". | |
| 758 "Bummer.") | |
| 759 unless $term->isa("Bio::Ontology::TermI"); | |
| 760 $term = $term->identifier(); | |
| 761 } | |
| 762 # don't fuss if it looks remotely standard | |
| 763 return $term if $term =~ /^[A-Z]{1,8}:\d{3,}$/; | |
| 764 # prefix with something if only numbers | |
| 765 if($term =~ /^\d+$/) { | |
| 766 $self->warn(ref($self).": identifier [$term] is only numbers - ". | |
| 767 "prefixing with 'GO:'"); | |
| 768 return "GO:" . $term; | |
| 769 } | |
| 770 # we shouldn't have gotten here if it's at least a remotely decent ID | |
| 771 $self->warn(ref($self). | |
| 772 ": Are you sure '$term' is a valid identifier? ". | |
| 773 "If you see problems, this may be the cause."); | |
| 774 return $term; | |
| 775 } # _get_id | |
| 776 | |
| 777 | |
| 778 # Helper for getting children and parent terms | |
| 779 sub _get_child_parent_terms_helper { | |
| 780 my ( $self, $term, $do_get_child_terms, @types ) = @_; | |
| 781 | |
| 782 foreach my $type ( @types ) { | |
| 783 $self->_check_class( $type, "Bio::Ontology::TermI" ); | |
| 784 } | |
| 785 | |
| 786 my @relative_terms = (); | |
| 787 | |
| 788 $term = $self->_get_id( $term ); | |
| 789 if ( ! $self->graph()->has_vertex( $term ) ) { | |
| 790 $self->throw( "Ontology does not contain a term with an identifier of \"$term\"" ); | |
| 791 } | |
| 792 | |
| 793 my @all_relative_terms = (); | |
| 794 if ( $do_get_child_terms ) { | |
| 795 @all_relative_terms = $self->graph()->successors( $term ); | |
| 796 } | |
| 797 else { | |
| 798 @all_relative_terms = $self->graph()->predecessors( $term ); | |
| 799 } | |
| 800 | |
| 801 foreach my $relative ( @all_relative_terms ) { | |
| 802 if ( scalar( @types ) > 0 ) { | |
| 803 foreach my $type ( @types ) { | |
| 804 my $relative_type; | |
| 805 if ( $do_get_child_terms ) { | |
| 806 $relative_type = $self->graph()->get_attribute( TYPE, $term, $relative ); | |
| 807 } | |
| 808 else { | |
| 809 $relative_type = $self->graph()->get_attribute( TYPE, $relative, $term ); | |
| 810 } | |
| 811 if ( $relative_type->equals( $type ) ) { | |
| 812 push( @relative_terms, $relative ); | |
| 813 } | |
| 814 } | |
| 815 } | |
| 816 else { | |
| 817 push( @relative_terms, $relative ); | |
| 818 } | |
| 819 } | |
| 820 | |
| 821 return $self->get_terms( @relative_terms ); | |
| 822 | |
| 823 } # get_child_terms | |
| 824 | |
| 825 | |
| 826 # Recursive helper | |
| 827 sub _get_descendant_terms_helper { | |
| 828 my ( $self, $term, $ids_ref, $types_ref ) = @_; | |
| 829 | |
| 830 my @child_terms = $self->get_child_terms( $term, @$types_ref ); | |
| 831 | |
| 832 if ( scalar( @child_terms ) < 1 ) { | |
| 833 return; | |
| 834 } | |
| 835 | |
| 836 foreach my $child_term ( @child_terms ) { | |
| 837 my $child_term_id = $child_term->identifier(); | |
| 838 $ids_ref->{ $child_term_id } = 0; | |
| 839 $self->_get_descendant_terms_helper( $child_term_id, $ids_ref, $types_ref ); | |
| 840 } | |
| 841 | |
| 842 } # _get_descendant_terms_helper | |
| 843 | |
| 844 | |
| 845 # Recursive helper | |
| 846 sub _get_ancestor_terms_helper { | |
| 847 my ( $self, $term, $ids_ref, $types_ref ) = @_; | |
| 848 | |
| 849 my @parent_terms = $self->get_parent_terms( $term, @$types_ref ); | |
| 850 | |
| 851 if ( scalar( @parent_terms ) < 1 ) { | |
| 852 return; | |
| 853 } | |
| 854 | |
| 855 foreach my $parent_term ( @parent_terms ) { | |
| 856 my $parent_term_id = $parent_term->identifier(); | |
| 857 $ids_ref->{ $parent_term_id } = 0; | |
| 858 $self->_get_ancestor_terms_helper( $parent_term_id, $ids_ref, $types_ref ); | |
| 859 } | |
| 860 | |
| 861 } # get_ancestor_terms_helper | |
| 862 | |
| 863 | |
| 864 | |
| 865 sub _check_class { | |
| 866 my ( $self, $value, $expected_class ) = @_; | |
| 867 | |
| 868 if ( ! defined( $value ) ) { | |
| 869 $self->throw( "Found [undef] where [$expected_class] expected" ); | |
| 870 } | |
| 871 elsif ( ! ref( $value ) ) { | |
| 872 $self->throw( "Found [scalar] where [$expected_class] expected" ); | |
| 873 } | |
| 874 elsif ( ! $value->isa( $expected_class ) ) { | |
| 875 $self->throw( "Found [" . ref( $value ) . "] where [$expected_class] expected" ); | |
| 876 } | |
| 877 | |
| 878 } # _check_class | |
| 879 | |
| 880 | |
| 881 ################################################################# | |
| 882 # aliases | |
| 883 ################################################################# | |
| 884 | |
| 885 *get_relationship_types = \&get_predicate_terms; | |
| 886 | |
| 887 | |
| 888 1; |
