rbbt-rest 1.6.2 → 1.6.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.
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
+