rbbt-rest 1.6.2 → 1.6.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rbbt/rest/common/misc.rb +10 -0
  3. data/lib/rbbt/rest/workflow/jobs.rb +8 -7
  4. data/share/views/compass/app.sass +278 -3
  5. data/share/views/compass/base/color.sass +66 -0
  6. data/share/views/compass/blocks.sass +0 -0
  7. data/share/views/compass/mixins/_blocks.sass +76 -80
  8. data/share/views/compass/mixins/_compass.sass +0 -0
  9. data/share/views/compass/mixins/_hide.sass +76 -1
  10. data/share/views/compass/table.sass +142 -0
  11. data/share/views/compass/variables/colors.sass +7 -0
  12. data/share/views/compass/variables/sizes.sass +5 -0
  13. data/share/views/entity_partials/action_card.haml +5 -5
  14. data/share/views/entity_partials/action_controller.haml +31 -33
  15. data/share/views/entity_partials/entity_card.haml +28 -27
  16. data/share/views/entity_partials/entity_list_card.haml +30 -42
  17. data/share/views/entity_partials/entity_map_card.haml +35 -43
  18. data/share/views/entity_partials/list_container.haml +6 -6
  19. data/share/views/layout.haml +53 -59
  20. data/share/views/layout/coda.haml +1 -0
  21. data/share/views/layout/doctype.haml +8 -0
  22. data/share/views/layout/footer.haml +36 -10
  23. data/share/views/layout/header.haml +47 -0
  24. data/share/views/layout/top_menu.haml +27 -13
  25. data/share/views/partials/form.haml +4 -4
  26. data/share/views/partials/table.haml +2 -1
  27. data/share/views/partials/table/column.haml +8 -9
  28. data/share/views/partials/table/files.haml +2 -2
  29. data/share/views/partials/table/filters.haml +16 -16
  30. data/share/views/partials/table/page.haml +9 -15
  31. data/share/views/public/js/ng-favourites.js +13 -0
  32. data/share/views/public/js/rbbt.aesthetics.js +51 -0
  33. data/share/views/public/js/rbbt.entity.js +62 -0
  34. data/share/views/public/js/rbbt.entity_list.js +54 -0
  35. data/share/views/public/js/rbbt.entity_map.js +52 -0
  36. data/share/views/public/js/rbbt.favourites.js +286 -0
  37. data/share/views/public/js/rbbt.favourites.js.old +195 -0
  38. data/share/views/public/js/rbbt.js +40 -0
  39. data/share/views/public/js/rbbt.knowledge_base.js +24 -0
  40. data/share/views/public/js/rbbt.page.js +32 -0
  41. data/share/views/public/js/rbbt/actions.js +15 -14
  42. data/share/views/public/js/rbbt/table.js +6 -4
  43. data/share/views/tools/cytoscape.haml +310 -0
  44. data/share/views/tools/protein_tool.haml +383 -0
  45. data/share/views/tools/protein_tool/controls.haml +315 -0
  46. metadata +23 -2
@@ -0,0 +1,383 @@
1
+ - position = nil unless defined? position
2
+ - sequence = protein.sequence
3
+ - jmol_id = 'Jmol-' << protein
4
+ - select_id = jmol_id + '-select'
5
+ - pdbs = protein.pdbs
6
+ - position = nil unless defined? position
7
+ - colors = %w(red blue green yellow black white purple)
8
+
9
+ - organism = protein.organism
10
+ - uni = Organism.protein_identifiers(organism).index :target => "UniProt/SwissProt Accession", :persist => true
11
+
12
+ :sass
13
+ .protein_tool > .controls
14
+ float: right
15
+ margin-bottom: -1px
16
+ .tabular.menu
17
+ width: 300px
18
+
19
+ .protein_tool.very.basic.ui.segment(id=id)
20
+ .controls
21
+ .ui.action.input
22
+ %input(placeholder='Position' type='text' name='position')
23
+ .mark.submit.ui.button Mark
24
+ .clear.submit.ui.button Clear
25
+ .align.submit.ui.button Align
26
+ .ui.tabular.menu.top.attached
27
+ .item.active(data-tab='Sequence') Sequence
28
+ .item(data-tab='JMol') JMol
29
+ .item(data-tab='COSMIC') COSMIC
30
+ .window.bottom.attached.ui.segment
31
+ .secondary_structure.active.very.basic.ui.segment.tab(data-tab='Sequence' style='background:white')
32
+ .svg(data-sequence_length='#{sequence.length}')
33
+ - log :svg, "Downloading SVG"
34
+ - begin
35
+ = protein.marked_svg([])
36
+ - rescue Exception
37
+ %p.error.ui.message
38
+ Could not download protein SVG, try again later.
39
+ %pre=$!.message
40
+ .sequence(style='width: 677px; overflow-x: auto;font-family: monospace;margin-left:123px')
41
+ %span.sequence(width="100%")= sequence
42
+ %span.marks(width="100%")
43
+ - size = sequence.length
44
+ - marks = size / 10
45
+ - str = ""
46
+ - marks.times do |mark|
47
+ - txt = "|"
48
+ - str << ("_" * (10 - txt.length)) << txt
49
+ = str
50
+ %span.counts(width="100%")
51
+ - size = sequence.length
52
+ - marks = size / 10
53
+ - str = ""
54
+ - marks.times do |mark|
55
+ - mark = (mark + 1) * 10
56
+ - txt = mark.to_s
57
+ - str << ("_" * (10 - txt.length)) << txt
58
+ = str
59
+ %p.scroll.ui.message
60
+ Scroll horizontaly across the sequence
61
+
62
+ .jmol.very.basic.ui.segment.tab(data-tab='JMol')
63
+
64
+ .ui.field
65
+ %label(for=select_id) Load a structure PDB
66
+ %select.pdb(id=select_id style='width: 200px')
67
+ %option(selected="selected") Select a PDB
68
+ - (pdbs || []).each do |pdb, info|
69
+ %option(attr-pdb="=#{pdb}")= "#{pdb}"
70
+ - uniprot = uni[protein]
71
+
72
+ - if uniprot and Structure::I3D_PROTEINS.include? uniprot
73
+ - filepos = Structure::I3D_PROTEINS.identify_field "FILENAME"
74
+ - Structure::I3D_PROTEINS[uniprot][filepos].each do |filename|
75
+ - type = filename =~ /EXP/ ? :pdb : :model
76
+ - url = "http://interactome3d.irbbarcelona.org/pdb.php?dataset=human&type1=proteins&type2=#{ type }&pdb=#{ filename }"
77
+ -# url = "http://darthcaedus:28873/" << ["Structure", "get_protein_pdb"] * "/" << "?" << Misc.hash2GET_params(:_format => :raw, :filename => filename)
78
+ %option.protein(attr-pdb=url)= "#{filename}"
79
+
80
+ - if uniprot and Structure::I3D_INTERACTIONS.include? uniprot
81
+ - filepos = Structure::I3D_INTERACTIONS.identify_field "FILENAME"
82
+ - Structure::I3D_INTERACTIONS[uniprot][filepos].each do |filename|
83
+ - type = filename =~ /EXP/ ? :pdb : :model
84
+ - url = "http://interactome3d.irbbarcelona.org/pdb.php?dataset=human&type1=interactions&type2=#{ type }&pdb=#{ filename }"
85
+ -# url = "http://darthcaedus:28873/" << ["Structure", "get_interaction_pdb"] * "/" << "?" << Misc.hash2GET_params(:_format => :raw, :filename => filename)
86
+ %option.interaction(attr-pdb=url)= "#{filename}"
87
+ .window
88
+
89
+ .COSMIC.very.basic.ui.segment.tab(data-tab='COSMIC')
90
+ = fragment do
91
+ .highlight.submit.ui.button Highlight
92
+ .ui.message
93
+ In JMol positions with 1 mutation are white, with 2 are green, with 3 are orange, and with more than 3 are red
94
+ -#%select(name='color')
95
+ - colors.each do |c|
96
+ %option(value=c)= c
97
+
98
+
99
+ - header "Genomic Mutation", "GenomicMutation", {:organism => Organism.default_code("Hsa"), :watson => false}
100
+ - filter "Primary site"
101
+ = table :table_id => "COSMIC mutations for #{ protein.name || protein }", :row_ids => :consume do
102
+ - association_items = COSMIC.knowledge_base.subset(:mutation_protein_changes, :target => [protein], :source => :all)
103
+ - associations = association_items.tsv.to_double
104
+
105
+ - log :sample_mutations
106
+ - sample_mutations = COSMIC.knowledge_base.get_database(:sample_mutations, :type => :double, :merge => true, :target => "Sample name=~Sample", :source => "Genomic Mutation")
107
+ - sample_mutations.fields = ["Sample"]
108
+
109
+ - associations = associations.attach(sample_mutations)
110
+
111
+ - log :sample_info
112
+ - sample_info = COSMIC.sample_info.find.tsv
113
+ - sample_info.key_field = "Sample"
114
+
115
+ - associations = associations.attach(sample_info)
116
+
117
+ - good_fields = associations.fields - ["Ensembl Protein ID"]
118
+
119
+ - log :slice_and_show
120
+ - associations.slice(good_fields)
121
+
122
+ :deferjs
123
+
124
+ $('.highlight.submit').click(function(){
125
+ var link = $(this);
126
+ var COSMIC = link.parents('.COSMIC').first();
127
+ var protein_tool = COSMIC.parents('.protein_tool').first();
128
+ var svg_element = protein_tool.find('.svg').first();
129
+ var jmol_element = protein_tool.find('.jmol').first();
130
+
131
+ var table = COSMIC.find('table');
132
+ var url = table.attr('attr-url');
133
+ var filter = table.attr('attr-filter');
134
+
135
+ url = add_parameter(url, '_format', 'json')
136
+ url = add_parameter(url, '_page', 'all')
137
+ url = add_parameter(url, '_column', 'Change')
138
+ if (undefined != filter){ url = add_parameter(url, '_filter', escape(filter)) }
139
+
140
+ var color = 'red'
141
+
142
+ $.ajax({
143
+ url: url,
144
+ success: function(data){
145
+ data = JSON.parse(data);
146
+ var change_positions = [];
147
+ for (mutation in data){
148
+ var change = data[mutation][0];
149
+ var samples = data[mutation][1];
150
+ if (m = change.match(/[A-Z*](\d*)[A-Z*]/)){
151
+ change_positions.push(parseInt(m[1]));
152
+ }
153
+ }
154
+ var change_counts = []
155
+
156
+ for (i in change_positions){
157
+ var position = change_positions[i]
158
+ if (change_counts[position] === undefined){
159
+ change_counts[position] = 1
160
+ }else{
161
+ change_counts[position] = change_counts[position] + 1
162
+ }
163
+ }
164
+
165
+ var protein_tool = $('.protein_tool#' + '#{id}');
166
+ rbbt.svg.mark_positions(svg_element, change_positions, color);
167
+ for (position in change_counts){
168
+ var jcolor = 'white';
169
+ if (change_counts[position] > 1) jcolor = 'green'
170
+ if (change_counts[position] > 2) jcolor = 'organge'
171
+ if (change_counts[position] > 3) jcolor = 'red'
172
+
173
+ rbbt.jmol.mark_position(jmol_element, position, jcolor);
174
+ }
175
+
176
+ }
177
+ })
178
+ return false;
179
+ })
180
+
181
+ :sass
182
+ .jmol:not(.active)
183
+ display: block !important
184
+ visibility: hidden
185
+ height: 0px
186
+
187
+ :deferjs
188
+ rbbt.sequence = {}
189
+ $('.tabular.menu .item').tab()
190
+
191
+ $('svg').attr('viewport-fill', 'white')
192
+ rbbt.sequence.clear = function(element){
193
+ var seq = element.find('span.sequence');
194
+ var marked_chars = seq.find('.sequence_char_position')
195
+ marked_chars.each(function(marked_char){ marked_char = $(this); marked_char.replaceWith(marked_char.html()) })
196
+ }
197
+
198
+ rbbt.sequence.mark_position = function(element, position, color){
199
+ if (undefined === color) color = 'red';
200
+ var seq = element.find('span.sequence');
201
+ var str = seq.html();
202
+ var char_pos = position - 1;
203
+ str = str.slice(0, char_pos) + $('<span class="sequence_char_position" data-sequence_position=' + position + ' style="color:' + color + '">' + str[char_pos] + '</span>')[0].outerHTML + str.slice(char_pos+1)
204
+ seq.html(str)
205
+ }
206
+
207
+ rbbt.svg = {}
208
+
209
+ rbbt.svg.clear = function(element){
210
+ var svg = element.find('svg');
211
+ var vlines = svg.find('.rbbt-vline')
212
+ vlines.remove()
213
+ var vregions = svg.find('.rbbt-region')
214
+ vregions.remove()
215
+ }
216
+
217
+ rbbt.svg.position_offset = function(element, position){
218
+ var svg = element.find('svg');
219
+ var width = parseInt(svg.attr('width'));
220
+ var start = parseInt(svg.find('rect.ac').attr('x'));
221
+ var seq_len = parseInt(element.attr('data-sequence_length'));
222
+ return start + position * (width - start)/seq_len
223
+ }
224
+
225
+ rbbt.svg.mark_position = function(element, position, color){
226
+ if (undefined === color) color = 'red';
227
+ var svg = element.find('svg');
228
+
229
+ var width = parseInt(svg.attr('width'));
230
+ var height = parseInt(svg.attr('height'));
231
+ var offset = rbbt.svg.position_offset(element, position)
232
+
233
+ var line = document.createElementNS("http://www.w3.org/2000/svg", "line");
234
+ line.setAttributeNS(null, "x1", offset);
235
+ line.setAttributeNS(null, "y1", 5);
236
+ line.setAttributeNS(null, "x2", offset);
237
+ line.setAttributeNS(null, "y2", height - 5);
238
+ line.setAttributeNS(null, "class", 'rbbt-vline');
239
+ line.setAttributeNS(null, "style", "stroke:" + color + ";opacity:0.5;stroke-width:1;");
240
+
241
+ svg.append(line);
242
+ }
243
+
244
+ rbbt.svg.mark_positions = function(element, positions, color){
245
+ for ( i in positions){
246
+ var position = positions[i]
247
+ rbbt.svg.mark_position(element, position, color)
248
+ }
249
+ }
250
+
251
+ rbbt.svg.mark_region = function(element, first, last, color){
252
+ var svg = element.find('svg')
253
+ var width = parseInt(svg.attr('width'));
254
+ var height = parseInt(svg.attr('height'));
255
+ var start = parseInt(svg.find('rect.ac').attr('x'));
256
+ var seq_len = parseInt(element.attr('data-sequence_length'));
257
+
258
+ var offset_start = rbbt.svg.position_offset(element, first)
259
+ var offset_end = rbbt.svg.position_offset(element, last)
260
+
261
+ var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
262
+
263
+ rect.setAttributeNS(null, "x", offset_start);
264
+ rect.setAttributeNS(null, "class", 'rbbt-region');
265
+ rect.setAttributeNS(null, "y", 10);
266
+ rect.setAttributeNS(null, "width", offset_end - offset_start);
267
+ rect.setAttributeNS(null, "height", height - 30);
268
+ rect.setAttributeNS(null, "style", "stroke:black;stroke-width: 2; opacity:0.3;fill:" + color + ";");
269
+
270
+ svg.append(rect);
271
+ }
272
+
273
+ rbbt.svg.mark_aligned_region = function(element, map, color){
274
+ if (undefined === color) color = 'blue'
275
+
276
+ var positions = []
277
+ for(seq_pos in map){
278
+ positions.push(parseInt(seq_pos))
279
+ }
280
+
281
+ positions = positions.sort();
282
+ console.log(positions)
283
+ var last = -1
284
+ var start = -1;
285
+ for (var i = 0; i < positions.length; i++){
286
+ if (positions[i] != last + 1){
287
+ if (start != -1) { rbbt.svg.mark_region(element, start, last, color); }
288
+ start = positions[i]
289
+ }
290
+ last = positions[i]
291
+ }
292
+ if (start != -1) { rbbt.svg.mark_region(element, start, last, color); }
293
+ }
294
+
295
+
296
+ rbbt.jmol = {}
297
+ rbbt.jmol.clear = function(element){
298
+ element.jmol_tool('clear')
299
+ }
300
+ rbbt.jmol.mark_position = function(element, position, color){
301
+ if (undefined === color) color = 'red'
302
+ element.jmol_tool('mark_position', position, color)
303
+ }
304
+
305
+ rbbt.jmol.mark_positions = function(element, positions, color){
306
+ for (i in positions){
307
+ var position = positions[i]
308
+ rbbt.jmol.mark_position(element, position, color)
309
+ }
310
+ }
311
+
312
+ require_js("/js/jmol.js", function(){
313
+ var position = #{position ? position : "undefined"}
314
+ var tool = $('.jmol').last().jmol_tool({protein:"#{ protein }", sequence: "#{protein.sequence}"});
315
+
316
+ $('select.pdb').change(function(){
317
+ var option = $(this).find('option:selected');
318
+ var pdb = option.attr('attr-pdb');
319
+ if (pdb == "Select a pdb") return false
320
+ tool.jmol_tool("load_pdb", pdb)
321
+ clean = pdb.replace(/=/,'')
322
+ tool.find('.pdb_info > dd.pdbfile').html(clean)
323
+
324
+ if (position !== undefined){
325
+ tool.jmol_tool("clear")
326
+ tool.jmol_tool("mark_position", position, 'red')
327
+ }
328
+ })
329
+ })
330
+
331
+
332
+ $('.clear.submit').click(function(){
333
+ var link = $(this);
334
+ var controls = link.parents('.controls').first();
335
+ var protein_tool = controls.parents('.protein_tool').first();
336
+ var sequence_element = protein_tool.find('.sequence').first();
337
+ var svg_element = protein_tool.find('.svg').first();
338
+ var jmol_element = protein_tool.find('.jmol').first();
339
+
340
+ rbbt.sequence.clear(sequence_element)
341
+ rbbt.svg.clear(svg_element)
342
+ rbbt.jmol.clear(jmol_element)
343
+ })
344
+
345
+ $('.mark.submit').click(function(){
346
+ var link = $(this);
347
+ var controls = link.parents('.controls').first();
348
+ var protein_tool = controls.parents('.protein_tool').first();
349
+ var sequence_element = protein_tool.find('.sequence').first();
350
+ var svg_element = protein_tool.find('.svg').first();
351
+ var jmol_element = protein_tool.find('.jmol').first();
352
+
353
+ var position = parseInt(controls.find('input[name=position]').val());
354
+
355
+ if (! position > 0) return alert("No position specified")
356
+
357
+ rbbt.sequence.clear(sequence_element)
358
+ rbbt.svg.clear(svg_element)
359
+
360
+ rbbt.sequence.mark_position(sequence_element, position)
361
+ rbbt.svg.mark_position(svg_element, position)
362
+ rbbt.jmol.mark_position(jmol_element, position)
363
+ })
364
+
365
+
366
+ $('.align.submit').click(function(){
367
+ var link = $(this);
368
+ var controls = link.parents('.controls').first();
369
+ var protein_tool = controls.parents('.protein_tool').first();
370
+ var svg_element = protein_tool.find('.svg').first();
371
+
372
+ var jmol = $('.jmol');
373
+
374
+ if(jmol.jmol_tool('is_pdb_loaded')){
375
+ var map = jmol.jmol_tool('alignment_map');
376
+ jmol.jmol_tool('mark_aligned_region', 'blue');
377
+ rbbt.svg.mark_aligned_region(svg_element, map, 'blue');
378
+ }else{
379
+ alert("Select a PDB")
380
+ }
381
+ return false;
382
+ })
383
+
@@ -0,0 +1,315 @@
1
+ - colors = %w(red blue green yellow black white purple)
2
+
3
+ .tool_menu.top.attached.tabular.ui.menu
4
+ - if user
5
+ .item(data-tab='Controls') Controls
6
+
7
+ .item(data-tab='Appris') Appris
8
+
9
+ .item(data-tab='COSMIC') COSMIC
10
+
11
+
12
+ - if user
13
+ .controls.bottom.attached.ui.tab.segment(data-tab='Controls')
14
+ = action_parameters nil, {:klass => ''}, :action => '#' do
15
+ - input :list, :select, "Genomic Mutation list", nil, :html_options => {:class => 'favourite_lists', :type => 'GenomicMutation'}
16
+ - input :color, :select, "Color to use", 'green', :select_options => colors
17
+
18
+ .appris.bottom.attached.ui.tab.segment(data-tab='Appris')
19
+ .controls.ui.form
20
+ .ui.field
21
+ %label Highlight color
22
+ %select.ui.select(name='color')
23
+ - colors.each do |c|
24
+ %option(value=c)= c
25
+ %dl
26
+ - (protein.appris_residues || []).each do |type, list|
27
+ %dt= Misc.humanize type
28
+ %dd
29
+ %ul.clean_list
30
+ - list.each do |range|
31
+ %li
32
+ %a.appris_highlight.ui.button(href="#" attr-start="#{range['start']}" attr-end="#{range['end']}") Highlight
33
+ == (#{range['start']}..#{range['end']})
34
+
35
+ :deferjs
36
+ $('a.appris_highlight, a.feature_highlight').click(function(){
37
+ var link = $(this)
38
+ var color = link.parents('dd').find('select').first().val();
39
+ var start = parseInt(link.attr('attr-start'));
40
+ var end = parseInt(link.attr('attr-end'));
41
+
42
+ var protein_tool = $(this).parents('.protein_tool').first()
43
+
44
+ if (start == end){
45
+ protein_tool.protein_tool('mark_position', start, color)
46
+ }else{
47
+ protein_tool.protein_tool('mark_region', start, end, color)
48
+ }
49
+ return false
50
+ })
51
+
52
+ .COSMIC.bottom.attached.ui.tab.segment(data-tab='COSMIC')
53
+ = fragment do
54
+
55
+ .highlight.ui.form
56
+ .ui.field
57
+ %label Highlight color
58
+ %select.ui.select(name='color')
59
+ - colors.each do |c|
60
+ %option(value=c)= c
61
+ %a.highlight.ui.button(href="#") highlight
62
+
63
+ - header "Genomic Mutation", "GenomicMutation", {:organism => Organism.default_code("Hsa"), :watson => false}
64
+ - filter "Primary site"
65
+ = table :table_id => "COSMIC mutations for #{ protein.name || protein }", :row_ids => :consume do
66
+ - association_items = COSMIC.knowledge_base.subset(:mutation_protein_changes, :target => [protein], :source => :all)
67
+ - associations = association_items.tsv.to_double
68
+
69
+ - log :sample_mutations
70
+ - sample_mutations = COSMIC.knowledge_base.get_database(:sample_mutations, :type => :double, :merge => true, :target => "Sample name=~Sample", :source => "Genomic Mutation")
71
+ - sample_mutations.fields = ["Sample"]
72
+
73
+ - associations = associations.attach(sample_mutations)
74
+
75
+ - log :sample_info
76
+ - sample_info = COSMIC.sample_info.find.tsv
77
+ - sample_info.key_field = "Sample"
78
+
79
+ - associations = associations.attach(sample_info)
80
+
81
+ - good_fields = associations.fields - ["Ensembl Protein ID"]
82
+
83
+ - log :slice_and_show
84
+ - associations.slice(good_fields)
85
+
86
+ :deferjs
87
+ $('.COSMIC ul.highlight > li > a.highlight').click(function(){
88
+
89
+ var table = $(this).parents('dd').first().find('table');
90
+ var url = table.attr('attr-url');
91
+ var filter = table.attr('attr-filter');
92
+
93
+ url = add_parameter(url, '_format', 'json')
94
+ url = add_parameter(url, '_page', 'all')
95
+ url = add_parameter(url, '_column', 'Change')
96
+ if (undefined != filter){ url = add_parameter(url, '_filter', escape(filter)) }
97
+
98
+ var color = $(this).parents('dd').first().find('select[name=color]').val();
99
+
100
+ $.ajax({
101
+ url: url,
102
+ success: function(data){
103
+ data = JSON.parse(data);
104
+ var change_positions = [];
105
+ for (mutation in data){
106
+ var change = data[mutation][0];
107
+ if (m = change.match(/[A-Z*](\d*)[A-Z*]/)){
108
+ change_positions.push(parseInt(m[1]));
109
+ }
110
+ }
111
+ var protein_tool = $('.protein_tool#' + '#{id}');
112
+ protein_tool.protein_tool('mark_positions', change_positions, color);
113
+ }
114
+ })
115
+ return false;
116
+ })
117
+
118
+
119
+ :deferjs
120
+ $('.tabular.menu > .item').tab()
121
+ -#
122
+
123
+ %dd.COSMIC
124
+ = fragment do
125
+
126
+ %ul.highlight
127
+ %li.button
128
+ %a.highlight(href="#") highlight
129
+ %li
130
+ %select(name='color')
131
+ - colors.each do |c|
132
+ %option(value=c)= c
133
+
134
+
135
+ - header "Genomic Mutation", "GenomicMutation", {:organism => Organism.default_code("Hsa"), :watson => false}
136
+ - filter "Primary site"
137
+ = table :table_id => "COSMIC mutations for #{ protein.name || protein }", :row_ids => :consume do
138
+ - association_items = COSMIC.knowledge_base.subset(:mutation_protein_changes, :target => [protein], :source => :all)
139
+ - associations = association_items.tsv.to_double
140
+
141
+ - log :sample_mutations
142
+ - sample_mutations = COSMIC.knowledge_base.get_database(:sample_mutations, :type => :double, :merge => true, :target => "Sample name=~Sample", :source => "Genomic Mutation")
143
+ - sample_mutations.fields = ["Sample"]
144
+
145
+ - associations = associations.attach(sample_mutations)
146
+
147
+ - log :sample_info
148
+ - sample_info = COSMIC.sample_info.find.tsv
149
+ - sample_info.key_field = "Sample"
150
+
151
+ - associations = associations.attach(sample_info)
152
+
153
+ - good_fields = associations.fields - ["Ensembl Protein ID"]
154
+
155
+ - log :slice_and_show
156
+ - associations.slice(good_fields)
157
+
158
+ :deferjs
159
+ $('.COSMIC ul.highlight > li > a.highlight').click(function(){
160
+
161
+ var table = $(this).parents('dd').first().find('table');
162
+ var url = table.attr('attr-url');
163
+ var filter = table.attr('attr-filter');
164
+
165
+ url = add_parameter(url, '_format', 'json')
166
+ url = add_parameter(url, '_page', 'all')
167
+ url = add_parameter(url, '_column', 'Change')
168
+ if (undefined != filter){ url = add_parameter(url, '_filter', escape(filter)) }
169
+
170
+ var color = $(this).parents('dd').first().find('select[name=color]').val();
171
+
172
+ $.ajax({
173
+ url: url,
174
+ success: function(data){
175
+ data = JSON.parse(data);
176
+ var change_positions = [];
177
+ for (mutation in data){
178
+ var change = data[mutation][0];
179
+ if (m = change.match(/[A-Z*](\d*)[A-Z*]/)){
180
+ change_positions.push(parseInt(m[1]));
181
+ }
182
+ }
183
+ var protein_tool = $('.protein_tool#' + '#{id}');
184
+ protein_tool.protein_tool('mark_positions', change_positions, color);
185
+ }
186
+ })
187
+ return false;
188
+ })
189
+
190
+ - if protein.uniprot
191
+ - uniprot_alignment, ensembl_alignment = SmithWaterman.align(UniProt.sequence(protein.uniprot), protein.sequence)
192
+ - alignment_map = Structure.alignment_map(uniprot_alignment, ensembl_alignment)
193
+
194
+ %dt.next UniProt mutations
195
+ %dd.UniProt
196
+ = fragment do
197
+
198
+ %ul.highlight
199
+ %li
200
+ %a.highlight(href="#") highlight
201
+ %li
202
+ %select(name='color')
203
+ - colors.each do |c|
204
+ %option(value=c)= c
205
+
206
+
207
+ = table :id => "UniProt mutations for #{ protein }" do
208
+ - tsv = UniProt.annotated_variants.tsv(:persist => true, :type => :double, :key_field => "UniProt Variant ID", :zipped => true, :namespace => protein.organism)
209
+ - tsv = tsv.select("UniProt/SwissProt Accession" => protein.uniprot)
210
+
211
+ - tsv.add_field "Aligned Change" do |key, values|
212
+ - change = values["Amino Acid Mutation"]
213
+ - change = change.first if Array === change
214
+ - if change.nil? or change.empty?
215
+ - [""]
216
+ - else
217
+ - wt, pos, mut = change.match(/([A-Z])(\d+)([A-Z*])/).values_at 1, 2, 3
218
+ - pos = alignment_map[pos.to_i]
219
+ - [[wt, pos, mut] * ""]
220
+ - tsv
221
+
222
+ :deferjs
223
+ $('.UniProt a.highlight').click(function(){
224
+ var table = $(this).parents('dd').first().find('table');
225
+ var url = table.attr('attr-url');
226
+ var filter = table.attr('attr-filter');
227
+
228
+ url = add_parameter(url, '_format', 'json')
229
+ url = add_parameter(url, '_page', 'all')
230
+ url = add_parameter(url, '_column', 'Aligned Change')
231
+ if (undefined != filter){ url = add_parameter(url, '_filter', escape(filter)) }
232
+
233
+ var color = $(this).parents('dd').first().find('select[name=color]').val();
234
+
235
+ $.ajax({
236
+ url: url,
237
+ success: function(data){
238
+ data = JSON.parse(data);
239
+ var change_positions = [];
240
+ for (mutation in data){
241
+ var changes = data[mutation];
242
+ for (i in changes){
243
+ var c = changes[i];
244
+ if (m = c.match(/(\d+)/)){
245
+ change_positions.push(parseInt(m[1]));
246
+ }
247
+ }
248
+ }
249
+ var protein_tool = $('.protein_tool#' + '#{id}');
250
+ protein_tool.protein_tool('mark_positions', change_positions, color);
251
+ }
252
+ })
253
+
254
+ return false;
255
+ })
256
+
257
+ %dt.next UniProt features
258
+ %dd.UniProt_features
259
+ .controls
260
+ %ul.controls
261
+ %li
262
+ %select(name='color')
263
+ - colors.each do |c|
264
+ %option(value=c)= c
265
+
266
+ - features = UniProt.features(protein.uniprot)
267
+ - feature_types = {}
268
+ - features.each{|info| feature_types[info[:type]] ||= [] ; feature_types[info[:type]] << info}
269
+ %dl
270
+ - feature_types.sort_by{|k,v| k}.each do |type, list|
271
+ %dt= type
272
+ %dd
273
+ - list.sort_by{|info| info[:start].to_i}.each do |info|
274
+ - type, start, eend, description = info.values_at :type, :start, :end, :description
275
+ - start = alignment_map[start]
276
+ - eend = alignment_map[eend]
277
+ - next if start.nil? or eend.nil?
278
+ %li
279
+ %a.feature_highlight(href="#" attr-start="#{start}" attr-end="#{eend}") Highlight
280
+ == #{ type } (#{start}..#{eend}): #{description}
281
+
282
+ :deferjs
283
+ $('.UniProt a.highlight').click(function(){
284
+ var table = $(this).parents('dd').first().find('table');
285
+ var url = table.attr('attr-url');
286
+ var filter = table.attr('attr-filter');
287
+
288
+ url = add_parameter(url, '_format', 'json')
289
+ url = add_parameter(url, '_page', 'all')
290
+ url = add_parameter(url, '_column', 'Aligned Change')
291
+ if (undefined != filter){ url = add_parameter(url, '_filter', escape(filter)) }
292
+
293
+ $.ajax({
294
+ url: url,
295
+ success: function(data){
296
+ data = JSON.parse(data);
297
+ var change_positions = [];
298
+ for (mutation in data){
299
+ var changes = data[mutation];
300
+ for (i in changes){
301
+ var c = changes[i];
302
+ if (m = c.match(/(\d+)/)){
303
+ change_positions.push(parseInt(m[1]));
304
+ }
305
+ }
306
+ }
307
+ var protein_tool = $('.protein_tool#' + '#{id}');
308
+ protein_tool.protein_tool('mark_positions', change_positions, color);
309
+ }
310
+ })
311
+
312
+ return false;
313
+ })
314
+
315
+