Mercurial > repos > mahtabm > ensembl
comparison variant_effect_predictor/Bio/Ontology/SimpleOntologyEngine.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: SimpleOntologyEngine.pm,v 1.3.2.5 2003/07/03 00:41:40 lapp Exp $ | |
2 # | |
3 # BioPerl module for SimpleOntologyEngine | |
4 # | |
5 # Cared for by Peter Dimitrov <dimitrov@gnf.org> | |
6 # | |
7 # Copyright Peter Dimitrov | |
8 # (c) Peter Dimitrov, dimitrov@gnf.org, 2002. | |
9 # (c) GNF, Genomics Institute of the Novartis Research Foundation, 2002. | |
10 # | |
11 # You may distribute this module under the same terms as perl itself. | |
12 # Refer to the Perl Artistic License (see the license accompanying this | |
13 # software package, or see http://www.perl.com/language/misc/Artistic.html) | |
14 # for the terms under which you may use, modify, and redistribute this module. | |
15 # | |
16 # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED | |
17 # WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF | |
18 # MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | |
19 # | |
20 # POD documentation - main docs before the code | |
21 | |
22 =head1 NAME | |
23 | |
24 SimpleOntologyEngine - Implementation of OntologyEngineI interface | |
25 | |
26 =head1 SYNOPSIS | |
27 | |
28 my $soe = Bio::Ontology::SimpleOntologyEngine->new; | |
29 | |
30 | |
31 =head1 DESCRIPTION | |
32 | |
33 This is a "simple" implementation of Bio::Ontology::OntologyEngineI. | |
34 | |
35 =head1 FEEDBACK | |
36 | |
37 =head2 Mailing Lists | |
38 | |
39 User feedback is an integral part of the evolution of this and other | |
40 Bioperl modules. Send your comments and suggestions preferably to | |
41 the Bioperl mailing list. Your participation is much appreciated. | |
42 | |
43 bioperl-l@bioperl.org - General discussion | |
44 http://bioperl.org/MailList.shtml - About the mailing lists | |
45 | |
46 =head2 Reporting Bugs | |
47 | |
48 Report bugs to the Bioperl bug tracking system to help us keep track | |
49 of the bugs and their resolution. Bug reports can be submitted via | |
50 email or the web: | |
51 | |
52 bioperl-bugs@bioperl.org | |
53 http://bioperl.org/bioperl-bugs/ | |
54 | |
55 =head1 AUTHOR - Peter Dimitrov | |
56 | |
57 Email dimitrov@gnf.org | |
58 | |
59 =head1 CONTRIBUTORS | |
60 | |
61 Hilmar Lapp, hlapp at gmx.net | |
62 | |
63 =head1 APPENDIX | |
64 | |
65 The rest of the documentation details each of the object methods. | |
66 Internal methods are usually preceded with a _ | |
67 | |
68 =cut | |
69 | |
70 | |
71 # Let the code begin... | |
72 | |
73 | |
74 package Bio::Ontology::SimpleOntologyEngine; | |
75 use vars qw(@ISA); | |
76 use strict; | |
77 use Carp; | |
78 use Bio::Root::Root; | |
79 use Bio::Ontology::RelationshipFactory; | |
80 use Bio::Ontology::OntologyEngineI; | |
81 use Data::Dumper; | |
82 | |
83 @ISA = qw( Bio::Root::Root Bio::Ontology::OntologyEngineI ); | |
84 | |
85 =head2 new | |
86 | |
87 Title : new | |
88 Usage : $soe = Bio::Ontology::SimpleOntologyEngine->new; | |
89 Function: Initializes the ontology engine. | |
90 Example : $soe = Bio::Ontology::SimpleOntologyEngine->new; | |
91 Returns : Object of class SimpleOntologyEngine. | |
92 Args : | |
93 | |
94 | |
95 =cut | |
96 | |
97 sub new{ | |
98 my ($class, @args) = @_; | |
99 my $self = $class->SUPER::new(@args); | |
100 # my %param = @args; | |
101 | |
102 $self->_term_store( {} ); | |
103 $self->_relationship_store( {} ); | |
104 $self->_inverted_relationship_store( {} ); | |
105 $self->_relationship_type_store( {} ); | |
106 $self->_instantiated_terms_store( {} ); | |
107 | |
108 # set defaults for the factories | |
109 $self->relationship_factory(Bio::Ontology::RelationshipFactory->new( | |
110 -type => "Bio::Ontology::Relationship")); | |
111 return $self; | |
112 } | |
113 | |
114 =head2 _instantiated_terms_store | |
115 | |
116 Title : _instantiated_terms_store | |
117 Usage : $obj->_instantiated_terms_store($newval) | |
118 Function: | |
119 Example : | |
120 Returns : hash | |
121 Args : empty hash | |
122 | |
123 | |
124 =cut | |
125 | |
126 sub _instantiated_terms_store{ | |
127 my ($self, $value) = @_; | |
128 | |
129 if( defined $value) { | |
130 $self->{'_instantiated_terms_store'} = $value; | |
131 } | |
132 return $self->{'_instantiated_terms_store'}; | |
133 } | |
134 | |
135 =head2 mark_instantiated | |
136 | |
137 Title : mark_instantiated | |
138 Usage : $self->mark_instantiated(TermI[] terms): TermI[] | |
139 Function: Marks TermI objects as fully instantiated, | |
140 allowing for proper counting of the number of terms in the term store. | |
141 The TermI objects has to be already stored in the term store in order to | |
142 be marked. | |
143 Example : $self->mark_instantiated($term); | |
144 Returns : its argument or throws an exception if a term is not | |
145 in the term store. | |
146 Args : array of objects of class TermI. | |
147 | |
148 =cut | |
149 | |
150 sub mark_instantiated{ | |
151 my ($self, @terms) = @_; | |
152 | |
153 foreach my $term (@terms) { | |
154 $self->throw( "term ".$term->identifier." not in the term store\n" ) | |
155 if !defined $self->_term_store->{$term->identifier}; | |
156 $self->_instantiated_terms_store->{$term->identifier} = 1; | |
157 } | |
158 | |
159 return @terms; | |
160 } | |
161 | |
162 =head2 mark_uninstantiated | |
163 | |
164 Title : mark_uninstantiated | |
165 Usage : $self->mark_uninstantiated(TermI[] terms): TermI[] | |
166 Function: Marks TermI objects as not fully instantiated, | |
167 Example : $self->mark_uninstantiated($term); | |
168 Returns : its argument or throws an exception if a term is not | |
169 in the term store(if the term is not marked it does nothing). | |
170 Args : array of objects of class TermI. | |
171 | |
172 | |
173 =cut | |
174 | |
175 sub mark_uninstantiated{ | |
176 my ($self, @terms) = @_; | |
177 | |
178 foreach my $term (@terms) { | |
179 $self->throw( "term ".$term->identifier." not in the term store\n" ) | |
180 if !defined $self->_term_store->{$term->identifier}; | |
181 delete $self->_instantiated_terms_store->{$term->identifier} | |
182 if defined $self->_instantiated_terms_store->{$term->identifier}; | |
183 } | |
184 | |
185 return @terms; | |
186 } | |
187 | |
188 =head2 _term_store | |
189 | |
190 Title : term_store | |
191 Usage : $obj->_term_store($newval) | |
192 Function: | |
193 Example : | |
194 Returns : reference to an array of Bio::Ontology::TermI objects | |
195 Args : reference to an array of Bio::Ontology::TermI objects | |
196 | |
197 =cut | |
198 | |
199 sub _term_store{ | |
200 my ($self, $value) = @_; | |
201 | |
202 if( defined $value) { | |
203 if ( defined $self->{'_term_store'}) { | |
204 $self->throw("_term_store already defined\n"); | |
205 } | |
206 else { | |
207 $self->{'_term_store'} = $value; | |
208 } | |
209 } | |
210 | |
211 return $self->{'_term_store'}; | |
212 } | |
213 | |
214 =head2 add_term | |
215 | |
216 Title : add_term | |
217 Usage : add_term(TermI term): TermI | |
218 Function: Adds TermI object to the ontology engine term store. | |
219 Marks the term fully instantiated by default. | |
220 Example : $soe->add_term($term) | |
221 Returns : its argument. | |
222 Args : object of class TermI. | |
223 | |
224 =cut | |
225 | |
226 sub add_term{ | |
227 my ($self, $term) = @_; | |
228 my $term_store = $self->_term_store; | |
229 | |
230 if ( defined $term_store -> {$term->identifier}) { | |
231 $self->throw( "term ".$term->identifier." already defined\n" ); | |
232 } | |
233 else { | |
234 $term_store->{$term->identifier} = $term; | |
235 $self->_instantiated_terms_store->{$term->identifier} = 1; | |
236 } | |
237 | |
238 return $term; | |
239 } | |
240 | |
241 =head2 get_term_by_identifier | |
242 | |
243 Title : get_term_by_identifier | |
244 Usage : get_term_by_identifier(String[] id): TermI[] | |
245 Function: Retrieves terms from the term store by their identifier | |
246 field, or undef if not there. | |
247 Example : $term = $soe->get_term_by_identifier("IPR000001"); | |
248 Returns : An array of zero or more Bio::Ontology::TermI objects. | |
249 Args : An array of identifier strings | |
250 | |
251 | |
252 =cut | |
253 | |
254 sub get_term_by_identifier{ | |
255 my ($self, @ids) = @_; | |
256 my @ans = (); | |
257 | |
258 foreach my $id (@ids) { | |
259 my $term = $self->_term_store->{$id}; | |
260 push @ans, $term if defined $term; | |
261 } | |
262 | |
263 return @ans; | |
264 } | |
265 | |
266 =head2 _get_number_rels | |
267 | |
268 Title : get_number_rels | |
269 Usage : | |
270 Function: | |
271 Example : | |
272 Returns : | |
273 Args : | |
274 | |
275 | |
276 =cut | |
277 | |
278 sub _get_number_rels{ | |
279 my ($self) = @_; | |
280 my $num_rels = 0; | |
281 | |
282 foreach my $entry ($self->_relationship_store) { | |
283 $num_rels += scalar keys %$entry; | |
284 } | |
285 return $num_rels; | |
286 } | |
287 | |
288 =head2 _get_number_terms | |
289 | |
290 Title : _get_number_terms | |
291 Usage : | |
292 Function: | |
293 Example : | |
294 Returns : | |
295 Args : | |
296 | |
297 | |
298 =cut | |
299 | |
300 sub _get_number_terms{ | |
301 my ($self) = @_; | |
302 | |
303 return scalar $self->_filter_unmarked( values %{$self->_term_store} ); | |
304 | |
305 } | |
306 | |
307 =head2 _relationship_store | |
308 | |
309 Title : _storerelationship_store | |
310 Usage : $obj->relationship_store($newval) | |
311 Function: | |
312 Example : | |
313 Returns : reference to an array of Bio::Ontology::TermI objects | |
314 Args : reference to an array of Bio::Ontology::TermI objects | |
315 | |
316 | |
317 =cut | |
318 | |
319 sub _relationship_store{ | |
320 my ($self, $value) = @_; | |
321 | |
322 if( defined $value) { | |
323 if ( defined $self->{'_relationship_store'}) { | |
324 $self->throw("_relationship_store already defined\n"); | |
325 } | |
326 else { | |
327 $self->{'_relationship_store'} = $value; | |
328 } | |
329 } | |
330 | |
331 return $self->{'_relationship_store'}; | |
332 } | |
333 | |
334 =head2 _inverted_relationship_store | |
335 | |
336 Title : _inverted_relationship_store | |
337 Usage : | |
338 Function: | |
339 Example : | |
340 Returns : reference to an array of Bio::Ontology::TermI objects | |
341 Args : reference to an array of Bio::Ontology::TermI objects | |
342 | |
343 | |
344 =cut | |
345 | |
346 sub _inverted_relationship_store{ | |
347 my ($self, $value) = @_; | |
348 | |
349 if( defined $value) { | |
350 if ( defined $self->{'_inverted_relationship_store'}) { | |
351 $self->throw("_inverted_relationship_store already defined\n"); | |
352 } | |
353 else { | |
354 $self->{'_inverted_relationship_store'} = $value; | |
355 } | |
356 } | |
357 | |
358 return $self->{'_inverted_relationship_store'}; | |
359 } | |
360 | |
361 =head2 _relationship_type_store | |
362 | |
363 Title : _relationship_type_store | |
364 Usage : $obj->_relationship_type_store($newval) | |
365 Function: | |
366 Example : | |
367 Returns : reference to an array of Bio::Ontology::RelationshipType objects | |
368 Args : reference to an array of Bio::Ontology::RelationshipType objects | |
369 | |
370 | |
371 =cut | |
372 | |
373 sub _relationship_type_store{ | |
374 my ($self, $value) = @_; | |
375 | |
376 if( defined $value) { | |
377 if ( defined $self->{'_relationship_type_store'}) { | |
378 $self->throw("_relationship_type_store already defined\n"); | |
379 } | |
380 else { | |
381 $self->{'_relationship_type_store'} = $value; | |
382 } | |
383 } | |
384 | |
385 return $self->{'_relationship_type_store'}; | |
386 } | |
387 | |
388 =head2 _add_relationship_simple | |
389 | |
390 Title : _add_relationship_simple | |
391 Usage : | |
392 Function: | |
393 Example : | |
394 Returns : | |
395 Args : | |
396 | |
397 | |
398 =cut | |
399 | |
400 sub _add_relationship_simple{ | |
401 my ($self, $store, $rel, $inverted) = @_; | |
402 my $parent_id; | |
403 my $child_id; | |
404 | |
405 if ($inverted) { | |
406 $parent_id = $rel->subject_term->identifier; | |
407 $child_id = $rel->object_term->identifier; | |
408 } | |
409 else { | |
410 $parent_id = $rel->object_term->identifier; | |
411 $child_id = $rel->subject_term->identifier; | |
412 } | |
413 if((defined $store->{$parent_id}->{$child_id}) && | |
414 ($store->{$parent_id}->{$child_id}->name != $rel->predicate_term->name)){ | |
415 $self->throw("relationship ".Dumper($rel->predicate_term). | |
416 " between ".$parent_id." and ".$child_id. | |
417 " already defined as ". | |
418 Dumper($store->{$parent_id}->{$child_id})."\n"); | |
419 } | |
420 else { | |
421 $store->{$parent_id}->{$child_id} = $rel->predicate_term; | |
422 } | |
423 } | |
424 | |
425 =head2 add_relationship | |
426 | |
427 Title : add_relationship | |
428 Usage : add_relationship(RelationshipI relationship): RelationshipI | |
429 Function: Adds a relationship object to the ontology engine. | |
430 Example : | |
431 Returns : Its argument. | |
432 Args : A RelationshipI object. | |
433 | |
434 | |
435 =cut | |
436 | |
437 sub add_relationship{ | |
438 my ($self, $rel) = @_; | |
439 | |
440 $self->_add_relationship_simple($self->_relationship_store, | |
441 $rel, 0); | |
442 $self->_add_relationship_simple($self->_inverted_relationship_store, | |
443 $rel, 1); | |
444 $self->_relationship_type_store->{ | |
445 $self->_unique_termid($rel->predicate_term)} = $rel->predicate_term; | |
446 | |
447 return $rel; | |
448 } | |
449 | |
450 =head2 get_relationships | |
451 | |
452 Title : get_relationships | |
453 Usage : get_relationships(): RelationshipI[] | |
454 Function: Retrieves all relationship objects. | |
455 Example : | |
456 Returns : Array of RelationshipI objects | |
457 Args : | |
458 | |
459 | |
460 =cut | |
461 | |
462 sub get_relationships{ | |
463 my $self = shift; | |
464 my $term = shift; | |
465 my @rels; | |
466 my $store = $self->_relationship_store; | |
467 my $relfact = $self->relationship_factory(); | |
468 | |
469 my @parent_ids = $term ? | |
470 # if a term is supplied then only get the term's parents | |
471 (map { $_->identifier(); } $self->get_parent_terms($term)) : | |
472 # otherwise use all parent ids | |
473 (keys %{$store}); | |
474 # add the term as a parent too if one is supplied | |
475 push(@parent_ids,$term->identifier) if $term; | |
476 | |
477 foreach my $parent_id (@parent_ids) { | |
478 my $parent_entry = $store->{$parent_id}; | |
479 | |
480 # if a term is supplied, add a relationship for the parent to the term | |
481 # except if the parent is the term itself (we added that one before) | |
482 if($term && ($parent_id ne $term->identifier())) { | |
483 my $parent_term = $self->get_term_by_identifier($parent_id); | |
484 push(@rels, | |
485 $relfact->create_object(-object_term => $parent_term, | |
486 -subject_term => $term, | |
487 -predicate_term => | |
488 $parent_entry->{$term->identifier}, | |
489 -ontology => $term->ontology() | |
490 ) | |
491 ); | |
492 | |
493 } else { | |
494 # otherwise, i.e., no term supplied, or the parent equals the | |
495 # supplied term | |
496 my $parent_term = $term ? | |
497 $term : $self->get_term_by_identifier($parent_id); | |
498 foreach my $child_id (keys %$parent_entry) { | |
499 my $rel_info = $parent_entry->{$child_id}; | |
500 | |
501 push(@rels, | |
502 $relfact->create_object(-object_term => $parent_term, | |
503 -subject_term => | |
504 $self->get_term_by_identifier( | |
505 $child_id), | |
506 -predicate_term => $rel_info, | |
507 -ontology =>$parent_term->ontology | |
508 ) | |
509 ); | |
510 } | |
511 } | |
512 } | |
513 | |
514 return @rels; | |
515 } | |
516 | |
517 =head2 get_all_relationships | |
518 | |
519 Title : get_all_relationships | |
520 Usage : get_all_relationships(): RelationshipI[] | |
521 Function: Retrieves all relationship objects. | |
522 Example : | |
523 Returns : Array of RelationshipI objects | |
524 Args : | |
525 | |
526 | |
527 =cut | |
528 | |
529 sub get_all_relationships{ | |
530 return shift->get_relationships(); | |
531 } | |
532 | |
533 =head2 get_predicate_terms | |
534 | |
535 Title : get_predicate_terms | |
536 Usage : get_predicate_terms(): TermI[] | |
537 Function: Retrives all relationship types stored in the engine | |
538 Example : | |
539 Returns : reference to an array of Bio::Ontology::RelationshipType objects | |
540 Args : | |
541 | |
542 | |
543 =cut | |
544 | |
545 sub get_predicate_terms{ | |
546 my ($self) = @_; | |
547 | |
548 return values %{$self->_relationship_type_store}; | |
549 } | |
550 | |
551 =head2 _is_rel_type | |
552 | |
553 Title : _is_rel_type | |
554 Usage : | |
555 Function: | |
556 Example : | |
557 Returns : | |
558 Args : | |
559 | |
560 | |
561 =cut | |
562 | |
563 sub _is_rel_type{ | |
564 my ($self, $term, @rel_types) = @_; | |
565 | |
566 foreach my $rel_type (@rel_types) { | |
567 if($rel_type->identifier || $term->identifier) { | |
568 return 1 if $rel_type->identifier eq $term->identifier; | |
569 } else { | |
570 return 1 if $rel_type->name eq $term->name; | |
571 } | |
572 } | |
573 | |
574 return 0; | |
575 } | |
576 | |
577 =head2 _typed_traversal | |
578 | |
579 Title : _typed_traversal | |
580 Usage : | |
581 Function: | |
582 Example : | |
583 Returns : | |
584 Args : | |
585 | |
586 | |
587 =cut | |
588 | |
589 sub _typed_traversal{ | |
590 my ($self, $rel_store, $level, $term_id, @rel_types) = @_; | |
591 return undef if !defined($rel_store->{$term_id}); | |
592 my %parent_entry = %{$rel_store->{$term_id}}; | |
593 my @children = keys %parent_entry; | |
594 | |
595 my @ans; | |
596 | |
597 if (@rel_types > 0) { | |
598 @ans = (); | |
599 | |
600 foreach my $child_id (@children) { | |
601 push @ans, $child_id | |
602 if $self->_is_rel_type( $rel_store->{$term_id}->{$child_id}, | |
603 @rel_types); | |
604 } | |
605 } | |
606 else { | |
607 @ans = @children; | |
608 } | |
609 if ($level < 1) { | |
610 my @ans1 = (); | |
611 | |
612 foreach my $child_id (@ans) { | |
613 push @ans1, $self->_typed_traversal($rel_store, | |
614 $level - 1, $child_id, @rel_types) | |
615 if defined $rel_store->{$child_id}; | |
616 } | |
617 push @ans, @ans1; | |
618 } | |
619 | |
620 return @ans; | |
621 } | |
622 | |
623 =head2 get_child_terms | |
624 | |
625 Title : get_child_terms | |
626 Usage : get_child_terms(TermI term, TermI[] predicate_terms): TermI[] | |
627 get_child_terms(TermI term, RelationshipType[] predicate_terms): TermI[] | |
628 Function: Retrieves all child terms of a given term, that satisfy a | |
629 relationship among those that are specified in the second | |
630 argument or undef otherwise. get_child_terms is a special | |
631 case of get_descendant_terms, limiting the search to the | |
632 direct descendants. | |
633 | |
634 Example : | |
635 Returns : Array of TermI objects. | |
636 Args : First argument is the term of interest, second is the list of relationship type terms. | |
637 | |
638 | |
639 =cut | |
640 | |
641 sub get_child_terms{ | |
642 my ($self, $term, @relationship_types) = @_; | |
643 | |
644 $self->throw("must provide TermI compliant object") | |
645 unless defined($term) && $term->isa("Bio::Ontology::TermI"); | |
646 | |
647 return $self->_filter_unmarked( | |
648 $self->get_term_by_identifier( | |
649 $self->_typed_traversal($self->_relationship_store, | |
650 1, | |
651 $term->identifier, | |
652 @relationship_types) ) ); | |
653 } | |
654 | |
655 =head2 get_descendant_terms | |
656 | |
657 Title : get_descendant_terms | |
658 Usage : get_descendant_terms(TermI term, TermI[] rel_types): TermI[] | |
659 get_child_terms(TermI term, RelationshipType[] predicate_terms): TermI[] | |
660 Function: Retrieves all descendant terms of a given term, that | |
661 satisfy a relationship among those that are specified in | |
662 the second argument or undef otherwise. Uses | |
663 _typed_traversal to find all descendants. | |
664 | |
665 Example : | |
666 Returns : Array of TermI objects. | |
667 Args : First argument is the term of interest, second is the list of relationship type terms. | |
668 | |
669 | |
670 =cut | |
671 | |
672 sub get_descendant_terms{ | |
673 my ($self, $term, @relationship_types) = @_; | |
674 | |
675 $self->throw("must provide TermI compliant object") | |
676 unless defined($term) && $term->isa("Bio::Ontology::TermI"); | |
677 | |
678 return $self->_filter_unmarked( | |
679 $self->_filter_repeated( | |
680 $self->get_term_by_identifier( | |
681 $self->_typed_traversal($self->_relationship_store, | |
682 0, | |
683 $term->identifier, | |
684 @relationship_types) ) ) ); | |
685 } | |
686 | |
687 =head2 get_parent_terms | |
688 | |
689 Title : get_parent_terms | |
690 Usage : get_parent_terms(TermI term, TermI[] predicate_terms): TermI[] | |
691 get_child_terms(TermI term, RelationshipType[] predicate_terms): TermI[] | |
692 Function: Retrieves all parent terms of a given term, that satisfy a | |
693 relationship among those that are specified in the second | |
694 argument or undef otherwise. get_parent_terms is a special | |
695 case of get_ancestor_terms, limiting the search to the | |
696 direct ancestors. | |
697 | |
698 Example : | |
699 Returns : Array of TermI objects. | |
700 Args : First argument is the term of interest, second is the list of relationship type terms. | |
701 | |
702 | |
703 =cut | |
704 | |
705 sub get_parent_terms{ | |
706 my ($self, $term, @relationship_types) = @_; | |
707 $self->throw("term must be a valid object, not undef") unless defined $term; | |
708 | |
709 return $self->_filter_unmarked( | |
710 $self->get_term_by_identifier( | |
711 $self->_typed_traversal($self->_inverted_relationship_store, | |
712 1, | |
713 $term->identifier, | |
714 @relationship_types) ) ); | |
715 } | |
716 | |
717 =head2 get_ancestor_terms | |
718 | |
719 Title : get_ancestor_terms | |
720 Usage : get_ancestor_terms(TermI term, TermI[] predicate_terms): TermI[] | |
721 get_child_terms(TermI term, RelationshipType[] predicate_terms): TermI[] | |
722 Function: Retrieves all ancestor terms of a given term, that satisfy | |
723 a relationship among those that are specified in the second | |
724 argument or undef otherwise. Uses _typed_traversal to find | |
725 all ancestors. | |
726 | |
727 Example : | |
728 Returns : Array of TermI objects. | |
729 Args : First argument is the term of interest, second is the list | |
730 of relationship type terms. | |
731 | |
732 | |
733 =cut | |
734 | |
735 sub get_ancestor_terms{ | |
736 my ($self, $term, @relationship_types) = @_; | |
737 $self->throw("term must be a valid object, not undef") unless defined $term; | |
738 | |
739 return $self->_filter_unmarked( | |
740 $self->_filter_repeated( | |
741 $self->get_term_by_identifier( | |
742 $self->_typed_traversal($self->_inverted_relationship_store, | |
743 0, | |
744 $term->identifier, | |
745 @relationship_types) ) ) ); | |
746 } | |
747 | |
748 =head2 get_leaf_terms | |
749 | |
750 Title : get_leaf_terms | |
751 Usage : get_leaf_terms(): TermI[] | |
752 Function: Retrieves all leaf terms from the ontology. Leaf term is a term w/o descendants. | |
753 Example : @leaf_terms = $obj->get_leaf_terms() | |
754 Returns : Array of TermI objects. | |
755 Args : | |
756 | |
757 | |
758 =cut | |
759 | |
760 sub get_leaf_terms{ | |
761 my ($self) = @_; | |
762 my @leaf_terms; | |
763 | |
764 foreach my $term (values %{$self->_term_store}) { | |
765 push @leaf_terms, $term | |
766 if !defined $self->_relationship_store->{$term->identifier} && | |
767 defined $self->_instantiated_terms_store->{$term->identifier}; | |
768 } | |
769 | |
770 return @leaf_terms; | |
771 } | |
772 | |
773 =head2 get_root_terms | |
774 | |
775 Title : get_root_terms | |
776 Usage : get_root_terms(): TermI[] | |
777 Function: Retrieves all root terms from the ontology. Root term is a term w/o descendants. | |
778 Example : @root_terms = $obj->get_root_terms() | |
779 Returns : Array of TermI objects. | |
780 Args : | |
781 | |
782 | |
783 =cut | |
784 | |
785 sub get_root_terms{ | |
786 my ($self) = @_; | |
787 my @root_terms; | |
788 | |
789 foreach my $term (values %{$self->_term_store}) { | |
790 push @root_terms, $term | |
791 if !defined $self->_inverted_relationship_store->{$term->identifier} && | |
792 defined $self->_instantiated_terms_store->{$term->identifier}; | |
793 } | |
794 | |
795 return @root_terms; | |
796 } | |
797 | |
798 =head2 _filter_repeated | |
799 | |
800 Title : _filter_repeated | |
801 Usage : @lst = $self->_filter_repeated(@old_lst); | |
802 Function: Removes repeated terms | |
803 Example : | |
804 Returns : List of unique TermI objects | |
805 Args : List of TermI objects | |
806 | |
807 | |
808 =cut | |
809 | |
810 sub _filter_repeated{ | |
811 my ($self, @args) = @_; | |
812 my %h; | |
813 | |
814 foreach my $element (@args) { | |
815 $h{$element->identifier} = $element if !defined $h{$element->identifier}; | |
816 } | |
817 | |
818 return values %h; | |
819 } | |
820 | |
821 =head2 get_all_terms | |
822 | |
823 Title : get_all_terms | |
824 Usage : get_all_terms(): TermI[] | |
825 Function: Retrieves all terms currently stored in the ontology. | |
826 Example : @all_terms = $obj->get_all_terms() | |
827 Returns : Array of TermI objects. | |
828 Args : | |
829 | |
830 | |
831 =cut | |
832 | |
833 sub get_all_terms{ | |
834 my ($self) = @_; | |
835 | |
836 return $self->_filter_unmarked( values %{$self->_term_store} ); | |
837 } | |
838 | |
839 =head2 find_terms | |
840 | |
841 Title : find_terms | |
842 Usage : ($term) = $oe->find_terms(-identifier => "SO:0000263"); | |
843 Function: Find term instances matching queries for their attributes. | |
844 | |
845 This implementation can efficiently resolve queries by | |
846 identifier. | |
847 | |
848 Example : | |
849 Returns : an array of zero or more Bio::Ontology::TermI objects | |
850 Args : Named parameters. The following parameters should be recognized | |
851 by any implementations: | |
852 | |
853 -identifier query by the given identifier | |
854 -name query by the given name | |
855 | |
856 | |
857 =cut | |
858 | |
859 sub find_terms{ | |
860 my ($self,@args) = @_; | |
861 my @terms; | |
862 | |
863 my ($id,$name) = $self->_rearrange([qw(IDENTIFIER NAME)],@args); | |
864 | |
865 if(defined($id)) { | |
866 @terms = $self->get_term_by_identifier($id); | |
867 } else { | |
868 @terms = $self->get_all_terms(); | |
869 } | |
870 if(defined($name)) { | |
871 @terms = grep { $_->name() eq $name; } @terms; | |
872 } | |
873 return @terms; | |
874 } | |
875 | |
876 | |
877 =head2 relationship_factory | |
878 | |
879 Title : relationship_factory | |
880 Usage : $fact = $obj->relationship_factory() | |
881 Function: Get/set the object factory to be used when relationship | |
882 objects are created by the implementation on-the-fly. | |
883 | |
884 Example : | |
885 Returns : value of relationship_factory (a Bio::Factory::ObjectFactoryI | |
886 compliant object) | |
887 Args : on set, a Bio::Factory::ObjectFactoryI compliant object | |
888 | |
889 | |
890 =cut | |
891 | |
892 sub relationship_factory{ | |
893 my $self = shift; | |
894 | |
895 return $self->{'relationship_factory'} = shift if @_; | |
896 return $self->{'relationship_factory'}; | |
897 } | |
898 | |
899 =head2 term_factory | |
900 | |
901 Title : term_factory | |
902 Usage : $fact = $obj->term_factory() | |
903 Function: Get/set the object factory to be used when term objects are | |
904 created by the implementation on-the-fly. | |
905 | |
906 Note that this ontology engine implementation does not | |
907 create term objects on the fly, and therefore setting this | |
908 attribute is meaningless. | |
909 | |
910 Example : | |
911 Returns : value of term_factory (a Bio::Factory::ObjectFactoryI | |
912 compliant object) | |
913 Args : on set, a Bio::Factory::ObjectFactoryI compliant object | |
914 | |
915 | |
916 =cut | |
917 | |
918 sub term_factory{ | |
919 my $self = shift; | |
920 | |
921 if(@_) { | |
922 $self->warn("setting term factory, but ".ref($self). | |
923 " does not create terms on-the-fly"); | |
924 return $self->{'term_factory'} = shift; | |
925 } | |
926 return $self->{'term_factory'}; | |
927 } | |
928 | |
929 =head2 _filter_unmarked | |
930 | |
931 Title : _filter_unmarked | |
932 Usage : _filter_unmarked(TermI[] terms): TermI[] | |
933 Function: Removes the uninstantiated terms from the list of terms | |
934 Example : | |
935 Returns : array of fully instantiated TermI objects | |
936 Args : array of TermI objects | |
937 | |
938 | |
939 =cut | |
940 | |
941 sub _filter_unmarked{ | |
942 my ($self, @terms) = @_; | |
943 my @filtered_terms = (); | |
944 | |
945 if ( scalar(@terms) >= 1) { | |
946 foreach my $term (@terms) { | |
947 push @filtered_terms, $term | |
948 if defined $self->_instantiated_terms_store->{$term->identifier}; | |
949 } | |
950 } | |
951 | |
952 return @filtered_terms; | |
953 } | |
954 | |
955 =head2 remove_term_by_id | |
956 | |
957 Title : remove_term_by_id | |
958 Usage : remove_term_by_id(String id): TermI | |
959 Function: Removes TermI object from the ontology engine using the | |
960 string id as an identifier. Current implementation does not | |
961 enforce consistency of the relationships using that term. | |
962 Example : $term = $soe->remove_term_by_id($id); | |
963 Returns : Object of class TermI or undef if not found. | |
964 Args : The string identifier of a term. | |
965 | |
966 | |
967 =cut | |
968 | |
969 sub remove_term_by_id{ | |
970 my ($self, $id) = @_; | |
971 | |
972 if ( $self->get_term_by_identifier($id) ) { | |
973 my $term = $self->{_term_store}->{$id}; | |
974 delete $self->{_term_store}->{$id}; | |
975 return $term; | |
976 } | |
977 else { | |
978 $self->warn("Term with id '$id' is not in the term store"); | |
979 return undef; | |
980 } | |
981 } | |
982 | |
983 =head2 to_string | |
984 | |
985 Title : to_string | |
986 Usage : print $sv->to_string(); | |
987 Function: Currently returns formatted string containing the number of | |
988 terms and number of relationships from the ontology engine. | |
989 Example : print $sv->to_string(); | |
990 Returns : | |
991 Args : | |
992 | |
993 | |
994 =cut | |
995 | |
996 sub to_string{ | |
997 my ($self) = @_; | |
998 my $s = ""; | |
999 | |
1000 $s .= "-- # Terms:\n"; | |
1001 $s .= scalar($self->get_all_terms)."\n"; | |
1002 $s .= "-- # Relationships:\n"; | |
1003 $s .= $self->_get_number_rels."\n"; | |
1004 | |
1005 return $s; | |
1006 } | |
1007 | |
1008 =head2 _unique_termid | |
1009 | |
1010 Title : _unique_termid | |
1011 Usage : | |
1012 Function: Returns a string that can be used as ID using fail-over | |
1013 approaches. | |
1014 | |
1015 If the identifier attribute is not set, it uses the | |
1016 combination of name and ontology name, provided both are | |
1017 set. If they aren't, it returns the name alone. | |
1018 | |
1019 Note that this is a private method. Call from inheriting | |
1020 classes but not from outside. | |
1021 | |
1022 Example : | |
1023 Returns : a string | |
1024 Args : a Bio::Ontology::TermI compliant object | |
1025 | |
1026 | |
1027 =cut | |
1028 | |
1029 sub _unique_termid{ | |
1030 my $self = shift; | |
1031 my $term = shift; | |
1032 | |
1033 return $term->identifier() if $term->identifier(); | |
1034 my $id = $term->ontology->name() if $term->ontology(); | |
1035 if($id) { | |
1036 $id .= '|'; | |
1037 } else { | |
1038 $id = ''; | |
1039 } | |
1040 $id .= $term->name(); | |
1041 } | |
1042 | |
1043 | |
1044 ################################################################# | |
1045 # aliases | |
1046 ################################################################# | |
1047 | |
1048 *get_relationship_types = \&get_predicate_terms; | |
1049 | |
1050 1; |