sequenceserver 2.1.0 → 3.0
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 +4 -4
- data/COPYRIGHT.txt +1 -1
- data/bin/sequenceserver +10 -3
- data/lib/sequenceserver/blast/error.rb +53 -0
- data/lib/sequenceserver/blast/formatter.rb +13 -4
- data/lib/sequenceserver/blast/job.rb +2 -43
- data/lib/sequenceserver/blast/report.rb +33 -3
- data/lib/sequenceserver/config.rb +4 -1
- data/lib/sequenceserver/job.rb +21 -11
- data/lib/sequenceserver/makeblastdb-modified-with-cache.rb +345 -0
- data/lib/sequenceserver/makeblastdb.rb +97 -75
- data/lib/sequenceserver/pool.rb +1 -1
- data/lib/sequenceserver/report.rb +1 -5
- data/lib/sequenceserver/routes.rb +52 -5
- data/lib/sequenceserver/server.rb +1 -1
- data/lib/sequenceserver/sys.rb +1 -1
- data/lib/sequenceserver/version.rb +1 -1
- data/lib/sequenceserver.rb +11 -2
- data/public/404.html +27 -0
- data/public/config.js +0 -6
- data/public/css/grapher.css +1 -1
- data/public/css/sequenceserver.css +22 -11
- data/public/css/sequenceserver.min.css +2 -2
- data/public/js/circos.js +7 -3
- data/public/js/dnd.js +3 -3
- data/public/js/fastq_to_fasta.js +35 -0
- data/public/js/form.js +30 -11
- data/public/js/grapher.js +123 -113
- data/public/js/hit.js +8 -2
- data/public/js/hits_overview.js +4 -1
- data/public/js/jquery_world.js +0 -1
- data/public/js/kablammo.js +4 -0
- data/public/js/length_distribution.js +5 -1
- data/public/js/null_plugins/download_links.js +7 -0
- data/public/js/null_plugins/hit_buttons.js +11 -0
- data/public/js/null_plugins/report_plugins.js +18 -0
- data/public/js/query.js +26 -6
- data/public/js/report.js +92 -22
- data/public/js/search.js +0 -8
- data/public/js/sidebar.js +11 -1
- data/public/js/tests/advanced_parameters.spec.js +36 -0
- data/public/js/tests/mock_data/sequences.js +49 -0
- data/public/js/tests/report.spec.js +62 -6
- data/public/js/tests/search_query.spec.js +45 -19
- data/public/js/visualisation_helpers.js +1 -1
- data/public/sequenceserver-report.min.js +76 -42
- data/public/sequenceserver-search.min.js +34 -33
- data/views/layout.erb +9 -12
- metadata +34 -23
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68dcb3dda53edae5d095423c164568484e786b927fcf733a4722eafde7c3a155
|
4
|
+
data.tar.gz: afb985fe5e762b8a1ab9e1dc4e8dd0bc6158f601a3cc95c0029f03a8587c1fa2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb122a17858e6b7c567a418bda05358ae1a9b34ef1dfdcc11bb5f83097b47e427d7344e61e9f9102488f59f6448592b7d66e1e67ee213498e750dfea5e2e7c8f
|
7
|
+
data.tar.gz: b7b7504faf439acda18aafa0866e74f3645e431b4252bdb12ffd4896d7cf6ee065756db9e1bba027184794f306ce3b732c4911dce56d8b4a96e734dcf86c336c
|
data/COPYRIGHT.txt
CHANGED
@@ -3,7 +3,7 @@ SequenceServer is copyright Anurag Priyam, Ben J Woodcroft and Yannick Wurm,
|
|
3
3
|
version 3, the text of which can be found in LICENSE.txt.
|
4
4
|
|
5
5
|
Components of SequenceServer, including Sinatra, Ox, Slop, html5shiv,
|
6
|
-
Underscore, jQuery, jQuery UI
|
6
|
+
Underscore, jQuery, jQuery UI and Bootstrap, are licensed under
|
7
7
|
the MIT license. D3.js is licensed under BSD license. biojs-vis-sequence
|
8
8
|
is licensed under Apache license. Thin and JSON are licensed under Ruby
|
9
9
|
license. All unmodified files from these and other sources retain their
|
data/bin/sequenceserver
CHANGED
@@ -119,6 +119,11 @@ begin
|
|
119
119
|
'Port to run SequenceServer on',
|
120
120
|
argument: true
|
121
121
|
|
122
|
+
on 'o', 'optimistic=',
|
123
|
+
'Optimistic mode does not perform database compatibility checks, which can be faster. ' \
|
124
|
+
'Only use this if you format FASTAs with "sequenceserver -make-blast-databases"',
|
125
|
+
argument: true
|
126
|
+
|
122
127
|
on 's', 'set',
|
123
128
|
'Set configuration value in default or given config file'
|
124
129
|
|
@@ -296,7 +301,7 @@ begin
|
|
296
301
|
unless response =~ /^[n]$/i
|
297
302
|
puts
|
298
303
|
puts 'Searching ...'
|
299
|
-
if SequenceServer.makeblastdb.
|
304
|
+
if SequenceServer.makeblastdb.any_to_format?
|
300
305
|
formatted = SequenceServer.makeblastdb.format
|
301
306
|
exit! if formatted.empty? && !set?
|
302
307
|
redo unless set?
|
@@ -353,7 +358,9 @@ begin
|
|
353
358
|
end
|
354
359
|
|
355
360
|
if make_blast_databases?
|
356
|
-
if SequenceServer.makeblastdb.
|
361
|
+
if SequenceServer.makeblastdb.no_fastas?
|
362
|
+
puts "Couldn't find any FASTA files in #{SequenceServer.config[:database_dir]}."
|
363
|
+
elsif SequenceServer.makeblastdb.any_to_format_or_reformat?
|
357
364
|
puts
|
358
365
|
puts <<~MSG
|
359
366
|
SequenceServer has scanned your databases directory and will now offer
|
@@ -375,7 +382,7 @@ begin
|
|
375
382
|
print '>> '
|
376
383
|
response = STDIN.gets.to_s.strip
|
377
384
|
SequenceServer.makeblastdb.run unless response =~ /^[n]$/i
|
378
|
-
|
385
|
+
else
|
379
386
|
puts "All FASTA files in #{SequenceServer.config[:database_dir]} " \
|
380
387
|
'are formatted.'
|
381
388
|
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# http://www.ncbi.nlm.nih.gov/books/NBK1763/ (Appendices)
|
2
|
+
|
3
|
+
module SequenceServer
|
4
|
+
module BLAST
|
5
|
+
class Error
|
6
|
+
attr_reader :exitstatus, :stdout, :stderr
|
7
|
+
|
8
|
+
def initialize(exitstatus:, stdout:, stderr:)
|
9
|
+
@exitstatus = exitstatus
|
10
|
+
@stdout = stdout
|
11
|
+
@stderr = stderr
|
12
|
+
end
|
13
|
+
|
14
|
+
def raise!
|
15
|
+
return true if exitstatus.zero? && !File.zero?(stdout)
|
16
|
+
|
17
|
+
case exitstatus
|
18
|
+
when 1..2
|
19
|
+
# 1: Error in query sequences or options.
|
20
|
+
# 2: Error in BLAST databases.
|
21
|
+
error = IO.foreach(stderr).grep(ERROR_LINE).join
|
22
|
+
error = File.read(stderr) if error.empty?
|
23
|
+
fail InputError, "(#{exitstatus}) #{error}"
|
24
|
+
when 4
|
25
|
+
# Out of memory. User can retry with a shorter search, so raising
|
26
|
+
# InputError here instead of SystemError.
|
27
|
+
fail InputError, <<~MSG
|
28
|
+
Ran out of memory. Please try a smaller query, fewer and smaller
|
29
|
+
databases, or limiting the output by using advanced options.
|
30
|
+
MSG
|
31
|
+
when 6
|
32
|
+
# Error creating output files. It can't be a permission issue as that
|
33
|
+
# would have been caught while creating job directory. But we can run
|
34
|
+
# out of storage after creating the job directory and while running
|
35
|
+
# the job. This is a SystemError.
|
36
|
+
fail SystemError, 'Ran out of disk space.'
|
37
|
+
else
|
38
|
+
# I am not sure what the exit codes 3 means and we should not
|
39
|
+
# encounter exit code 5. The only other error that I know can happen
|
40
|
+
# but is not yet handled is when BLAST+ binaries break such as after
|
41
|
+
# macOS updates. So raise SystemError, include the exit status in the
|
42
|
+
# message, and say that that the "most likely" reason is broken BLAST+
|
43
|
+
# binaries.
|
44
|
+
|
45
|
+
error = File.read(stderr)
|
46
|
+
error = 'Most likely there is a problem with the BLAST+ binaries.' if error.empty?
|
47
|
+
|
48
|
+
fail SystemError, "BLAST failed abruptly (exit status: #{exitstatus}). #{error}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -25,23 +25,32 @@ module SequenceServer
|
|
25
25
|
|
26
26
|
attr_reader :format, :mime, :specifiers
|
27
27
|
|
28
|
-
def
|
29
|
-
@
|
28
|
+
def filepath
|
29
|
+
@filepath ||= File.join(job.dir, filename)
|
30
|
+
end
|
31
|
+
|
32
|
+
def size
|
33
|
+
File.size(filepath)
|
30
34
|
end
|
31
35
|
|
32
36
|
def filename
|
33
37
|
@filename ||= "sequenceserver-#{type}_report.#{mime}"
|
34
38
|
end
|
35
39
|
|
40
|
+
def read_file
|
41
|
+
File.read(filepath)
|
42
|
+
end
|
43
|
+
|
36
44
|
private
|
37
45
|
|
38
46
|
attr_reader :job, :type
|
39
47
|
|
40
48
|
def run
|
41
|
-
return if File.exist?(
|
49
|
+
return if File.exist?(filepath)
|
50
|
+
|
42
51
|
command = "blast_formatter -archive '#{job.stdout}'" \
|
43
52
|
" -outfmt '#{format} #{specifiers}'"
|
44
|
-
sys(command, path: config[:bin], dir: DOTDIR, stdout:
|
53
|
+
sys(command, path: config[:bin], dir: DOTDIR, stdout: filepath)
|
45
54
|
rescue CommandFailed => e
|
46
55
|
# Mostly we will never get here: empty archive file,
|
47
56
|
# file permissions, broken BLAST binaries, etc. will
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'sequenceserver/job'
|
2
2
|
require 'sequenceserver/zip_file_generator'
|
3
|
+
require 'sequenceserver/blast/error'
|
3
4
|
|
4
5
|
module SequenceServer
|
5
6
|
# BLAST module.
|
@@ -56,46 +57,8 @@ module SequenceServer
|
|
56
57
|
" -query '#{qfile}' #{options}"
|
57
58
|
end
|
58
59
|
|
59
|
-
# Override Job#raise! to raise specific API errors based on exitstatus
|
60
|
-
# and using contents of stderr to provide context about the error.
|
61
|
-
#
|
62
60
|
def raise!
|
63
|
-
|
64
|
-
return true if exitstatus.zero? && !File.zero?(stdout)
|
65
|
-
|
66
|
-
# Handle error. See [1].
|
67
|
-
case exitstatus
|
68
|
-
when 1..2
|
69
|
-
# 1: Error in query sequences or options.
|
70
|
-
# 2: Error in BLAST databases.
|
71
|
-
error = IO.foreach(stderr).grep(ERROR_LINE).join
|
72
|
-
error = File.read(stderr) if error.empty?
|
73
|
-
fail InputError, "(#{exitstatus}) #{error}"
|
74
|
-
when 4
|
75
|
-
# Out of memory. User can retry with a shorter search, so raising
|
76
|
-
# InputError here instead of SystemError.
|
77
|
-
fail InputError, <<~MSG
|
78
|
-
Ran out of memory. Please try a smaller query, fewer and smaller
|
79
|
-
databases, or limiting the output by using advanced options.
|
80
|
-
MSG
|
81
|
-
when 6
|
82
|
-
# Error creating output files. It can't be a permission issue as that
|
83
|
-
# would have been caught while creating job directory. But we can run
|
84
|
-
# out of storage after creating the job directory and while running
|
85
|
-
# the job. This is a SystemError.
|
86
|
-
fail SystemError, 'Ran out of disk space.'
|
87
|
-
else
|
88
|
-
# I am not sure what the exit codes 3 means and we should not
|
89
|
-
# encounter exit code 5. The only other error that I know can happen
|
90
|
-
# but is not yet handled is when BLAST+ binaries break such as after
|
91
|
-
# macOS updates. So raise SystemError, include the exit status in the
|
92
|
-
# message, and say that that the "most likely" reason is broken BLAST+
|
93
|
-
# binaries.
|
94
|
-
fail SystemError, <<~MSG
|
95
|
-
BLAST failed abruptly (exit status: #{exitstatus}). Most likely there is a
|
96
|
-
problem with the BLAST+ binaries.
|
97
|
-
MSG
|
98
|
-
end
|
61
|
+
SequenceServer::BLAST::Error.new(exitstatus: exitstatus, stdout: stdout, stderr: stderr).raise!
|
99
62
|
end
|
100
63
|
|
101
64
|
# Use it with a block to get a self-cleaning temporary archive file
|
@@ -189,7 +152,3 @@ module SequenceServer
|
|
189
152
|
end
|
190
153
|
end
|
191
154
|
end
|
192
|
-
|
193
|
-
# References
|
194
|
-
# ----------
|
195
|
-
# [1]: http://www.ncbi.nlm.nih.gov/books/NBK1763/ (Appendices)
|
@@ -36,6 +36,8 @@ module SequenceServer
|
|
36
36
|
attr_reader :querydb, :dbtype, :params
|
37
37
|
|
38
38
|
def to_json(*_args)
|
39
|
+
generate
|
40
|
+
|
39
41
|
%i[querydb program program_version params stats
|
40
42
|
queries].inject({}) do |h, k|
|
41
43
|
h[k] = send(k)
|
@@ -48,10 +50,18 @@ module SequenceServer
|
|
48
50
|
non_parse_seqids: !!job.databases&.any?(&:non_parse_seqids?)).to_json
|
49
51
|
end
|
50
52
|
|
51
|
-
|
53
|
+
def xml_file_size
|
54
|
+
return File.size(job.imported_xml_file) if job.imported_xml_file
|
55
|
+
|
56
|
+
generate
|
57
|
+
|
58
|
+
xml_formatter.size
|
59
|
+
end
|
52
60
|
|
53
61
|
# Generate report.
|
54
62
|
def generate
|
63
|
+
return self if @_generated
|
64
|
+
|
55
65
|
job.raise!
|
56
66
|
xml_ir = nil
|
57
67
|
tsv_ir = nil
|
@@ -63,14 +73,34 @@ module SequenceServer
|
|
63
73
|
end
|
64
74
|
end
|
65
75
|
else
|
66
|
-
xml_ir = parse_xml
|
67
|
-
tsv_ir = parse_tsv
|
76
|
+
xml_ir = parse_xml(xml_formatter.read_file)
|
77
|
+
tsv_ir = parse_tsv(tsv_formatter.read_file)
|
68
78
|
end
|
69
79
|
extract_program_info xml_ir
|
70
80
|
extract_db_info xml_ir
|
71
81
|
extract_params xml_ir
|
72
82
|
extract_stats xml_ir
|
73
83
|
extract_queries xml_ir, tsv_ir
|
84
|
+
|
85
|
+
@_generated = true
|
86
|
+
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
def done?
|
91
|
+
return true if job.imported_xml_file
|
92
|
+
|
93
|
+
File.exist?(xml_formatter.filepath) && File.exist?(tsv_formatter.filepath)
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def xml_formatter
|
99
|
+
@xml_formatter ||= Formatter.run(job, 'xml')
|
100
|
+
end
|
101
|
+
|
102
|
+
def tsv_formatter
|
103
|
+
@tsv_formatter ||= Formatter.run(job, 'custom_tsv')
|
74
104
|
end
|
75
105
|
|
76
106
|
# Make program name and program name + version available via `program`
|
@@ -131,7 +131,10 @@ module SequenceServer
|
|
131
131
|
num_jobs: 1,
|
132
132
|
job_lifetime: 43_200,
|
133
133
|
# Set cloud_share_url to 'disabled' to disable the cloud sharing feature
|
134
|
-
cloud_share_url: 'https://share.sequenceserver.com/api/v1/shared-job'
|
134
|
+
cloud_share_url: 'https://share.sequenceserver.com/api/v1/shared-job',
|
135
|
+
# Warn in the UI before rendering results larger than this value
|
136
|
+
large_result_warning_threshold: 250 * 1024 * 1024,
|
137
|
+
optimistic: false # Faster, but does not perform DB compatibility checks
|
135
138
|
}
|
136
139
|
end
|
137
140
|
end
|
data/lib/sequenceserver/job.rb
CHANGED
@@ -28,16 +28,25 @@ module SequenceServer
|
|
28
28
|
enqueue(job)
|
29
29
|
end
|
30
30
|
|
31
|
+
def serializable_classes
|
32
|
+
[
|
33
|
+
Time,
|
34
|
+
Symbol,
|
35
|
+
SequenceServer::Job,
|
36
|
+
SequenceServer::BLAST::Job,
|
37
|
+
SequenceServer::Database
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
31
41
|
# Fetches job with the given id.
|
32
42
|
def fetch(id)
|
33
43
|
job_file = File.join(DOTDIR, id, 'job.yaml')
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
44
|
+
return nil unless File.exist?(job_file)
|
45
|
+
|
46
|
+
YAML.safe_load_file(
|
47
|
+
job_file,
|
48
|
+
permitted_classes: serializable_classes
|
49
|
+
)
|
41
50
|
end
|
42
51
|
|
43
52
|
# Deletes job with the given id.
|
@@ -75,8 +84,8 @@ module SequenceServer
|
|
75
84
|
# of job data will be held, yields (if block given) and saves the job.
|
76
85
|
#
|
77
86
|
# Subclasses should extend `initialize` as per requirement.
|
78
|
-
def initialize(
|
79
|
-
@id = SecureRandom.uuid
|
87
|
+
def initialize(params = {})
|
88
|
+
@id = params.fetch(:id, SecureRandom.uuid)
|
80
89
|
@submitted_at = Time.now
|
81
90
|
mkdir_p dir
|
82
91
|
yield if block_given?
|
@@ -85,7 +94,7 @@ module SequenceServer
|
|
85
94
|
raise SystemError, 'Not enough disk space to start a new job'
|
86
95
|
rescue Errno::EACCES
|
87
96
|
raise SystemError, "Permission denied to write to #{DOTDIR}"
|
88
|
-
rescue => e
|
97
|
+
rescue StandardError => e
|
89
98
|
rm_rf dir
|
90
99
|
raise e
|
91
100
|
end
|
@@ -117,7 +126,7 @@ module SequenceServer
|
|
117
126
|
# should be called on a completed job before attempting to use the results.
|
118
127
|
# Subclasses should provide their own implementation.
|
119
128
|
def raise!
|
120
|
-
|
129
|
+
fail if done? && exitstatus != 0
|
121
130
|
end
|
122
131
|
|
123
132
|
# Where will the stdout be written to during execution and read from later.
|
@@ -163,6 +172,7 @@ module SequenceServer
|
|
163
172
|
def fetch(key)
|
164
173
|
filename = File.join(dir, key)
|
165
174
|
fail unless File.exist? filename
|
175
|
+
|
166
176
|
filename
|
167
177
|
end
|
168
178
|
|