rbbt-rest 1.6.5 → 1.6.6
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c8171c90d69575b3554125d4f2f4e26676c33a57
|
4
|
+
data.tar.gz: d6a2cc6d4f2bd526e631538f688de83f0dd23649
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bea46a56129ed371de3e787f847b30570b97e9da74bc46c129b15b20894a341ced2c1ba15f1ca5a6c19d514cff595da40c5ce0b25254e56b9cd8b29809e3ab6c
|
7
|
+
data.tar.gz: 289978f606c05cb55324a469ea703c8ae6328a9fba822778df957389db6ff1792c65920e42f4436016c6317a00d39805ff381efa92a735be3209c4f48771d95f
|
data/lib/rbbt/rest/web_tool.rb
CHANGED
@@ -5,6 +5,7 @@ module Sinatra
|
|
5
5
|
options[:id] ||= toolname.to_s + "_#{rand(10000)}"
|
6
6
|
|
7
7
|
template_file = locate_template("tools/#{toolname}")
|
8
|
+
Log.debug "Loading tool #{toolname} from: #{template_file}"
|
8
9
|
content = Tilt::HamlTemplate.new(template_file, :filename => template_file, :ugly => production?).render(self, options)
|
9
10
|
|
10
11
|
styles = begin
|
@@ -9,9 +9,10 @@
|
|
9
9
|
// Semantic-ui
|
10
10
|
|
11
11
|
|
12
|
-
-# record_css '/plugins/foundation-icons/foundation-icons.css'
|
13
12
|
- record_css '/plugins/semantic-ui/dist/semantic.min.css'
|
14
13
|
|
14
|
+
- record_css '/plugins/jquery-ui/css/custom-theme/jquery-ui-1.8.14.custom.css'
|
15
|
+
|
15
16
|
-# record_css '/stylesheets/layout'
|
16
17
|
-# record_css '/stylesheets/responsive'
|
17
18
|
-# record_css '/stylesheets/text'
|
@@ -39,6 +40,7 @@
|
|
39
40
|
- record_js '/plugins/jquery.tablesorter/jquery.tablesorter.min.js'
|
40
41
|
- record_js '/plugins/jquery.scrollTo/jquery.scrollTo'
|
41
42
|
- record_js '/plugins/semantic-ui/dist/semantic.min.js'
|
43
|
+
- record_js '/plugins/FileSaver/js/FileSaver.js'
|
42
44
|
|
43
45
|
- %w(helpers _md5 _ajax_replace _ellipsis).each do |file|
|
44
46
|
- record_js "/js-find/#{ file }"
|
@@ -0,0 +1,248 @@
|
|
1
|
+
/* FileSaver.js
|
2
|
+
* A saveAs() FileSaver implementation.
|
3
|
+
* 2015-03-04
|
4
|
+
*
|
5
|
+
* By Eli Grey, http://eligrey.com
|
6
|
+
* License: X11/MIT
|
7
|
+
* See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
|
8
|
+
*/
|
9
|
+
|
10
|
+
/*global self */
|
11
|
+
/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
|
12
|
+
|
13
|
+
/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
|
14
|
+
|
15
|
+
var saveAs = saveAs
|
16
|
+
// IE 10+ (native saveAs)
|
17
|
+
|| (typeof navigator !== "undefined" &&
|
18
|
+
navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator))
|
19
|
+
// Everyone else
|
20
|
+
|| (function(view) {
|
21
|
+
"use strict";
|
22
|
+
// IE <10 is explicitly unsupported
|
23
|
+
if (typeof navigator !== "undefined" &&
|
24
|
+
/MSIE [1-9]\./.test(navigator.userAgent)) {
|
25
|
+
return;
|
26
|
+
}
|
27
|
+
var
|
28
|
+
doc = view.document
|
29
|
+
// only get URL when necessary in case Blob.js hasn't overridden it yet
|
30
|
+
, get_URL = function() {
|
31
|
+
return view.URL || view.webkitURL || view;
|
32
|
+
}
|
33
|
+
, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
|
34
|
+
, can_use_save_link = "download" in save_link
|
35
|
+
, click = function(node) {
|
36
|
+
var event = doc.createEvent("MouseEvents");
|
37
|
+
event.initMouseEvent(
|
38
|
+
"click", true, false, view, 0, 0, 0, 0, 0
|
39
|
+
, false, false, false, false, 0, null
|
40
|
+
);
|
41
|
+
node.dispatchEvent(event);
|
42
|
+
}
|
43
|
+
, webkit_req_fs = view.webkitRequestFileSystem
|
44
|
+
, req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem
|
45
|
+
, throw_outside = function(ex) {
|
46
|
+
(view.setImmediate || view.setTimeout)(function() {
|
47
|
+
throw ex;
|
48
|
+
}, 0);
|
49
|
+
}
|
50
|
+
, force_saveable_type = "application/octet-stream"
|
51
|
+
, fs_min_size = 0
|
52
|
+
// See https://code.google.com/p/chromium/issues/detail?id=375297#c7 and
|
53
|
+
// https://github.com/eligrey/FileSaver.js/commit/485930a#commitcomment-8768047
|
54
|
+
// for the reasoning behind the timeout and revocation flow
|
55
|
+
, arbitrary_revoke_timeout = 500 // in ms
|
56
|
+
, revoke = function(file) {
|
57
|
+
var revoker = function() {
|
58
|
+
if (typeof file === "string") { // file is an object URL
|
59
|
+
get_URL().revokeObjectURL(file);
|
60
|
+
} else { // file is a File
|
61
|
+
file.remove();
|
62
|
+
}
|
63
|
+
};
|
64
|
+
if (view.chrome) {
|
65
|
+
revoker();
|
66
|
+
} else {
|
67
|
+
setTimeout(revoker, arbitrary_revoke_timeout);
|
68
|
+
}
|
69
|
+
}
|
70
|
+
, dispatch = function(filesaver, event_types, event) {
|
71
|
+
event_types = [].concat(event_types);
|
72
|
+
var i = event_types.length;
|
73
|
+
while (i--) {
|
74
|
+
var listener = filesaver["on" + event_types[i]];
|
75
|
+
if (typeof listener === "function") {
|
76
|
+
try {
|
77
|
+
listener.call(filesaver, event || filesaver);
|
78
|
+
} catch (ex) {
|
79
|
+
throw_outside(ex);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
}
|
83
|
+
}
|
84
|
+
, FileSaver = function(blob, name) {
|
85
|
+
// First try a.download, then web filesystem, then object URLs
|
86
|
+
var
|
87
|
+
filesaver = this
|
88
|
+
, type = blob.type
|
89
|
+
, blob_changed = false
|
90
|
+
, object_url
|
91
|
+
, target_view
|
92
|
+
, dispatch_all = function() {
|
93
|
+
dispatch(filesaver, "writestart progress write writeend".split(" "));
|
94
|
+
}
|
95
|
+
// on any filesys errors revert to saving with object URLs
|
96
|
+
, fs_error = function() {
|
97
|
+
// don't create more object URLs than needed
|
98
|
+
if (blob_changed || !object_url) {
|
99
|
+
object_url = get_URL().createObjectURL(blob);
|
100
|
+
}
|
101
|
+
if (target_view) {
|
102
|
+
target_view.location.href = object_url;
|
103
|
+
} else {
|
104
|
+
var new_tab = view.open(object_url, "_blank");
|
105
|
+
if (new_tab == undefined && typeof safari !== "undefined") {
|
106
|
+
//Apple do not allow window.open, see http://bit.ly/1kZffRI
|
107
|
+
view.location.href = object_url
|
108
|
+
}
|
109
|
+
}
|
110
|
+
filesaver.readyState = filesaver.DONE;
|
111
|
+
dispatch_all();
|
112
|
+
revoke(object_url);
|
113
|
+
}
|
114
|
+
, abortable = function(func) {
|
115
|
+
return function() {
|
116
|
+
if (filesaver.readyState !== filesaver.DONE) {
|
117
|
+
return func.apply(this, arguments);
|
118
|
+
}
|
119
|
+
};
|
120
|
+
}
|
121
|
+
, create_if_not_found = {create: true, exclusive: false}
|
122
|
+
, slice
|
123
|
+
;
|
124
|
+
filesaver.readyState = filesaver.INIT;
|
125
|
+
if (!name) {
|
126
|
+
name = "download";
|
127
|
+
}
|
128
|
+
if (can_use_save_link) {
|
129
|
+
object_url = get_URL().createObjectURL(blob);
|
130
|
+
save_link.href = object_url;
|
131
|
+
save_link.download = name;
|
132
|
+
click(save_link);
|
133
|
+
filesaver.readyState = filesaver.DONE;
|
134
|
+
dispatch_all();
|
135
|
+
revoke(object_url);
|
136
|
+
return;
|
137
|
+
}
|
138
|
+
// prepend BOM for UTF-8 XML and text/plain types
|
139
|
+
if (/^\s*(?:text\/(?:plain|xml)|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
|
140
|
+
blob = new Blob(["\ufeff", blob], {type: blob.type});
|
141
|
+
}
|
142
|
+
// Object and web filesystem URLs have a problem saving in Google Chrome when
|
143
|
+
// viewed in a tab, so I force save with application/octet-stream
|
144
|
+
// http://code.google.com/p/chromium/issues/detail?id=91158
|
145
|
+
// Update: Google errantly closed 91158, I submitted it again:
|
146
|
+
// https://code.google.com/p/chromium/issues/detail?id=389642
|
147
|
+
if (view.chrome && type && type !== force_saveable_type) {
|
148
|
+
slice = blob.slice || blob.webkitSlice;
|
149
|
+
blob = slice.call(blob, 0, blob.size, force_saveable_type);
|
150
|
+
blob_changed = true;
|
151
|
+
}
|
152
|
+
// Since I can't be sure that the guessed media type will trigger a download
|
153
|
+
// in WebKit, I append .download to the filename.
|
154
|
+
// https://bugs.webkit.org/show_bug.cgi?id=65440
|
155
|
+
if (webkit_req_fs && name !== "download") {
|
156
|
+
name += ".download";
|
157
|
+
}
|
158
|
+
if (type === force_saveable_type || webkit_req_fs) {
|
159
|
+
target_view = view;
|
160
|
+
}
|
161
|
+
if (!req_fs) {
|
162
|
+
fs_error();
|
163
|
+
return;
|
164
|
+
}
|
165
|
+
fs_min_size += blob.size;
|
166
|
+
req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) {
|
167
|
+
fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) {
|
168
|
+
var save = function() {
|
169
|
+
dir.getFile(name, create_if_not_found, abortable(function(file) {
|
170
|
+
file.createWriter(abortable(function(writer) {
|
171
|
+
writer.onwriteend = function(event) {
|
172
|
+
target_view.location.href = file.toURL();
|
173
|
+
filesaver.readyState = filesaver.DONE;
|
174
|
+
dispatch(filesaver, "writeend", event);
|
175
|
+
revoke(file);
|
176
|
+
};
|
177
|
+
writer.onerror = function() {
|
178
|
+
var error = writer.error;
|
179
|
+
if (error.code !== error.ABORT_ERR) {
|
180
|
+
fs_error();
|
181
|
+
}
|
182
|
+
};
|
183
|
+
"writestart progress write abort".split(" ").forEach(function(event) {
|
184
|
+
writer["on" + event] = filesaver["on" + event];
|
185
|
+
});
|
186
|
+
writer.write(blob);
|
187
|
+
filesaver.abort = function() {
|
188
|
+
writer.abort();
|
189
|
+
filesaver.readyState = filesaver.DONE;
|
190
|
+
};
|
191
|
+
filesaver.readyState = filesaver.WRITING;
|
192
|
+
}), fs_error);
|
193
|
+
}), fs_error);
|
194
|
+
};
|
195
|
+
dir.getFile(name, {create: false}, abortable(function(file) {
|
196
|
+
// delete file if it already exists
|
197
|
+
file.remove();
|
198
|
+
save();
|
199
|
+
}), abortable(function(ex) {
|
200
|
+
if (ex.code === ex.NOT_FOUND_ERR) {
|
201
|
+
save();
|
202
|
+
} else {
|
203
|
+
fs_error();
|
204
|
+
}
|
205
|
+
}));
|
206
|
+
}), fs_error);
|
207
|
+
}), fs_error);
|
208
|
+
}
|
209
|
+
, FS_proto = FileSaver.prototype
|
210
|
+
, saveAs = function(blob, name) {
|
211
|
+
return new FileSaver(blob, name);
|
212
|
+
}
|
213
|
+
;
|
214
|
+
FS_proto.abort = function() {
|
215
|
+
var filesaver = this;
|
216
|
+
filesaver.readyState = filesaver.DONE;
|
217
|
+
dispatch(filesaver, "abort");
|
218
|
+
};
|
219
|
+
FS_proto.readyState = FS_proto.INIT = 0;
|
220
|
+
FS_proto.WRITING = 1;
|
221
|
+
FS_proto.DONE = 2;
|
222
|
+
|
223
|
+
FS_proto.error =
|
224
|
+
FS_proto.onwritestart =
|
225
|
+
FS_proto.onprogress =
|
226
|
+
FS_proto.onwrite =
|
227
|
+
FS_proto.onabort =
|
228
|
+
FS_proto.onerror =
|
229
|
+
FS_proto.onwriteend =
|
230
|
+
null;
|
231
|
+
|
232
|
+
return saveAs;
|
233
|
+
}(
|
234
|
+
typeof self !== "undefined" && self
|
235
|
+
|| typeof window !== "undefined" && window
|
236
|
+
|| this.content
|
237
|
+
));
|
238
|
+
// `self` is undefined in Firefox for Android content script context
|
239
|
+
// while `this` is nsIContentFrameMessageManager
|
240
|
+
// with an attribute `content` that corresponds to the window
|
241
|
+
|
242
|
+
if (typeof module !== "undefined" && module.exports) {
|
243
|
+
module.exports.saveAs = saveAs;
|
244
|
+
} else if ((typeof define !== "undefined" && define !== null) && (define.amd != null)) {
|
245
|
+
define([], function() {
|
246
|
+
return saveAs;
|
247
|
+
});
|
248
|
+
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rbbt-rest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.6.
|
4
|
+
version: 1.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -388,6 +388,7 @@ files:
|
|
388
388
|
- share/views/public/js/rbbt/reveal.js
|
389
389
|
- share/views/public/js/rbbt/table.js
|
390
390
|
- share/views/public/js/rbbt/workflow.js
|
391
|
+
- share/views/public/plugins/FileSaver/js/FileSaver.js
|
391
392
|
- share/views/public/plugins/angular/angular.js
|
392
393
|
- share/views/public/plugins/cytoscapejs/arbor.js
|
393
394
|
- share/views/public/plugins/cytoscapejs/cytoscape.js
|
@@ -1751,8 +1752,6 @@ files:
|
|
1751
1752
|
- share/views/public/plugins/underscore/js/underscore.js
|
1752
1753
|
- share/views/tasks.haml
|
1753
1754
|
- share/views/tools/cytoscape.haml
|
1754
|
-
- share/views/tools/protein_tool.haml
|
1755
|
-
- share/views/tools/protein_tool/controls.haml
|
1756
1755
|
- share/views/wait.haml
|
1757
1756
|
homepage: http://github.com/mikisvaz/rbbt-rest
|
1758
1757
|
licenses:
|
@@ -1,391 +0,0 @@
|
|
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
|
14
|
-
.controls
|
15
|
-
float: right
|
16
|
-
margin-bottom: -2px
|
17
|
-
.ui.input, .ui.buttons
|
18
|
-
padding: 0px
|
19
|
-
input
|
20
|
-
width: 100% !important
|
21
|
-
.tabular.menu
|
22
|
-
width: 300px !important
|
23
|
-
|
24
|
-
.protein_tool.very.basic.ui.segment(id=id)
|
25
|
-
.controls.very.basic.segment
|
26
|
-
.ui.input
|
27
|
-
%input(placeholder='Position' type='text' name='position')
|
28
|
-
.ui.buttons
|
29
|
-
.mark.submit.ui.button Mark
|
30
|
-
.clear.submit.ui.button Clear
|
31
|
-
.align.submit.ui.button Align
|
32
|
-
.ui.tabular.menu.top.attached
|
33
|
-
.item.active(data-tab='Sequence') Sequence
|
34
|
-
.item(data-tab='JMol') JMol
|
35
|
-
.item(data-tab='COSMIC') COSMIC
|
36
|
-
.window.bottom.attached.ui.segment
|
37
|
-
.secondary_structure.active.very.basic.ui.segment.tab(data-tab='Sequence' style='background:white')
|
38
|
-
.svg(data-sequence_length='#{sequence.length}')
|
39
|
-
- log :svg, "Downloading SVG"
|
40
|
-
- begin
|
41
|
-
= protein.marked_svg([])
|
42
|
-
- rescue Exception
|
43
|
-
%p.error.ui.message
|
44
|
-
Could not download protein SVG, try again later.
|
45
|
-
%pre=$!.message
|
46
|
-
.sequence(style='width: 677px; overflow-x: auto;font-family: monospace;margin-left:123px')
|
47
|
-
%span.sequence(width="100%")= sequence
|
48
|
-
%span.marks(width="100%")
|
49
|
-
- size = sequence.length
|
50
|
-
- marks = size / 10
|
51
|
-
- str = ""
|
52
|
-
- marks.times do |mark|
|
53
|
-
- txt = "|"
|
54
|
-
- str << ("_" * (10 - txt.length)) << txt
|
55
|
-
= str
|
56
|
-
%span.counts(width="100%")
|
57
|
-
- size = sequence.length
|
58
|
-
- marks = size / 10
|
59
|
-
- str = ""
|
60
|
-
- marks.times do |mark|
|
61
|
-
- mark = (mark + 1) * 10
|
62
|
-
- txt = mark.to_s
|
63
|
-
- str << ("_" * (10 - txt.length)) << txt
|
64
|
-
= str
|
65
|
-
%p.scroll.ui.message
|
66
|
-
Scroll horizontaly across the sequence
|
67
|
-
|
68
|
-
.jmol.very.basic.ui.segment.tab(data-tab='JMol')
|
69
|
-
|
70
|
-
.ui.field
|
71
|
-
%label(for=select_id) Load a structure PDB
|
72
|
-
%select.pdb(id=select_id style='width: 200px')
|
73
|
-
%option(selected="selected") Select a PDB
|
74
|
-
- (pdbs || []).each do |pdb, info|
|
75
|
-
%option(attr-pdb="=#{pdb}")= "#{pdb}"
|
76
|
-
- uniprot = uni[protein]
|
77
|
-
|
78
|
-
- if uniprot and Structure::I3D_PROTEINS.include? uniprot
|
79
|
-
- filepos = Structure::I3D_PROTEINS.identify_field "FILENAME"
|
80
|
-
- Structure::I3D_PROTEINS[uniprot][filepos].each do |filename|
|
81
|
-
- type = filename =~ /EXP/ ? :pdb : :model
|
82
|
-
- url = "http://interactome3d.irbbarcelona.org/pdb.php?dataset=human&type1=proteins&type2=#{ type }&pdb=#{ filename }"
|
83
|
-
-# url = "http://darthcaedus:28873/" << ["Structure", "get_protein_pdb"] * "/" << "?" << Misc.hash2GET_params(:_format => :raw, :filename => filename)
|
84
|
-
%option.protein(attr-pdb=url)= "#{filename}"
|
85
|
-
|
86
|
-
- if uniprot and Structure::I3D_INTERACTIONS.include? uniprot
|
87
|
-
- filepos = Structure::I3D_INTERACTIONS.identify_field "FILENAME"
|
88
|
-
- Structure::I3D_INTERACTIONS[uniprot][filepos].each do |filename|
|
89
|
-
- type = filename =~ /EXP/ ? :pdb : :model
|
90
|
-
- url = "http://interactome3d.irbbarcelona.org/pdb.php?dataset=human&type1=interactions&type2=#{ type }&pdb=#{ filename }"
|
91
|
-
-# url = "http://darthcaedus:28873/" << ["Structure", "get_interaction_pdb"] * "/" << "?" << Misc.hash2GET_params(:_format => :raw, :filename => filename)
|
92
|
-
%option.interaction(attr-pdb=url)= "#{filename}"
|
93
|
-
.window
|
94
|
-
|
95
|
-
.COSMIC.very.basic.ui.segment.tab(data-tab='COSMIC')
|
96
|
-
= fragment do
|
97
|
-
.highlight.submit.ui.button Highlight
|
98
|
-
.ui.message
|
99
|
-
In JMol positions with 1 mutation are white, with 2 are green, with 3 are orange, and with more than 3 are red
|
100
|
-
-#%select(name='color')
|
101
|
-
- colors.each do |c|
|
102
|
-
%option(value=c)= c
|
103
|
-
|
104
|
-
|
105
|
-
- header "Genomic Mutation", "GenomicMutation", {:organism => Organism.default_code("Hsa"), :watson => false}
|
106
|
-
- filter "Primary site"
|
107
|
-
= table :table_id => "COSMIC mutations for #{ protein.name || protein }", :row_ids => :consume do
|
108
|
-
- association_items = COSMIC.knowledge_base.subset(:mutation_protein_changes, :target => [protein], :source => :all)
|
109
|
-
- associations = association_items.tsv.to_double
|
110
|
-
|
111
|
-
- log :sample_mutations
|
112
|
-
- sample_mutations = COSMIC.knowledge_base.get_database(:sample_mutations, :type => :double, :merge => true, :target => "Sample name=~Sample", :source => "Genomic Mutation")
|
113
|
-
- sample_mutations.fields = ["Sample"]
|
114
|
-
|
115
|
-
- associations = associations.attach(sample_mutations)
|
116
|
-
|
117
|
-
- log :sample_info
|
118
|
-
- sample_info = COSMIC.sample_info.find.tsv
|
119
|
-
- sample_info.key_field = "Sample"
|
120
|
-
|
121
|
-
- associations = associations.attach(sample_info)
|
122
|
-
|
123
|
-
- good_fields = associations.fields - ["Ensembl Protein ID"]
|
124
|
-
|
125
|
-
- log :slice_and_show
|
126
|
-
- associations.slice(good_fields)
|
127
|
-
|
128
|
-
:deferjs
|
129
|
-
|
130
|
-
$('.highlight.submit').click(function(){
|
131
|
-
var link = $(this);
|
132
|
-
var COSMIC = link.parents('.COSMIC').first();
|
133
|
-
var protein_tool = COSMIC.parents('.protein_tool').first();
|
134
|
-
var svg_element = protein_tool.find('.svg').first();
|
135
|
-
var jmol_element = protein_tool.find('.jmol').first();
|
136
|
-
|
137
|
-
var table = COSMIC.find('table');
|
138
|
-
var url = table.attr('attr-url');
|
139
|
-
var filter = table.attr('attr-filter');
|
140
|
-
|
141
|
-
url = add_parameter(url, '_format', 'json')
|
142
|
-
url = add_parameter(url, '_page', 'all')
|
143
|
-
url = add_parameter(url, '_column', 'Change')
|
144
|
-
if (undefined != filter){ url = add_parameter(url, '_filter', escape(filter)) }
|
145
|
-
|
146
|
-
var color = 'red'
|
147
|
-
|
148
|
-
$.ajax({
|
149
|
-
url: url,
|
150
|
-
success: function(data){
|
151
|
-
data = JSON.parse(data);
|
152
|
-
var change_positions = [];
|
153
|
-
for (mutation in data){
|
154
|
-
var change = data[mutation][0];
|
155
|
-
var samples = data[mutation][1];
|
156
|
-
if (m = change.match(/[A-Z*](\d*)[A-Z*]/)){
|
157
|
-
change_positions.push(parseInt(m[1]));
|
158
|
-
}
|
159
|
-
}
|
160
|
-
var change_counts = []
|
161
|
-
|
162
|
-
for (i in change_positions){
|
163
|
-
var position = change_positions[i]
|
164
|
-
if (change_counts[position] === undefined){
|
165
|
-
change_counts[position] = 1
|
166
|
-
}else{
|
167
|
-
change_counts[position] = change_counts[position] + 1
|
168
|
-
}
|
169
|
-
}
|
170
|
-
|
171
|
-
var protein_tool = $('.protein_tool#' + '#{id}');
|
172
|
-
rbbt.svg.mark_positions(svg_element, change_positions, color);
|
173
|
-
for (position in change_counts){
|
174
|
-
var jcolor = 'white';
|
175
|
-
if (change_counts[position] > 1) jcolor = 'green'
|
176
|
-
if (change_counts[position] > 2) jcolor = 'organge'
|
177
|
-
if (change_counts[position] > 3) jcolor = 'red'
|
178
|
-
|
179
|
-
rbbt.jmol.mark_position(jmol_element, position, jcolor);
|
180
|
-
}
|
181
|
-
|
182
|
-
}
|
183
|
-
})
|
184
|
-
return false;
|
185
|
-
})
|
186
|
-
|
187
|
-
:sass
|
188
|
-
.jmol:not(.active)
|
189
|
-
display: block !important
|
190
|
-
visibility: hidden
|
191
|
-
height: 0px
|
192
|
-
margin: 0px
|
193
|
-
padding: 0px
|
194
|
-
|
195
|
-
:deferjs
|
196
|
-
rbbt.sequence = {}
|
197
|
-
$('.tabular.menu .item').tab()
|
198
|
-
|
199
|
-
$('svg').attr('viewport-fill', 'white')
|
200
|
-
rbbt.sequence.clear = function(element){
|
201
|
-
var seq = element.find('span.sequence');
|
202
|
-
var marked_chars = seq.find('.sequence_char_position')
|
203
|
-
marked_chars.each(function(marked_char){ marked_char = $(this); marked_char.replaceWith(marked_char.html()) })
|
204
|
-
}
|
205
|
-
|
206
|
-
rbbt.sequence.mark_position = function(element, position, color){
|
207
|
-
if (undefined === color) color = 'red';
|
208
|
-
var seq = element.find('span.sequence');
|
209
|
-
var str = seq.html();
|
210
|
-
var char_pos = position - 1;
|
211
|
-
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)
|
212
|
-
seq.html(str)
|
213
|
-
}
|
214
|
-
|
215
|
-
rbbt.svg = {}
|
216
|
-
|
217
|
-
rbbt.svg.clear = function(element){
|
218
|
-
var svg = element.find('svg');
|
219
|
-
var vlines = svg.find('.rbbt-vline')
|
220
|
-
vlines.remove()
|
221
|
-
var vregions = svg.find('.rbbt-region')
|
222
|
-
vregions.remove()
|
223
|
-
}
|
224
|
-
|
225
|
-
rbbt.svg.position_offset = function(element, position){
|
226
|
-
var svg = element.find('svg');
|
227
|
-
var width = parseInt(svg.attr('width'));
|
228
|
-
var start = parseInt(svg.find('rect.ac').attr('x'));
|
229
|
-
var seq_len = parseInt(element.attr('data-sequence_length'));
|
230
|
-
return start + position * (width - start)/seq_len
|
231
|
-
}
|
232
|
-
|
233
|
-
rbbt.svg.mark_position = function(element, position, color){
|
234
|
-
if (undefined === color) color = 'red';
|
235
|
-
var svg = element.find('svg');
|
236
|
-
|
237
|
-
var width = parseInt(svg.attr('width'));
|
238
|
-
var height = parseInt(svg.attr('height'));
|
239
|
-
var offset = rbbt.svg.position_offset(element, position)
|
240
|
-
|
241
|
-
var line = document.createElementNS("http://www.w3.org/2000/svg", "line");
|
242
|
-
line.setAttributeNS(null, "x1", offset);
|
243
|
-
line.setAttributeNS(null, "y1", 5);
|
244
|
-
line.setAttributeNS(null, "x2", offset);
|
245
|
-
line.setAttributeNS(null, "y2", height - 5);
|
246
|
-
line.setAttributeNS(null, "class", 'rbbt-vline');
|
247
|
-
line.setAttributeNS(null, "style", "stroke:" + color + ";opacity:0.5;stroke-width:1;");
|
248
|
-
|
249
|
-
svg.append(line);
|
250
|
-
}
|
251
|
-
|
252
|
-
rbbt.svg.mark_positions = function(element, positions, color){
|
253
|
-
for ( i in positions){
|
254
|
-
var position = positions[i]
|
255
|
-
rbbt.svg.mark_position(element, position, color)
|
256
|
-
}
|
257
|
-
}
|
258
|
-
|
259
|
-
rbbt.svg.mark_region = function(element, first, last, color){
|
260
|
-
var svg = element.find('svg')
|
261
|
-
var width = parseInt(svg.attr('width'));
|
262
|
-
var height = parseInt(svg.attr('height'));
|
263
|
-
var start = parseInt(svg.find('rect.ac').attr('x'));
|
264
|
-
var seq_len = parseInt(element.attr('data-sequence_length'));
|
265
|
-
|
266
|
-
var offset_start = rbbt.svg.position_offset(element, first)
|
267
|
-
var offset_end = rbbt.svg.position_offset(element, last)
|
268
|
-
|
269
|
-
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
|
270
|
-
|
271
|
-
rect.setAttributeNS(null, "x", offset_start);
|
272
|
-
rect.setAttributeNS(null, "class", 'rbbt-region');
|
273
|
-
rect.setAttributeNS(null, "y", 10);
|
274
|
-
rect.setAttributeNS(null, "width", offset_end - offset_start);
|
275
|
-
rect.setAttributeNS(null, "height", height - 30);
|
276
|
-
rect.setAttributeNS(null, "style", "stroke:black;stroke-width: 2; opacity:0.3;fill:" + color + ";");
|
277
|
-
|
278
|
-
svg.append(rect);
|
279
|
-
}
|
280
|
-
|
281
|
-
rbbt.svg.mark_aligned_region = function(element, map, color){
|
282
|
-
if (undefined === color) color = 'blue'
|
283
|
-
|
284
|
-
var positions = []
|
285
|
-
for(seq_pos in map){
|
286
|
-
positions.push(parseInt(seq_pos))
|
287
|
-
}
|
288
|
-
|
289
|
-
positions = positions.sort();
|
290
|
-
console.log(positions)
|
291
|
-
var last = -1
|
292
|
-
var start = -1;
|
293
|
-
for (var i = 0; i < positions.length; i++){
|
294
|
-
if (positions[i] != last + 1){
|
295
|
-
if (start != -1) { rbbt.svg.mark_region(element, start, last, color); }
|
296
|
-
start = positions[i]
|
297
|
-
}
|
298
|
-
last = positions[i]
|
299
|
-
}
|
300
|
-
if (start != -1) { rbbt.svg.mark_region(element, start, last, color); }
|
301
|
-
}
|
302
|
-
|
303
|
-
|
304
|
-
rbbt.jmol = {}
|
305
|
-
rbbt.jmol.clear = function(element){
|
306
|
-
element.jmol_tool('clear')
|
307
|
-
}
|
308
|
-
rbbt.jmol.mark_position = function(element, position, color){
|
309
|
-
if (undefined === color) color = 'red'
|
310
|
-
element.jmol_tool('mark_position', position, color)
|
311
|
-
}
|
312
|
-
|
313
|
-
rbbt.jmol.mark_positions = function(element, positions, color){
|
314
|
-
for (i in positions){
|
315
|
-
var position = positions[i]
|
316
|
-
rbbt.jmol.mark_position(element, position, color)
|
317
|
-
}
|
318
|
-
}
|
319
|
-
|
320
|
-
require_js("/js/jmol.js", function(){
|
321
|
-
var position = #{position ? position : "undefined"}
|
322
|
-
var tool = $('.jmol').last().jmol_tool({protein:"#{ protein }", sequence: "#{protein.sequence}"});
|
323
|
-
|
324
|
-
$('select.pdb').change(function(){
|
325
|
-
var option = $(this).find('option:selected');
|
326
|
-
var pdb = option.attr('attr-pdb');
|
327
|
-
if (pdb == "Select a pdb") return false
|
328
|
-
tool.jmol_tool("load_pdb", pdb)
|
329
|
-
clean = pdb.replace(/=/,'')
|
330
|
-
tool.find('.pdb_info > dd.pdbfile').html(clean)
|
331
|
-
|
332
|
-
if (position !== undefined){
|
333
|
-
tool.jmol_tool("clear")
|
334
|
-
tool.jmol_tool("mark_position", position, 'red')
|
335
|
-
}
|
336
|
-
})
|
337
|
-
})
|
338
|
-
|
339
|
-
|
340
|
-
$('.clear.submit').click(function(){
|
341
|
-
var link = $(this);
|
342
|
-
var controls = link.parents('.controls').first();
|
343
|
-
var protein_tool = controls.parents('.protein_tool').first();
|
344
|
-
var sequence_element = protein_tool.find('.sequence').first();
|
345
|
-
var svg_element = protein_tool.find('.svg').first();
|
346
|
-
var jmol_element = protein_tool.find('.jmol').first();
|
347
|
-
|
348
|
-
rbbt.sequence.clear(sequence_element)
|
349
|
-
rbbt.svg.clear(svg_element)
|
350
|
-
rbbt.jmol.clear(jmol_element)
|
351
|
-
})
|
352
|
-
|
353
|
-
$('.mark.submit').click(function(){
|
354
|
-
var link = $(this);
|
355
|
-
var controls = link.parents('.controls').first();
|
356
|
-
var protein_tool = controls.parents('.protein_tool').first();
|
357
|
-
var sequence_element = protein_tool.find('.sequence').first();
|
358
|
-
var svg_element = protein_tool.find('.svg').first();
|
359
|
-
var jmol_element = protein_tool.find('.jmol').first();
|
360
|
-
|
361
|
-
var position = parseInt(controls.find('input[name=position]').val());
|
362
|
-
|
363
|
-
if (! position > 0) return alert("No position specified")
|
364
|
-
|
365
|
-
rbbt.sequence.clear(sequence_element)
|
366
|
-
rbbt.svg.clear(svg_element)
|
367
|
-
|
368
|
-
rbbt.sequence.mark_position(sequence_element, position)
|
369
|
-
rbbt.svg.mark_position(svg_element, position)
|
370
|
-
rbbt.jmol.mark_position(jmol_element, position)
|
371
|
-
})
|
372
|
-
|
373
|
-
|
374
|
-
$('.align.submit').click(function(){
|
375
|
-
var link = $(this);
|
376
|
-
var controls = link.parents('.controls').first();
|
377
|
-
var protein_tool = controls.parents('.protein_tool').first();
|
378
|
-
var svg_element = protein_tool.find('.svg').first();
|
379
|
-
|
380
|
-
var jmol = $('.jmol');
|
381
|
-
|
382
|
-
if(jmol.jmol_tool('is_pdb_loaded')){
|
383
|
-
var map = jmol.jmol_tool('alignment_map');
|
384
|
-
jmol.jmol_tool('mark_aligned_region', 'blue');
|
385
|
-
rbbt.svg.mark_aligned_region(svg_element, map, 'blue');
|
386
|
-
}else{
|
387
|
-
alert("Select a PDB")
|
388
|
-
}
|
389
|
-
return false;
|
390
|
-
})
|
391
|
-
|
@@ -1,315 +0,0 @@
|
|
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
|
-
|