sequenceserver 3.1.2 → 3.2.0

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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/lib/sequenceserver/api_errors.rb +18 -0
  3. data/lib/sequenceserver/blast/hit.rb +1 -2
  4. data/lib/sequenceserver/blast/job.rb +15 -5
  5. data/lib/sequenceserver/blast/report.rb +5 -1
  6. data/lib/sequenceserver/blast/tasks.rb +1 -1
  7. data/lib/sequenceserver/database.rb +5 -1
  8. data/lib/sequenceserver/job.rb +26 -10
  9. data/lib/sequenceserver/makeblastdb.rb +2 -1
  10. data/lib/sequenceserver/routes.rb +38 -13
  11. data/lib/sequenceserver/version.rb +1 -1
  12. data/lib/sequenceserver/zip_file_generator.rb +1 -1
  13. data/lib/sequenceserver.rb +1 -1
  14. data/public/404.html +8 -16
  15. data/public/css/app.css +794 -111
  16. data/public/css/app.min.css +1 -1
  17. data/public/css/sequenceserver.min.css +1 -8
  18. data/public/js/alignment_exporter.js +16 -28
  19. data/public/js/circos.js +103 -96
  20. data/public/{packages/circosJS@1.7.0.js → js/circosjs.js} +156 -778
  21. data/public/js/cloud_share_modal.js +95 -98
  22. data/public/js/collapse_preferences.js +13 -15
  23. data/public/js/databases.js +4 -3
  24. data/public/js/databases_tree.js +51 -30
  25. data/public/js/error_modal.js +35 -22
  26. data/public/js/exporter.js +2 -0
  27. data/public/js/form.js +55 -17
  28. data/public/js/grapher.js +94 -92
  29. data/public/js/hit.js +24 -22
  30. data/public/js/hits.js +283 -0
  31. data/public/js/hits_overview.js +8 -27
  32. data/public/js/hsp.js +140 -144
  33. data/public/js/jquery_world.js +25 -16
  34. data/public/js/kablammo.js +14 -10
  35. data/public/js/length_distribution.js +23 -37
  36. data/public/js/mailto.js +1 -3
  37. data/public/js/null_plugins/report_plugins.js +4 -5
  38. data/public/js/options.js +19 -25
  39. data/public/js/query.js +36 -35
  40. data/public/js/report/alignment_results.js +18 -0
  41. data/public/js/report/graphical_overview.js +38 -0
  42. data/public/js/report/report_header.js +28 -0
  43. data/public/js/report/run_summary.js +43 -0
  44. data/public/js/report.js +124 -348
  45. data/public/js/report_root.js +10 -8
  46. data/public/js/search.js +31 -11
  47. data/public/js/search_button.js +85 -78
  48. data/public/js/sequence.js +169 -180
  49. data/public/js/sequence_modal.js +58 -65
  50. data/public/js/share_url.js +5 -5
  51. data/public/js/sidebar.js +152 -89
  52. data/public/js/svgExporter.js +8 -3
  53. data/public/js/tests/alignment_exporter.spec.js +38 -0
  54. data/public/js/tests/cloud_share_modal.spec.js +75 -0
  55. data/public/js/tests/form.spec.js +1 -1
  56. data/public/js/tests/report.spec.js +37 -15
  57. data/public/js/tests/visualisation_helpers.spec.js +28 -0
  58. data/public/js/visualisation_helpers.js +24 -27
  59. data/public/packages/jquery-ui@1.13.3.js +19070 -0
  60. data/public/sequenceserver-report.min.js +3 -2481
  61. data/public/sequenceserver-report.min.js.LICENSE.txt +213 -0
  62. data/public/sequenceserver-report.min.js.map +1 -0
  63. data/public/sequenceserver-search.min.js +3 -2382
  64. data/public/sequenceserver-search.min.js.LICENSE.txt +262 -0
  65. data/public/sequenceserver-search.min.js.map +1 -0
  66. data/views/error.erb +1 -1
  67. data/views/layout.erb +122 -133
  68. data/views/report.erb +3 -2
  69. data/views/search.erb +10 -14
  70. metadata +21 -28
  71. data/public/config.js +0 -147
  72. data/public/css/fonts.css +0 -31
  73. data/public/css/grapher.css +0 -670
  74. data/public/css/sequenceserver.css +0 -527
  75. data/public/packages/jquery-ui@1.11.4.js +0 -16624
  76. data/public/vendor/github/mbostock/d3@3.5.6/d3.js +0 -9506
  77. data/public/vendor/github/mbostock/d3@3.5.6.js +0 -1
  78. data/views/search_layout.erb +0 -153
@@ -1,5 +1,6 @@
1
1
  import * as Exporter from './exporter';
2
2
  import _ from 'underscore';
3
+
3
4
  export default class AlignmentExporter {
4
5
  constructor() {
5
6
  this.prepare_alignments_for_export = this.prepare_alignments_for_export.bind(this);
@@ -7,49 +8,36 @@ export default class AlignmentExporter {
7
8
  }
8
9
 
9
10
  wrap_string(str, width) {
10
- var idx = 0;
11
- var wrapped = '';
12
- while(true) {
13
- wrapped += str.substring(idx, idx + width);
14
- idx += width;
15
- if(idx < str.length) {
16
- wrapped += '\n';
17
- } else {
18
- break;
19
- }
20
- }
21
- return wrapped;
11
+ return str.match(new RegExp(`.{1,${width}}`, 'g')).join('\n');
22
12
  }
23
13
 
24
14
  generate_fasta(hsps) {
15
+ let fasta = '';
25
16
 
26
- var fasta = '';
17
+ hsps.map(hsp => {
18
+ fasta += `>${hsp.query_id}:${hsp.qstart}-${hsp.qend}\n`;
19
+ fasta += `${hsp.qseq}\n`;
20
+ fasta += `>${hsp.query_id}:${hsp.qstart}-${hsp.qend}_alignment_${hsp.hit_id}:${hsp.sstart}-${hsp.send}\n`;
21
+ fasta += `${hsp.midline}\n`;
22
+ fasta += `>${hsp.hit_id}:${hsp.sstart}-${hsp.send}\n`;
23
+ fasta += `${hsp.sseq}\n`;
24
+ });
27
25
 
28
- _.each(hsps, _.bind(function (hsp) {
29
- fasta += '>'+hsp.query_id+':'+hsp.qstart+'-'+hsp.qend+'\n';
30
- fasta += hsp.qseq+'\n';
31
- fasta += '>'+hsp.query_id+':'+hsp.qstart+'-'+hsp.qend+'_alignment_'+hsp.hit_id+':'+hsp.sstart+'-'+hsp.send+'\n';
32
- fasta += hsp.midline+'\n';
33
- fasta += '>'+hsp.hit_id+':'+hsp.sstart+'-'+hsp.send+'\n';
34
- fasta += hsp.sseq+'\n';
35
- }, this));
36
26
  return fasta;
37
27
  }
38
28
 
39
29
  get_alignments_download_metadata(hsps, filename_prefix){
40
- var fasta = this.generate_fasta(hsps);
41
- var blob = new Blob([fasta], { type: 'text/fasta' });
42
- var filename = Exporter.sanitize_filename(filename_prefix) + '.txt';
30
+ const fasta = this.generate_fasta(hsps);
31
+ const blob = new Blob([fasta], { type: 'text/fasta' });
32
+ const filename = Exporter.sanitize_filename(filename_prefix) + '.txt';
43
33
  return {filename, blob};
44
34
  }
45
35
 
46
-
47
36
  prepare_alignments_for_export(hsps, filename_prefix) {
48
37
  const { filename, blob } = this.get_alignments_download_metadata(hsps, filename_prefix);
49
- const blob_url = Exporter.generate_blob_url(blob, filename);
50
- return blob_url;
38
+ return Exporter.generate_blob_url(blob, filename);
51
39
  }
52
-
40
+
53
41
  export_alignments(hsps, filename_prefix) {
54
42
  const { filename, blob } = this.get_alignments_download_metadata(hsps, filename_prefix);
55
43
  Exporter.download_blob(blob, filename);
data/public/js/circos.js CHANGED
@@ -1,5 +1,5 @@
1
- import d3 from 'd3';
2
- import Circos from '../packages/circosJS@1.7.0';
1
+ import * as d3 from 'd3';
2
+ import Circos from './circosjs';
3
3
  import _ from 'underscore';
4
4
 
5
5
  import Grapher from 'grapher';
@@ -37,52 +37,55 @@ class Graph {
37
37
  this.svgContainer = $svgContainer;
38
38
  this.seq_type = Helpers.get_seq_type(props.program);
39
39
  this.algorithm = props.program;
40
- this.initiate();
41
- }
42
-
43
- initiate() {
44
- // this.width = 700;
40
+ // Initialize dimensions
45
41
  this.width = this.svgContainer.width();
46
42
  this.height = 600;
47
43
  this.innerRadius = 200;
48
44
  this.outerRadius = 230;
45
+
46
+ // Initialize data arrays
49
47
  this.query_arr = [];
50
48
  this.hit_arr = [];
51
49
  this.layout_arr = [];
52
50
  this.chords_arr = [];
53
- // this.max_length = 0;
51
+
52
+ // Initialize other properties
54
53
  this.hsp_count = 50;
55
54
  this.denominator = 1;
56
55
  this.spacing = 20;
57
56
  this.labelSpacing = 10;
58
- var suffixes = { amino_acid: 'aa', nucleic_acid: 'bp' };
57
+ this.initiate();
58
+ }
59
+
60
+ initiate() {
61
+ // Call initialization methods
59
62
  this.construct_layout();
60
63
  this.iterator_for_edits();
64
+
65
+ // Remove duplicate hits
61
66
  this.hit_arr = _.uniq(this.hit_arr);
67
+
68
+ // Handle spacing
62
69
  this.handle_spacing();
63
- var prefix = d3.formatPrefix(this.max_length);
64
- this.suffix =
65
- ' ' + prefix.symbol + suffixes[this.seq_type.subject_seq_type];
66
- if (prefix.symbol == 'k') {
67
- this.denominator = 1000;
68
- } else if (prefix.symbol == 'M') {
69
- this.denominator = 1000000;
70
- this.spacing = 1000000;
71
- this.labelSpacing = 200000;
72
- } else if (prefix.symbol == 'g') {
73
- this.denominator = 1000000000;
74
- }
70
+
71
+ // Insert the circos container
75
72
  d3.select(this.svgContainer[0])
76
- .insert('svg', ':first-child')
73
+ .insert('div', ':first-child')
77
74
  .attr('class', 'circosContainer');
75
+
76
+ // Create the instance
78
77
  this.create_instance(this.svgContainer, this.width, this.height);
78
+
79
+ // Render the instance or show an error
79
80
  if (this.chords_arr.length && this.layout_arr.length) {
80
81
  this.instance_render();
81
82
  } else {
82
83
  this.render_error();
83
84
  }
85
+
86
+ // Setup the tooltip
84
87
  this.setupTooltip();
85
- // this.drawLegend();
88
+ // this.drawLegend();
86
89
  }
87
90
 
88
91
  iterator_for_edits() {
@@ -94,71 +97,64 @@ class Graph {
94
97
 
95
98
  // Generate both layout_arr and chords_arr with top hsps set by this.hsp_count
96
99
  construct_layout() {
97
- var hsp_count = 0;
98
- var query_count = 0;
99
100
  var num_karyotype = 32;
100
101
  var num_queries = this.queries.length;
101
102
  var x = Math.min(num_karyotype / 2, num_queries);
102
103
  var num_hits = (num_karyotype - x) / x;
103
104
  this.new_layout = [];
104
- this.data = _.map(
105
- this.queries,
106
- _.bind(function (query) {
107
- if (query_count < x) {
108
- var label = query.id;
109
- var len = query.length;
110
- var item1 = {
111
- len: len,
112
- color: '#8dd3c7',
113
- label: label,
114
- id: 'Query_' + this.clean_id(query.id),
115
- ori_id: label,
116
- };
117
- this.layout_arr.push(item1);
118
- var hit_details = _.map(
119
- query.hits,
120
- _.bind(function (hit) {
121
- if (hit.number < num_hits) {
122
- var hsp_details = _.map(
123
- hit.hsps,
124
- _.bind(function (hsp) {
125
- if (_.indexOf(this.hit_arr, hit.id) == -1) {
126
- var label = hit.id;
127
- var len = hit.length;
128
- this.hit_arr.push(hit.id);
129
- var item2 = {
130
- len: len,
131
- color: '#80b1d3',
132
- label: label,
133
- id: 'Hit_' + this.clean_id(hit.id),
134
- ori_id: label,
135
- };
136
- this.layout_arr.push(item2);
137
- }
138
-
139
- var item3 = [
140
- 'Query_' + this.clean_id(query.id),
141
- hsp.qstart,
142
- hsp.qend,
143
- 'Hit_' + this.clean_id(hit.id),
144
- hsp.sstart,
145
- hsp.send,
146
- hit.number,
147
- hsp,
148
- ];
149
- this.chords_arr.push(item3);
150
- return hsp;
151
- }, this)
152
- );
153
- return hit;
154
- }
155
- }, this)
156
- );
157
- }
158
- this.query_arr.push(query.id);
159
- return query;
160
- }, this)
161
- );
105
+ this.data = _.map(this.queries, _.bind(this.processQuery, this, x, num_hits));
106
+ }
107
+
108
+ processQuery(x, num_hits, query) {
109
+ if (this.query_arr.length < x) {
110
+ var label = query.id;
111
+ var len = query.length;
112
+ var item1 = {
113
+ len: len,
114
+ color: '#8dd3c7',
115
+ label: label,
116
+ id: 'Query_' + this.clean_id(query.id),
117
+ ori_id: label,
118
+ };
119
+ this.layout_arr.push(item1);
120
+ _.map(query.hits, _.bind(this.processHit, this, num_hits, query));
121
+ }
122
+ this.query_arr.push(query.id);
123
+ return query;
124
+ }
125
+
126
+ processHit(num_hits, query, hit) {
127
+ if (hit.number < num_hits) {
128
+ if (_.indexOf(this.hit_arr, hit.id) == -1) {
129
+ var label = hit.id;
130
+ var len = hit.length;
131
+ this.hit_arr.push(hit.id);
132
+ var item2 = {
133
+ len: len,
134
+ color: '#80b1d3',
135
+ label: label,
136
+ id: 'Hit_' + this.clean_id(hit.id),
137
+ ori_id: label,
138
+ };
139
+ this.layout_arr.push(item2);
140
+ }
141
+ _.map(hit.hsps, _.bind(this.processHSP, this, query, hit));
142
+ }
143
+ return hit;
144
+ }
145
+
146
+ processHSP(query, hit, hsp) {
147
+ this.chords_arr.push([
148
+ 'Query_' + this.clean_id(query.id),
149
+ hsp.qstart,
150
+ hsp.qend,
151
+ 'Hit_' + this.clean_id(hit.id),
152
+ hsp.sstart,
153
+ hsp.send,
154
+ hit.number,
155
+ hsp,
156
+ ]);
157
+ return hsp;
162
158
  }
163
159
 
164
160
  // rearraging hit and query karyotypes to have all query in one place
@@ -349,7 +345,6 @@ class Graph {
349
345
  this.paletteSize = this.chords_arr.length;
350
346
  }
351
347
  return {
352
- usePalette: true,
353
348
  colorPaletteSize: this.paletteSize,
354
349
  // color: 'rgb(0,0,0)',
355
350
  colorPalette: 'RdYlBu', // colors of chords based on last value in chords
@@ -373,7 +368,7 @@ class Graph {
373
368
  spacing: this.spacing, // the ticks values to display
374
369
  labelSpacing: this.labelSpacing, // ticks value apper in interval
375
370
  labelDenominator: this.denominator, // divide the value by this value
376
- labelSuffix: this.suffix,
371
+ labelSuffix: '',
377
372
  labelSize: '10px',
378
373
  majorSpacing: this.labelSpacing, // major ticks apper in interval
379
374
  size: {
@@ -493,7 +488,6 @@ class Graph {
493
488
  this.layoutHide = [];
494
489
  if (id) {
495
490
  $('.circos .Query_' + this.clean_id(id))
496
- .attr('data-toggle', 'tooltip')
497
491
  .attr('title', id)
498
492
  .on(
499
493
  'click',
@@ -523,7 +517,6 @@ class Graph {
523
517
  this.layoutHide = [];
524
518
  if (id) {
525
519
  $('.circos .Hit_' + this.clean_id(id))
526
- .attr('data-toggle', 'tooltip')
527
520
  .attr('title', id)
528
521
  .on(
529
522
  'click',
@@ -549,7 +542,6 @@ class Graph {
549
542
  var algorithm = this.algorithm;
550
543
  _.each(this.chords_arr, function (obj) {
551
544
  $('#' + obj[0] + '_' + obj[3])
552
- .attr('data-toggle', 'tooltip')
553
545
  .attr('title', function () {
554
546
  // E value and identity.
555
547
  var alt_tooltip =
@@ -574,12 +566,28 @@ class Graph {
574
566
  return alt_tooltip;
575
567
  });
576
568
  });
577
- $('[data-toggle="tooltip"]').tooltip({
578
- placement: 'top',
579
- container: 'body',
580
- html: 'true',
581
- delay: 0,
582
- 'white-space': 'nowrap',
569
+ $('.circos').tooltip({
570
+ position: {
571
+ my: 'left+3 bottom-3',
572
+ at: 'right bottom',
573
+ using: function(position, feedback) {
574
+ $(this).css(position);
575
+ $('<div>')
576
+ .addClass('arrow')
577
+ .addClass(feedback.vertical)
578
+ .addClass(feedback.horizontal)
579
+ .appendTo(this);
580
+ }
581
+ },
582
+ items: '.chord1 path, .cs-layout g',
583
+ show: false,
584
+ hide: false,
585
+ content: function() {
586
+ var title = $(this).attr('title');
587
+ if (!title) return false;
588
+ var parsedHTML = $.parseHTML(title);
589
+ return parsedHTML;
590
+ }
583
591
  });
584
592
  }
585
593
 
@@ -658,7 +666,6 @@ class Graph {
658
666
  return 'q' + s + '-' + this.paletteSize;
659
667
  }, this)
660
668
  )
661
- .attr('data-toggle', 'tooltip')
662
669
  .attr('title', function (d) {
663
670
  return d.evalue;
664
671
  })
@@ -667,7 +674,7 @@ class Graph {
667
674
  .attr('height', 20);
668
675
  // .attr('fill','#43ff21');
669
676
 
670
- var scale = d3.scale.linear().domain([0, 250]).range([0, 100]);
677
+ var scale = d3.scaleLinear().domain([0, 250]).range([0, 100]);
671
678
 
672
679
  // this.legend.append('rect')
673
680
  // .attr('x', 7*14)