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.
@@ -5,10 +5,12 @@ require 'rbbt/mutation/mutation_assessor'
5
5
  require 'rbbt/mutation/sift'
6
6
  require 'rbbt/entity/protein'
7
7
  require 'rbbt/sources/uniprot'
8
+ require 'rbbt/sources/InterPro'
8
9
  require 'rbbt/entity/gene'
9
10
  require 'nokogiri'
10
11
 
11
12
  Workflow.require_workflow 'structure'
13
+ Workflow.require_workflow 'MutEval'
12
14
 
13
15
  module MutatedIsoform
14
16
  extend Entity
@@ -16,10 +18,12 @@ module MutatedIsoform
16
18
 
17
19
  self.format = "Mutated Isoform"
18
20
 
21
+ DEFAULT_DAMAGE_PREDICTORS = [:sift, :mutation_assessor]
22
+
19
23
  property :protein => :array2single do
20
- Protein.setup(self.collect{|mutation| mutation.split(":").first if mutation =~ /^ENSP/}, "Ensembl Protein ID", organism)
24
+ proteins = self.collect{|mutation| mutation.split(":").first if mutation[0..3] == "ENSP"}
25
+ Protein.setup(proteins, "Ensembl Protein ID", organism)
21
26
  end
22
- persist :protein
23
27
 
24
28
  property :transcript => :array2single do
25
29
  begin
@@ -27,12 +31,10 @@ module MutatedIsoform
27
31
  Transcript.setup(protein.transcript.zip(self.collect{|mutation| mutation.split(":").first}).collect{|p| p.compact.first}, "Ensembl Transcript ID", organism)
28
32
  end
29
33
  end
30
- persist :transcript
31
34
 
32
35
  property :change => :array2single do
33
36
  self.collect{|mi| mi.split(":").last}
34
37
  end
35
- persist :change
36
38
 
37
39
  property :position => :array2single do
38
40
  change.collect{|c|
@@ -43,13 +45,11 @@ module MutatedIsoform
43
45
  end
44
46
  }
45
47
  end
46
- persist :position
47
48
 
48
49
  property :ensembl_protein_image_url => :single2array do
49
50
  ensembl_url = if organism == "Hsa" then "www.ensembl.org" else "#{organism.sub(/.*\//,'')}.archive.ensembl.org" end
50
51
  "http://#{ensembl_url}/Homo_sapiens/Component/Transcript/Web/TranslationImage?db=core;p=#{protein};_rmd=d2a8;export=svg"
51
52
  end
52
- persist :ensembl_protein_image_url
53
53
 
54
54
  property :marked_svg => :single2array do
55
55
  svg = Open.read(protein.ensembl_protein_image_url)
@@ -57,7 +57,6 @@ module MutatedIsoform
57
57
  seq_len = protein.sequence_length
58
58
  position = self.position
59
59
 
60
-
61
60
  doc = Nokogiri::XML(svg)
62
61
  return nil unless doc.css('svg')
63
62
  width = doc.css('svg').first.attr('width').to_f
@@ -71,14 +70,17 @@ module MutatedIsoform
71
70
  svg
72
71
  end
73
72
  end
74
- persist :marked_svg
75
73
 
76
74
  ASTERISK = "*"[0]
77
75
  CONSECUENCES = %w(UTR SYNONYMOUS NOSTOP MISS-SENSE INDEL FRAMESHIFT NONSENSE)
78
76
  property :consequence => :single2array do
77
+ return nil if self.nil?
78
+
79
79
  prot, change = self.split(":")
80
80
 
81
81
  case
82
+ when change.nil?
83
+ nil
82
84
  when change =~ /UTR/
83
85
  "UTR"
84
86
  when (change[0] == ASTERISK and not change[0] == change[-1])
@@ -95,37 +97,111 @@ module MutatedIsoform
95
97
  "MISS-SENSE"
96
98
  end
97
99
  end
98
- persist :consequence
100
+
101
+ property :in_utr => :array2single do
102
+ consequence.collect{|c|
103
+ c == "UTR"
104
+ }
105
+ end
106
+
107
+ property :synonymous => :array2single do
108
+ consequence.collect{|c|
109
+ c == "SYNONYMOUS"
110
+ }
111
+ end
112
+
113
+ property :non_synonymous => :array2single do
114
+ consequence.collect{|c|
115
+ not c.nil? and c != "SYNONYMOUS" and c != "UTR"
116
+ }
117
+ end
118
+
119
+ property :affected_interpro_domains => :single do
120
+ if protein.nil?
121
+ []
122
+ else
123
+ InterProDomain.setup(Misc.zip_fields(protein.interpro_domain_positions || []).select{|d,s,e|
124
+ e.to_i > position and s.to_i < position
125
+ }.collect{|d,s,e| d }, organism)
126
+ end
127
+ end
128
+
129
+ property :affected_interpro_domain_positions => :single do
130
+ if protein.nil?
131
+ []
132
+ else
133
+ Misc.zip_fields(protein.interpro_domain_positions || []).select{|d,s,e|
134
+ e.to_i > position and s.to_i < position
135
+ }.collect{|d,s,e| [d, position - s.to_i, s.to_i, e.to_i]}
136
+ end
137
+ end
138
+
139
+ property :affected_domain_positions => :single do
140
+ affected_interpro_domain_positions
141
+ end
142
+
143
+ property :affected_domains => :single do
144
+ affected_interpro_domains
145
+ end
146
+
147
+ property :ablated_interpro_domains => :single do
148
+ if protein.nil?
149
+ []
150
+ else
151
+ InterProDomain.setup(Misc.zip_fields(protein.interpro_domain_positions || []).select{|d,s,e|
152
+ e.to_i > position
153
+ }.collect{|d,s,e| d }, organism)
154
+ end
155
+ end
156
+
157
+ property :ablated_interpro_domain_positions => :single do
158
+ if protein.nil?
159
+ []
160
+ else
161
+ Misc.zip_fields(protein.interpro_domain_positions || []).select{|d,s,e|
162
+ e.to_i > position
163
+ }.collect{|d,s,e| [d, s.to_i, e.to_i]}
164
+ end
165
+ end
166
+
167
+ property :ablated_domain_positions => :single do
168
+ ablated_interpro_domain_positions
169
+ end
170
+
171
+ property :ablated_domains => :single do
172
+ ablated_interpro_domains
173
+ end
99
174
 
100
175
  property :truncated => :array2single do
101
176
  begin
102
177
  proteins = self.protein.compact.flatten
103
- protein2sequence_length = Misc.process_to_hash(proteins){|list| proteins.sequence_length}
178
+ protein2sequence_length = Misc.process_to_hash(proteins){|list| proteins.any? ? proteins.sequence_length : []}
104
179
 
105
180
  self.collect do |isoform_mutation|
106
181
 
107
- next if isoform_mutation.consequence != "FRAMESHIFT" and isoform_mutation.consequence != "NONSENSE"
108
- protein = isoform_mutation.protein
109
- position = isoform_mutation.position
110
- sequence_length = protein2sequence_length[protein]
111
-
112
- case
113
- when (sequence_length.nil? or position.nil?)
114
- nil
115
- when position < sequence_length.to_f * 0.7
116
- true
117
- else
118
- false
119
- end
120
- end
121
- end
182
+ next if isoform_mutation.consequence != "FRAMESHIFT" and isoform_mutation.consequence != "NONSENSE"
183
+ protein = isoform_mutation.protein
184
+ position = isoform_mutation.position
185
+ sequence_length = protein2sequence_length[protein]
186
+
187
+ case
188
+ when (sequence_length.nil? or position.nil?)
189
+ nil
190
+ when position < sequence_length.to_f * 0.7
191
+ true
192
+ when (isoform_mutation.ablated_domains.any?)
193
+ true
194
+ else
195
+ false
196
+ end
197
+ end
198
+ end
122
199
  end
123
- persist :truncated
124
200
 
125
201
  property :damage_scores => :array2single do |*args|
126
202
  begin
127
203
  methods = args.first
128
- methods = [:sift, :mutation_assessor] if methods.nil?
204
+ methods = MutatedIsoform::DEFAULT_DAMAGE_PREDICTORS if methods.nil?
129
205
  methods = [methods] unless Array === methods
130
206
  values = methods.collect{|method|
131
207
  case method.to_sym
@@ -133,6 +209,12 @@ module MutatedIsoform
133
209
  sift_scores
134
210
  when :mutation_assessor
135
211
  mutation_assessor_scores
212
+ when :polyphen
213
+ polyphen_scores
214
+ when :snps_and_go
215
+ snps_and_go_scores
216
+ when :transFIC
217
+ transFIC_scores(:mutation_assessor)
136
218
  else
137
219
  raise "Unknown predictive method: #{ method }"
138
220
  end
@@ -154,94 +236,100 @@ module MutatedIsoform
154
236
  end
155
237
  end
156
238
  end
157
- persist :damage_scores
158
239
 
159
240
  property :damaged? => :array2single do |*args|
160
241
  begin
161
242
  methods, threshold = args
243
+ threshold, methods = methods, nil if threshold.nil? and not Array === methods
162
244
  threshold = 0.8 if threshold.nil?
163
245
  damage_scores = self.damage_scores(methods)
164
246
  truncated = self.truncated
247
+
165
248
  damage_scores.zip(truncated).collect{|damage, truncated| truncated or (not damage.nil? and damage > threshold) }
166
249
  end
167
250
  end
168
- persist :damaged?
169
251
 
170
- property :sift_scores => :array2single do
252
+ property :snps_and_go_scores => :array2single do
171
253
  begin
172
- missense = self.select{|iso_mut| iso_mut.consequence == "MISS-SENSE"}
173
-
174
- values = SIFT.chunked_predict(missense).values_at(*self).collect{|v|
175
- v.nil? ? nil : 1.0 - v["Score 1"].to_f
254
+ missense = self.select{|mutation| mutation.consequence == "MISS-SENSE"}
255
+ res = MutEval.job(:snps_and_go, "MutatedIsoforms (#{self.length})", :mutations => missense.sort, :organism => organism).run
256
+ res.values_at(*self).collect{|v| (v.nil? or v["SNPSandGO Score"].nil? or v["SNPSandGO Score"].empty?) ?
257
+ nil :
258
+ (v["SNPSandGO Prediction"] == "Disease" ? 1.0 - (10.0 - v["SNPSandGO Score"].to_f) / 20 : 0 + (10.0 - v["SNPSandGO Score"].to_f) / 20)
176
259
  }
177
-
178
- values
179
-
180
- #range = {nil => nil,
181
- # "" => nil,
182
- # "TOLERATED" => 0,
183
- # "*DAMAGING" => 1,
184
- # "DAMAGING" => 1}
185
-
186
- #range.values_at *values
260
+ rescue
261
+ Log.warn $!.message
262
+ [nil] * self.length
187
263
  end
188
264
  end
189
- persist :sift_scores
190
265
 
191
- property :mutation_assessor_scores => :array2single do
266
+ property :polyphen_scores => :array2single do
192
267
  begin
193
268
  missense = self.select{|mutation| mutation.consequence == "MISS-SENSE"}
269
+ res = MutEval.job(:polyphen, "MutatedIsoforms (#{self.length})", :mutations => missense.sort, :organism => organism).run
270
+ res.values_at(*self).collect{|v| (v.nil? or v["Polyphen Score"].nil? or v["Polyphen Score"].empty?) ? nil : v["Polyphen Score"].to_f / 10}
271
+ rescue
272
+ Log.warn $!.message
273
+ [nil] * self.length
274
+ end
275
+ end
194
276
 
195
- correspondance = {}
196
- list = missense.zip(missense.protein.to "UniProt/SwissProt ID").collect do |mutation, uniprot|
197
- prot, change = mutation.split(":")
198
- next if uniprot.nil?
199
- uniprot_change = [uniprot.upcase, change.upcase]
200
- correspondance[uniprot_change] ||= []
201
- correspondance[uniprot_change] << mutation
202
- uniprot_change
203
- end.compact
204
-
205
- return [nil] * self.length if list.empty?
206
-
207
- tsv = MutationAssessor.chunked_predict(list.sort_by{|p| p * "_"})
208
-
209
- return [nil] * self.length if tsv.empty?
277
+ property :sift_scores => :array2single do
278
+ begin
279
+ missense = self.select{|mutation| mutation.consequence == "MISS-SENSE"}
280
+ res = MutEval.job(:sift, "MutatedIsoforms (#{self.length})", :mutations => missense.sort, :organism => organism).run
281
+ res.values_at(*self).collect{|v| (v.nil? or v["SIFT Score"].nil? or v["SIFT Score"].empty?) ? nil : 1.0 - v["SIFT Score"].to_f}
282
+ rescue
283
+ Log.warn $!.message
284
+ [nil] * self.length
285
+ end
286
+ end
210
287
 
211
- new = TSV.setup({}, :key_field => "Mutated Isoform", :fields => ["Func. Impact"], :type => :list)
288
+ property :transFIC_scores => :array2single do |*args|
289
+ method = args.first || :mutation_assessor
290
+ range = {nil => nil,
291
+ "" => nil,
292
+ "low_impact" => 0,
293
+ "medium_impact" => 0.7,
294
+ "high_impact" => 1.0}
295
+ field_names = {
296
+ }
297
+ begin
298
+ missense = self.select{|mutation| mutation.consequence == "MISS-SENSE"}
212
299
 
213
- tsv.each do |key, values|
214
- uniprot, change = key.split(" ")
215
- uniprot_change = [uniprot.upcase, change.upcase]
216
-
217
- if correspondance.include? uniprot_change
218
- correspondance[uniprot_change].each do |mutation|
219
- new[mutation] = values["Func. Impact"]
220
- end
221
- else
222
- Log.medium "Correspondace value missing: #{uniprot_change.inspect}"
223
- end
224
- end
300
+ field_name = {
301
+ :mutation_assessor => "maTransfic",
302
+ }[method.to_sym]
225
303
 
304
+ MutEval.job(:transFIC, "MutatedIsoforms (#{self.length})", :mutations => missense.sort, :organism => organism).run.values_at(*self).collect{|v| (v.nil? or v[field_name].nil? or v[field_name].empty?) ? nil : v[field_name].to_f}
305
+ rescue
306
+ Log.warn $!.message
307
+ [nil] * self.length
308
+ end
309
+ end
226
310
 
227
- range = {nil => nil,
228
- "" => nil,
229
- "neutral" => 0,
230
- "low" => 0.5,
231
- "medium" => 0.7,
232
- "high" => 1.0}
311
+ property :mutation_assessor_scores => :array2single do
312
+ range = {nil => nil,
313
+ "" => nil,
314
+ "neutral" => 0,
315
+ "low" => 0.5,
316
+ "medium" => 0.7,
317
+ "high" => 1.0}
233
318
 
234
- range.values_at *new.values_at(*self)
319
+ begin
320
+ missense = self.select{|mutation| mutation.consequence == "MISS-SENSE"}
321
+ MutEval.job(:mutation_assessor, "MutatedIsoforms (#{self.length})", :mutations => missense.sort, :organism => organism).run.values_at(*self).collect{|v| (v.nil? or v["Mutation Assessor Prediction"].nil? or v["Mutation Assessor Prediction"].empty?) ? nil : range[v["Mutation Assessor Prediction"]]}
322
+ rescue
323
+ Log.warn $!.message
324
+ [nil] * self.length
235
325
  end
236
326
  end
237
- persist :mutation_assessor_scores
238
327
 
239
328
  property :pdbs => :single do
240
329
  uniprot = self.transcript.protein.uniprot
241
330
  next if uniprot.nil?
242
331
  UniProt.pdbs_covering_aa_position(uniprot, self.position)
243
332
  end
244
- persist :pdbs
245
333
 
246
334
  property :pdbs_and_positions => :single do
247
335
  pdbs.collect do |pdb, info|
@@ -1,13 +1,21 @@
1
1
  require 'rbbt/entity'
2
2
  require 'rbbt/entity/document'
3
3
  require 'rbbt/sources/pubmed'
4
+ require 'rbbt/sources/gscholar'
4
5
 
5
6
  module PMID
6
7
  extend Entity
7
8
  include Document
8
9
 
10
+ self.annotation :default_type
11
+
9
12
  self.format = "PMID"
10
13
 
14
+ property :docid => :single do |*args|
15
+ type = args.first || default_type
16
+ ["PMID", self, type].compact * ":"
17
+ end
18
+
11
19
  property :article => :array2single do
12
20
  PubMed.get_article(self).values_at(*self)
13
21
  end
@@ -15,25 +23,44 @@ module PMID
15
23
  property :abstract => :array2single do
16
24
  article.collect{|a| a.nil? ? nil : a.abstract}
17
25
  end
18
- persist :abstract
19
26
 
20
27
  property :title => :array2single do
21
28
  article.collect{|a| a.nil? ? nil : a.title}
22
29
  end
23
- persist :title
24
30
 
25
31
  property :journal => :array2single do
26
32
  article.collect{|a| a.nil? ? nil : a.journal}
27
33
  end
28
- persist :journal
29
34
 
30
35
  property :year => :array2single do
31
36
  article.collect{|a| a.nil? ? nil : a.year}
32
37
  end
33
- persist :year
34
38
 
35
- property :_get_text => :array2single do
36
- article.collect{|a| a.nil? ? nil : a.text}
39
+ property :cites => :single2array do
40
+ if title
41
+ begin
42
+ GoogleScholar.number_cites(title)
43
+ rescue
44
+ nil
45
+ end
46
+ else
47
+ nil
48
+ end
49
+ end
50
+
51
+ property :_get_text => :array2single do |*args|
52
+ type = args.first || default_type
53
+
54
+ case type.to_s
55
+ when "full_text", 'fulltext'
56
+ article.collect{|a| a.nil? ? nil : a.full_text}
57
+ when "abstract"
58
+ article.collect{|a| a.nil? ? nil : a.abstract }
59
+ when "best"
60
+ article.collect{|a| a.nil? ? nil : (a.full_text || a.text) }
61
+ else
62
+ article.collect{|a| a.nil? ? nil : a.text}
63
+ end
37
64
  end
38
65
 
39
66
  property :pubmed_url => :single2array do
@@ -19,7 +19,7 @@ module Protein
19
19
 
20
20
  def self.ensp2sequence(organism, protein)
21
21
  @@ensp2sequence ||= {}
22
- @@ensp2sequence[organism] ||= Organism.protein_sequence(organism).tsv :persist => true
22
+ @@ensp2sequence[organism] ||= Organism.protein_sequence(organism).tsv :persist => true, :unnamed => true
23
23
  if Array === protein
24
24
  @@ensp2sequence[organism].values_at *protein
25
25
  else
@@ -29,7 +29,7 @@ module Protein
29
29
 
30
30
  def self.ensp2enst(organism, protein)
31
31
  @@ensp2enst ||= {}
32
- @@ensp2enst[organism] ||= Organism.transcripts(organism).tsv(:type => :single, :key_field => "Ensembl Protein ID", :fields => ["Ensembl Transcript ID"], :persist => true)
32
+ @@ensp2enst[organism] ||= Organism.transcripts(organism).tsv(:type => :single, :key_field => "Ensembl Protein ID", :fields => ["Ensembl Transcript ID"], :persist => true, :unnamed => true)
33
33
  @@ensp2enst[organism][protein]
34
34
  end
35
35
 
@@ -51,6 +51,7 @@ module Protein
51
51
  persist :transcript
52
52
 
53
53
  property :ensembl_protein_image_url => :single2array do
54
+ organism = self.organism || "Hsa"
54
55
  ensembl_url = if organism == "Hsa" then "www.ensembl.org" else "#{organism.sub(/.*\//,'')}.archive.ensembl.org" end
55
56
  "http://#{ensembl_url}/Homo_sapiens/Component/Transcript/Web/TranslationImage?db=core;p=#{ensembl};_rmd=d2a8;export=svg"
56
57
  end
@@ -67,13 +68,12 @@ module Protein
67
68
  end
68
69
 
69
70
  property :gene => :array do
70
- Gene.setup(to("Ensembl Protein ID").clean_annotations, "Ensembl Protein ID", organism)
71
+ Gene.setup(to("Ensembl Protein ID").clean_annotations, "Ensembl Protein ID", organism).ensembl
71
72
  end
72
73
  persist :gene #, :yaml, :file => '/tmp/testes'
73
74
 
74
75
  property :pfam => :array2single do
75
- index = Organism.gene_pfam(organism).tsv :flat, :persist => true
76
- index.unnamed = true
76
+ index = Organism.gene_pfam(organism).tsv :flat, :persist => true, :unnamed => true
77
77
  pfam = index.values_at(*self).flatten
78
78
  Pfam.setup pfam
79
79
  end
@@ -82,12 +82,41 @@ module Protein
82
82
  property :sequence => :array2single do
83
83
  Protein.ensp2sequence(organism, self.ensembl)
84
84
  end
85
- persist :sequence
85
+ persist :_ary_sequence
86
86
 
87
87
  property :sequence_length => :array2single do
88
88
  sequence.collect{|seq| seq.nil? ? nil : seq.length}
89
89
  end
90
- persist :sequence_length
90
+ persist :_ary_sequence_length
91
+
92
+ property :marked_svg => :single2array do |*args|
93
+ positions = args.first
94
+ svg = Open.read(ensembl_protein_image_url)
95
+
96
+ seq_len = sequence_length
97
+
98
+ doc = Nokogiri::XML(svg)
99
+ return nil unless doc.css('svg').any?
100
+ width = doc.css('svg').first.attr('width').to_f
101
+ height = doc.css('svg').first.attr('height').to_f
102
+ start = doc.css('rect.ac').first.attr('x').to_f
103
+
104
+ positions.each do |position|
105
+ if width and height and start and seq_len and position
106
+ offset = (width - start)/seq_len * position + start + rand * 10
107
+ svg = svg.sub(/<\/svg>/,"<rect x='#{offset}' y='1' width='1' height='#{height}' style='fill:rgb(255,0,0);opacity:0.5;stroke:none;'></svg>")
108
+ end
109
+ end
110
+
111
+ svg
112
+ end
113
+
114
+ property :pdbs => :single do
115
+ next if uniprot.nil?
116
+ UniProt.pdbs(uniprot)
117
+ end
118
+ persist :pdbs
119
+
91
120
 
92
121
  end
93
122
 
@@ -10,7 +10,7 @@ module Transcript
10
10
 
11
11
  def self.enst2ensg(organism, transcript)
12
12
  @@enst2ensg ||= {}
13
- @@enst2ensg[organism] ||= Organism.gene_transcripts(organism).tsv(:type => :single, :key_field => "Ensembl Transcript ID", :fields => ["Ensembl Gene ID"], :persist => true).tap{|o| o.unnamed = true}
13
+ @@enst2ensg[organism] ||= Organism.gene_transcripts(organism).tsv(:type => :single, :key_field => "Ensembl Transcript ID", :fields => ["Ensembl Gene ID"], :persist => true, :unnamed => true)
14
14
  res = if Array === transcript
15
15
  @@enst2ensg[organism].values_at *transcript
16
16
  else
@@ -22,7 +22,7 @@ module Transcript
22
22
 
23
23
  def self.enst2ensp(organism, transcript)
24
24
  @@enst2ensp ||= {}
25
- @@enst2ensp[organism] ||= Organism.transcripts(organism).tsv(:type => :single, :key_field => "Ensembl Transcript ID", :fields => ["Ensembl Protein ID"], :persist => true)
25
+ @@enst2ensp[organism] ||= Organism.transcripts(organism).tsv(:type => :single, :key_field => "Ensembl Transcript ID", :fields => ["Ensembl Protein ID"], :persist => true, :unnamed => true)
26
26
  res = if Array === transcript
27
27
  @@enst2ensp[organism].values_at *transcript
28
28
  else
@@ -31,6 +31,18 @@ module Transcript
31
31
  Protein.setup(res, "Ensembl Protein ID", organism)
32
32
  end
33
33
 
34
+ def self.enst2ense(organism, transcript)
35
+ @@enst2ense ||= {}
36
+ @@enst2ense[organism] ||= Organism.transcript_exons(organism).tsv(:persist => true, :fields => "Ensembl Exon ID", :unnamed => true)
37
+ res = if Array === transcript
38
+ @@enst2ense[organism].chunked_values_at transcript
39
+ else
40
+ @@enst2ense[organism][transcript]
41
+ end
42
+ res
43
+ end
44
+
45
+
34
46
 
35
47
  property :to! => :array2single do |new_format|
36
48
  return self if format == new_format
@@ -44,13 +56,17 @@ module Transcript
44
56
  to!(new_format).collect!{|v| v.nil? ? nil : v.first}
45
57
  end
46
58
 
59
+ property :exons => :array2single do
60
+ Transcript.enst2ense(organism, self)
61
+ end
62
+ persist :_ary_exons
63
+
47
64
  property :ensembl => :array2single do
48
65
  to "Ensembl Transcript ID"
49
66
  end
50
67
 
51
68
  property :sequence => :array2single do
52
- transcript_sequence = Organism.transcript_sequence(organism).tsv :persist => true
53
- transcript_sequence.unnamed = true
69
+ transcript_sequence = Organism.transcript_sequence(organism).tsv :persist => true, :unnamed => true
54
70
  transcript_sequence.values_at *self.ensembl
55
71
  end
56
72