sequenceserver 1.1.0.beta5 → 1.1.0.beta6
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.
Potentially problematic release.
This version of sequenceserver might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/lib/sequenceserver/blast/job.rb +1 -1
- data/lib/sequenceserver/database.rb +1 -1
- data/lib/sequenceserver/version.rb +1 -1
- data/public/js/alignmentsoverview.js +9 -25
- data/public/js/grapher.js +3 -1
- data/public/js/lengthdistribution.js +5 -13
- data/public/js/report.js +148 -120
- data/public/sequenceserver-report.min.js +16 -16
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da64719d5d51834a93bd4071cf01f7dd9f45dfce
|
4
|
+
data.tar.gz: 071fa0cfc1d276a53d613b43fab36e85180a3e8e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f5486cf92ad273fd348fcd3d2dbcf4656b6bccd70f4040e2013e787b4ee68cd9c2d0c26473eb21a4ba2c0eb0d240d6f2f955110cd3f1442ddb37df94a8f5fc9
|
7
|
+
data.tar.gz: bdaf284e009ee77987e2c89652fcdbe3501d783c5cdb0a568dac29535072dde48db28c716b6371ee6eb2dd31cdac364954033a58d886ce2b9eb9d30f941943cf
|
@@ -36,7 +36,7 @@ module SequenceServer
|
|
36
36
|
def raise!
|
37
37
|
return true if exitstatus == 0
|
38
38
|
|
39
|
-
stderr = File.readlines(
|
39
|
+
stderr = File.readlines(self.stderr)
|
40
40
|
if exitstatus == 1 # error in query sequence or options; see [1]
|
41
41
|
error = stderr.grep(ERROR_LINE)
|
42
42
|
error = stderr if error.empty?
|
@@ -215,7 +215,7 @@ module SequenceServer
|
|
215
215
|
default = 0
|
216
216
|
print 'Enter taxid (optional): '
|
217
217
|
user_response = STDIN.gets.strip
|
218
|
-
user_response && Integer(user_response)
|
218
|
+
user_response.empty? && default || Integer(user_response)
|
219
219
|
rescue
|
220
220
|
puts 'taxid should be a number'
|
221
221
|
retry
|
@@ -10,7 +10,7 @@ class Graph {
|
|
10
10
|
}
|
11
11
|
|
12
12
|
static className() {
|
13
|
-
return 'alignment-overview
|
13
|
+
return 'alignment-overview';
|
14
14
|
}
|
15
15
|
|
16
16
|
static collapseId(props) {
|
@@ -22,9 +22,10 @@ class Graph {
|
|
22
22
|
}
|
23
23
|
|
24
24
|
constructor($svgContainer, props) {
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
this.svg_container = $svgContainer;
|
26
|
+
$queryDiv = $svgContainer.parents('.resultn');
|
27
|
+
hits = this.extractData(props.query.hits, props.query.number);
|
28
|
+
this.graphIt($queryDiv, $svgContainer, 0, 20, null, hits);
|
28
29
|
}
|
29
30
|
|
30
31
|
extractData(query_hits, number) {
|
@@ -50,13 +51,10 @@ class Graph {
|
|
50
51
|
}
|
51
52
|
|
52
53
|
setupTooltip() {
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
'delay': 0,
|
58
|
-
'white-space': 'nowrap'
|
59
|
-
});
|
54
|
+
this.svg_container.find('[data-toggle="tooltip"]').tooltip({
|
55
|
+
'placement': 'top', 'container': 'body', 'html': 'true',
|
56
|
+
'delay': 0, 'white-space': 'nowrap'
|
57
|
+
});
|
60
58
|
}
|
61
59
|
|
62
60
|
setupClick($graphDiv) {
|
@@ -67,18 +65,6 @@ class Graph {
|
|
67
65
|
});
|
68
66
|
}
|
69
67
|
|
70
|
-
setupResponsiveness($queryDiv, $graphDiv, index, opts, hits) {
|
71
|
-
var currentWidth = $(window).width();
|
72
|
-
var debounced_draw = _.debounce(_.bind(function () {
|
73
|
-
if (currentWidth !== $(window).width()) {
|
74
|
-
var shownHits = $queryDiv.find('.ghit > g').length;
|
75
|
-
this.graphIt($queryDiv, $graphDiv, shownHits, index, opts, hits);
|
76
|
-
currentWidth = $(window).width();
|
77
|
-
}
|
78
|
-
},this), 125);
|
79
|
-
$(window).resize(debounced_draw);
|
80
|
-
}
|
81
|
-
|
82
68
|
graphControls($queryDiv, $graphDiv, isInit, opts, hits) {
|
83
69
|
var MIN_HITS_TO_SHOW = 20;
|
84
70
|
|
@@ -393,8 +379,6 @@ class Graph {
|
|
393
379
|
// been drawn for first time.
|
394
380
|
if (index === 0) {
|
395
381
|
this.graphControls($queryDiv, $graphDiv, true, opts, inhits);
|
396
|
-
// Redraw the SVG on a browser resize...
|
397
|
-
// this.setupResponsiveness($queryDiv, $graphDiv, index, opts, inhits);
|
398
382
|
}
|
399
383
|
// Refresh tooltip each time graph is redrawn.
|
400
384
|
this.setupTooltip();
|
data/public/js/grapher.js
CHANGED
@@ -64,9 +64,11 @@ export default function Grapher(Graph) {
|
|
64
64
|
}
|
65
65
|
|
66
66
|
svgContainerJSX () {
|
67
|
+
var cssClasses = Graph.className() + ' svg-container collapse';
|
68
|
+
if (!this.state.collapsed) cssClasses += ' in';
|
67
69
|
return (
|
68
70
|
<div ref="svgContainer" id={this.collapseId()}
|
69
|
-
className={
|
71
|
+
className={cssClasses}>
|
70
72
|
</div>
|
71
73
|
);
|
72
74
|
}
|
@@ -13,7 +13,7 @@ class Graph {
|
|
13
13
|
}
|
14
14
|
|
15
15
|
static className() {
|
16
|
-
return 'length-distribution
|
16
|
+
return 'length-distribution';
|
17
17
|
}
|
18
18
|
|
19
19
|
static collapseId(props) {
|
@@ -31,11 +31,6 @@ class Graph {
|
|
31
31
|
|
32
32
|
this._margin = {top: 30, right: 25, bottom: 55, left: 12.5};
|
33
33
|
this.initiate($svg_container.width(), $svg_container.height());
|
34
|
-
var test = $('#Collapse_length_'+props.query.number);
|
35
|
-
test.removeClass('in');
|
36
|
-
test.parent().find('.caption').find('i').
|
37
|
-
removeClass('fa-minus-square-o').addClass('fa-plus-square-o');
|
38
|
-
test.parent().find('.graph-links').hide();
|
39
34
|
}
|
40
35
|
|
41
36
|
initiate(width, height) {
|
@@ -80,13 +75,10 @@ class Graph {
|
|
80
75
|
}
|
81
76
|
|
82
77
|
setupTooltip() {
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
'delay': 0,
|
88
|
-
'white-space': 'nowrap'
|
89
|
-
});
|
78
|
+
this.svg_container.find('[data-toggle="tooltip"]').tooltip({
|
79
|
+
'placement': 'top', 'container': 'body', 'html': 'true',
|
80
|
+
'delay': 0, 'white-space': 'nowrap'
|
81
|
+
});
|
90
82
|
}
|
91
83
|
|
92
84
|
setupResponsiveness() {
|
data/public/js/report.js
CHANGED
@@ -10,7 +10,7 @@ import GraphicalOverview from './alignmentsoverview';
|
|
10
10
|
//import Kablammo from './kablammo';
|
11
11
|
import './sequence';
|
12
12
|
import AlignmentExporter from './alignment_exporter';
|
13
|
-
|
13
|
+
import LengthDistribution from './lengthdistribution';
|
14
14
|
import Circos from './circos';
|
15
15
|
|
16
16
|
|
@@ -677,14 +677,9 @@ var Query = React.createClass({
|
|
677
677
|
</div>
|
678
678
|
{this.numhits() &&
|
679
679
|
(
|
680
|
-
<div
|
681
|
-
|
682
|
-
|
683
|
-
<GraphicalOverview key={"GO_"+this.props.query.number} query={this.props.query} program={this.props.data.program}/>
|
684
|
-
|
685
|
-
{/*
|
686
|
-
<LengthDistribution key={"LD_"+this.props.query.id} query={this.props.query} algorithm={this.props.data.program}/>
|
687
|
-
*/}
|
680
|
+
<div className="section-content">
|
681
|
+
<GraphicalOverview key={"GO_"+this.props.query.number} query={this.props.query} program={this.props.data.program} collapsed={this.props.data.veryBig}/>
|
682
|
+
<LengthDistribution key={"LD_"+this.props.query.id} query={this.props.query} algorithm={this.props.data.program} collapsed="true"/>
|
688
683
|
<HitsTable key={"HT_"+this.props.query.number} query={this.props.query}/>
|
689
684
|
<div
|
690
685
|
id="hits">
|
@@ -796,16 +791,12 @@ var SideBar = React.createClass({
|
|
796
791
|
render: function () {
|
797
792
|
return (
|
798
793
|
<div className="sidebar">
|
799
|
-
{ this.
|
794
|
+
{ this.props.shouldShowIndex && this.index() }
|
800
795
|
{ this.downloads() }
|
801
796
|
</div>
|
802
797
|
)
|
803
798
|
},
|
804
799
|
|
805
|
-
showIndex: function () {
|
806
|
-
return this.props.data.queries.length <= 8;
|
807
|
-
},
|
808
|
-
|
809
800
|
index: function () {
|
810
801
|
return (
|
811
802
|
<div className="index">
|
@@ -986,35 +977,22 @@ var Report = React.createClass({
|
|
986
977
|
|
987
978
|
// Internal helpers. //
|
988
979
|
|
989
|
-
|
990
|
-
* Fetch results.
|
991
|
-
*/
|
992
|
-
fetch_results: function () {
|
993
|
-
var intervals = [200, 400, 800, 1200, 2000, 3000, 5000];
|
980
|
+
// Life-cycle methods. //
|
994
981
|
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
this.setState(jqXHR.responseJSON);
|
1010
|
-
break;
|
1011
|
-
case 404:
|
1012
|
-
case 400:
|
1013
|
-
case 500:
|
1014
|
-
showErrorModal(jqXHR.responseJSON);
|
1015
|
-
break;
|
1016
|
-
}
|
1017
|
-
}, this));
|
982
|
+
getInitialState: function () {
|
983
|
+
return {
|
984
|
+
search_id: '',
|
985
|
+
program: '',
|
986
|
+
program_version: '',
|
987
|
+
queries: [],
|
988
|
+
querydb: [],
|
989
|
+
params: [],
|
990
|
+
stats: []
|
991
|
+
};
|
992
|
+
},
|
993
|
+
|
994
|
+
render: function () {
|
995
|
+
return (this.isResultAvailable() ? this.resultsJSX() : this.loadingJSX());
|
1018
996
|
},
|
1019
997
|
|
1020
998
|
/**
|
@@ -1027,17 +1005,9 @@ var Report = React.createClass({
|
|
1027
1005
|
},
|
1028
1006
|
|
1029
1007
|
/**
|
1030
|
-
* Returns
|
1031
|
-
*
|
1032
|
-
* Sidebar is not shown if there is only one query and there are no hits
|
1033
|
-
* corresponding to the query.
|
1008
|
+
* Returns loading message
|
1034
1009
|
*/
|
1035
|
-
|
1036
|
-
return !(this.state.queries.length == 1 &&
|
1037
|
-
this.state.queries[0].hits.length == 0);
|
1038
|
-
},
|
1039
|
-
|
1040
|
-
loading: function () {
|
1010
|
+
loadingJSX: function () {
|
1041
1011
|
return (
|
1042
1012
|
<div
|
1043
1013
|
className="row">
|
@@ -1063,6 +1033,59 @@ var Report = React.createClass({
|
|
1063
1033
|
);
|
1064
1034
|
},
|
1065
1035
|
|
1036
|
+
/**
|
1037
|
+
* Return results JSX.
|
1038
|
+
*/
|
1039
|
+
resultsJSX: function () {
|
1040
|
+
return (
|
1041
|
+
<div className="row">
|
1042
|
+
{ this.shouldShowSidebar() &&
|
1043
|
+
(
|
1044
|
+
<div
|
1045
|
+
className="col-md-3 hidden-sm hidden-xs">
|
1046
|
+
<SideBar data={this.state} shouldShowIndex={this.shouldShowIndex()}/>
|
1047
|
+
</div>
|
1048
|
+
)
|
1049
|
+
}
|
1050
|
+
<div className={this.shouldShowSidebar() ?
|
1051
|
+
'col-md-9' : 'col-md-12'}>
|
1052
|
+
{ this.overview() }
|
1053
|
+
<Circos queries={this.state.queries}
|
1054
|
+
program={this.state.program} collapsed="true"/>
|
1055
|
+
{
|
1056
|
+
_.map(this.state.queries, _.bind(function (query) {
|
1057
|
+
return (
|
1058
|
+
<Query key={"Query_"+query.id} query={query} data={this.state}
|
1059
|
+
selectHit={this.selectHit}/>
|
1060
|
+
);
|
1061
|
+
}, this))
|
1062
|
+
}
|
1063
|
+
</div>
|
1064
|
+
</div>
|
1065
|
+
);
|
1066
|
+
},
|
1067
|
+
|
1068
|
+
/**
|
1069
|
+
* Returns true if sidebar should be shown.
|
1070
|
+
*
|
1071
|
+
* Sidebar is not shown if there is only one query and there are no hits
|
1072
|
+
* corresponding to the query.
|
1073
|
+
*/
|
1074
|
+
shouldShowSidebar: function () {
|
1075
|
+
return !(this.state.queries.length == 1 &&
|
1076
|
+
this.state.queries[0].hits.length == 0);
|
1077
|
+
},
|
1078
|
+
|
1079
|
+
/**
|
1080
|
+
* Returns true if index should be shown in the sidebar.
|
1081
|
+
*
|
1082
|
+
* Index is not shown in the sidebar if there are more than eight queries
|
1083
|
+
* in total.
|
1084
|
+
*/
|
1085
|
+
shouldShowIndex: function () {
|
1086
|
+
return this.state.queries.length <= 8;
|
1087
|
+
},
|
1088
|
+
|
1066
1089
|
/**
|
1067
1090
|
* Renders report overview.
|
1068
1091
|
*/
|
@@ -1095,36 +1118,79 @@ var Report = React.createClass({
|
|
1095
1118
|
);
|
1096
1119
|
},
|
1097
1120
|
|
1121
|
+
componentDidMount: function () {
|
1122
|
+
this.fetchResults();
|
1123
|
+
},
|
1124
|
+
|
1098
1125
|
/**
|
1099
|
-
*
|
1126
|
+
* Fetch results.
|
1100
1127
|
*/
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1128
|
+
fetchResults: function () {
|
1129
|
+
var intervals = [200, 400, 800, 1200, 2000, 3000, 5000];
|
1130
|
+
|
1131
|
+
$.getJSON(location.pathname + '.json')
|
1132
|
+
.complete(_.bind(function (jqXHR) {
|
1133
|
+
switch (jqXHR.status) {
|
1134
|
+
case 202:
|
1135
|
+
var interval;
|
1136
|
+
if (intervals.length === 1) {
|
1137
|
+
interval = intervals[0];
|
1111
1138
|
}
|
1112
|
-
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1123
|
-
|
1124
|
-
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1139
|
+
else {
|
1140
|
+
interval = intervals.shift;
|
1141
|
+
}
|
1142
|
+
setTimeout(this.fetchResults, interval);
|
1143
|
+
break;
|
1144
|
+
case 200:
|
1145
|
+
this.updatePage(jqXHR.responseJSON);
|
1146
|
+
break;
|
1147
|
+
case 404:
|
1148
|
+
case 400:
|
1149
|
+
case 500:
|
1150
|
+
showErrorModal(jqXHR.responseJSON);
|
1151
|
+
break;
|
1152
|
+
}
|
1153
|
+
}, this));
|
1154
|
+
},
|
1155
|
+
|
1156
|
+
updatePage: function(responseJSON) {
|
1157
|
+
var queries = responseJSON.queries;
|
1158
|
+
|
1159
|
+
// Render results for first 50 queries and set flag if total queries is
|
1160
|
+
// more than 250.
|
1161
|
+
var numHits = 0;
|
1162
|
+
responseJSON.veryBig = queries.length > 250;
|
1163
|
+
//responseJSON.veryBig = !_.every(queries, (query) => {
|
1164
|
+
//numHits += query.hits.length;
|
1165
|
+
//return (numHits <= 500);
|
1166
|
+
//});
|
1167
|
+
responseJSON.queries = queries.splice(0, 50);
|
1168
|
+
this.setState(responseJSON);
|
1169
|
+
|
1170
|
+
// Render results for remaining queries.
|
1171
|
+
var update = function () {
|
1172
|
+
if (queries.length > 0) {
|
1173
|
+
this.setState({
|
1174
|
+
queries: this.state.queries.concat(queries.splice(0, 50))
|
1175
|
+
});
|
1176
|
+
setTimeout(update.bind(this), 500);
|
1177
|
+
}
|
1178
|
+
else {
|
1179
|
+
this.componentFinishedUpdating();
|
1180
|
+
}
|
1181
|
+
};
|
1182
|
+
setTimeout(update.bind(this), 500);
|
1183
|
+
},
|
1184
|
+
|
1185
|
+
/**
|
1186
|
+
* Locks Sidebar in its position, prevents folding of hits during
|
1187
|
+
* text-selection, etc.
|
1188
|
+
*/
|
1189
|
+
componentFinishedUpdating: function () {
|
1190
|
+
this.affixSidebar();
|
1191
|
+
this.shouldShowIndex() && this.setupScrollSpy();
|
1192
|
+
this.setupHitSelection();
|
1193
|
+
this.setupDownloadLinks();
|
1128
1194
|
},
|
1129
1195
|
|
1130
1196
|
/**
|
@@ -1191,57 +1257,19 @@ var Report = React.createClass({
|
|
1191
1257
|
});
|
1192
1258
|
});
|
1193
1259
|
},
|
1194
|
-
|
1195
|
-
// Life-cycle methods. //
|
1196
|
-
|
1197
|
-
getInitialState: function () {
|
1198
|
-
return {
|
1199
|
-
search_id: '',
|
1200
|
-
program: '',
|
1201
|
-
program_version: '',
|
1202
|
-
queries: [],
|
1203
|
-
querydb: [],
|
1204
|
-
params: [],
|
1205
|
-
stats: []
|
1206
|
-
};
|
1207
|
-
},
|
1208
|
-
|
1209
|
-
render: function () {
|
1210
|
-
return (this.isResultAvailable() && this.results() || this.loading());
|
1211
|
-
},
|
1212
|
-
|
1213
|
-
componentDidMount: function () {
|
1214
|
-
this.fetch_results();
|
1215
|
-
},
|
1216
|
-
|
1217
|
-
/**
|
1218
|
-
* Locks Sidebar in its position.
|
1219
|
-
* Prevents folding of hits during text-selection
|
1220
|
-
*/
|
1221
|
-
componentDidUpdate: function () {
|
1222
|
-
this.affixSidebar();
|
1223
|
-
this.setupScrollSpy();
|
1224
|
-
this.setupHitSelection();
|
1225
|
-
this.setupDownloadLinks();
|
1226
|
-
}
|
1227
1260
|
});
|
1228
1261
|
|
1229
1262
|
var Page = React.createClass({
|
1230
1263
|
render: function () {
|
1231
1264
|
return (
|
1232
1265
|
<div>
|
1233
|
-
<div
|
1234
|
-
className="container">
|
1266
|
+
<div className="container">
|
1235
1267
|
<Report ref="report"/>
|
1236
1268
|
</div>
|
1237
1269
|
|
1238
|
-
<div
|
1239
|
-
id='circos-demo' className='modal'>
|
1240
|
-
</div>
|
1270
|
+
<div id='circos-demo' className='modal'></div>
|
1241
1271
|
|
1242
|
-
<canvas
|
1243
|
-
id="png-exporter" hidden>
|
1244
|
-
</canvas>
|
1272
|
+
<canvas id="png-exporter" hidden></canvas>
|
1245
1273
|
</div>
|
1246
1274
|
);
|
1247
1275
|
}
|