ols 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,9 @@
1
+ === 0.3.0 2011-11-08
2
+
3
+ * Addition of new functions to deatch graphs from parents/children.
4
+ * Small code clean and refactor of utility functions.
5
+ * The OLS::Term.size method has been altered to return a count of unique nodes.
6
+
1
7
  === 0.2.1 2011-11-07
2
8
 
3
9
  * Cache bugfix. Removed the use of 'Dir.chdir' as it was firing warnings.
@@ -9,12 +15,13 @@
9
15
  === 0.1.0 2011-11-04
10
16
 
11
17
  * Total rewrite (as a result please note API changes)...
12
- * Switch to using the OLS SOAP service instead of local MySQL instance
13
- * Remove the use of RubyTree as ontologies are Directed Acyclic Graphs (DAGs), not trees
18
+ * Switch to using the OLS SOAP service instead of local MySQL instance.
19
+ * Remove the use of RubyTree as ontologies are Directed Acyclic Graphs (DAGs), not trees.
14
20
 
15
21
  === 0.0.1 2011-04-15
16
22
 
17
23
  * Initial release:
18
- * Basic wrapper around OLS database
19
- * Builds tree objects automagically
20
- * User configurable connection details
24
+ * Basic wrapper around OLS database.
25
+ * Builds tree objects automagically.
26
+ * User configurable connection details.
27
+
@@ -81,10 +81,10 @@ module OLS
81
81
  def add_relationship(parent,child)
82
82
  raise TypeError, "You must pass an OLS::Term object" unless parent.is_a? OLS::Term
83
83
  raise TypeError, "You must pass an OLS::Term object" unless child.is_a? OLS::Term
84
-
84
+
85
85
  add_to_graph(parent) if self.find(parent.term_id).nil?
86
86
  add_to_graph(child) if self.find(child.term_id).nil?
87
-
87
+
88
88
  @graph[parent.term_id][:children].push(child.term_id) unless @graph[parent.term_id][:children].include?(child.term_id)
89
89
  @graph[child.term_id][:parents].push(parent.term_id) unless @graph[child.term_id][:parents].include?(parent.term_id)
90
90
  end
@@ -82,11 +82,11 @@ module OLS
82
82
  "#{@term_id} - #{@term_name}"
83
83
  end
84
84
 
85
- # Returns the size of the full ontology graph.
85
+ # Returns the size of the full ontology graph (unique nodes).
86
86
  #
87
- # @return [Integer] The size of the full ontology graph
87
+ # @return [Integer] The size of the full ontology graph (unique nodes)
88
88
  def size
89
- self.root.all_children.size + 1
89
+ self.root.all_children.uniq.size + 1
90
90
  end
91
91
 
92
92
  # Returns depth of this term in its ontology graph. Depth of a node is defined as:
@@ -351,7 +351,7 @@ module OLS
351
351
  #
352
352
  # @see #focus_graph
353
353
  def focus_graph!
354
- really_focus_graph_around_term(self)
354
+ self.really_focus_graph_around_term!
355
355
  end
356
356
 
357
357
  # Flesh out and/or focus the ontology graph around this term.
@@ -395,36 +395,47 @@ module OLS
395
395
  # @see #focus_graph!
396
396
  def focus_graph
397
397
  copy = self.dup
398
- really_focus_graph_around_term(copy)
398
+ copy.really_focus_graph_around_term!
399
399
  copy
400
400
  end
401
401
 
402
- # Utility function for the #focus_graph and #focus_graph! methods. This does the
403
- # real work of editing the OLS::Graph.
402
+ # Remove the children from this ontology graph.
404
403
  #
405
- # @param [OLS::Term] term The term (and graph) to focus around
406
- def really_focus_graph_around_term(term)
407
- term.all_parents.each { |parent| parent.lock }
408
- term.all_children.each { |child| child.lock }
404
+ # @see #detach_parents
405
+ # @since 0.3.0
406
+ def detach_parents!
407
+ self.really_detach_parents!
408
+ end
409
409
 
410
- focus_terms = [term.term_id] + term.all_parent_ids + term.all_child_ids
411
- graph = term.graph.raw_graph
410
+ # Returns a copy of this ontology term object with the children removed.
411
+ #
412
+ # @return [OLS::Term] A copy of this term with the children removed
413
+ #
414
+ # @see #detach_parents!
415
+ # @since 0.3.0
416
+ def detach_parents
417
+ copy = self.dup
418
+ copy.really_detach_parents!
419
+ copy
420
+ end
412
421
 
413
- graph.delete_if { |key,val| !focus_terms.include?(key) }
414
- graph.each do |key,val|
415
- val[:parents].delete_if { |elm| !focus_terms.include?(elm) }
416
- val[:children].delete_if { |elm| !focus_terms.include?(elm) }
417
- end
422
+ # Removes the parents from this ontology graph.
423
+ #
424
+ # @see #detach_children
425
+ # @since 0.3.0
426
+ def detach_children!
427
+ self.really_detach_children!
418
428
  end
419
- private(:really_focus_graph_around_term)
420
429
 
421
430
  # Returns a copy of this ontology term object with the parents removed.
422
431
  #
423
- # @return [OLS::Term] A copy of this ontology term object with the parents removed
424
- def detached_subgraph_copy
432
+ # @return [OLS::Term] A copy of this term with the parents removed
433
+ #
434
+ # @see #detach_children!
435
+ # @since 0.3.0
436
+ def detach_children
425
437
  copy = self.dup
426
- copy.parents = []
427
- copy.lock_parents
438
+ copy.really_detach_children!
428
439
  copy
429
440
  end
430
441
 
@@ -551,6 +562,12 @@ module OLS
551
562
  @graph[self.term_id][:parents] = parents.map(&:term_id)
552
563
  end
553
564
 
565
+ def children=(children)
566
+ raise ArgumentError, "You must pass an array" unless children.is_a?(Array)
567
+ children.each { |p| raise TypeError, "You must pass an array of OLS::Term objects" unless p.is_a?(OLS::Term) }
568
+ @graph[self.term_id][:children] = children.map(&:term_id)
569
+ end
570
+
554
571
  # Graph access function. Adds a parent relationship (for this term) to the graph.
555
572
  #
556
573
  # @param [OLS::Term] parent The OLS::Term to add as a parent
@@ -576,6 +593,53 @@ module OLS
576
593
  @graph.find(term_id)
577
594
  end
578
595
 
596
+ # Graph utility function. Removes terms from the ontology graph
597
+ # that are not in the list passed to it.
598
+ #
599
+ # @param [Array] ids_to_retain The list of term_ids to keep in the graph
600
+ def flush_graph( ids_to_retain )
601
+ graph = @graph.raw_graph
602
+
603
+ graph.delete_if { |key,val| !ids_to_retain.include?(key) }
604
+ graph.each do |key,val|
605
+ val[:parents].delete_if { |elm| !ids_to_retain.include?(elm) }
606
+ val[:children].delete_if { |elm| !ids_to_retain.include?(elm) }
607
+ end
608
+ end
609
+
610
+ # Utility function for the #focus_graph and #focus_graph! methods. This does the
611
+ # real work of editing the OLS::Graph.
612
+ #
613
+ # @see #focus_graph
614
+ # @see #focus_graph!
615
+ def really_focus_graph_around_term!
616
+ self.all_parents.each { |parent| parent.lock }
617
+ self.all_children.each { |child| child.lock }
618
+ self.flush_graph( [self.term_id] + self.all_parent_ids + self.all_child_ids )
619
+ end
620
+
621
+ # Utility function for #detach_parents and #detach_parents! that
622
+ # actually does the work of removing children.
623
+ #
624
+ # @see #detach_parents
625
+ # @see #detach_parents!
626
+ def really_detach_parents!
627
+ self.children = []
628
+ self.lock_children
629
+ self.flush_graph( [self.term_id] + self.all_parent_ids )
630
+ end
631
+
632
+ # Utility function for #detach_children and #detach_children! that
633
+ # actually does the work of removing parents.
634
+ #
635
+ # @see #detach_children
636
+ # @see #detach_children!
637
+ def really_detach_children!
638
+ self.parents = []
639
+ self.lock_parents
640
+ self.flush_graph( [self.term_id] + self.all_child_ids )
641
+ end
642
+
579
643
  private
580
644
 
581
645
  # Utility function to hit the :get_term_metadata soap endpoint and extract the
@@ -611,7 +675,7 @@ module OLS
611
675
  names_to_merge = names2 - names1
612
676
  names_to_merge.each do |name|
613
677
  # puts "--- MERGING #{name} INTO #{graph1.term_id} ---"
614
- new_child = graph2[name].detached_subgraph_copy
678
+ new_child = graph2[name].detach_children
615
679
 
616
680
  # replace the new_child's graph
617
681
  graph1_graph = graph1.graph
@@ -2,5 +2,5 @@
2
2
 
3
3
  module OLS
4
4
  # OLS::VERSION - The OLS gem version
5
- VERSION = "0.2.1"
5
+ VERSION = "0.3.0"
6
6
  end
@@ -42,8 +42,8 @@ VCR.config do |c|
42
42
 
43
43
  c.stub_with :webmock
44
44
  c.ignore_localhost = true
45
- c.default_cassette_options = {
46
- :record => :new_episodes,
45
+ c.default_cassette_options = {
46
+ :record => :new_episodes,
47
47
  :match_requests_on => [:uri, :method, :body]
48
48
  }
49
49
  end
@@ -240,7 +240,7 @@ class OLSTermTest < Test::Unit::TestCase
240
240
  # cut it back to the origninal focused graph
241
241
  @emap_term.focus_graph!
242
242
  raw_graph = @emap_term.instance_variable_get(:@graph).raw_graph
243
-
243
+
244
244
  assert_equal 19, @emap_term.size
245
245
  assert_equal 19, raw_graph.keys.size
246
246
  assert_equal false, raw_graph.keys.include?('EMAP:3003')
@@ -260,17 +260,85 @@ class OLSTermTest < Test::Unit::TestCase
260
260
 
261
261
  orig_raw_graph = @emap_term.instance_variable_get(:@graph).raw_graph
262
262
  new_raw_graph = new_graph.instance_variable_get(:@graph).raw_graph
263
-
263
+
264
264
  assert_equal 34, @emap_term.size
265
265
  assert_equal 19, new_graph.size
266
-
266
+
267
267
  assert_equal 34, orig_raw_graph.keys.size
268
268
  assert_equal 19, new_raw_graph.keys.size
269
-
269
+
270
270
  assert orig_raw_graph.keys.include?('EMAP:3003')
271
271
  assert_equal false, new_raw_graph.keys.include?('EMAP:3003')
272
272
  end
273
273
 
274
+ should 'be able to "detach" the graph to be able to retain just parents' do
275
+ # We expect the following here...
276
+ #
277
+ # * EMAP:0
278
+ # |---+ EMAP:2636
279
+ # |---+ EMAP:2822
280
+ # |---+ EMAP:2987
281
+ # |---+ EMAP:3018
282
+
283
+ @emap_term.focus_graph!
284
+ @emap_term.detach_parents!
285
+
286
+ assert_equal 'EMAP:3018', @emap_term.term_id
287
+ assert_equal 'EMAP:0', @emap_term.root.term_id
288
+ assert_equal 5, @emap_term.size
289
+ assert_equal 5, @emap_term.instance_variable_get(:@graph).raw_graph.size
290
+
291
+ # Test the copy variant of this function
292
+ @mp_term.focus_graph!
293
+ new_term = @mp_term.detach_parents
294
+
295
+ assert new_term.object_id != @mp_term.object_id
296
+ assert new_term.is_leaf?
297
+ assert_equal 'MP:0000001', new_term.root.term_id
298
+ assert_equal 7, new_term.size
299
+ assert_equal 7, new_term.instance_variable_get(:@graph).raw_graph.size
300
+ assert_equal 102, @mp_term.size
301
+ assert_equal 102, @mp_term.instance_variable_get(:@graph).raw_graph.size
302
+ end
303
+
304
+ should 'be able to "detach" the graph to be able to retain just children' do
305
+ # We expect the following here...
306
+ #
307
+ # |---+ EMAP:3018
308
+ # |---+ EMAP:3022
309
+ # |---+ EMAP:3023
310
+ # |---+ EMAP:3024
311
+ # |---> EMAP:3025
312
+ # |---> EMAP:3026
313
+ # |---+ EMAP:3027
314
+ # |---> EMAP:3029
315
+ # |---> EMAP:3028
316
+ # |---+ EMAP:3030
317
+ # |---> EMAP:3031
318
+ # |---> EMAP:3032
319
+ # |---> EMAP:3019
320
+ # |---+ EMAP:3020
321
+ # |---> EMAP:3021
322
+
323
+ @emap_term.focus_graph!
324
+ @emap_term.detach_children!
325
+
326
+ assert_equal 'EMAP:3018', @emap_term.term_id
327
+ assert @emap_term.is_root?
328
+ assert_equal 15, @emap_term.size
329
+ assert_equal 15, @emap_term.instance_variable_get(:@graph).raw_graph.size
330
+
331
+ # Test the copy variant of this function
332
+ @mp_term.focus_graph!
333
+ new_term = @mp_term.detach_children
334
+
335
+ assert new_term.object_id != @mp_term.object_id
336
+ assert_equal 96, new_term.size
337
+ assert_equal 96, new_term.instance_variable_get(:@graph).raw_graph.size
338
+ assert_equal 102, @mp_term.size
339
+ assert_equal 102, @mp_term.instance_variable_get(:@graph).raw_graph.size
340
+ end
341
+
274
342
  should 'be able to merge in another ontology graph that shares a common root term' do
275
343
  # We're going to try and merge this subgraph (for EMAP:3018)
276
344
  #
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ols
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-07 00:00:00.000000000 Z
12
+ date: 2011-11-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: savon
16
- requirement: &2156971680 !ruby/object:Gem::Requirement
16
+ requirement: &2157089040 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2156971680
24
+ version_requirements: *2157089040
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &2156971240 !ruby/object:Gem::Requirement
27
+ requirement: &2157088600 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *2156971240
35
+ version_requirements: *2157088600
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: shoulda
38
- requirement: &2156970820 !ruby/object:Gem::Requirement
38
+ requirement: &2157088180 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2156970820
46
+ version_requirements: *2157088180
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: vcr
49
- requirement: &2156970400 !ruby/object:Gem::Requirement
49
+ requirement: &2157087760 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2156970400
57
+ version_requirements: *2157087760
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: webmock
60
- requirement: &2156969980 !ruby/object:Gem::Requirement
60
+ requirement: &2157087340 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2156969980
68
+ version_requirements: *2157087340
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: simplecov
71
- requirement: &2156969560 !ruby/object:Gem::Requirement
71
+ requirement: &2157086920 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *2156969560
79
+ version_requirements: *2157086920
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: simplecov-rcov
82
- requirement: &2156969140 !ruby/object:Gem::Requirement
82
+ requirement: &2157086500 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2156969140
90
+ version_requirements: *2157086500
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: mocha
93
- requirement: &2156968720 !ruby/object:Gem::Requirement
93
+ requirement: &2157086080 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,7 +98,7 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *2156968720
101
+ version_requirements: *2157086080
102
102
  description: ! "\n OLS provides a simple interface to the EBI's Ontology Lookup
103
103
  Service (http://www.ebi.ac.uk/ontology-lookup/).\n It provides an easy lookup
104
104
  of ontology terms and automagically builds up ontology trees for you.\n "