ols 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ coverage/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ols.gemspec
4
+ gemspec
data/History.txt ADDED
@@ -0,0 +1,6 @@
1
+ === 0.0.1 2011-04-15
2
+
3
+ * Initial release:
4
+ * Basic wrapper around OLS database
5
+ * Builds tree objects automagically
6
+ * User configurable connection details
data/README.rdoc ADDED
@@ -0,0 +1,117 @@
1
+ = OLS
2
+
3
+ http://github.com/dazoakley/ols
4
+
5
+ OLS provides a simple interface to the EBI's Ontology Lookup Service (http://www.ebi.ac.uk/ontology-lookup/).
6
+ It provides an easy lookup of ontology terms and automagically builds up ontology trees using RubyTree
7
+ (http://rubytree.rubyforge.org/) as a base library.
8
+
9
+ <b>PLEASE NOTE</b>: The current version of this gem requires a local install of the OLS database running on MySQL.
10
+ Please see http://www.ebi.ac.uk/ontology-lookup/databaseExport.do I will update the code in the future
11
+ to run off the soap service.
12
+
13
+ == Install
14
+
15
+ gem install ols
16
+
17
+ == Usage
18
+
19
+ Include the module in your code:
20
+
21
+ require 'rubygems'
22
+ require 'ols'
23
+
24
+ Then, to lookup an ontology term:
25
+
26
+ ont = OLS::OntologyTerm.new('EMAP:3018')
27
+
28
+ This will create a simple tree object for the EMAP term EMAP:3018
29
+
30
+ ont.name # => "EMAP:3018"
31
+ ont.term # => "EMAP:3018"
32
+
33
+ ont.content # => "TS18,nose"
34
+ ont.term_name # => "TS18,nose"
35
+
36
+ Find out about your ontology term
37
+
38
+ ont.is_root? # => false
39
+ ont.is_leaf? # => false
40
+
41
+ <b>NOTE</b>: OntologyTerm's are lazily loaded, so upon initial build the OntologyTerm is just a single node in a
42
+ tree - no parents, no children. See here (note the "Total Nodes Loaded" count):
43
+
44
+ ont.to_s # => "Term: EMAP:3018 Term Name: TS18,nose Root Term?: false Leaf Node?: false Total Nodes Loaded: 1"
45
+
46
+ The tree for the term is built up (parents) and down (children) as it is requested:
47
+
48
+ ont.parentage # => Array of all parent terms (these will be loaded into the tree now)
49
+ ont.children # => Array of all direct child terms (these will also be loaded into the tree now)
50
+ ont.to_s # => "Term: EMAP:3018 Term Name: TS18,nose Root Term?: false Leaf Node?: false Total Nodes Loaded: 4"
51
+
52
+ Alternatively, if you want to force load the tree:
53
+
54
+ ont.buld_tree # => Will load both parents and children into the tree
55
+
56
+ Find out more about your tree:
57
+
58
+ ont.root # => Gives you the root node - in this case: "EMAP:0"
59
+ ont.all_child_terms # => An array of all child ontology terms
60
+ ont.all_child_name # => An array of all child ontology term names
61
+
62
+ For more information on general usage, take a look in the test suite. Also, OLS::OntologyTerm is a child object of
63
+ Tree::TreeNode (from the rubytree gem - http://rubytree.rubyforge.org/) and as such inherits all of its methods.
64
+
65
+ == Database Connection Details
66
+
67
+ The default database connection details are:
68
+
69
+ {
70
+ :database => 'ols',
71
+ :host => '127.0.0.1',
72
+ :port => 3306,
73
+ :user => 'ols',
74
+ :password => 'ols'
75
+ }
76
+
77
+ If your local copy of the OLS database requires different details, simply do the following once in your code
78
+ (substituting in your connection details) before any calls to OLS::OntologyTerm are made:
79
+
80
+ OLS.db_connection_details = {
81
+ :database => 'my_ols',
82
+ :host => 'ols.example.com',
83
+ :port => 3307,
84
+ :user => 'user1',
85
+ :password => 'pass1'
86
+ }
87
+
88
+ == Meta
89
+
90
+ Written by Darren Oakley (daz dot oakley at gmail dot com)
91
+
92
+ http://github.com/dazoakley/ols
93
+
94
+ == License
95
+
96
+ (The MIT License)
97
+
98
+ Copyright (c) 2011 Darren Oakley
99
+
100
+ Permission is hereby granted, free of charge, to any person obtaining
101
+ a copy of this software and associated documentation files (the
102
+ 'Software'), to deal in the Software without restriction, including
103
+ without limitation the rights to use, copy, modify, merge, publish,
104
+ distribute, sublicense, and/or sell copies of the Software, and to
105
+ permit persons to whom the Software is furnished to do so, subject to
106
+ the following conditions:
107
+
108
+ The above copyright notice and this permission notice shall be
109
+ included in all copies or substantial portions of the Software.
110
+
111
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
112
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
113
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
114
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
115
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
116
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
117
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'shoulda'
5
+ require 'rake/testtask'
6
+
7
+ desc 'Run the test suite under /test'
8
+ Rake::TestTask.new do |t|
9
+ t.libs << 'test'
10
+ t.test_files = FileList['test/test*.rb']
11
+ t.verbose = true
12
+ end
data/lib/ols.rb ADDED
@@ -0,0 +1,422 @@
1
+
2
+ require 'rubygems'
3
+ require 'tree'
4
+ require 'sequel'
5
+ require 'mysql2'
6
+ require 'json'
7
+
8
+ # Simple wrapper for interacting with the OLS (Ontology Lookup Service - http://www.ebi.ac.uk/ontology-lookup/)
9
+ # database (created and managed by the EBI). Handles interaction with the service and automagically turns
10
+ # the retieved ontology terms into usable tree stuctures.
11
+ #
12
+ # @author Darren Oakley
13
+ module OLS
14
+
15
+ class << self
16
+ attr_accessor :db_connection_details
17
+
18
+ def ols_db
19
+ @ols_db = connect_to_db() if @ols_db.nil?
20
+ @ols_db
21
+ end
22
+
23
+ private
24
+
25
+ def get_db_connection_details
26
+ defaults = {
27
+ :database => 'ols',
28
+ :host => '127.0.0.1',
29
+ :port => 3306,
30
+ :user => 'ols',
31
+ :password => 'ols'
32
+ }
33
+
34
+ if !OLS.db_connection_details.nil? and OLS.db_connection_details.is_a? Hash
35
+ defaults.merge!(OLS.db_connection_details)
36
+ end
37
+
38
+ defaults
39
+ end
40
+
41
+ def connect_to_db
42
+ params = { :adapter => 'mysql2', :encoding => 'utf8' }.merge(get_db_connection_details)
43
+ Sequel.connect(params)
44
+ end
45
+ end
46
+
47
+ # Error class for when we can't find a given ontology term.
48
+ class OntologyTermNotFoundError < StandardError; end
49
+
50
+ # Class representing an ontology term as part of a tree structure. Uses the Tree::TreeNode (rubytree)
51
+ # gem as a base class.
52
+ class OntologyTerm < Tree::TreeNode
53
+ attr_accessor :already_fetched_parents, :already_fetched_children
54
+
55
+ attr_accessor :root_term, :leaf_node
56
+ attr_writer :all_child_terms, :all_child_names
57
+ protected :root_term, :leaf_node
58
+
59
+ # @param [String] name The ontology term (id) i.e. GO:00032
60
+ # @param [String] content The ontology term name/description - optional this will be looked up in the OLS database
61
+ def initialize( name, content=nil )
62
+ super
63
+
64
+ @already_fetched_parents = false
65
+ @already_fetched_children = false
66
+ @root_term = false
67
+ @leaf_node = false
68
+
69
+ @all_child_terms = nil
70
+ @all_child_names = nil
71
+
72
+ get_term_details if @content.nil? or @content.empty?
73
+ end
74
+
75
+ # Override to ensure compatibility with Tree::TreeNode.
76
+ #
77
+ # @return [String] The ontology term (id) i.e. GO00032
78
+ def term
79
+ self.name
80
+ end
81
+
82
+ # Override to ensure compatibility with Tree::TreeNode.
83
+ #
84
+ # @return [String] The ontology term name/description
85
+ def term_name
86
+ self.content
87
+ end
88
+
89
+ # Returns +true+ if the receiver is a root node. Note that
90
+ # orphaned children will also be reported as root nodes.
91
+ #
92
+ # @return [Boolean] +true+ if this is a root node.
93
+ def is_root?
94
+ @root_term
95
+ end
96
+
97
+ # Returns +true+ if the receiver node is a 'leaf' - i.e., one without
98
+ # any children.
99
+ #
100
+ # @return [Boolean] +true+ if this is a leaf node.
101
+ def is_leaf?
102
+ @leaf_node
103
+ end
104
+
105
+ # Returns string representation of the receiver node.
106
+ # This method is primarily meant for debugging purposes.
107
+ #
108
+ # @return [String] A string representation of the node.
109
+ def to_s
110
+ "Term: #{@name}" +
111
+ " Term Name: " + (@content || "<Empty>") +
112
+ " Root Term?: #{is_root?}" +
113
+ " Leaf Node?: #{is_leaf?} " +
114
+ " Total Nodes Loaded: #{size()}"
115
+ end
116
+
117
+ # Returns an array of parent OntologyTerm objects.
118
+ #
119
+ # @return [Array] An array of parent OntologyTerm objects
120
+ def parentage
121
+ get_parents
122
+ super
123
+ end
124
+
125
+ # Returns the children of this term as a tree. Will include the current term
126
+ # as the 'root' of the tree.
127
+ #
128
+ # @return [OntologyTerm] The children of this term as a tree. Will include the current term as the 'root' of the tree.
129
+ def child_tree
130
+ build_tree
131
+ child_tree = self.clone
132
+ child_tree.remove_from_parent!
133
+ child_tree
134
+ end
135
+
136
+ # Returns an array of the direct children (OntologyTerm objects) of this term.
137
+ #
138
+ # @return [Array] An array of the direct children (OntologyTerm objects) of this term.
139
+ def children
140
+ get_children
141
+ super
142
+ end
143
+
144
+ # Returns a flat array containing all the possible child terms
145
+ # for this given ontology term.
146
+ #
147
+ # @return [Array] An array of all possible child terms (Strings) for this given ontology term
148
+ def all_child_terms
149
+ get_all_child_lists
150
+ return @all_child_terms
151
+ end
152
+
153
+ # Returns a flat array containing all the possible child term
154
+ # names for this given ontology term.
155
+ #
156
+ # @return [Array] A flat array containing all the possible child term names (Strings) for this given ontology term
157
+ def all_child_names
158
+ get_all_child_lists
159
+ return @all_child_names
160
+ end
161
+
162
+ # Function to force the OntologyTerm object to flesh out it's structure
163
+ # from the OLS database. By default OntologyTerm objects are lazy and will
164
+ # only retieve child data one level below themselves, so this is used to
165
+ # recursivley flesh out a full tree.
166
+ def build_tree
167
+ get_parents
168
+ get_children( self, true )
169
+ end
170
+
171
+ # Creates a JSON representation of this node including all it's children. This requires the JSON gem to be
172
+ # available, or else the operation fails with a warning message.
173
+ #
174
+ # @return The JSON representation of this subtree.
175
+ #
176
+ # @see {OntologyTerm#json_create}
177
+ def to_json(*a)
178
+ json_hash = {
179
+ "name" => name,
180
+ "content" => content,
181
+ "root_term" => @root_term,
182
+ "leaf_node" => @leaf_node,
183
+ "all_child_terms" => @all_child_terms,
184
+ "all_child_names" => @all_child_names,
185
+ JSON.create_id => self.class.name
186
+ }
187
+
188
+ if has_children?
189
+ json_hash["children"] = children
190
+ end
191
+
192
+ return JSON.generate( json_hash, :max_nesting => false )
193
+ end
194
+
195
+ # Class level function to build an OntologyTerm object from a serialized JSON hash
196
+ #
197
+ # @example
198
+ # emap = JSON.parse( File.read("emap.json"), :max_nesting => false )
199
+ #
200
+ # @param [Hash] json_hash The parsed JSON hash to de-serialize
201
+ # @return [OntologyTerm] The de-serialized object
202
+ def self.json_create(json_hash)
203
+ node = new(json_hash["name"], json_hash["content"])
204
+ node.already_fetched_children = true if json_hash["children"]
205
+
206
+ node.root_term = true if json_hash["root_term"]
207
+ node.leaf_node = true if json_hash["leaf_node"]
208
+ node.all_child_terms = json_hash["all_child_terms"]
209
+ node.all_child_names = json_hash["all_child_names"]
210
+
211
+ json_hash["children"].each do |child|
212
+ child.already_fetched_parents = true
213
+ child.already_fetched_children = true if child.has_children?
214
+ node << child
215
+ end if json_hash["children"]
216
+
217
+ return node
218
+ end
219
+
220
+ # Method to set the parent node for the receiver node.
221
+ # This method should *NOT* be invoked by client code.
222
+ #
223
+ # @param [OntologyTerm] parent The parent node.
224
+ # @return [OntologyTerm] The parent node.
225
+ def parent=(parent) # :nodoc:
226
+ @parent = parent
227
+ end
228
+
229
+ # Recursive function to query the OLS database and collect all of
230
+ # the parent objects and insert them into @parents in the correct
231
+ # order.
232
+ def get_parents( node=self )
233
+ unless @already_fetched_parents
234
+ sql = <<-SQL
235
+ select
236
+ subject_term.identifier as child_identifier,
237
+ subject_term.term_name as child_term,
238
+ predicate_term.term_name as relation,
239
+ object_term.identifier as parent_identifier,
240
+ object_term.term_name as parent_term,
241
+ object_term.is_root_term as parent_is_root
242
+ from
243
+ term_relationship tr
244
+ join term as subject_term on tr.subject_term_pk = subject_term.term_pk
245
+ join term as predicate_term on tr.predicate_term_pk = predicate_term.term_pk
246
+ join term as object_term on tr.object_term_pk = object_term.term_pk
247
+ where
248
+ predicate_term.term_name in ('part_of','is_a','develops_from')
249
+ and subject_term.identifier = ?
250
+ SQL
251
+
252
+ OLS.ols_db[ sql, node.term ].each do |row|
253
+ parent = OntologyTerm.new( row[:parent_identifier], row[:parent_term] )
254
+ parent.root_term = true if row[:parent_is_root].to_i == 1
255
+ parent << node
256
+ get_parents( parent )
257
+ end
258
+
259
+ @already_fetched_parents = true
260
+ end
261
+ end
262
+
263
+ # Recursive function to query the OLS database and collect all of
264
+ # the child objects and build up a tree of OntologyTerm's.
265
+ def get_children( node=self, recursively=false )
266
+ unless @already_fetched_children or node.has_children?
267
+ sql = <<-SQL
268
+ select
269
+ subject_term.identifier as child_identifier,
270
+ subject_term.term_name as child_term,
271
+ subject_term.is_leaf as child_is_leaf,
272
+ predicate_term.term_name as relation,
273
+ object_term.identifier as parent_identifier,
274
+ object_term.term_name as parent_term
275
+ from
276
+ term_relationship tr
277
+ join term as subject_term on tr.subject_term_pk = subject_term.term_pk
278
+ join term as predicate_term on tr.predicate_term_pk = predicate_term.term_pk
279
+ join term as object_term on tr.object_term_pk = object_term.term_pk
280
+ where
281
+ predicate_term.term_name in ('part_of','is_a','develops_from')
282
+ and object_term.identifier = ?
283
+ SQL
284
+
285
+ OLS.ols_db[sql,node.term].each do |row|
286
+ child = OntologyTerm.new( row[:child_identifier], row[:child_term] )
287
+ child.leaf_node = true if row[:child_is_leaf].to_i == 1
288
+ child.get_children( child, true ) if recursively and !child.is_leaf?
289
+ node << child
290
+ end
291
+
292
+ @already_fetched_children = true
293
+ end
294
+ end
295
+
296
+ # Returns a copy of the receiver node, with its parent and children links removed.
297
+ # The original node remains attached to its tree.
298
+ #
299
+ # @return [OntologyTerm] A copy of the receiver node.
300
+ def detached_copy
301
+ copy = OLS::OntologyTerm.new(@name, @content ? @content.clone : nil)
302
+ copy.root_term = @root_term
303
+ copy.leaf_node = @leaf_node
304
+ return copy
305
+ end
306
+
307
+ # Function that merges one OntologyTerm tree into another.
308
+ #
309
+ # @param [OntologyTerm] tree The tree that is to be merged into self
310
+ # @return [OntologyTerm] The merged tree
311
+ def merge( tree )
312
+ unless tree.is_a?(OLS::OntologyTerm)
313
+ raise TypeError, "You can only merge in another OntologyTerm tree!"
314
+ end
315
+
316
+ unless self.root.name == tree.root.name
317
+ raise ArgumentError, "Unable to merge trees as they do not share the same root!"
318
+ end
319
+
320
+ new_tree = merge_subtrees( self.root, tree.root )
321
+ end
322
+
323
+ private
324
+
325
+ # Utility function to recursivley merge two subtrees
326
+ #
327
+ # @param [OntologyTerm] tree1 The target tree to merge into
328
+ # @param [OntologyTerm] tree2 The donor tree (that will be merged into target)
329
+ def merge_subtrees( tree1, tree2 )
330
+ names1 = tree1.has_children? ? tree1.children.map { |child| child.name } : []
331
+ names2 = tree2.has_children? ? tree2.children.map { |child| child.name } : []
332
+
333
+ names_to_merge = names2 - names1
334
+ names_to_merge.each do |name|
335
+ tree1 << tree2[name].detached_subtree_copy
336
+ end
337
+
338
+ tree1.children.each do |child|
339
+ unless tree2[child.name].nil?
340
+ merge_subtrees( child, tree2[child.name] )
341
+ end
342
+ end
343
+
344
+ return tree1
345
+ end
346
+
347
+ # Helper function to query the OLS database and grab the full
348
+ # details of the ontology term.
349
+ def get_term_details
350
+ # This query ensures we look at the most recent fully loaded ontologies
351
+ sql = <<-SQL
352
+ select term.*
353
+ from term
354
+ join ontology on ontology.ontology_id = term.ontology_id
355
+ where term.identifier = ?
356
+ order by ontology.fully_loaded desc, ontology.load_date asc
357
+ SQL
358
+
359
+ term_set = OLS.ols_db[ sql, @name ].all()
360
+
361
+ if term_set.size == 0
362
+ get_term_from_synonym
363
+ else
364
+ subject = term_set.first
365
+ @content = subject[:term_name]
366
+ @term_pk = subject[:term_pk]
367
+ @ontology_id = subject[:ontology_id]
368
+ @root_term = true if subject[:is_root_term].to_i == 1
369
+ @leaf_node = true if subject[:is_leaf].to_i == 1
370
+ end
371
+ end
372
+
373
+ # Helper function to try to find an ontology term via a synonym.
374
+ def get_term_from_synonym
375
+ sql = <<-SQL
376
+ select term.*
377
+ from term
378
+ join ontology on ontology.ontology_id = term.ontology_id
379
+ join term_synonym on term.term_pk = term_synonym.term_pk
380
+ where term_synonym.synonym_value = ?
381
+ order by ontology.fully_loaded desc, ontology.load_date asc
382
+ SQL
383
+
384
+ term_set = OLS.ols_db[ sql, @name ].all()
385
+
386
+ if term_set.size == 0
387
+ raise OLS::OntologyTermNotFoundError, "Unable to find the term '#{@name}' in the OLS database."
388
+ end
389
+
390
+ subject = term_set.first
391
+ @name = subject[:identifier]
392
+ @content = subject[:term_name]
393
+ @term_pk = subject[:term_pk]
394
+ @ontology_id = subject[:ontology_id]
395
+ @root_term = true if subject[:is_root_term].to_i == 1
396
+ @leaf_node = true if subject[:is_leaf].to_i == 1
397
+ end
398
+
399
+ # Helper function to produce the flat lists of all the child
400
+ # terms and names.
401
+ def get_all_child_lists
402
+ get_children
403
+
404
+ if @all_child_terms.nil? and @all_child_names.nil?
405
+ @all_child_terms = []
406
+ @all_child_names = []
407
+
408
+ self.children.each do |child|
409
+ @all_child_terms.push( child.term )
410
+ @all_child_terms.push( child.all_child_terms )
411
+ @all_child_names.push( child.term_name )
412
+ @all_child_names.push( child.all_child_names )
413
+ end
414
+
415
+ @all_child_terms = @all_child_terms.flatten.uniq
416
+ @all_child_names = @all_child_names.flatten.uniq
417
+ end
418
+ end
419
+
420
+ end
421
+
422
+ end
@@ -0,0 +1,3 @@
1
+ module OLS
2
+ VERSION = "0.0.1"
3
+ end
data/ols.gemspec ADDED
@@ -0,0 +1,39 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ols/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ols"
7
+ s.version = OLS::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Darren Oakley"]
10
+ s.email = ["daz.oakley@gmail.com"]
11
+ s.homepage = "https://github.com/dazoakley/ols"
12
+ s.summary = %q{A simple wrapper around a local copy of the OLS database}
13
+ s.description = %q{
14
+ OLS provides a simple interface to the EBI's Ontology Lookup Service (http://www.ebi.ac.uk/ontology-lookup/).
15
+ It provides an easy lookup of ontology terms and automagically builds up ontology trees using RubyTree
16
+ (http://rubytree.rubyforge.org/) as a base library.
17
+
18
+ PLEASE NOTE: The current version of this gem requires a local install of the OLS database running on MySQL.
19
+ Please see http://www.ebi.ac.uk/ontology-lookup/databaseExport.do I will update the code in the future
20
+ to run off the soap service.
21
+ }
22
+
23
+ s.rubyforge_project = "ols"
24
+
25
+ s.files = `git ls-files`.split("\n")
26
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
27
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
28
+ s.require_paths = ["lib"]
29
+
30
+ s.add_dependency "rubytree"
31
+ s.add_dependency "sequel"
32
+ s.add_dependency "mysql2"
33
+ s.add_dependency "json"
34
+
35
+ s.add_development_dependency "rake"
36
+ s.add_development_dependency "shoulda"
37
+ s.add_development_dependency "simplecov"
38
+ s.add_development_dependency "simplecov-rcov"
39
+ end
@@ -0,0 +1,34 @@
1
+ # Add the lib directory to the search path
2
+ $:.unshift( "#{File.expand_path(File.dirname(__FILE__))}/../lib" )
3
+
4
+ require 'rubygems'
5
+
6
+ # Set-up SimpleCov (code coverage tool for Ruby 1.9)
7
+ if /^1.9/ === RUBY_VERSION
8
+ begin
9
+ require 'simplecov'
10
+ require 'simplecov-rcov'
11
+
12
+ class SimpleCov::Formatter::MergedFormatter
13
+ def format(result)
14
+ SimpleCov::Formatter::HTMLFormatter.new.format(result)
15
+ SimpleCov::Formatter::RcovFormatter.new.format(result)
16
+ end
17
+ end
18
+
19
+ SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
20
+ SimpleCov.start
21
+ rescue LoadError
22
+ puts "[ERROR] Unable to load 'simplecov' - please run 'bundle install'"
23
+ end
24
+ end
25
+
26
+ require 'shoulda'
27
+ require 'ols'
28
+
29
+ OLS.db_connection_details = {
30
+ :port => 13306,
31
+ :database => 'htgt_ols',
32
+ :user => 'htgt',
33
+ :password => 'htgt'
34
+ }
data/test/test_ols.rb ADDED
@@ -0,0 +1,124 @@
1
+ require 'test_helper'
2
+
3
+ class OLSTest < Test::Unit::TestCase
4
+ include OLS
5
+
6
+ context "An OntologyTerm object" do
7
+ setup do
8
+ @emap_id = "EMAP:3018"
9
+ @emap_name = "TS18,nose"
10
+ @ont = OntologyTerm.new(@emap_id)
11
+ end
12
+
13
+ should "have basic attributes" do
14
+ assert_equal( @emap_id, @ont.name, "OntologyTerm.name does not equal '#{@emap_id}'." )
15
+ assert_equal( @emap_id, @ont.term, "OntologyTerm.term does not equal '#{@emap_id}'." )
16
+
17
+ assert_equal( @emap_name, @ont.content, "OntologyTerm.content does not equal '#{@emap_name}'." )
18
+ assert_equal( @emap_name, @ont.term_name, "OntologyTerm.term_name does not equal '#{@emap_name}'." )
19
+
20
+ assert_equal( false, @ont.term_name.nil?, "The OntologyTerm.term_name is nil." )
21
+ assert_equal( false, @ont.content.nil?, "The OntologyTerm.term_name is nil." )
22
+ end
23
+
24
+ should "raise appropriate errors" do
25
+ assert_raise(OntologyTermNotFoundError) { OntologyTerm.new("FLIBBLE:5") }
26
+ end
27
+
28
+ should "be able to represent itself as a String" do
29
+ string = @ont.to_s
30
+
31
+ assert( string.include?('Term Name'), "OntologyTerm.to_s does not include 'Term Name'." )
32
+ assert( string.include?(@ont.content), "OntologyTerm.to_s does not include '@content'." )
33
+ assert( string.include?('Root Term?'), "OntologyTerm.to_s does not include 'Root Term?'." )
34
+ assert( string.include?('Leaf Node?'), "OntologyTerm.to_s does not include 'Leaf Node?'." )
35
+ end
36
+
37
+ should "respond correctly to the .parentage method" do
38
+ assert( @ont.parentage.is_a?(Array), "OntologyTerm.parentage is not an Array when we have parents." )
39
+ assert( @ont.parentage[0].is_a?(OntologyTerm), "OntologyTerm.parentage[0] does not return an OntologyTerm tree." )
40
+ assert_equal( 4, @ont.parentage.size, "OntologyTerm.parentage is not returning the correct number of entries (we expect 4 for #{@emap_id})." )
41
+ end
42
+
43
+ should "be able to generate its child tree" do
44
+ assert( @ont.child_tree.is_a?(OntologyTerm), "OntologyTerm.child_tree does not return an OntologyTerm tree." )
45
+ assert_equal( @ont.term, @ont.child_tree.term, "OntologyTerm.child_tree.root is equal to self." )
46
+ end
47
+
48
+ should "respond correctly to the .children method" do
49
+ assert( @ont.children.is_a?(Array), "OntologyTerm.children is not an Array when we have children." )
50
+ assert( @ont.children[0].is_a?(OntologyTerm), "OntologyTerm.children[0] does not return an OntologyTerm tree." )
51
+ assert_equal( 3, @ont.children.size, "OntologyTerm.children is not returning the correct number of entries (we expect 3 direct children for #{@emap_id})." )
52
+ end
53
+
54
+ should "be able to generate a flat list of all child terms/names" do
55
+ assert( @ont.all_child_terms.is_a?(Array), "OntologyTerm.all_child_terms is not an Array." )
56
+ assert( @ont.all_child_terms[0].is_a?(String), "OntologyTerm.all_child_terms[0] is not an String." )
57
+ assert_equal( 14, @ont.all_child_terms.size, "OntologyTerm.all_child_terms is not returning the correct number of entries (we expect 14 children for #{@emap_id})." )
58
+
59
+ assert( @ont.all_child_names.is_a?(Array), "OntologyTerm.all_child_names is not an Array." )
60
+ assert( @ont.all_child_names[0].is_a?(String), "OntologyTerm.all_child_names[0] is not an String." )
61
+ assert_equal( 14, @ont.all_child_names.size, "OntologyTerm.all_child_names is not returning the correct number of entries (we expect 14 children for #{@emap_id})." )
62
+
63
+ assert_equal( @ont.all_child_terms.size, @ont.all_child_names.size, "OntologyTerm.all_child_terms and OntologyTerm.all_child_names do not produce an array of the same size." )
64
+ end
65
+
66
+ should "be able to locate ontology terms via synonyms" do
67
+ go_id = 'GO:0007242'
68
+ ont = OntologyTerm.new(go_id)
69
+
70
+ assert_equal( 'GO:0023034', ont.term, "A synonym search for GO:0007242 has not found GO:0023034." )
71
+ assert_equal( 'intracellular signaling pathway', ont.term_name, "A synonym search for GO:0007242 has not found 'intracellular signaling pathway'." )
72
+ end
73
+
74
+ should "be able to serialize/deserialize itself as a JSON string" do
75
+ @ont.build_tree()
76
+
77
+ json_string = nil
78
+ assert_nothing_raised(Exception) { json_string = @ont.to_json }
79
+ assert( json_string.is_a?(String) )
80
+
81
+ duplicate = nil
82
+ assert_nothing_raised(Exception) { duplicate = JSON.parse(json_string) }
83
+ assert( duplicate.is_a?(OntologyTerm) )
84
+ assert_equal( @ont.term, duplicate.term )
85
+ assert_equal( @ont.term_name, duplicate.term_name )
86
+ assert_equal( @ont.is_root?, duplicate.is_root? )
87
+ assert_equal( @ont.is_leaf?, duplicate.is_leaf? )
88
+ end
89
+
90
+ should "be able to produce a detached copy of itself" do
91
+ @ont.build_tree()
92
+ duplicate = @ont.detached_copy
93
+
94
+ assert_equal( @ont.term, duplicate.term )
95
+ assert_equal( @ont.term_name, duplicate.term_name )
96
+ assert_equal( @ont.is_root?, duplicate.is_root? )
97
+ assert_equal( @ont.is_leaf?, duplicate.is_leaf? )
98
+
99
+ assert_equal( false, duplicate.send(:already_fetched_parents) )
100
+ assert_equal( false, duplicate.send(:already_fetched_children) )
101
+ end
102
+
103
+ should "be able to merge two ontology trees" do
104
+ @ont2 = OntologyTerm.new('EMAP:3003')
105
+
106
+ @ont.build_tree
107
+ @ont2.build_tree
108
+
109
+ merged_tree = @ont.merge(@ont2)
110
+
111
+ assert( merged_tree['EMAP:2636']['EMAP:2822']['EMAP:2987'].is_a?(OntologyTerm) )
112
+ assert_equal( 2, merged_tree['EMAP:2636']['EMAP:2822']['EMAP:2987'].children.size )
113
+ assert_equal( 34, merged_tree.size )
114
+
115
+ another_ont = OntologyTerm.new('GO:0023034')
116
+ yet_another_ont = OntologyTerm.new('EMAP:3003')
117
+ another_ont.build_tree
118
+ yet_another_ont.build_tree
119
+
120
+ assert_raise(ArgumentError) { foo = another_ont.merge(yet_another_ont) }
121
+ assert_raise(TypeError) { bar = another_ont.merge('EMAP:3003') }
122
+ end
123
+ end
124
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ols
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - Darren Oakley
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-04-15 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rubytree
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
28
+ name: sequel
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: mysql2
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ prerelease: false
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: json
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ type: :runtime
58
+ prerelease: false
59
+ version_requirements: *id004
60
+ - !ruby/object:Gem::Dependency
61
+ name: rake
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *id005
71
+ - !ruby/object:Gem::Dependency
72
+ name: shoulda
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: "0"
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *id006
82
+ - !ruby/object:Gem::Dependency
83
+ name: simplecov
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: *id007
93
+ - !ruby/object:Gem::Dependency
94
+ name: simplecov-rcov
95
+ requirement: &id008 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: "0"
101
+ type: :development
102
+ prerelease: false
103
+ version_requirements: *id008
104
+ description: "\n OLS provides a simple interface to the EBI's Ontology Lookup Service (http://www.ebi.ac.uk/ontology-lookup/). \n It provides an easy lookup of ontology terms and automagically builds up ontology trees using RubyTree \n (http://rubytree.rubyforge.org/) as a base library.\n\n PLEASE NOTE: The current version of this gem requires a local install of the OLS database running on MySQL. \n Please see http://www.ebi.ac.uk/ontology-lookup/databaseExport.do I will update the code in the future \n to run off the soap service.\n "
105
+ email:
106
+ - daz.oakley@gmail.com
107
+ executables: []
108
+
109
+ extensions: []
110
+
111
+ extra_rdoc_files: []
112
+
113
+ files:
114
+ - .gitignore
115
+ - Gemfile
116
+ - History.txt
117
+ - README.rdoc
118
+ - Rakefile
119
+ - lib/ols.rb
120
+ - lib/ols/version.rb
121
+ - ols.gemspec
122
+ - test/test_helper.rb
123
+ - test/test_ols.rb
124
+ has_rdoc: true
125
+ homepage: https://github.com/dazoakley/ols
126
+ licenses: []
127
+
128
+ post_install_message:
129
+ rdoc_options: []
130
+
131
+ require_paths:
132
+ - lib
133
+ required_ruby_version: !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ hash: -2283321119041692548
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ none: false
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ hash: -2283321119041692548
148
+ segments:
149
+ - 0
150
+ version: "0"
151
+ requirements: []
152
+
153
+ rubyforge_project: ols
154
+ rubygems_version: 1.6.2
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: A simple wrapper around a local copy of the OLS database
158
+ test_files:
159
+ - test/test_helper.rb
160
+ - test/test_ols.rb