exodb 0.1.2 → 0.1.3

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.
@@ -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