sequenceserver 2.0.0.beta3 → 2.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of sequenceserver might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.eslintrc.json +36 -0
- data/.rubocop.yml +1 -1
- data/.travis.yml +53 -20
- data/AppImage/recipe.yml +15 -0
- data/AppImage/sequenceserver.desktop +8 -0
- data/AppImage/sequenceserver.png +0 -0
- data/AppImage/sequenceserver.sh +11 -0
- data/README.md +79 -46
- data/bin/sequenceserver +4 -4
- data/lib/sequenceserver/version.rb +1 -1
- data/package.json +2 -0
- data/public/css/grapher.css +3 -0
- data/public/css/sequenceserver.css +17 -6
- data/public/css/sequenceserver.min.css +3 -3
- data/public/js/circos.js +515 -491
- data/public/js/grapher.js +12 -6
- data/public/js/hits_overview.js +321 -308
- data/public/js/hsp.js +12 -7
- data/public/js/length_distribution.js +241 -234
- data/public/js/report.js +196 -174
- data/public/js/search.js +3 -3
- data/public/js/sequenceserver.js +9 -9
- data/public/js/utils.js +17 -10
- data/public/js/visualisation_helpers.js +77 -77
- data/public/sequenceserver-report.min.js +17 -17
- data/public/sequenceserver-search.min.js +1 -1
- data/public/vendor/github/nicgirault/circosJs@1.7.0/dist/circosJS.js +1 -5
- data/sequenceserver.gemspec +1 -2
- data/spec/blast_versions/blast_2.2.30/blast_2.2.30_spec.rb +13 -13
- data/spec/blast_versions/blast_2.2.30/import_spec_capybara_local_2.2.30.rb +555 -25
- data/spec/blast_versions/blast_2.2.31/blast_2.2.31_spec.rb +13 -13
- data/spec/blast_versions/blast_2.2.31/import_spec_capybara_local_2.2.31.rb +558 -24
- data/spec/blast_versions/blast_2.3.0/blast_2.3.0_spec.rb +13 -13
- data/spec/blast_versions/blast_2.3.0/import_spec_capybara_local_2.3.0.rb +561 -26
- data/spec/blast_versions/blast_2.4.0/blast_2.4.0_spec.rb +13 -13
- data/spec/blast_versions/blast_2.4.0/import_spec_capybara_local_2.4.0.rb +561 -25
- data/spec/blast_versions/blast_2.5.0/blast_2.5.0_spec.rb +13 -13
- data/spec/blast_versions/blast_2.5.0/import_spec_capybara_local_2.5.0.rb +558 -24
- data/spec/blast_versions/blast_2.6.0/blast_2.6.0_spec.rb +13 -13
- data/spec/blast_versions/blast_2.6.0/import_spec_capybara_local_2.6.0.rb +559 -24
- data/spec/blast_versions/blast_2.7.1/blast_2.7.1_spec.rb +13 -13
- data/spec/blast_versions/blast_2.7.1/import_spec_capybara_local_2.7.1.rb +559 -28
- data/spec/blast_versions/blast_2.8.1/blast_2.8.1_spec.rb +13 -13
- data/spec/blast_versions/blast_2.8.1/import_spec_capybara_local_2.8.1.rb +559 -27
- data/spec/blast_versions/blast_2.9.0/blast_2.9.0_spec.rb +13 -13
- data/spec/blast_versions/blast_2.9.0/import_spec_capybara_local_2.9.0.rb +557 -25
- data/spec/blast_versions/diamond_0.9.24/diamond_0.9.24_spec.rb +13 -13
- data/spec/blast_versions/diamond_0.9.24/import_spec_capybara_local_0.9.24.rb +219 -21
- data/spec/capybara_spec.rb +25 -28
- data/spec/download_helper.rb +6 -3
- data/spec/sequences/MH011443_1_gi_1486783306_gb_MH011443_1.txt +6 -0
- data/spec/sequences/MH011443_1_gi_1486783307_gb_AYF55702_1.txt +6 -0
- data/spec/sequences/MH011443_1_gi_1528997474_gb_MH447967_1.txt +30 -0
- data/spec/sequences/MH011443_1_sp_P04637_P53_HUMAN.txt +6 -0
- data/spec/sequences/alignment-35_hits_diamond_blastp.txt +210 -0
- data/spec/sequences/alignment-35_hits_diamond_blastx.txt +210 -0
- data/spec/sequences/alignment-3_hits.txt +18 -0
- data/spec/sequences/alignment-40_hits_blastn.txt +246 -0
- data/spec/sequences/alignment-40_hits_blastp.txt +240 -0
- data/spec/sequences/alignment-40_hits_blastp_2.2.30.txt +240 -0
- data/spec/sequences/alignment-40_hits_blastx.txt +240 -0
- data/spec/sequences/alignment-40_hits_tblastn.txt +240 -0
- data/spec/sequences/alignment-40_hits_tblastn_2.2.30.txt +240 -0
- data/spec/sequences/alignment-40_hits_tblastx.txt +2664 -0
- data/spec/sequences/alignment-4_hits.txt +24 -0
- data/spec/sequences/alignment-4_hits_blastn.txt +24 -0
- data/spec/sequences/alignment-4_hits_blastp.txt +24 -0
- data/spec/sequences/alignment-4_hits_blastp_2.2.30.txt +24 -0
- data/spec/sequences/alignment-4_hits_blastx.txt +24 -0
- data/spec/sequences/alignment-4_hits_diamond_blastp.txt +24 -0
- data/spec/sequences/alignment-4_hits_diamond_blastx.txt +24 -0
- data/spec/sequences/alignment-4_hits_tblastn.txt +24 -0
- data/spec/sequences/alignment-4_hits_tblastn_2.2.30.txt +24 -0
- data/spec/sequences/alignment-4_hits_tblastx.txt +318 -0
- data/spec/sequences/sp_P04637_P53_HUMAN_gi_1099170394_ref_XP_018868681_1.txt +6 -0
- data/spec/sequences/sp_P04637_P53_HUMAN_gi_120407068_ref_NP_000537_3.txt +6 -0
- data/spec/sequences/sp_P04637_P53_HUMAN_gi_1484127324_gb_MG595988_1.txt +6 -0
- data/spec/sequences/sp_P04637_P53_HUMAN_gi_395440626_gb_JQ694049_1.txt +6 -0
- data/spec/sequences/sp_P04637_P53_HUMAN_sp_P04637_P53_HUMAN.txt +6 -0
- data/spec/spec_helper.rb +3 -3
- metadata +67 -57
- data/.eslintrc +0 -213
- data/Rakefile +0 -8
- data/spec/dotdir/blast_2.4.0/blastn/TBLASTN_XML_2.4.0.xml +0 -1181
- data/spec/dotdir/blast_2.5.0/blastn/BLASTN_LONG_XML_2.5.0.xml +0 -18813
- data/spec/import_spec_capybara_local.rb +0 -61
data/public/js/report.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import './sequenceserver' // for custom $.tooltip function
|
1
|
+
import './sequenceserver'; // for custom $.tooltip function
|
2
2
|
import React from 'react';
|
3
3
|
import _ from 'underscore';
|
4
4
|
|
@@ -19,8 +19,8 @@ import showErrorModal from './error_modal';
|
|
19
19
|
*/
|
20
20
|
var downloadFASTA = function (sequence_ids, database_ids) {
|
21
21
|
var form = $('<form/>').attr('method', 'post').attr('action', 'get_sequence');
|
22
|
-
addField(
|
23
|
-
addField(
|
22
|
+
addField('sequence_ids', sequence_ids);
|
23
|
+
addField('database_ids', database_ids);
|
24
24
|
form.appendTo('body').submit().remove();
|
25
25
|
|
26
26
|
function addField(name, val) {
|
@@ -28,7 +28,7 @@ var downloadFASTA = function (sequence_ids, database_ids) {
|
|
28
28
|
$('<input>').attr('type', 'hidden').attr('name', name).val(val)
|
29
29
|
);
|
30
30
|
}
|
31
|
-
}
|
31
|
+
};
|
32
32
|
|
33
33
|
/**
|
34
34
|
* Base component of report page. This component is later rendered into page's
|
@@ -86,24 +86,24 @@ var Report = React.createClass({
|
|
86
86
|
$.getJSON(location.pathname + '.json')
|
87
87
|
.complete(function (jqXHR) {
|
88
88
|
switch (jqXHR.status) {
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
89
|
+
case 202:
|
90
|
+
var interval;
|
91
|
+
if (intervals.length === 1) {
|
92
|
+
interval = intervals[0];
|
93
|
+
}
|
94
|
+
else {
|
95
|
+
interval = intervals.shift();
|
96
|
+
}
|
97
|
+
setTimeout(poll, interval);
|
98
|
+
break;
|
99
|
+
case 200:
|
100
|
+
component.updateState(jqXHR.responseJSON);
|
101
|
+
break;
|
102
|
+
case 404:
|
103
|
+
case 400:
|
104
|
+
case 500:
|
105
|
+
showErrorModal(jqXHR.responseJSON);
|
106
|
+
break;
|
107
107
|
}
|
108
108
|
});
|
109
109
|
}
|
@@ -188,19 +188,14 @@ var Report = React.createClass({
|
|
188
188
|
<div className={this.shouldShowSidebar() ?
|
189
189
|
'col-md-9' : 'col-md-12'}>
|
190
190
|
{ this.overviewJSX() }
|
191
|
-
{ this.
|
192
|
-
? <Circos queries={this.state.queries}
|
193
|
-
program={this.state.program} collapsed="true"/>
|
194
|
-
: <span></span> }
|
191
|
+
{ this.circosJSX() }
|
195
192
|
{
|
196
193
|
_.map(this.state.queries, _.bind(function (query) {
|
197
194
|
return (
|
198
|
-
<Query key={
|
199
|
-
program={this.state.program} querydb={this.state.querydb}
|
200
|
-
|
201
|
-
|
202
|
-
imported_xml={this.state.imported_xml} />
|
203
|
-
);
|
195
|
+
<Query key={'Query_'+query.id} query={query} showQueryCrumbs={this.state.num_queries > 1}
|
196
|
+
selectHit={this.selectHit} program={this.state.program} querydb={this.state.querydb}
|
197
|
+
veryBig={this.state.veryBig} imported_xml={this.state.imported_xml} />
|
198
|
+
);
|
204
199
|
}, this))
|
205
200
|
}
|
206
201
|
</div>
|
@@ -214,25 +209,36 @@ var Report = React.createClass({
|
|
214
209
|
overviewJSX: function () {
|
215
210
|
return (
|
216
211
|
<div className="overview">
|
217
|
-
<
|
212
|
+
<p className="text-monospace">
|
218
213
|
{this.state.program_version}{this.state.submitted_at
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
this.state.querydb.map((db) => { return db.title }).join(
|
224
|
-
}
|
225
|
-
|
214
|
+
&& `, query submitted on ${this.state.submitted_at}`}
|
215
|
+
</p>
|
216
|
+
<p className="text-monospace">
|
217
|
+
Databases: {
|
218
|
+
this.state.querydb.map((db) => { return db.title; }).join(', ')
|
219
|
+
} ({this.state.stats.nsequences} sequences,
|
220
|
+
{this.state.stats.ncharacters} characters)
|
221
|
+
</p>
|
222
|
+
<p className="text-monospace">
|
226
223
|
Parameters: {
|
227
224
|
_.map(this.state.params, function (val, key) {
|
228
|
-
return key +
|
229
|
-
}).join(
|
225
|
+
return key + ' ' + val;
|
226
|
+
}).join(', ')
|
230
227
|
}
|
231
|
-
</
|
228
|
+
</p>
|
232
229
|
</div>
|
233
230
|
);
|
234
|
-
|
231
|
+
},
|
235
232
|
|
233
|
+
/**
|
234
|
+
* Return JSX for circos if we have at least one hit.
|
235
|
+
*/
|
236
|
+
circosJSX: function () {
|
237
|
+
return this.atLeastTwoHits()
|
238
|
+
? <Circos queries={this.state.queries}
|
239
|
+
program={this.state.program} collapsed="true"/>
|
240
|
+
: <span></span>;
|
241
|
+
},
|
236
242
|
|
237
243
|
// Controller //
|
238
244
|
|
@@ -245,12 +251,19 @@ var Report = React.createClass({
|
|
245
251
|
return this.state.queries.length >= 1;
|
246
252
|
},
|
247
253
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
254
|
+
/**
|
255
|
+
* Returns true if we have at least one hit.
|
256
|
+
*/
|
257
|
+
atLeastOneHit: function () {
|
258
|
+
return this.state.queries.some(query => query.hits.length > 0);
|
259
|
+
},
|
260
|
+
|
261
|
+
atLeastTwoHits: function () {
|
262
|
+
var hit_num = 0;
|
263
|
+
return this.state.queries.some(query => {
|
264
|
+
hit_num += query.hits.length;
|
265
|
+
return hit_num > 1;
|
252
266
|
});
|
253
|
-
return !(cnt == this.state.queries.length);
|
254
267
|
},
|
255
268
|
|
256
269
|
/**
|
@@ -265,13 +278,12 @@ var Report = React.createClass({
|
|
265
278
|
},
|
266
279
|
|
267
280
|
/**
|
268
|
-
* Returns true if index should be shown in the sidebar.
|
269
|
-
*
|
270
|
-
* Index is not shown in the sidebar if there are more than eight queries
|
271
|
-
* in total.
|
281
|
+
* Returns true if index should be shown in the sidebar. Index is shown
|
282
|
+
* only for 2 and 8 queries.
|
272
283
|
*/
|
273
284
|
shouldShowIndex: function () {
|
274
|
-
|
285
|
+
var num_queries = this.state.queries.length;
|
286
|
+
return num_queries >= 2 && num_queries <= 8;
|
275
287
|
},
|
276
288
|
|
277
289
|
/**
|
@@ -309,7 +321,7 @@ var Report = React.createClass({
|
|
309
321
|
* Prevents folding of hits during text-selection.
|
310
322
|
*/
|
311
323
|
preventCollapseOnSelection: function () {
|
312
|
-
$('body').on('mousedown',
|
324
|
+
$('body').on('mousedown', '.hit > .section-header > h4', function (event) {
|
313
325
|
var $this = $(this);
|
314
326
|
$this.on('mouseup mousemove', function handler(event) {
|
315
327
|
if (event.type === 'mouseup') {
|
@@ -355,7 +367,7 @@ var Report = React.createClass({
|
|
355
367
|
*/
|
356
368
|
selectHit: function (id) {
|
357
369
|
|
358
|
-
var checkbox = $(
|
370
|
+
var checkbox = $('#' + id);
|
359
371
|
var num_checked = $('.hit-links :checkbox:checked').length;
|
360
372
|
|
361
373
|
if (!checkbox || !checkbox.val()) {
|
@@ -366,7 +378,7 @@ var Report = React.createClass({
|
|
366
378
|
|
367
379
|
// Highlight selected hit and enable 'Download FASTA/Alignment of
|
368
380
|
// selected' links.
|
369
|
-
if (checkbox.is(
|
381
|
+
if (checkbox.is(':checked')) {
|
370
382
|
$hit.find('.section-content').addClass('glow');
|
371
383
|
$('.download-alignment-of-selected').enable();
|
372
384
|
$('.download-fasta-of-selected').enable();
|
@@ -406,7 +418,11 @@ var Query = React.createClass({
|
|
406
418
|
* Returns the id of query.
|
407
419
|
*/
|
408
420
|
domID: function () {
|
409
|
-
return
|
421
|
+
return 'Query_' + this.props.query.number;
|
422
|
+
},
|
423
|
+
|
424
|
+
queryLength: function () {
|
425
|
+
return this.props.query.length;
|
410
426
|
},
|
411
427
|
|
412
428
|
/**
|
@@ -423,59 +439,57 @@ var Query = React.createClass({
|
|
423
439
|
<div className="resultn" id={this.domID()}
|
424
440
|
data-query-len={this.props.query.length}
|
425
441
|
data-algorithm={this.props.program}>
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
</
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
}
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
className="section-content">
|
466
|
-
<p>
|
467
|
-
Query length: {this.props.query.length}
|
468
|
-
</p>
|
469
|
-
<br/>
|
470
|
-
<br/>
|
471
|
-
<p>
|
472
|
-
<strong> ****** No hits found ****** </strong>
|
473
|
-
</p>
|
474
|
-
</div>
|
475
|
-
)
|
442
|
+
{ this.headerJSX() }
|
443
|
+
{ this.numhits() && this.hitsListJSX() || this.noHitsJSX() }
|
444
|
+
</div>
|
445
|
+
);
|
446
|
+
},
|
447
|
+
|
448
|
+
headerJSX: function () {
|
449
|
+
var meta = `length: ${this.queryLength().toLocaleString()}`;
|
450
|
+
if (this.props.showQueryCrumbs) {
|
451
|
+
meta = `query ${this.props.query.number}, ` + meta;
|
452
|
+
}
|
453
|
+
return <div className="section-header">
|
454
|
+
<h3>
|
455
|
+
Query= {this.props.query.id}
|
456
|
+
<small>{this.props.query.title}</small>
|
457
|
+
</h3>
|
458
|
+
<span className="label label-reset pos-label">{ meta }</span>
|
459
|
+
</div>;
|
460
|
+
},
|
461
|
+
|
462
|
+
hitsListJSX: function () {
|
463
|
+
return <div className="section-content">
|
464
|
+
<HitsOverview key={'GO_' + this.props.query.number} query={this.props.query} program={this.props.program} collapsed={this.props.veryBig} />
|
465
|
+
<LengthDistribution key={'LD_' + this.props.query.id} query={this.props.query} algorithm={this.props.program} collapsed="true" />
|
466
|
+
<HitsTable key={'HT_' + this.props.query.number} query={this.props.query} imported_xml={this.props.imported_xml} />
|
467
|
+
<div id="hits">
|
468
|
+
{
|
469
|
+
_.map(this.props.query.hits, _.bind(function (hit) {
|
470
|
+
return (
|
471
|
+
<Hit key={'HIT_' + hit.number} hit={hit}
|
472
|
+
algorithm={this.props.program}
|
473
|
+
querydb={this.props.querydb}
|
474
|
+
query={this.props.query}
|
475
|
+
imported_xml={this.props.imported_xml}
|
476
|
+
selectHit={this.props.selectHit}
|
477
|
+
showHitCrumbs={this.numhits() > 1}
|
478
|
+
showQueryCrumbs={this.props.showQueryCrumbs} />
|
479
|
+
);
|
480
|
+
}, this))
|
476
481
|
}
|
477
482
|
</div>
|
478
|
-
|
483
|
+
</div>;
|
484
|
+
},
|
485
|
+
|
486
|
+
noHitsJSX: function () {
|
487
|
+
return <div className="section-content">
|
488
|
+
<br />
|
489
|
+
<p>
|
490
|
+
<strong> ****** No hits found ****** </strong>
|
491
|
+
</p>
|
492
|
+
</div>;
|
479
493
|
},
|
480
494
|
|
481
495
|
shouldComponentUpdate: function (nextProps, nextState) {
|
@@ -490,9 +504,9 @@ var HitsTable = React.createClass({
|
|
490
504
|
mixins: [Utils],
|
491
505
|
render: function () {
|
492
506
|
var count = 0,
|
493
|
-
|
494
|
-
|
495
|
-
|
507
|
+
hasName = _.every(this.props.query.hits, function(hit) {
|
508
|
+
return hit.sciname !== '';
|
509
|
+
});
|
496
510
|
|
497
511
|
return (
|
498
512
|
<table
|
@@ -514,9 +528,9 @@ var HitsTable = React.createClass({
|
|
514
528
|
_.map(this.props.query.hits, _.bind(function (hit) {
|
515
529
|
return (
|
516
530
|
<tr key={hit.number}>
|
517
|
-
<td className="text-left">{hit.number +
|
531
|
+
<td className="text-left">{hit.number + '.'}</td>
|
518
532
|
<td>
|
519
|
-
<a href={
|
533
|
+
<a href={'#Query_' + this.props.query.number + '_hit_' + hit.number}>
|
520
534
|
{hit.id}
|
521
535
|
</a>
|
522
536
|
</td>
|
@@ -526,7 +540,7 @@ var HitsTable = React.createClass({
|
|
526
540
|
<td className="text-right">{this.inExponential(hit.hsps[0].evalue)}</td>
|
527
541
|
<td className="text-right">{hit.identity}</td>
|
528
542
|
</tr>
|
529
|
-
)
|
543
|
+
);
|
530
544
|
}, this))
|
531
545
|
}
|
532
546
|
</tbody>
|
@@ -551,7 +565,7 @@ var Hit = React.createClass({
|
|
551
565
|
/**
|
552
566
|
* Returns length of the hit sequence.
|
553
567
|
*/
|
554
|
-
|
568
|
+
hitLength: function () {
|
555
569
|
return this.props.hit.length;
|
556
570
|
},
|
557
571
|
|
@@ -561,7 +575,7 @@ var Hit = React.createClass({
|
|
561
575
|
* Returns id that will be used for the DOM node corresponding to the hit.
|
562
576
|
*/
|
563
577
|
domID: function () {
|
564
|
-
return
|
578
|
+
return 'Query_' + this.props.query.number + '_hit_' + this.props.hit.number;
|
565
579
|
},
|
566
580
|
|
567
581
|
databaseIDs: function () {
|
@@ -593,10 +607,10 @@ var Hit = React.createClass({
|
|
593
607
|
hsp.query_id = this.props.query.id;
|
594
608
|
hsp.hit_id = this.props.hit.id;
|
595
609
|
return hsp;
|
596
|
-
}, this))
|
610
|
+
}, this));
|
597
611
|
|
598
612
|
var aln_exporter = new AlignmentExporter();
|
599
|
-
aln_exporter.export_alignments(hsps, this.props.query.id+
|
613
|
+
aln_exporter.export_alignments(hsps, this.props.query.id+'_'+this.props.hit.id);
|
600
614
|
},
|
601
615
|
|
602
616
|
|
@@ -608,7 +622,7 @@ var Hit = React.createClass({
|
|
608
622
|
|
609
623
|
// Return JSX for view sequence button.
|
610
624
|
viewSequenceButton: function () {
|
611
|
-
if (this.
|
625
|
+
if (this.hitLength() > 10000) {
|
612
626
|
return (
|
613
627
|
<button
|
614
628
|
className="btn btn-link view-sequence disabled"
|
@@ -630,49 +644,57 @@ var Hit = React.createClass({
|
|
630
644
|
|
631
645
|
render: function () {
|
632
646
|
return (
|
633
|
-
<div className="hit" id={this.domID()}
|
634
|
-
data-hit-
|
635
|
-
|
636
|
-
<div className="section-header">
|
637
|
-
<h4 data-toggle="collapse"
|
638
|
-
data-target={this.domID() + "_content"}>
|
639
|
-
<i className="fa fa-chevron-down"></i>
|
640
|
-
|
641
|
-
<span>
|
642
|
-
{this.props.hit.id}
|
643
|
-
|
644
|
-
<small>
|
645
|
-
{this.props.hit.title}
|
646
|
-
</small>
|
647
|
-
</span>
|
648
|
-
</h4>
|
649
|
-
<span className="label label-reset pos-label"
|
650
|
-
title={"Query " + this.props.query.number + ". Hit "
|
651
|
-
+ this.props.hit.number + " of "
|
652
|
-
+ this.props.query.hits.length + "."}
|
653
|
-
data-toggle="tooltip">
|
654
|
-
{this.props.hit.number + "/" + this.props.query.hits.length}
|
655
|
-
</span>
|
656
|
-
</div>
|
657
|
-
<div id={this.domID() + "_content"}
|
658
|
-
className="section-content collapse in">
|
659
|
-
{ this.hitLinks() }
|
660
|
-
<HSPOverview key={"kablammo"+this.props.query.id}
|
661
|
-
query={this.props.query} hit={this.props.hit}
|
662
|
-
algorithm={this.props.algorithm}/>
|
663
|
-
{ this.hspListJSX() }
|
664
|
-
</div>
|
647
|
+
<div className="hit" id={this.domID()} data-hit-def={this.props.hit.id}
|
648
|
+
data-hit-len={this.props.hit.length} data-hit-evalue={this.props.hit.evalue}>
|
649
|
+
{ this.headerJSX() } { this.contentJSX() }
|
665
650
|
</div>
|
666
651
|
);
|
667
652
|
},
|
668
653
|
|
654
|
+
headerJSX: function () {
|
655
|
+
var meta = `length: ${this.hitLength().toLocaleString()}`;
|
656
|
+
|
657
|
+
if (this.props.showQueryCrumbs && this.props.showHitCrumbs) {
|
658
|
+
// Multiper queries, multiple hits
|
659
|
+
meta = `hit ${this.props.hit.number} of query ${this.props.query.number}, ` + meta;
|
660
|
+
}
|
661
|
+
else if (this.props.showQueryCrumbs && !this.props.showHitCrumbs) {
|
662
|
+
// Multiple queries, single hit
|
663
|
+
meta = `the only hit of query ${this.props.query.number}, ` + meta;
|
664
|
+
}
|
665
|
+
else if (!this.props.showQueryCrumbs && this.props.showHitCrumbs) {
|
666
|
+
// Single query, multiple hits
|
667
|
+
meta = `hit ${this.props.hit.number}, ` + meta;
|
668
|
+
}
|
669
|
+
|
670
|
+
return <div className="section-header">
|
671
|
+
<h4 data-toggle="collapse" data-target={this.domID() + '_content'}>
|
672
|
+
<i className="fa fa-chevron-down"></i>
|
673
|
+
<span>
|
674
|
+
{this.props.hit.id}
|
675
|
+
<small>{this.props.hit.title}</small>
|
676
|
+
</span>
|
677
|
+
</h4>
|
678
|
+
<span className="label label-reset pos-label">{ meta }</span>
|
679
|
+
</div>;
|
680
|
+
},
|
681
|
+
|
682
|
+
contentJSX: function () {
|
683
|
+
return <div id={this.domID() + '_content'} className="section-content collapse in">
|
684
|
+
{ this.hitLinks() }
|
685
|
+
<HSPOverview key={'kablammo' + this.props.query.id} query={this.props.query}
|
686
|
+
hit={this.props.hit} algorithm={this.props.algorithm} />
|
687
|
+
{ this.hspListJSX() }
|
688
|
+
</div>;
|
689
|
+
},
|
690
|
+
|
669
691
|
hitLinks: function () {
|
670
692
|
return (
|
671
693
|
<div className="hit-links">
|
672
694
|
<label>
|
673
|
-
<input type="checkbox" id={this.domID() +
|
695
|
+
<input type="checkbox" id={this.domID() + '_checkbox'}
|
674
696
|
value={this.accession()} onChange={function () {
|
675
|
-
this.props.selectHit(this.domID() +
|
697
|
+
this.props.selectHit(this.domID() + '_checkbox');
|
676
698
|
}.bind(this)} data-target={'#' + this.domID()}
|
677
699
|
/> Select
|
678
700
|
</label>
|
@@ -714,10 +736,10 @@ var Hit = React.createClass({
|
|
714
736
|
return <HSP key={hsp.number}
|
715
737
|
algorithm={this.props.algorithm}
|
716
738
|
queryNumber={this.props.query.number}
|
717
|
-
hitNumber={this.props.hit.number} hsp={hsp}
|
739
|
+
hitNumber={this.props.hit.number} hsp={hsp}/>;
|
718
740
|
}, this)
|
719
741
|
}
|
720
|
-
</div
|
742
|
+
</div>;
|
721
743
|
}
|
722
744
|
});
|
723
745
|
|
@@ -886,7 +908,7 @@ var SequenceViewer = (function () {
|
|
886
908
|
sequences: response.sequences,
|
887
909
|
error_msgs: response.error_msgs,
|
888
910
|
requestCompleted: true
|
889
|
-
})
|
911
|
+
});
|
890
912
|
}, this))
|
891
913
|
.fail(function (jqXHR, status, error) {
|
892
914
|
showErrorModal(jqXHR, function () {
|
@@ -941,11 +963,11 @@ var SideBar = React.createClass({
|
|
941
963
|
hsp.hit_id = hit.id;
|
942
964
|
hsp.query_id = query.id;
|
943
965
|
hsps_arr.push(hsp);
|
944
|
-
})
|
945
|
-
})
|
966
|
+
});
|
967
|
+
});
|
946
968
|
}, this));
|
947
969
|
console.log('len '+hsps_arr.length);
|
948
|
-
aln_exporter.export_alignments(hsps_arr,
|
970
|
+
aln_exporter.export_alignments(hsps_arr, 'alignment-'+sequence_ids.length+'_hits');
|
949
971
|
return false;
|
950
972
|
},
|
951
973
|
|
@@ -967,7 +989,7 @@ var SideBar = React.createClass({
|
|
967
989
|
}
|
968
990
|
});
|
969
991
|
}, this));
|
970
|
-
aln_exporter.export_alignments(hsps_arr,
|
992
|
+
aln_exporter.export_alignments(hsps_arr, 'alignment-'+sequence_ids.length+'_hits');
|
971
993
|
return false;
|
972
994
|
},
|
973
995
|
|
@@ -979,29 +1001,29 @@ var SideBar = React.createClass({
|
|
979
1001
|
{ this.props.shouldShowIndex && this.index() }
|
980
1002
|
{ this.downloads() }
|
981
1003
|
</div>
|
982
|
-
)
|
1004
|
+
);
|
983
1005
|
},
|
984
1006
|
|
985
1007
|
index: function () {
|
986
1008
|
return (
|
987
1009
|
<div className="index">
|
988
1010
|
<div
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
1011
|
+
className="section-header">
|
1012
|
+
<h4>
|
1013
|
+
{ this.summary() }
|
1014
|
+
</h4>
|
993
1015
|
</div>
|
994
1016
|
<ul
|
995
1017
|
className="nav hover-reset active-bold">
|
996
1018
|
{
|
997
1019
|
_.map(this.props.data.queries, _.bind(function (query) {
|
998
1020
|
return (
|
999
|
-
<li key={
|
1021
|
+
<li key={'Side_bar_'+query.id}>
|
1000
1022
|
<a
|
1001
1023
|
className="nowrap-ellipsis hover-bold"
|
1002
|
-
href={
|
1003
|
-
title={
|
1004
|
-
{
|
1024
|
+
href={'#Query_' + query.number}
|
1025
|
+
title={'Query= ' + query.id + ' ' + query.title}>
|
1026
|
+
{'Query= ' + query.id}
|
1005
1027
|
</a>
|
1006
1028
|
</li>
|
1007
1029
|
);
|
@@ -1019,7 +1041,7 @@ var SideBar = React.createClass({
|
|
1019
1041
|
|
1020
1042
|
return (
|
1021
1043
|
program.toUpperCase() + ': ' +
|
1022
|
-
numqueries + ' ' + (numqueries > 1 ? 'queries' : 'query') +
|
1044
|
+
numqueries + ' ' + (numqueries > 1 ? 'queries' : 'query') + ', ' +
|
1023
1045
|
numquerydb + ' ' + (numquerydb > 1 ? 'databases' : 'database')
|
1024
1046
|
);
|
1025
1047
|
},
|
@@ -1068,7 +1090,7 @@ var SideBar = React.createClass({
|
|
1068
1090
|
name, alignment length, mismatches, gaps, identity,
|
1069
1091
|
start and end coordinates, e value, bitscore, query
|
1070
1092
|
coverage per subject and per HSP."
|
1071
|
-
href={
|
1093
|
+
href={'download/' + this.props.data.search_id + '.std_tsv'}>
|
1072
1094
|
Standard tabular report
|
1073
1095
|
</a>
|
1074
1096
|
</li>
|
@@ -1080,7 +1102,7 @@ var SideBar = React.createClass({
|
|
1080
1102
|
accessions, and length; alignment details;
|
1081
1103
|
taxonomy details of subject sequence(s) and
|
1082
1104
|
query coverage per subject and per HSP."
|
1083
|
-
href={
|
1105
|
+
href={'download/' + this.props.data.search_id + '.full_tsv'}>
|
1084
1106
|
Full tabular report
|
1085
1107
|
</a>
|
1086
1108
|
</li>
|
@@ -1089,7 +1111,7 @@ var SideBar = React.createClass({
|
|
1089
1111
|
!this.props.data.imported_xml && <li>
|
1090
1112
|
<a className="download" data-toggle="tooltip"
|
1091
1113
|
title="Results in XML format."
|
1092
|
-
href={
|
1114
|
+
href={'download/' + this.props.data.search_id + '.xml'}>
|
1093
1115
|
Full XML report
|
1094
1116
|
</a>
|
1095
1117
|
</li>
|