exodb 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,193 @@
1
+ #
2
+ # Exodb
3
+ # Copyright (C) 2014
4
+ #
5
+ # author: Natapol Pornputtapong <natapol.por@gmail.com>
6
+ #
7
+ # Documentation: Natapol Pornputtapong (RDoc'd and embellished by William Webber)
8
+ #
9
+
10
+ # raise "Please, use ruby 1.9.0 or later." if RUBY_VERSION < "1.9.0"
11
+
12
+ module Exodb
13
+
14
+ class Chrref < Reference
15
+
16
+ include Exodb::GeneLocationField
17
+
18
+ index({oid: 1}, background: true)
19
+
20
+ end
21
+
22
+ class Generef < Reference
23
+
24
+ include Exodb::GeneLocationField
25
+
26
+ @@expanding = 500
27
+
28
+ field :psuedo, type: Boolean
29
+
30
+ index({sequence: 'text'}, background: true)
31
+ index({oid: 1, psudo: 1, chrrefseq: 1, assembly: 1}, background: true)
32
+
33
+ has_many :genes
34
+ embeds_many :isoforms
35
+ embeds_many :occurrents
36
+
37
+ validates_format_of :chrrefseq, with: /\A(urn:miriam:refseq)/
38
+
39
+ #oid = "chrrefseq:start..stop"
40
+
41
+ def self.expanding
42
+ return @@expanding
43
+ end
44
+
45
+ # Download gene symbol from HGNC service
46
+ #
47
+ def dl_symbol!
48
+
49
+ baseuri = "http://rest.genenames.org/search"
50
+
51
+
52
+ query = ""
53
+
54
+ if self.get_xref('urn:miriam:refseq')
55
+ query = "#{baseuri}/refseq_accession/#{self.chrrefseq.id.split('.')[0]}"
56
+ elsif self.get_xref('urn:miriam:ncbigene')
57
+ query = ""
58
+ end
59
+
60
+ if !query.empty?
61
+ response = JSON.parse(open(query, 'Accept' => 'application/json').read)['response']
62
+ if !response['docs'].empty?
63
+
64
+ response['docs'].each do |e|
65
+ self.add_to_set(:xrefs, "urn:miriam:hgnc:#{e["hgnc_id"]}")
66
+ self.add_to_set(:xrefs, "urn:miriam:hgnc.symbol:#{e["symbol"]}")
67
+ end
68
+
69
+ self.save!
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+
77
+ # Download incident data from TCGA
78
+ #
79
+ def dl_occurrent!
80
+
81
+ if self.get_xref('urn:miriam:hgnc.symbol')
82
+
83
+ cancerstudies = []
84
+
85
+ open("http://www.cbioportal.org/public-portal/webservice.do?cmd=getCancerStudies") {|f|
86
+ f.each_line {|line| cancerstudies.push(line.chomp.split("\t")[0])}
87
+ }
88
+
89
+ occurrents = {}
90
+ totalcase = {}
91
+
92
+ cancerstudies.each do |study|
93
+
94
+ totalcase[study] = 0 if !totalcase.has_key?(study)
95
+
96
+ open("http://www.cbioportal.org/public-portal/webservice.do?cmd=getCaseLists&cancer_study_id=#{study}") do |f|
97
+ f.each_line do |line|
98
+ totalcase[study] += line.chomp.split(/\t/)[4].split(' ').length if line =~ /\tSequenced Tumors\t/
99
+ end
100
+ end
101
+
102
+ occurrents[study] = {} if !occurrents.has_key?(study)
103
+
104
+ open("http://www.cbioportal.org/public-portal/webservice.do?cmd=getMutationData&genetic_profile_id=#{study}_mutations&gene_list=#{self.get_xref('urn:miriam:hgnc.symbol').id}") do |f|
105
+ f.each_line do |line|
106
+ dat = line.chomp.split(/\t/)
107
+
108
+ if dat[5] == 'Missense_Mutation'
109
+
110
+ occurrents[study][dat[7].split(/(\d+)/)[1]] = [] if !occurrents[study].has_key?(dat[7].split(/(\d+)/)[1])
111
+ occurrents[study][dat[7].split(/(\d+)/)[1]].push(dat[2])
112
+
113
+ end
114
+
115
+ end
116
+
117
+
118
+ end
119
+ end
120
+
121
+ self.occurrents.clear if self.occurrents
122
+
123
+ occurrents.each_pair do |cancertype, v|
124
+ v.each_pair do |position, occur|
125
+ self.occurrents << Occurrent.new({cancertype: cancertype, position: position, occur: occur.uniq.sort, casenumber: totalcase[cancertype]})
126
+ end
127
+ end
128
+
129
+ self.save!
130
+
131
+ end
132
+
133
+ end
134
+
135
+ # return longest splice of this gene
136
+ def longest_splice()
137
+ length = 0
138
+ longest = nil
139
+ self.isoforms.each do |e|
140
+
141
+ if e.prot_len > length
142
+ length = e.prot_len
143
+ longest = e
144
+ end
145
+
146
+ end
147
+
148
+ return longest
149
+ end
150
+
151
+ alias_method :longest_isoform, :longest_splice
152
+
153
+ # Check that this gene has any splice variant
154
+ #
155
+ # @return [Boolean] true if has any splices
156
+ def has_splices?
157
+ return self.isoforms.exists?
158
+ end
159
+
160
+ alias_method :has_isoforms?, :has_splices?
161
+
162
+ # Check if Generef has sequence
163
+ #
164
+ # @return [Boolean] Return true if there is a sequence
165
+ def has_sequence?()
166
+ return self[:sequence] ? true : false
167
+ end
168
+
169
+ # Check if Generef can translate
170
+ #
171
+ # @return [Boolean] Return true if this can be translate
172
+ def can_translated?()
173
+ return self.has_sequence? && self.has_splices? && self.longest_splice != nil ? true : false
174
+ end
175
+
176
+ # Get gene symbol
177
+ #
178
+ # @return [String] Return gene symbol or any id from xrefs or 'nosymbol'
179
+ def symbol
180
+
181
+ if self.get_xref('urn:miriam:hgnc.symbol')
182
+ return self.get_xref('urn:miriam:hgnc.symbol').id
183
+ elsif self.xrefs && !self.xrefs.empty?
184
+ return self.xrefs.sort[0].id
185
+ else
186
+ return 'nosymbol'
187
+ end
188
+
189
+ end
190
+
191
+ end
192
+
193
+ end
@@ -0,0 +1,237 @@
1
+ #
2
+ # Exodb
3
+ # Copyright (C) 2014
4
+ #
5
+ # author: Natapol Pornputtapong <natapol.por@gmail.com>
6
+ #
7
+ # Documentation: Natapol Pornputtapong (RDoc'd and embellished by William Webber)
8
+ #
9
+
10
+ # raise "Please, use ruby 1.9.0 or later." if RUBY_VERSION < "1.9.0"
11
+
12
+ module Exodb
13
+
14
+ class Isoform
15
+
16
+ include Mongoid::Document
17
+
18
+ include Exodb::XrefsField
19
+
20
+ field :exon, type: Array # array of [start, stop]
21
+ field :cds, type: Array # array of [start, stop]
22
+
23
+ embedded_in :generef
24
+
25
+ # generate genbank style location string
26
+ #
27
+ # @param [Symbol] field to generate [:exon, :cds]
28
+ # @param [Symbol] type to generate [:rel, :abs, :trela]
29
+ #
30
+ # @return [String] a location string
31
+ def genbank_loc(field, type)
32
+
33
+ reducer = case type.to_sym
34
+ when :rel
35
+ self.generef[:start] - 1
36
+ when :trela
37
+ self.generef[:seqstart] - 1
38
+ else
39
+ 0
40
+ end
41
+
42
+ loc = []
43
+
44
+ self[field.to_sym].each do |pos|
45
+ loc.push("#{pos[0] - reducer}..#{pos[1] - reducer}")
46
+ end
47
+
48
+ return self.generef.strand == '+' ? "join(#{loc.join(',')})" : "complement(join(#{loc.join(',')}))"
49
+ end
50
+
51
+ protected :genbank_loc
52
+
53
+ # Get exon location
54
+ #
55
+ # @return [Bio::Locations] of exon
56
+ def exon_location
57
+ return Bio::Locations.new(genbank_loc(:exon, :abs))
58
+ end
59
+
60
+ # Get exon location
61
+ #
62
+ # @return [Bio::Locations] of exon
63
+ def cds_location
64
+ return Bio::Locations.new(genbank_loc(:cds, :abs))
65
+ end
66
+
67
+ # Get spliced RNA sequence
68
+ #
69
+ # @return [Bio::Sequence] an RNA sequence
70
+ def mrna_seq
71
+ return self.return self.generef.whole_seq.splice(genbank_loc(:exon, :trela)).rna
72
+ end
73
+
74
+ # Get spliced coding region sequence
75
+ #
76
+ # @param [Integer] end position to get sequence
77
+ #
78
+ # @return [Bio::Sequence] an coding region sequence
79
+ def cds_seq
80
+ return self.generef.whole_seq.splice(genbank_loc(:cds, :trela))
81
+ end
82
+
83
+ # Get spliced protein sequence
84
+ #
85
+ # @return [Bio::Sequence] an protein sequence
86
+ def prot_seq
87
+ return self.cds_seq().translate
88
+ end
89
+
90
+ # get length of spliced RNA
91
+ #
92
+ # @return [Integer] length of spliced RNA
93
+ def mrna_len
94
+ return self.exon_location.length
95
+ end
96
+
97
+ # get length of protein product
98
+ #
99
+ # @return [Integer] length of protein product
100
+ def prot_len
101
+ return self.cds_location.length
102
+ end
103
+
104
+ # Get the codon sequence at the giving position base on position of amino acid
105
+ #
106
+ # @param [Integer] codon position
107
+ # @return [Bio::Sequence] the codon at given position
108
+ def codon_at(codon_pos)
109
+ return self.cds_seq.subseq(((codon_pos - 1) * 3) + 1 , ((codon_pos - 1) * 3) + 3)
110
+ end
111
+
112
+ # convert genomic position to cds position
113
+ #
114
+ # @param [Integer] genomic position
115
+ # @return [Integer] Return all information of cds at given position
116
+ def genomic2cds_pos(pos)
117
+ cds_location.relative(pos)
118
+ end
119
+
120
+ # convert genomic position to cds position
121
+ #
122
+ # @param [Integer] genomic position
123
+ # @return [Array] Return [codon and position in codon]
124
+ def genomic2prot_pos(pos)
125
+ cds_location.relative(pos, :aa)
126
+ end
127
+
128
+ # get splice related position 1-3 base into exon and 3-8 base into intron
129
+ #
130
+ # @return [Array] Return position of splice related site in array of [start, stop]
131
+ # SPL-D splice_donor_variant SO:0001575
132
+ # SPL-A splice_acceptor_variant SO:0001574
133
+ # SPL-R splice_region_variant SO:0001630
134
+ def splice_rel_location
135
+
136
+ if @splice_location == nil
137
+
138
+ results = {}
139
+ right = nil
140
+
141
+ self[:exon].each do |exon|
142
+ if !right.blank?
143
+ if self.generef.strand == '+'
144
+ results[right + 1] = 'SPL-D'
145
+ results[right + 2] = 'SPL-D'
146
+ results[exon[0] - 1] = 'SPL-A'
147
+ results[exon[0] - 2] = 'SPL-A'
148
+ else
149
+ results[right + 1] = 'SPL-A'
150
+ results[right + 2] = 'SPL-A'
151
+ results[exon[0] - 1] = 'SPL-D'
152
+ results[exon[0] - 2] = 'SPL-D'
153
+ end
154
+
155
+ Range.new(right - 2, right).each {|e| results[e] = 'SPL-R'}
156
+ Range.new(right + 3, right + 8).each {|e| results[e] = 'SPL-R'}
157
+ Range.new(exon[0], exon[0] + 2).each {|e| results[e] = 'SPL-R'}
158
+ Range.new(exon[0] - 3, exon[0] - 8).each {|e| results[e] = 'SPL-R'}
159
+
160
+ right = exon[1]
161
+ else
162
+ right = exon[1]
163
+ end
164
+ end
165
+
166
+ @splice_location = results
167
+ return results
168
+ else
169
+ return @splice_location
170
+ end
171
+
172
+ end
173
+
174
+ def utr5location
175
+ return Bio::Locations.new(self.generef.strand == '+' ? "#{self[:exon][0][0]}..#{self[:cds][0][0] - 1}" : "complement(#{self[:cds][-1][1] + 1}..#{self[:exon][-1][1]})")
176
+ end
177
+
178
+ def utr3location
179
+ return Bio::Locations.new(self.generef.strand == '+' ? "#{self[:cds][-1][1] + 1}..#{self[:exon][-1][1]}" : "complement(#{self[:exon][0][0]}..#{self[:cds][0][0] - 1})")
180
+ end
181
+
182
+ # predict efect of variants
183
+ #
184
+ # @param [array] list of variants
185
+ #
186
+ # @return [array] list of predicted effect
187
+ # SPL-D splice_donor_variant SO:0001575
188
+ # SPL-A splice_acceptor_variant SO:0001574
189
+ # SPL-R splice_region_variant SO:0001630
190
+ # COD-SS
191
+ # COD-SN
192
+ # COD-DS
193
+ # COD-DN
194
+ # COD-IS
195
+ # COD-IN
196
+ # UTR-3
197
+ # UTR-5
198
+ # INT
199
+ # INI
200
+ # STO-L
201
+ # STO-G
202
+ # PRO
203
+ # TFB
204
+ def effect_pred(position, alt)
205
+
206
+ results = []
207
+
208
+ prot_pos = genomic2prot_pos(position)
209
+
210
+ if prot_pos
211
+ case alt
212
+ when /^-([ATCG])+/
213
+ results.push({vartype: $1.length % 3 == 0 ? 'COD-DS' : 'COD-DN'})
214
+ when /^\+([ATCG])+/
215
+ results.push({vartype: ($1.length - 1) % 3 == 0 ? 'COD-IS' : 'COD-IN'})
216
+ else
217
+ results.push({vartype: 'COD-SS'})
218
+ end
219
+ else
220
+ #case
221
+ #when test
222
+ # #code
223
+ #when test
224
+ # #code
225
+ #else
226
+ # results.push({vartype: 'INT'})
227
+ #end
228
+ end
229
+
230
+ results.push({vartype: splice_rel_location[position]}) if splice_rel_location.has_key?(position)
231
+
232
+ return results
233
+
234
+ end
235
+ end
236
+
237
+ end
@@ -28,7 +28,7 @@ module Exodb
28
28
  PATTERN = /(?<gene>[A-Z0-9]+)-?(?<position>[0-9,]*|[is]?)(?<to>[A-Z=]*)/
29
29
  SILENTSIGN = '='
30
30
 
31
- include Exodb::GenomeLocationField
31
+ include Exodb::VarLocationField
32
32
 
33
33
  field :reference, type: String
34
34
  field :alternate, type: String
@@ -48,339 +48,35 @@ module Exodb
48
48
 
49
49
  end
50
50
 
51
- class Generef < Reference
52
-
53
- include Exodb::GenomeLocationField
54
-
55
- field :sequence, type: String
56
- field :chrrefseq, type: String # refseq id of chromomose
57
- field :psuedo, type: Boolean
58
- field :genomeref, type: String
59
-
60
- index({sequence: 'text'}, background: true)
61
-
62
- has_many :genes
63
- embeds_many :isoforms
64
- embeds_many :occurrents
65
-
66
- validates_format_of :chrrefseq, with: /\A(urn:miriam:refseq)/
67
-
68
-
69
- # Download sequence from web service please use by caution. NCBI will block scamming sequest
70
- #
71
- def dl_seq!
72
-
73
- case self.chrrefseq
74
- when /\Aurn:miriam:refseq:/
75
- self.sequence = Bio::FastaFormat.new(Bio::NCBI::REST.efetch(self.chrrefseq.split(':', 4), {"db"=>"nucleotide", "rettype"=>"fasta", "retmode"=>"text", "seq_start"=>self.start, "seq_stop"=>self.end})).seq
76
- end
77
-
78
- self.save!
79
-
80
- end
81
-
82
- # Download gene symbol from HGNC service
83
- #
84
- def dl_symbol!
85
-
86
- baseuri = "http://rest.genenames.org/search"
87
-
88
-
89
- query = ""
90
-
91
- if self.get_xref('urn:miriam:refseq')
92
- query = "#{baseuri}/refseq_accession/#{self.chrrefseq.id.split('.')[0]}"
93
- elsif self.get_xref('urn:miriam:ncbigene')
94
- query = ""
95
- end
96
-
97
- if !query.empty?
98
- response = JSON.parse(open(query, 'Accept' => 'application/json').read)['response']
99
- if !response['docs'].empty?
100
-
101
- response['docs'].each do |e|
102
- self.add_to_set(:xrefs, "urn:miriam:hgnc:#{e["hgnc_id"]}")
103
- self.add_to_set(:xrefs, "urn:miriam:hgnc.symbol:#{e["symbol"]}")
104
- end
105
-
106
- self.save!
107
-
108
- end
109
-
110
- end
111
-
112
- end
113
-
114
- # Download incident data from TCGA
115
- #
116
- def dl_occurrent!
117
-
118
- if self.get_xref('urn:miriam:hgnc.symbol')
119
-
120
- cancerstudies = []
121
-
122
- open("http://www.cbioportal.org/public-portal/webservice.do?cmd=getCancerStudies") {|f|
123
- f.each_line {|line| cancerstudies.push(line.chomp.split("\t")[0])}
124
- }
125
-
126
- occurrents = {}
127
- totalcase = {}
128
-
129
- cancerstudies.each do |study|
130
-
131
- totalcase[study] = 0 if !totalcase.has_key?(study)
132
-
133
- open("http://www.cbioportal.org/public-portal/webservice.do?cmd=getCaseLists&cancer_study_id=#{study}") do |f|
134
- f.each_line do |line|
135
- totalcase[study] += line.chomp.split(/\t/)[4].split(' ').length if line =~ /\tSequenced Tumors\t/
136
- end
137
- end
138
-
139
- occurrents[study] = {} if !occurrents.has_key?(study)
140
-
141
- open("http://www.cbioportal.org/public-portal/webservice.do?cmd=getMutationData&genetic_profile_id=#{study}_mutations&gene_list=#{self.get_xref('urn:miriam:hgnc.symbol').id}") do |f|
142
- f.each_line do |line|
143
- dat = line.chomp.split(/\t/)
144
-
145
- if dat[5] == 'Missense_Mutation'
146
-
147
- occurrents[study][dat[7].split(/(\d+)/)[1]] = [] if !occurrents[study].has_key?(dat[7].split(/(\d+)/)[1])
148
- occurrents[study][dat[7].split(/(\d+)/)[1]].push(dat[2])
149
-
150
- end
151
-
152
- end
153
-
154
-
155
- end
156
- end
157
-
158
- self.occurrents.clear if self.occurrents
159
-
160
- occurrents.each_pair do |cancertype, v|
161
- v.each_pair do |position, occur|
162
- self.occurrents << Occurrent.new({cancertype: cancertype, position: position, occur: occur.uniq.sort, casenumber: totalcase[cancertype]})
163
- end
164
- end
165
-
166
- self.save!
167
-
168
- end
169
-
170
- end
171
-
172
- # return sequence as Bio::Sequence object
173
- #
174
- # @return [Bio::Sequence] the contents reversed lexically
175
- def to_seq
176
- return self.sequence ? Bio::Sequence.auto(self.sequence) : Bio::Sequence.auto("")
177
- end
178
-
179
- # return longest splice of this gene
180
- def longest_splice()
181
- length = 0
182
- longest = nil
183
- self.isoforms.each do |e|
184
-
185
- if e.prot_len > length
186
- length = e.prot_len
187
- longest = e
188
- end
189
-
190
- end
191
-
192
- return longest
193
- end
194
-
195
- # Check that this gene has any splice variant
196
- #
197
- # @return [Boolean] true if has any splices
198
- def has_splices?
199
- return self.isoforms.exists?
200
- end
201
-
202
- # Check if Generef has sequence
203
- #
204
- # @return [Boolean] Return true if there is a sequence
205
- def has_sequence?()
206
- return self[:sequence] ? true : false
207
- end
208
-
209
- # Check if Generef can translate
210
- #
211
- # @return [Boolean] Return true if this can be translate
212
- def can_translated?()
213
- return self.has_sequence? && self.has_splices? && self.longest_splice != nil ? true : false
214
- end
215
-
216
- # Get gene symbol
217
- #
218
- # @return [String] Return gene symbol or any id from xrefs or 'nosymbol'
219
- def symbol
220
-
221
- if self.get_xref('urn:miriam:hgnc.symbol')
222
- return self.get_xref('urn:miriam:hgnc.symbol').id
223
- elsif self.xrefs && !self.xrefs.empty?
224
- return self.xrefs.sort[0].id
225
- else
226
- return 'nosymbol'
227
- end
228
-
229
- end
230
-
231
- end
232
-
233
- class Isoform
51
+ class Mapping
234
52
 
235
53
  include Mongoid::Document
236
54
 
237
- include Exodb::XrefsField
238
-
239
- field :exon, type: Array
240
- field :cds, type: Array
241
-
242
- embedded_in :generef
243
-
244
- # join exon or cds position into a string
245
- #
246
- # @param [Array] input array exon or cds
247
- # @param [Interger] Position to stop positive value for forward read negative value for complement
248
- #
249
- # @return [String] a string in start..end,start..end,...
250
- def get_join_str(arr, position = 0)
251
-
252
- reducer = self.generef.start - 1
253
- tmparr = []
254
- found = false
255
-
256
- if position > 0
257
- add = true
258
- arr.each do |e|
259
-
260
- if e[0] <= position && position <= e[1]
261
- tmparr.push([e[0], position])
262
- add = false
263
- found = true
264
- else
265
- tmparr.push(e) if add
266
- end
267
-
268
- end
269
- elsif position < 0
270
- position = position.abs
271
- add = false
272
- arr.each do |e|
273
-
274
- if e[0] <= position && position <= e[1]
275
- tmparr.push([position, e[1]])
276
- add = true
277
- found = true
278
- else
279
- tmparr.push(e) if add
280
- end
281
-
282
- end
283
- else
284
- tmparr = arr
285
- end
286
-
287
- tmparr = [] if !found && position != 0
288
- str = []
289
-
290
- tmparr.each do |e|
291
- str.push("#{e[0] - reducer}..#{e[1] - reducer}")
292
- end
293
- return str.join(',')
294
-
295
- end
296
-
297
- def get_exon_join(position = 0)
298
- get_join_str(self[:exon], position)
299
- end
300
-
301
- def get_cds_join(position = 0)
302
- get_join_str(self[:cds], position)
303
- end
304
-
305
- # Get spliced DNA sequence
306
- #
307
- # @return [Bio::Sequence] an DNA sequence
308
- def get_dna_seq
309
- parent = self.generef
310
- return parent.strand == '+' ? parent.to_seq.splicing("join(#{self.get_exon_join})") : parent.to_seq.splicing("complement(join(#{self.get_exon_join}))")
311
- end
312
-
313
- # Get spliced RNA sequence
314
- #
315
- # @return [Bio::Sequence] an RNA sequence
316
- def get_mrna_seq
317
- parent = self.generef
318
- return parent.strand == '+' ? parent.to_seq.splicing("join(#{self.get_exon_join})").rna : parent.to_seq.splicing("complement(join(#{self.get_exon_join}))").rna
319
- end
320
-
321
- # Get spliced coding region sequence
322
- #
323
- # @param [Integer] end position to get sequence
324
- #
325
- # @return [Bio::Sequence] an coding region sequence
326
- def get_cds_seq(position = 0)
327
-
328
- parent = self.generef
329
- if parent.strand == '+'
330
- join = self.get_cds_join(position)
331
- return !join.empty? ? parent.to_seq.splicing("join(#{join})") : ""
332
- else
333
- join = self.get_cds_join(-position)
334
- return !join.empty? ? parent.to_seq.splicing("join(#{join})") : ""
55
+ field :chr, type: String
56
+ field :start, type: Integer
57
+ field :stop, type: Integer
58
+ field :tchr, type: String
59
+ field :tstart, type: Integer
60
+ field :tstop, type: Integer
61
+ field :coeff, type: Integer # coefficient for conversion
62
+ field :from, type: String # from assembly version
63
+ field :to, type: String # to assembly version
64
+
65
+ index({oid: 1, chr: 1, start: 1, stop: 1, from: 1, to: 1}, background: true)
66
+
67
+ def self.convert(locstr, target = Exodb::LATESTASSEMBLY)
68
+ begin
69
+ query = parse_locstr(locstr)
70
+ return self.where({from: query['assembly'], to: target, :start.lte => query[:pos], :stop.gte => query[:pos]}).first.convert(query[:pos])
71
+ rescue
72
+
335
73
  end
336
-
337
74
  end
338
75
 
339
- # Get spliced protein sequence
340
- #
341
- # @return [Bio::Sequence] an protein sequence
342
- def get_prot_seq
343
- parent = self.generef
344
- return parent.strand == '+' ? parent.to_seq.splicing("join(#{self.get_cds_join})").translate : parent.to_seq.splicing("complement(join(#{self.get_cds_join}))").translate
345
- end
346
-
347
- # get length of spliced RNA
348
- #
349
- # @return [Integer] length of spliced RNA
350
- def rna_len
351
- return self.get_mrna_seq.length
352
- end
353
-
354
- # get length of protein product
355
- #
356
- # @return [Integer] length of protein product
357
- def prot_len
358
- return self.get_prot_seq.length
359
- end
360
-
361
- # Get the codon sequence at the giving position base on position of amino acid
362
- #
363
- # @param [Integer] codon position
364
- # @return [Bio::Sequence] the codon at given position
365
- def get_codon(codon_pos)
366
- return self.get_cds_seq().subseq(((codon_pos - 1) * 3) + 1 , ((codon_pos - 1) * 3) + 3)
367
- end
368
-
369
- # convert genomic position to codon position
370
- #
371
- # @param [Integer] genomic position
372
- # @return [Array] Return all information of codon at given position
373
- def get_prot_pos(pos)
374
-
375
- seqlen = self.get_cds_seq(pos).length
376
- if seqlen != 0
377
- return [((seqlen - 1) / 3) + 1, ((seqlen - 1) % 3) + 1]
378
- else
379
- return []
380
- end
381
-
76
+ def convert(pos)
77
+ return "#{self[:tchr]}:#{(coeff > 0 ? tstart : tstop) + ((pos - self[:start]) * coeff)}:#{to}"
382
78
  end
383
79
 
384
80
  end
385
81
 
386
- end
82
+ end