0
|
1 # $Id: OntologyEngineI.pm,v 1.2.2.3 2003/03/27 10:07:56 lapp Exp $
|
|
2 #
|
|
3 # BioPerl module for OntologyEngineI
|
|
4 #
|
|
5 # Cared for by Peter Dimitrov <dimitrov@gnf.org>
|
|
6 #
|
|
7 # (c) Peter Dimitrov
|
|
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 OntologyEngineI - Interface a minimal Ontology implementation should satisfy
|
|
26
|
|
27 =head1 SYNOPSIS
|
|
28
|
|
29 # see documentation of methods
|
|
30
|
|
31 =head1 DESCRIPTION
|
|
32
|
|
33 This describes the minimal interface an ontology query engine should
|
|
34 provide. It intentionally doesn't make explicit references to the
|
|
35 ontology being a DAG, nor does it mandate that the ontology be a
|
|
36 vocabulary. Rather, it tries to generically express what should be
|
|
37 accessible (queriable) about an ontology.
|
|
38
|
|
39 The idea is to allow for different implementations for different
|
|
40 purposes, which may then differ as to which operations are efficient
|
|
41 and which aren't, and how much richer the functionality is on top of
|
|
42 this minimalistic set of methods. Check modules in the Bio::Ontology
|
|
43 namespace to find out which implementations exist. At the time of
|
|
44 writing, there is a SimpleOntologyEngine (which does not use
|
|
45 Graph.pm), and a Graph.pm-based implementation in SimpleGOEngine.
|
|
46
|
|
47 Ontology parsers in Bio::OntologyIO are required to return an
|
|
48 implementation of this interface.
|
|
49
|
|
50 =head1 FEEDBACK
|
|
51
|
|
52 =head2 Mailing Lists
|
|
53
|
|
54 User feedback is an integral part of the evolution of this and other
|
|
55 Bioperl modules. Send your comments and suggestions preferably to
|
|
56 the Bioperl mailing list. Your participation is much appreciated.
|
|
57
|
|
58 bioperl-l@bioperl.org - General discussion
|
|
59 http://bioperl.org/MailList.shtml - About the mailing lists
|
|
60
|
|
61 =head2 Reporting Bugs
|
|
62
|
|
63 Report bugs to the Bioperl bug tracking system to help us keep track
|
|
64 of the bugs and their resolution. Bug reports can be submitted via
|
|
65 email or the web:
|
|
66
|
|
67 bioperl-bugs@bioperl.org
|
|
68 http://bugzilla.bioperl.org/
|
|
69
|
|
70 =head1 AUTHOR - Peter Dimitrov
|
|
71
|
|
72 Email dimitrov@gnf.org
|
|
73
|
|
74 Describe contact details here
|
|
75
|
|
76 =head1 CONTRIBUTORS
|
|
77
|
|
78 Additional contributors names and emails here
|
|
79
|
|
80 =head1 APPENDIX
|
|
81
|
|
82 The rest of the documentation details each of the object methods.
|
|
83 Internal methods are usually preceded with a _
|
|
84
|
|
85 =cut
|
|
86
|
|
87
|
|
88 # Let the code begin...
|
|
89
|
|
90
|
|
91 package Bio::Ontology::OntologyEngineI;
|
|
92 use vars qw(@ISA);
|
|
93 use strict;
|
|
94 use Carp;
|
|
95 use Bio::Root::RootI;
|
|
96
|
|
97 @ISA = qw( Bio::Root::RootI );
|
|
98
|
|
99 =head2 add_term
|
|
100
|
|
101 Title : add_term
|
|
102 Usage : add_term(TermI term): TermI
|
|
103 Function: Adds TermI object to the ontology engine term store
|
|
104 Example : $oe->add_term($term)
|
|
105 Returns : its argument.
|
|
106 Args : object of class TermI.
|
|
107
|
|
108
|
|
109 =cut
|
|
110
|
|
111 sub add_term{
|
|
112 shift->throw_not_implemented();
|
|
113 }
|
|
114
|
|
115 =head2 add_relationship
|
|
116
|
|
117 Title : add_relationship
|
|
118 Usage : add_relationship(RelationshipI relationship): RelationshipI
|
|
119 Function: Adds a relationship object to the ontology engine.
|
|
120 Example :
|
|
121 Returns : Its argument.
|
|
122 Args : A RelationshipI object.
|
|
123
|
|
124
|
|
125 =cut
|
|
126
|
|
127 sub add_relationship{
|
|
128 shift->throw_not_implemented();
|
|
129 }
|
|
130
|
|
131 =head2 get_relationships
|
|
132
|
|
133 Title : get_relationships
|
|
134 Usage : get_relationships(TermI term): RelationshipI[]
|
|
135 Function: Retrieves all relationship objects from this ontology engine,
|
|
136 or all relationships of a term if a term is supplied.
|
|
137 Example :
|
|
138 Returns : Array of Bio::Ontology::RelationshipI objects
|
|
139 Args : None, or a Bio::Ontology::TermI compliant object for which
|
|
140 to retrieve the relationships.
|
|
141
|
|
142
|
|
143 =cut
|
|
144
|
|
145 sub get_relationships{
|
|
146 shift->throw_not_implemented();
|
|
147 }
|
|
148
|
|
149 =head2 get_predicate_terms
|
|
150
|
|
151 Title : get_predicate_terms
|
|
152 Usage : get_predicate_terms(): TermI[]
|
|
153 Function:
|
|
154 Example :
|
|
155 Returns :
|
|
156 Args :
|
|
157
|
|
158
|
|
159 =cut
|
|
160
|
|
161 sub get_predicate_terms{
|
|
162 shift->throw_not_implemented();
|
|
163 }
|
|
164
|
|
165 =head2 get_child_terms
|
|
166
|
|
167 Title : get_child_terms
|
|
168 Usage : get_child_terms(TermI term, TermI[] predicate_terms): TermI[]
|
|
169 Function: Retrieves all child terms of a given term, that satisfy a
|
|
170 relationship among those that are specified in the second
|
|
171 argument or undef otherwise. get_child_terms is a special
|
|
172 case of get_descendant_terms, limiting the search to the
|
|
173 direct descendants.
|
|
174
|
|
175 Example :
|
|
176 Returns : Array of TermI objects.
|
|
177 Args : First argument is the term of interest, second is the list
|
|
178 of relationship type terms.
|
|
179
|
|
180
|
|
181 =cut
|
|
182
|
|
183 sub get_child_terms{
|
|
184 shift->throw_not_implemented();
|
|
185 }
|
|
186
|
|
187 =head2 get_descendant_terms
|
|
188
|
|
189 Title : get_descendant_terms
|
|
190 Usage : get_descendant_terms(TermI term, TermI[] rel_types): TermI[]
|
|
191 Function: Retrieves all descendant terms of a given term, that
|
|
192 satisfy a relationship among those that are specified in
|
|
193 the second argument or undef otherwise.
|
|
194 Example :
|
|
195 Returns : Array of TermI objects.
|
|
196 Args : First argument is the term of interest, second is the list
|
|
197 of relationship type terms.
|
|
198
|
|
199
|
|
200 =cut
|
|
201
|
|
202 sub get_descendant_terms{
|
|
203 shift->throw_not_implemented();
|
|
204 }
|
|
205
|
|
206 =head2 get_parent_terms
|
|
207
|
|
208 Title : get_parent_terms
|
|
209 Usage : get_parent_terms(TermI term, TermI[] predicate_terms): TermI[]
|
|
210 Function: Retrieves all parent terms of a given term, that satisfy a
|
|
211 relationship among those that are specified in the second
|
|
212 argument or undef otherwise. get_parent_terms is a special
|
|
213 case of get_ancestor_terms, limiting the search to the
|
|
214 direct ancestors.
|
|
215
|
|
216 Example :
|
|
217 Returns : Array of TermI objects.
|
|
218 Args : First argument is the term of interest, second is the list
|
|
219 of relationship type terms.
|
|
220
|
|
221
|
|
222 =cut
|
|
223
|
|
224 sub get_parent_terms{
|
|
225 shift->throw_not_implemented();
|
|
226 }
|
|
227
|
|
228 =head2 get_ancestor_terms
|
|
229
|
|
230 Title : get_ancestor_terms
|
|
231 Usage : get_ancestor_terms(TermI term, TermI[] predicate_terms): TermI[]
|
|
232 Function: Retrieves all ancestor terms of a given term, that satisfy
|
|
233 a relationship among those that are specified in the second
|
|
234 argument or undef otherwise.
|
|
235
|
|
236 Example :
|
|
237 Returns : Array of TermI objects.
|
|
238 Args : First argument is the term of interest, second is the list
|
|
239 of relationship type terms.
|
|
240
|
|
241
|
|
242 =cut
|
|
243
|
|
244 sub get_ancestor_terms{
|
|
245 shift->throw_not_implemented();
|
|
246 }
|
|
247
|
|
248 =head2 get_leaf_terms
|
|
249
|
|
250 Title : get_leaf_terms
|
|
251 Usage : get_leaf_terms(): TermI[]
|
|
252 Function: Retrieves all leaf terms from the ontology. Leaf term is a
|
|
253 term w/o descendants.
|
|
254
|
|
255 Example : @leaf_terms = $obj->get_leaf_terms()
|
|
256 Returns : Array of TermI objects.
|
|
257 Args :
|
|
258
|
|
259
|
|
260 =cut
|
|
261
|
|
262 sub get_leaf_terms{
|
|
263 shift->throw_not_implemented();
|
|
264 }
|
|
265
|
|
266 =head2 get_root_terms
|
|
267
|
|
268 Title : get_root_terms
|
|
269 Usage : get_root_terms(): TermI[]
|
|
270 Function: Retrieves all root terms from the ontology. Root term is a
|
|
271 term w/o ancestors.
|
|
272
|
|
273 Example : @root_terms = $obj->get_root_terms()
|
|
274 Returns : Array of TermI objects.
|
|
275 Args :
|
|
276
|
|
277
|
|
278 =cut
|
|
279
|
|
280 sub get_root_terms{
|
|
281 shift->throw_not_implemented();
|
|
282 }
|
|
283
|
|
284 =head1 Factory for relationships and terms
|
|
285
|
|
286 =cut
|
|
287
|
|
288 =head2 relationship_factory
|
|
289
|
|
290 Title : relationship_factory
|
|
291 Usage : $fact = $obj->relationship_factory()
|
|
292 Function: Get (and set, if the implementation supports it) the object
|
|
293 factory to be used when relationship objects are created by
|
|
294 the implementation on-the-fly.
|
|
295
|
|
296 Example :
|
|
297 Returns : value of relationship_factory (a Bio::Factory::ObjectFactory
|
|
298 compliant object)
|
|
299 Args :
|
|
300
|
|
301
|
|
302 =cut
|
|
303
|
|
304 sub relationship_factory{
|
|
305 return shift->throw_not_implemented();
|
|
306 }
|
|
307
|
|
308 =head2 term_factory
|
|
309
|
|
310 Title : term_factory
|
|
311 Usage : $fact = $obj->term_factory()
|
|
312 Function: Get (and set, if the implementation supports it) the object
|
|
313 factory to be used when term objects are created by
|
|
314 the implementation on-the-fly.
|
|
315
|
|
316 Example :
|
|
317 Returns : value of term_factory (a Bio::Factory::ObjectFactory
|
|
318 compliant object)
|
|
319 Args :
|
|
320
|
|
321
|
|
322 =cut
|
|
323
|
|
324 sub term_factory{
|
|
325 return shift->throw_not_implemented();
|
|
326 }
|
|
327
|
|
328 =head1 Decorator Methods
|
|
329
|
|
330 These methods come with a default implementation that uses the
|
|
331 abstract methods defined for this interface. This may not be very
|
|
332 efficient, and hence implementors are encouraged to override these
|
|
333 methods if they can provide more efficient implementations.
|
|
334
|
|
335 =cut
|
|
336
|
|
337 =head2 get_all_terms
|
|
338
|
|
339 Title : get_all_terms
|
|
340 Usage : get_all_terms: TermI[]
|
|
341 Function: Retrieves all terms from the ontology.
|
|
342
|
|
343 This is more a decorator method. We provide a default
|
|
344 implementation here that loops over all root terms and gets
|
|
345 all descendants for each root term. The overall union of
|
|
346 terms is then made unique by name and ontology.
|
|
347
|
|
348 We do not mandate an order here in which the terms are
|
|
349 returned. In fact, the default implementation will return
|
|
350 them in unpredictable order.
|
|
351
|
|
352 Engine implementations that can provide a more efficient
|
|
353 method for obtaining all terms should definitely override
|
|
354 this.
|
|
355
|
|
356 Example : @terms = $obj->get_all_terms()
|
|
357 Returns : Array of TermI objects.
|
|
358 Args :
|
|
359
|
|
360
|
|
361 =cut
|
|
362
|
|
363 sub get_all_terms{
|
|
364 my $self = shift;
|
|
365 # get all root nodes
|
|
366 my @roots = $self->get_root_terms();
|
|
367 # accumulate all descendants for each root term
|
|
368 my @terms = map { $self->get_descendant_terms($_); } @roots;
|
|
369 # add on the root terms themselves
|
|
370 push(@terms, @roots);
|
|
371 # make unique by name and ontology
|
|
372 my %name_map = map { ($_->name."@".$_->ontology->name, $_); } @terms;
|
|
373 # done
|
|
374 return values %name_map;
|
|
375 }
|
|
376
|
|
377 =head2 find_terms
|
|
378
|
|
379 Title : find_terms
|
|
380 Usage : ($term) = $oe->find_terms(-identifier => "SO:0000263");
|
|
381 Function: Find term instances matching queries for their attributes.
|
|
382
|
|
383 An implementation may not support querying for arbitrary
|
|
384 attributes, but can generally be expected to accept
|
|
385 -identifier and -name as queries. If both are provided,
|
|
386 they are implicitly intersected.
|
|
387
|
|
388 Example :
|
|
389 Returns : an array of zero or more Bio::Ontology::TermI objects
|
|
390 Args : Named parameters. The following parameters should be recognized
|
|
391 by any implementation:
|
|
392
|
|
393 -identifier query by the given identifier
|
|
394 -name query by the given name
|
|
395
|
|
396
|
|
397 =cut
|
|
398
|
|
399 sub find_terms{
|
|
400 my $self = shift;
|
|
401 my %params = @_;
|
|
402 @params{ map { lc $_; } keys %params } = values %params; # lowercase keys
|
|
403
|
|
404 my @terms = grep {
|
|
405 my $ok = exists($params{-identifier}) ?
|
|
406 $_->identifier() eq $params{-identifier} : 1;
|
|
407 $ok && ((! exists($params{-name})) ||
|
|
408 ($_->name() eq $params{-name}));
|
|
409 } $self->get_all_terms();
|
|
410 return @terms;
|
|
411 }
|
|
412
|
|
413 1;
|