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.
- checksums.yaml +4 -4
- data/lib/exodb.rb +23 -0
- data/lib/exodb/addon/string.rb +139 -0
- data/lib/exodb/constant.rb +64 -0
- data/lib/exodb/datamodel.rb +4 -1
- data/lib/exodb/datamodel/genelocfield.rb +177 -0
- data/lib/exodb/datamodel/generef.rb +193 -0
- data/lib/exodb/datamodel/isoform.rb +237 -0
- data/lib/exodb/datamodel/reference.rb +23 -327
- data/lib/exodb/datamodel/region.rb +7 -5
- data/lib/exodb/datamodel/source.rb +1 -10
- data/lib/exodb/datamodel/variant.rb +14 -81
- data/lib/exodb/datamodel/varlocfield.rb +106 -0
- data/lib/exodb/datamodel/xrefsfield.rb +4 -0
- data/lib/exodb/extra.rb +17 -0
- data/lib/exodb/extra/upload.rb +43 -0
- data/lib/exodb/{utils → extra}/upload_generef.rb +35 -21
- data/lib/exodb/rositza/load.rb +56 -42
- data/lib/exodb/utils.rb +1 -2
- data/lib/exodb/utils/ensemblrest.rb +31 -3
- data/lib/exodb/utils/miriamrest.rb +23 -0
- data/lib/exodb/version.rb +1 -1
- metadata +10 -3
- data/lib/exodb/datamodel/locationfield.rb +0 -116
@@ -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::
|
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
|
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
|
-
|
238
|
-
|
239
|
-
field :
|
240
|
-
field :
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
#
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
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
|
-
|
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
|