rbbt-entities 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rbbt/entity.rb CHANGED
@@ -5,27 +5,34 @@ module Entity
5
5
  attr_accessor :formats, :entity_property_cache, :entity_list_cache
6
6
  end
7
7
 
8
- self.entity_property_cache = "cache/entity_property"
9
- self.entity_list_cache = "cache/entity_list"
8
+ self.entity_property_cache = "var/entity_property"
9
+ self.entity_list_cache = "var/entity_list"
10
10
  self.formats = {}
11
11
 
12
+ UNPERSISTED_PREFIX = "entity_unpersisted_property_"
13
+
12
14
  def self.extended(base)
13
15
  base.extend Annotation unless Annotation === base
14
16
 
17
+
15
18
  Entity.formats[base.to_s] = base
16
19
  base.module_eval do
20
+ attr_accessor :_ary_property_cache
21
+
17
22
  if not methods.include? "prev_entity_extended"
18
23
  class << self
19
- attr_accessor :template, :list_template, :action_template, :list_action_template
24
+ attr_accessor :template, :list_template, :action_template, :list_action_template, :keep_id
20
25
  alias prev_entity_extended extended
21
26
  end
22
27
 
23
28
  def self.extended(data)
24
29
  prev_entity_extended(data)
25
30
 
31
+ data._ary_property_cache = {}
32
+
26
33
  if Array === data and
27
34
  not AnnotatedArray === data and
28
- not (Annotated === data.compact.first and (data.annotation_types - data.compact.first.annotation_types).any?)
35
+ not (data.compact.first != nil and Annotated === data.compact.first and (data.annotation_types - data.compact.first.annotation_types).any?)
29
36
 
30
37
  data.extend AnnotatedArray
31
38
  end
@@ -41,25 +48,49 @@ module Entity
41
48
  end
42
49
  end
43
50
 
44
- def clean_annotations
51
+ def clean_annotations_old
52
+ return nil if self.nil?
53
+ return self.dup
45
54
  case
46
55
  when self.nil?
47
- self
56
+ nil
48
57
  when String === self
49
58
  "" << self
50
59
  when self.respond_to?(:annotated_array_clean_collect)
51
60
  self.annotated_array_clean_collect{|e| e.respond_to?(:clean_annotations)? e.clean_annotations : e}
52
61
  when Array === self
53
62
  self.collect{|e| e.respond_to?(:clean_annotations)? e.clean_annotations : e}
63
+ when (Fixnum === self)
64
+ 0 + self
65
+ when (Float === self)
66
+ 0.0 + self
54
67
  else
55
68
  raise "Unknown casuistic in clean_annotations for object: #{self.inspect}"
56
69
  end
57
70
  end
58
71
 
72
+ def clean_annotations
73
+ case
74
+ when self.nil?
75
+ nil
76
+ when Array === self
77
+ self.dup.collect{|e| e.respond_to?(:clean_annotations)? e.clean_annotations : e}
78
+ when String === self
79
+ "" << self
80
+ else
81
+ self.dup
82
+ end
83
+ end
84
+
59
85
  def to_yaml(*args)
60
- clean_annotations.to_yaml(*args)
86
+ self.clean_annotations.dup.to_yaml(*args)
87
+ end
88
+
89
+ def encode_with(coder)
90
+ coder.scalar = clean_annotations
61
91
  end
62
92
 
93
+
63
94
  def marshal_dump
64
95
  clean_annotations
65
96
  end
@@ -73,81 +104,105 @@ module Entity
73
104
  end
74
105
  }
75
106
  end
76
- end
77
- end
78
107
 
79
- def property(name, &block)
80
- case
81
- when (Hash === name and name.size == 1)
82
- name, type = name.collect.first
83
- when (String === name or Symbol === name)
84
- type = :single
85
- else
86
- raise "Format of name ( => type) not understood: #{name.inspect}"
87
- end
88
-
89
- name = name.to_s unless String === name
90
-
91
- case type
92
- when :single, :single2array
93
- self.module_eval do
94
- single_name = "_single_" << name
95
- define_method single_name, &block
96
- define_method name do |*args|
97
- if Array === self
98
- self.collect{|e| e.send(name, *args)}
99
- else
100
- self.send(single_name, *args)
101
- end
108
+ def self.property(name, &block)
109
+ case
110
+ when (Hash === name and name.size == 1)
111
+ name, type = name.collect.first
112
+ when (String === name or Symbol === name)
113
+ type = :single
114
+ else
115
+ raise "Format of name ( => type) not understood: #{name.inspect}"
102
116
  end
103
- end
104
- when :array, :array2single
105
- self.module_eval do
106
- ary_name = "_ary_" << name
107
- define_method ary_name, &block
108
-
109
- define_method name do |*args|
110
- case
111
- when Array === self
112
- self.send(ary_name, *args)
113
- when (Array === self.container and self.container.respond_to? ary_name)
114
- res = self.container.send(name, *args)
115
- if Hash === res
116
- res[self]
117
+
118
+ name = name.to_s unless String === name
119
+
120
+ persisted_name = UNPERSISTED_PREFIX + name
121
+ self.remove_method persisted_name if methods.include? persisted_name
122
+
123
+ case type
124
+ when :both
125
+ define_method name, &block
126
+
127
+ when :single, :single2array
128
+ single_name = "_single_" << name
129
+ define_method single_name, &block
130
+ define_method name do |*args|
131
+ if Array === self
132
+ self.collect{|e| e.send(name, *args)}
117
133
  else
118
- res[self.container_index]
134
+ self.send(single_name, *args)
135
+ end
136
+ end
137
+ when :array, :array2single
138
+ ary_name = "_ary_" << name
139
+ define_method ary_name, &block
140
+
141
+ define_method name do |*args|
142
+ #ary_name = "_ary_" << __method__.to_s
143
+ case
144
+ when Array === self
145
+ self.send(ary_name, *args)
146
+ when (Array === self.container and self.container.respond_to? ary_name)
147
+ cache_code = Misc.hash2md5({:name => ary_name, :args => args})
148
+ res = (self.container._ary_property_cache[cache_code] ||= self.container.send(name, *args))
149
+ if Hash === res
150
+ res[self]
151
+ else
152
+ res[self.container_index]
153
+ end
154
+ else
155
+ res = self.make_list.send(ary_name, *args)
156
+ Hash === res ? res[self] : res[0]
119
157
  end
120
- else
121
- res = self.make_list.send(ary_name, *args)
122
- Hash === res ? res[self] : res[0]
123
158
  end
124
- end
125
159
 
160
+ end
126
161
  end
127
- end
128
- end
129
162
 
130
- UNPERSISTED_PREFIX = "entity_unpersisted_property_"
131
- def persist(method_name, type = nil, options = {})
132
- type = :memory if type.nil?
133
- options = Misc.add_defaults options, :dir => Entity.entity_property_cache
163
+ def self.persist(method_name, type = nil, options = {})
164
+ type = :memory if type.nil?
165
+ options = Misc.add_defaults options, :dir => Entity.entity_property_cache
134
166
 
135
- self.module_eval do
136
- orig_name = UNPERSISTED_PREFIX + method_name.to_s
137
- alias_method orig_name, method_name unless instance_methods.include? orig_name
167
+ orig_name = UNPERSISTED_PREFIX + method_name.to_s
168
+ alias_method orig_name, method_name unless self.instance_methods.include? orig_name.to_sym
138
169
 
139
- define_method method_name do |*args|
140
- persist_name = __method__.to_s << ":" << self.id
170
+ define_method method_name do |*args|
171
+ id = self.id
172
+ persist_name = __method__.to_s << ":" << (Array === id ? Misc.hash2md5(:id => id) : id)
173
+ persist_name << ":" << Misc.hash2md5({:args => args}) unless args.nil? or args.empty?
141
174
 
142
- persist_options = options
143
- persist_options = persist_options.merge(:other => {:args => args}) if args.any?
175
+ persist_options = options
176
+ persist_options = persist_options.merge(:other => {:args => args}) if args.any?
144
177
 
145
- Persist.persist(persist_name, type, persist_options) do
146
- self.send(orig_name, *args)
178
+ Persist.persist(persist_name, type, persist_options) do
179
+ self.send(orig_name, *args)
180
+ end
147
181
  end
148
182
  end
149
- end
150
- end
151
183
 
184
+ def self.unpersist(method_name)
185
+ return unless persisted? method_name
186
+ orig_name = UNPERSISTED_PREFIX + method_name.to_s
187
+
188
+ alias_method method_name, orig_name
189
+ remove_method orig_name
190
+ end
191
+
192
+ def self.persisted?(method_name)
193
+ orig_name = UNPERSISTED_PREFIX + method_name.to_s
194
+ instance_methods.include? orig_name.to_sym
195
+ end
196
+
197
+ def self.with_persisted(method_name)
198
+ persisted = persisted? method_name
199
+ persist method_name unless persisted
200
+ res = yield
201
+ unpersist method_name unless persisted
202
+ res
203
+ end
204
+
205
+ end
206
+ end
152
207
  end
153
208
 
@@ -45,8 +45,22 @@ class TestGene < Test::Unit::TestCase
45
45
  end
46
46
 
47
47
  def test_range
48
- assert Range === CDK5.range
49
- assert Range === CDK5.make_list.range.first
48
+ assert Range === CDK5.chr_range
49
+ assert Range === CDK5.make_list.chr_range.first
50
+ end
51
+
52
+ def test_total_bases
53
+ require 'rbbt/entity/gene'
54
+ require 'rbbt/sources/kegg'
55
+
56
+ assert Gene.gene_list_bases(Gene.setup(KeggPathway.setup("hsa03040", "Hsa/jun2011").genes, "KEGG Gene ID", "Hsa/jun2011").ensembl) > 100000
57
+ end
58
+
59
+ def test_total_exon_bases
60
+ require 'rbbt/entity/gene'
61
+ require 'rbbt/sources/kegg'
62
+
63
+ assert Gene.gene_list_exon_bases(Gene.setup(KeggPathway.setup("hsa03040", "Hsa/jun2011").genes, "KEGG Gene ID", "Hsa/jun2011").ensembl) < 1000000
50
64
  end
51
65
 
52
66
  end
@@ -7,22 +7,74 @@ require 'rbbt/entity/genomic_mutation'
7
7
 
8
8
  class TestGenomicMutation < Test::Unit::TestCase
9
9
  MUTATION = GenomicMutation.setup("10:124745844:A:158", "Test", "Hsa/jun2011")
10
+ NON_CODING_MUTATION = GenomicMutation.setup("12:52844451:T", "Test", "Hsa/jun2011")
10
11
  SPLICING = GenomicMutation.setup("18:14787040:A", "Test", "Hsa/jun2011")
12
+ SPLICING2 = GenomicMutation.setup("3:125551372:G:1265.90:1", "test", "Hsa/jun2011", true)
13
+
14
+ FORWARD_STRAND_FIRST_EXON_START = GenomicMutation.setup("10:89622870", "Test", "Hsa/jun2011")
15
+ FORWARD_STRAND_FIRST_EXON_END = GenomicMutation.setup("10:89624305", "Test", "Hsa/jun2011")
16
+ FORWARD_STRAND_LAST_EXON_START = GenomicMutation.setup("10:89725044", "Test", "Hsa/jun2011")
17
+ FORWARD_STRAND_LAST_EXON_END = GenomicMutation.setup("10:89731687", "Test", "Hsa/jun2011")
18
+
19
+ REVERSE_STRAND_FIRST_EXON_START = GenomicMutation.setup("2:198256698", "Test", "Hsa/jun2011")
20
+ REVERSE_STRAND_FIRST_EXON_END = GenomicMutation.setup("2:198257185", "Test", "Hsa/jun2011")
21
+ REVERSE_STRAND_LAST_EXON_START = GenomicMutation.setup("2:198299696", "Test", "Hsa/jun2011")
22
+ REVERSE_STRAND_LAST_EXON_END = GenomicMutation.setup("2:198299815", "Test", "Hsa/jun2011")
23
+
11
24
 
12
25
  def test_mutated_isoforms
13
26
  assert MUTATION.mutated_isoforms.length > 1
14
- assert ["PSTK"], MUTATION.mutated_isoforms.protein.gene.to("Associated Gene Name").uniq
27
+ assert_equal ["PSTK"], MUTATION.mutated_isoforms.protein.gene.to("Associated Gene Name").uniq
15
28
  end
16
29
 
17
30
  def test_exon_junction
18
31
  assert(!(MUTATION.in_exon_junction?))
19
32
  assert SPLICING.in_exon_junction?
33
+
34
+ assert(!(FORWARD_STRAND_FIRST_EXON_START.in_exon_junction?))
35
+ assert( (FORWARD_STRAND_FIRST_EXON_END.in_exon_junction?))
36
+ assert( (FORWARD_STRAND_LAST_EXON_START.in_exon_junction?))
37
+ assert(!(FORWARD_STRAND_LAST_EXON_END.in_exon_junction?))
38
+
39
+ assert(!(REVERSE_STRAND_FIRST_EXON_START.in_exon_junction?))
40
+ assert( (REVERSE_STRAND_FIRST_EXON_END.in_exon_junction?))
41
+ assert( (REVERSE_STRAND_LAST_EXON_START.in_exon_junction?))
42
+ assert(!(REVERSE_STRAND_LAST_EXON_END.in_exon_junction?))
20
43
  end
21
44
 
22
45
  def test_over_gene
23
46
  assert MUTATION.over_gene? Gene.setup("PSTK", "Associated Gene Name", "Hsa/jun2011").ensembl
24
47
  assert(!(SPLICING.over_gene? Gene.setup("PSTK", "Associated Gene Name", "Hsa/jun2011").ensembl))
25
48
  end
49
+
50
+ def test_type
51
+ reference = "A"
52
+ mutation = GenomicMutation.setup("1:1727802:A", "Test", "Hsa/may2009", true)
53
+ assert_equal 'none', mutation.type
54
+ mutation = GenomicMutation.setup("1:1727802:C", "Test", "Hsa/may2009", true)
55
+ assert_equal 'transversion', mutation.type
56
+ mutation = GenomicMutation.setup("1:1727802:T", "Test", "Hsa/may2009", true)
57
+ assert_equal 'transversion', mutation.type
58
+ mutation = GenomicMutation.setup("1:1727802:G", "Test", "Hsa/may2009", true)
59
+ assert_equal 'transition', mutation.type
60
+ end
61
+
62
+ def test_coding
63
+ assert MUTATION.coding?
64
+ assert(!NON_CODING_MUTATION.coding?)
65
+ end
66
+
67
+ def test_masked_annotations
68
+ assert MUTATION.info.include?(:jobname)
69
+ assert(!MUTATION.info(true).include?(:jobname))
70
+ end
71
+
72
+ def test_transcripts_with_affected_splicing
73
+ assert(SPLICING.transcripts_with_affected_splicing.any?)
74
+ assert(SPLICING2.transcripts_with_affected_splicing.empty?)
75
+ end
76
+
77
+
26
78
  end
27
79
 
28
80
 
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ require 'test/unit'
4
+ require 'rbbt/util/tmpfile'
5
+ require 'test/unit'
6
+ require 'rbbt/entity/pmid'
7
+
8
+ class TestProtein < Test::Unit::TestCase
9
+
10
+ def test_pmid_id
11
+ assert_match /^PMID/, PMID.setup("21904853").docid
12
+ end
13
+
14
+ def test_pmid_text
15
+ assert_match /TET2/, PMID.setup("21904853").text
16
+ end
17
+ end
18
+
19
+
@@ -1,4 +1,5 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
2
+ require 'rbbt'
2
3
  require 'rbbt/entity'
3
4
  require 'rbbt/util/tmpfile'
4
5
  require 'test/unit'
@@ -30,6 +31,16 @@ module ReversableString
30
31
  $count += 1
31
32
  self.collect{|s| s.reverse}
32
33
  end
34
+
35
+ property :random => :single do
36
+ rand
37
+ end
38
+
39
+ property :annotation_list => :single do
40
+ self.chars.to_a.collect{|c|
41
+ ReversableString.setup(c)
42
+ }
43
+ end
33
44
 
34
45
  persist :reverse_text_ary_p
35
46
  persist :reverse_text_ary_p
@@ -37,10 +48,13 @@ module ReversableString
37
48
  persist :reverse_text_single_p
38
49
 
39
50
  persist :reverse_text_ary_p_array, :array, :dir => TmpFile.tmp_file
51
+
52
+ persist :annotation_list, :annotations, :dir => TmpFile.tmp_file
40
53
  end
54
+
41
55
  class TestEntity < Test::Unit::TestCase
42
56
 
43
- def test_property_ary
57
+ def _test_property_ary
44
58
  a = ["String1", "String2"]
45
59
  a.extend ReversableString
46
60
 
@@ -48,11 +62,19 @@ class TestEntity < Test::Unit::TestCase
48
62
 
49
63
  assert_equal "2gnirtS", a.reverse_text_ary.last
50
64
  assert_equal 1, $count
65
+ a._ary_property_cache.clear
51
66
  assert_equal "2gnirtS", a[1].reverse_text_ary
52
67
  assert_equal 2, $count
68
+ a._ary_property_cache.clear
69
+
70
+ $count = 0
71
+ a.each do |string|
72
+ string.reverse_text_ary
73
+ assert_equal 1, $count
74
+ end
53
75
  end
54
76
 
55
- def test_property_single
77
+ def _test_property_single
56
78
  a = ["String1", "String2"]
57
79
  a.extend ReversableString
58
80
 
@@ -64,7 +86,7 @@ class TestEntity < Test::Unit::TestCase
64
86
  assert_equal 3, $count
65
87
  end
66
88
 
67
- def test_property_ary_p
89
+ def _test_property_ary_p
68
90
  a = ["String1", "String2"]
69
91
  a.extend ReversableString
70
92
 
@@ -75,7 +97,7 @@ class TestEntity < Test::Unit::TestCase
75
97
  assert_equal 1, $count
76
98
  end
77
99
 
78
- def test_property_single_p
100
+ def _test_property_single_p
79
101
  a = ["String1", "String2"]
80
102
  a.extend ReversableString
81
103
 
@@ -87,7 +109,7 @@ class TestEntity < Test::Unit::TestCase
87
109
  assert_equal 2, $count
88
110
  end
89
111
 
90
- def test_property_ary_p_array
112
+ def _test_property_ary_p_array
91
113
  a = ["String1", "String2"]
92
114
  a.extend ReversableString
93
115
 
@@ -98,4 +120,77 @@ class TestEntity < Test::Unit::TestCase
98
120
  assert_equal "2gnirtS", a.reverse_text_ary_p_array.last
99
121
  assert_equal 1, $count
100
122
  end
123
+
124
+ def _test_unpersist
125
+ a = ["String1", "String2"]
126
+ a.extend ReversableString
127
+
128
+ # Before persist
129
+ assert(! ReversableString.persisted?(:random))
130
+
131
+ r1 = a.random
132
+ r2 = a.random
133
+ assert_not_equal r1, r2
134
+
135
+ # After persist
136
+ ReversableString.persist :random
137
+ assert(ReversableString.persisted?(:random))
138
+
139
+ r1 = a.random
140
+ r2 = a.random
141
+ assert_equal r1, r2
142
+
143
+ # After unpersist
144
+ ReversableString.unpersist :random
145
+ assert(! ReversableString.persisted?(:random))
146
+
147
+ r1 = a.random
148
+ r2 = a.random
149
+ assert_not_equal r1, r2
150
+
151
+ end
152
+
153
+ def _test_persist_annotations
154
+ string = 'aaabbbccc'
155
+ ReversableString.setup(string)
156
+ assert_equal string.length, string.annotation_list.length
157
+ assert_equal string.length, string.annotation_list.length
158
+ end
159
+
160
+ def __test_performance
161
+
162
+ require 'rbbt/workflow'
163
+ Workflow.require_workflow "StudyExplorer"
164
+
165
+ s = Study.setup("CLL")
166
+ mutations = s.cohort.metagenotype
167
+ Misc.profile_html(:min_percent => 1) do
168
+ mutated_isoforms = mutations.each{|m| m.genes.each{|g| g}}
169
+ end
170
+ end
171
+
172
+ def test_clean_annotations
173
+ require 'rbbt/workflow'
174
+ Workflow.require_workflow "StudyExplorer"
175
+
176
+ s = Study.setup("CLL")
177
+ mutations = s.cohort.metagenotype.mutated_isoforms
178
+
179
+ Misc.benchmark(100) do
180
+ mutations.each{|m| m}
181
+ end
182
+
183
+ Misc.benchmark(100) do
184
+ mutations.clean_annotations.each{|m| m}
185
+ end
186
+
187
+ m = mutations.first
188
+
189
+ assert_equal m.split(":")[1], m.position.to_s
190
+ assert_raise NoMethodError do
191
+ m.clean_annotations.position
192
+ end
193
+
194
+
195
+ end
101
196
  end