ols 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 "