sequenceserver 2.0.0.beta4 → 2.0.0.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.dockerignore +1 -0
- data/.travis.yml +7 -4
- data/AppImage/sequenceserver.sh +5 -0
- data/Dockerfile +14 -12
- data/bin/sequenceserver +37 -28
- data/lib/sequenceserver.rb +35 -7
- data/lib/sequenceserver/blast/job.rb +18 -25
- data/lib/sequenceserver/blast/report.rb +68 -34
- data/lib/sequenceserver/config.rb +1 -1
- data/lib/sequenceserver/database.rb +0 -129
- data/lib/sequenceserver/makeblastdb.rb +243 -0
- data/lib/sequenceserver/routes.rb +28 -2
- data/lib/sequenceserver/version.rb +1 -1
- data/public/SequenceServer_logo.png +0 -0
- data/public/css/grapher.css +8 -15
- data/public/css/sequenceserver.css +119 -55
- data/public/css/sequenceserver.min.css +3 -3
- data/public/js/circos.js +1 -1
- data/public/js/download_fasta.js +17 -0
- data/public/js/grapher.js +7 -9
- data/public/js/hit.js +217 -0
- data/public/js/hits_overview.js +12 -13
- data/public/js/hsp.js +104 -84
- data/public/js/{sequenceserver.js → jquery_world.js} +1 -18
- data/public/js/kablammo.js +337 -334
- data/public/js/length_distribution.js +1 -1
- data/public/js/query.js +147 -0
- data/public/js/report.js +216 -836
- data/public/js/search.js +194 -192
- data/public/js/sequence_modal.js +167 -0
- data/public/js/sidebar.js +210 -0
- data/public/js/utils.js +2 -19
- data/public/js/visualisation_helpers.js +2 -2
- data/public/sequenceserver-report.min.js +19 -19
- data/public/sequenceserver-search.min.js +11 -11
- data/public/vendor/github/twbs/bootstrap@3.3.5/js/bootstrap.js +2 -2
- data/spec/blast_versions/blast_2.2.30/import_spec_capybara_local_2.2.30.rb +15 -15
- data/spec/blast_versions/blast_2.2.31/import_spec_capybara_local_2.2.31.rb +15 -15
- data/spec/blast_versions/blast_2.3.0/import_spec_capybara_local_2.3.0.rb +15 -15
- data/spec/blast_versions/blast_2.4.0/import_spec_capybara_local_2.4.0.rb +15 -15
- data/spec/blast_versions/blast_2.5.0/import_spec_capybara_local_2.5.0.rb +15 -15
- data/spec/blast_versions/blast_2.6.0/import_spec_capybara_local_2.6.0.rb +15 -15
- data/spec/blast_versions/blast_2.7.1/import_spec_capybara_local_2.7.1.rb +15 -15
- data/spec/blast_versions/blast_2.8.1/import_spec_capybara_local_2.8.1.rb +15 -15
- data/spec/blast_versions/blast_2.9.0/import_spec_capybara_local_2.9.0.rb +15 -15
- data/spec/blast_versions/diamond_0.9.24/import_spec_capybara_local_0.9.24.rb +6 -6
- data/spec/capybara_spec.rb +14 -3
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.ndb +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhr +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nin +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nos +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.not +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.ntf +0 -0
- data/spec/database/sample/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nto +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pdb +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.phr +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pin +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pos +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pot +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.ptf +0 -0
- data/spec/database/sample/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pto +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pdb +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phr +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pin +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pos +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pot +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.ptf +0 -0
- data/spec/database/sample/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pto +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.ndb +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nhr +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nin +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nos +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.not +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsq +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.ntf +0 -0
- data/spec/database/sample/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nto +0 -0
- data/spec/database/v4/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhd +8 -0
- data/spec/database/v4/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhi +0 -0
- data/spec/database/v4/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nhr +0 -0
- data/spec/database/v4/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nin +0 -0
- data/spec/database/v4/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nog +0 -0
- data/spec/database/{sample → v4}/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsd +0 -0
- data/spec/database/{sample → v4}/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsi +0 -0
- data/spec/database/v4/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.fasta.nsq +0 -0
- data/spec/database/v4/genome/Solenopsis_invicta/Solenopsis_invicta_gnG_subset.txt +8 -0
- data/spec/database/v4/links.rb +23 -0
- data/spec/database/v4/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta +6449 -0
- data/spec/database/v4/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.phd +1189 -0
- data/spec/database/v4/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.phi +0 -0
- data/spec/database/v4/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.phr +0 -0
- data/spec/database/v4/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pin +0 -0
- data/spec/database/v4/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.pog +0 -0
- data/spec/database/{sample → v4}/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psd +0 -0
- data/spec/database/{sample → v4}/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psi +0 -0
- data/spec/database/v4/proteins/Solenopsis_invicta/Sinvicta2-2-3.prot.subset.fasta.psq +0 -0
- data/spec/database/v4/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phd +9140 -0
- data/spec/database/v4/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phi +0 -0
- data/spec/database/v4/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.phr +0 -0
- data/spec/database/v4/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pin +0 -0
- data/spec/database/v4/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.pog +0 -0
- data/spec/database/{sample → v4}/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psd +0 -0
- data/spec/database/{sample → v4}/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psi +0 -0
- data/spec/database/v4/proteins/uniprot/2018-04-Swiss-Prot_insecta.fasta.psq +0 -0
- data/spec/database/v4/proteins/uniprot/URL +1 -0
- data/spec/database/v4/si_uniprot_idmap.yml +14180 -0
- data/spec/database/v4/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta +5486 -0
- data/spec/database/v4/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nhd +473 -0
- data/spec/database/v4/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nhi +0 -0
- data/spec/database/v4/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nhr +0 -0
- data/spec/database/v4/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nin +0 -0
- data/spec/database/v4/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nog +0 -0
- data/spec/database/{sample → v4}/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsd +0 -0
- data/spec/database/{sample → v4}/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsi +0 -0
- data/spec/database/v4/transcripts/Solenopsis_invicta/Sinvicta2-2-3.cdna.subset.fasta.nsq +0 -0
- data/spec/database_spec.rb +0 -76
- data/spec/makeblastdb_spec.rb +121 -0
- data/views/layout.erb +5 -1
- metadata +75 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b04c2f43509bf7d4a15d555e3bd9cea86d3c7770c7a3e35016f963f877055ecf
|
4
|
+
data.tar.gz: 25678397eacb2c3f445902624baff80a90d2a47ca98d2b703e13de3eca84cf1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8e6a4c1b4917d9bd35d07ef8e580e1b75105bfd1709fb892d9ed523da91f8c3a08d50c1c9da304530cd0bb5d77da00a4944c65cd5ce90fc979c9d6099149058
|
7
|
+
data.tar.gz: ef493ec4cf1aef63b2f535251143b34154d0d332a47a1d15668c7a74b139d5e6c2a2f9c33b5c7072ae9c2fbbcf33048fad4e828273c85a199a6ab79874d6e766
|
data/.dockerignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
_site
|
data/.travis.yml
CHANGED
@@ -24,14 +24,17 @@ before_install:
|
|
24
24
|
- wget -c "https://github.com/mozilla/geckodriver/releases/download/v0.24.0/geckodriver-v0.24.0-linux64.tar.gz" && tar xvf geckodriver-*.tar.gz -C bin
|
25
25
|
# Download codeclimate test reporter to bin and make it executable
|
26
26
|
- wget -c "https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64" -O bin/cc-test-reporter && chmod +x bin/cc-test-reporter
|
27
|
-
# Download and extract NCBI BLAST+ 2.
|
28
|
-
- wget -c "ftp://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/2.
|
27
|
+
# Download and extract NCBI BLAST+ 2.10.0
|
28
|
+
- wget -c "ftp://ftp.ncbi.nlm.nih.gov/blast/executables/blast+/2.10.0/ncbi-blast-2.10.0+-x64-linux.tar.gz" && tar xvf ncbi-blast-*.tar.gz
|
29
29
|
# Conclude installation by adding opt/bin/ containing codeclimate test reporter
|
30
|
-
# and geckodriver, and opt/ncbi-blast-2.
|
30
|
+
# and geckodriver, and opt/ncbi-blast-2.10.0+/bin containing BLAST+ binaries to
|
31
31
|
# PATH.
|
32
|
-
- export PATH="$PWD/bin:$PWD/ncbi-blast-2.
|
32
|
+
- export PATH="$PWD/bin:$PWD/ncbi-blast-2.10.0+/bin:$PATH"
|
33
33
|
# Reset working directory or subsequent steps may fail.
|
34
34
|
- cd ..
|
35
|
+
# Update bundler. Travis was using bundler 1.16.2 at the time of this writing
|
36
|
+
# and the builds were failing because Gemfile.lock requires bundler > 2.0
|
37
|
+
- gem install bundler -v 2.1.4
|
35
38
|
|
36
39
|
env:
|
37
40
|
global:
|
data/AppImage/sequenceserver.sh
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
# cd back to the directory where the AppImage was launched from. AppRun changes
|
2
|
+
# the working directory so as to work with binaries that have /usr hard-coded;
|
3
|
+
# we don't.
|
4
|
+
cd $OWD
|
5
|
+
|
1
6
|
# Set GEM_PATH to where we installed gems in the AppImage.
|
2
7
|
export GEM_PATH=$APPDIR/var/lib/gems/2.3.0
|
3
8
|
|
data/Dockerfile
CHANGED
@@ -1,23 +1,25 @@
|
|
1
|
-
FROM debian:
|
1
|
+
FROM debian:buster-slim
|
2
2
|
|
3
3
|
LABEL Description="Intuitive local web frontend for the BLAST bioinformatics tool"
|
4
4
|
LABEL MailingList="https://groups.google.com/forum/#!forum/sequenceserver"
|
5
5
|
LABEL Website="http://www.sequenceserver.com"
|
6
|
-
LABEL Version="1.1.0 beta"
|
7
6
|
|
8
|
-
RUN apt-get update
|
9
|
-
build-essential \
|
10
|
-
|
11
|
-
curl wget \
|
12
|
-
gnupg \
|
13
|
-
git \
|
14
|
-
zlib1g-dev
|
7
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
8
|
+
ruby ruby-dev build-essential curl gnupg git wget \
|
9
|
+
zlib1g-dev && rm -rf /var/lib/apt/lists/*
|
15
10
|
|
16
11
|
VOLUME ["/db"]
|
17
12
|
EXPOSE 4567
|
18
13
|
|
19
14
|
COPY . /sequenceserver
|
20
15
|
WORKDIR /sequenceserver
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
# Install bundler, then use bundler to install SequenceServer's dependencies,
|
17
|
+
# and then use SequenceServer to install BLAST. In the last step, -s is used
|
18
|
+
# so that SequenceServer will exit after writing configuration file instead
|
19
|
+
# of starting up, while -d is used to suppress questions about database dir.
|
20
|
+
RUN gem install bundler && \
|
21
|
+
bundle install --without=development && \
|
22
|
+
yes '' | bundle exec bin/sequenceserver -s -d spec/database/sample
|
23
|
+
RUN touch ~/.sequenceserver/asked_to_join
|
24
|
+
|
25
|
+
CMD ["bundle", "exec", "bin/sequenceserver", "-d", "/db"]
|
data/bin/sequenceserver
CHANGED
@@ -20,6 +20,30 @@ def download_from_url(url)
|
|
20
20
|
system(cmd)
|
21
21
|
end
|
22
22
|
|
23
|
+
def ask_to_join
|
24
|
+
asked_to_join = File.join(SequenceServer::DOTDIR, 'asked_to_join')
|
25
|
+
unless File.exist?(asked_to_join)
|
26
|
+
puts
|
27
|
+
puts <<~MSG
|
28
|
+
Do you want to be notified of SequenceServer releases and any
|
29
|
+
other important announcements (3-12 messages a year)? If yes,
|
30
|
+
please provide your email address below or press enter to
|
31
|
+
continue (you won't be prompted again).
|
32
|
+
MSG
|
33
|
+
print '>> '
|
34
|
+
response = STDIN.gets.to_s.strip
|
35
|
+
puts
|
36
|
+
|
37
|
+
if response =~ /@/
|
38
|
+
post_email_cmd = "curl -m 5 https://docs.google.com/forms/u/0/d/e/" \
|
39
|
+
"1FAIpQLSe7sOCiKzYbI7LwErid-g3wfIU5Zpi6VTm0ILJyR036RqC8zg/formResponse " \
|
40
|
+
"-d ifq -d emailAddress=#{response} -d submit=Submit > /dev/null 2> /dev/null"
|
41
|
+
system post_email_cmd
|
42
|
+
end
|
43
|
+
system "touch #{asked_to_join}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
23
47
|
begin
|
24
48
|
Slop.parse!(strict: true, help: true) do
|
25
49
|
banner <<~BANNER
|
@@ -44,10 +68,6 @@ begin
|
|
44
68
|
# of threads to use in config file.
|
45
69
|
$ sequenceserver -s -n 16
|
46
70
|
|
47
|
-
# See if you have FASTA files in database dir that haven't
|
48
|
-
# been converted into BLAST database.
|
49
|
-
$ sequenceserver -u
|
50
|
-
|
51
71
|
# Search for FASTA files in database dir that haven't been
|
52
72
|
# converted into BLAST database yet, and convert them.
|
53
73
|
$ sequenceserver -m
|
@@ -111,9 +131,6 @@ begin
|
|
111
131
|
on 'l', 'list_databases',
|
112
132
|
'List BLAST databases'
|
113
133
|
|
114
|
-
on 'u', 'list-unformatted-fastas',
|
115
|
-
'List unformatted FASTA files'
|
116
|
-
|
117
134
|
on 'i', 'interactive',
|
118
135
|
'Run SequenceServer in interactive mode'
|
119
136
|
|
@@ -261,8 +278,7 @@ begin
|
|
261
278
|
fetch_option(:database_dir).value = response
|
262
279
|
redo
|
263
280
|
rescue SequenceServer::NO_BLAST_DATABASE_FOUND => e
|
264
|
-
unless list_databases? ||
|
265
|
-
make_blast_databases?
|
281
|
+
unless list_databases? || make_blast_databases?
|
266
282
|
|
267
283
|
# Print error raised.
|
268
284
|
puts
|
@@ -281,13 +297,13 @@ begin
|
|
281
297
|
unless response =~ /^[n]$/i
|
282
298
|
puts
|
283
299
|
puts 'Searching ...'
|
284
|
-
if SequenceServer
|
285
|
-
|
286
|
-
exit!
|
287
|
-
else
|
288
|
-
formatted = SequenceServer::Database.make_blast_databases
|
300
|
+
if SequenceServer.makeblastdb.scan
|
301
|
+
formatted = SequenceServer.makeblastdb.run
|
289
302
|
exit! if formatted.empty? && !set?
|
290
303
|
redo unless set?
|
304
|
+
else
|
305
|
+
puts "Couldn't find any FASTA files."
|
306
|
+
exit!
|
291
307
|
end
|
292
308
|
else
|
293
309
|
exit! unless set?
|
@@ -337,22 +353,13 @@ begin
|
|
337
353
|
exit
|
338
354
|
end
|
339
355
|
|
340
|
-
if
|
341
|
-
|
342
|
-
|
356
|
+
if make_blast_databases?
|
357
|
+
if SequenceServer.makeblastdb.scan
|
358
|
+
SequenceServer.makeblastdb.run
|
359
|
+
else
|
343
360
|
puts "All FASTA files in #{SequenceServer.config[:database_dir]} " \
|
344
361
|
'are formatted.'
|
345
|
-
exit
|
346
362
|
end
|
347
|
-
end
|
348
|
-
|
349
|
-
if list_unformatted_fastas?
|
350
|
-
puts unformatted_fastas
|
351
|
-
exit
|
352
|
-
end
|
353
|
-
|
354
|
-
if make_blast_databases?
|
355
|
-
SequenceServer::Database.make_blast_databases
|
356
363
|
exit
|
357
364
|
end
|
358
365
|
|
@@ -379,6 +386,8 @@ begin
|
|
379
386
|
|
380
387
|
SequenceServer.config.write_config_file if fetch_option(:set).value
|
381
388
|
|
389
|
+
ask_to_join
|
390
|
+
|
382
391
|
SequenceServer.run
|
383
392
|
end
|
384
393
|
end
|
@@ -386,4 +395,4 @@ rescue Slop::Error => e
|
|
386
395
|
puts e
|
387
396
|
puts "Run '#{$PROGRAM_NAME} -h' for help with command line options."
|
388
397
|
exit
|
389
|
-
end
|
398
|
+
end
|
data/lib/sequenceserver.rb
CHANGED
@@ -4,8 +4,12 @@ require 'resolv'
|
|
4
4
|
|
5
5
|
# Top level module / namespace.
|
6
6
|
module SequenceServer
|
7
|
-
#
|
8
|
-
BLAST_VERSION = '2.
|
7
|
+
# The default version of BLAST that will be downloaded and configured for use.
|
8
|
+
BLAST_VERSION = '2.10.0+'.freeze
|
9
|
+
# The minimum version of BLAST that SequenceServer is happy to run with. This
|
10
|
+
# is for compatiblity with older database formats. Users will download BLAST
|
11
|
+
# themselves.
|
12
|
+
MIN_BLAST_VERSION = '2.9.0+'.freeze
|
9
13
|
|
10
14
|
# Default location of configuration file.
|
11
15
|
DEFAULT_CONFIG_FILE = '~/.sequenceserver.conf'.freeze
|
@@ -20,6 +24,7 @@ module SequenceServer
|
|
20
24
|
require 'sequenceserver/config'
|
21
25
|
require 'sequenceserver/server'
|
22
26
|
require 'sequenceserver/routes'
|
27
|
+
require 'sequenceserver/makeblastdb'
|
23
28
|
require 'sequenceserver/job_remover'
|
24
29
|
require 'sequenceserver/exceptions'
|
25
30
|
require 'sequenceserver/sys'
|
@@ -53,6 +58,11 @@ module SequenceServer
|
|
53
58
|
end
|
54
59
|
end
|
55
60
|
|
61
|
+
# MAKEBLASTDB service object.
|
62
|
+
def makeblastdb
|
63
|
+
@makeblastdb ||= MAKEBLASTDB.new(config[:database_dir])
|
64
|
+
end
|
65
|
+
|
56
66
|
# SequenceServer initialisation routine.
|
57
67
|
def init(config = {})
|
58
68
|
# Use default config file if caller didn't specify one.
|
@@ -138,10 +148,14 @@ module SequenceServer
|
|
138
148
|
puts
|
139
149
|
puts '** Thank you for using SequenceServer :).'
|
140
150
|
puts ' Please cite: '
|
141
|
-
puts ' Priyam A, Woodcroft BJ, Rai V,
|
142
|
-
puts '
|
143
|
-
puts '
|
144
|
-
puts '
|
151
|
+
puts ' Priyam A, Woodcroft BJ, Rai V, Moghul I, Munagala A, Ter F,'
|
152
|
+
puts ' Chowdhary H, Pieniak I, Maynard LJ, Gibbins MA, Moon H,'
|
153
|
+
puts ' Davis-Richardson A, Uludag M, Watson-Haigh N, Challis R,'
|
154
|
+
puts ' Nakamura H, Favreau E, Gómez EA, Pluskal T, Leonard G,'
|
155
|
+
puts ' Rumpf W & Wurm Y.'
|
156
|
+
puts ' Sequenceserver: A modern graphical user interface for'
|
157
|
+
puts ' custom BLAST databases.'
|
158
|
+
puts ' Molecular Biology and Evolution (2019)'
|
145
159
|
end
|
146
160
|
|
147
161
|
# This method is invoked by the -i switch to start an IRB shell with
|
@@ -230,7 +244,7 @@ module SequenceServer
|
|
230
244
|
end
|
231
245
|
version = out.split[1]
|
232
246
|
fail BLAST_NOT_INSTALLED_OR_NOT_EXECUTABLE if version.empty?
|
233
|
-
fail BLAST_NOT_COMPATIBLE, version unless version
|
247
|
+
fail BLAST_NOT_COMPATIBLE, version unless is_compatible(version, MIN_BLAST_VERSION)
|
234
248
|
end
|
235
249
|
|
236
250
|
def server_url
|
@@ -281,5 +295,19 @@ module SequenceServer
|
|
281
295
|
def command?(command)
|
282
296
|
system("which #{command} > /dev/null 2>&1")
|
283
297
|
end
|
298
|
+
|
299
|
+
# Returns true if the given version is higher than the minimum expected
|
300
|
+
# version string.
|
301
|
+
def is_compatible(given, expected)
|
302
|
+
# The speceship operator (<=>) below returns -1, 0, 1 depending on
|
303
|
+
# on whether the left operand is lower, same, or higher than the
|
304
|
+
# right operand. We want the left operand to be the same or higher.
|
305
|
+
(parse_version(given) <=> parse_version(expected)) >= 0
|
306
|
+
end
|
307
|
+
|
308
|
+
# Turn version string into an arrary of its component numbers.
|
309
|
+
def parse_version(version_string)
|
310
|
+
version_string.split('.').map(&:to_i)
|
311
|
+
end
|
284
312
|
end
|
285
313
|
end
|
@@ -13,7 +13,6 @@ module SequenceServer
|
|
13
13
|
# itself is self-contained. This will help with tests among
|
14
14
|
# other things.
|
15
15
|
FileUtils.cp(params[:xml], dir)
|
16
|
-
@advanced_params = {}
|
17
16
|
@databases = []
|
18
17
|
done!
|
19
18
|
end
|
@@ -23,17 +22,19 @@ module SequenceServer
|
|
23
22
|
@method = params[:method]
|
24
23
|
@qfile = store('query.fa', params[:sequence])
|
25
24
|
@databases = Database[params[:databases]]
|
26
|
-
@
|
27
|
-
@
|
25
|
+
@advanced = params[:advanced].to_s.strip
|
26
|
+
@options = @advanced + defaults
|
28
27
|
end
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
32
|
-
attr_reader :advanced_params
|
33
|
-
|
34
31
|
# :nodoc:
|
35
32
|
# Attributes used by us - should be considered private.
|
36
|
-
attr_reader :method, :qfile, :databases, :options
|
33
|
+
attr_reader :method, :qfile, :databases, :advanced, :options
|
34
|
+
|
35
|
+
# :nodoc:
|
36
|
+
# Deprecated; see Report#extract_params
|
37
|
+
attr_reader :advanced_params
|
37
38
|
|
38
39
|
# :nodoc:
|
39
40
|
# Returns path to the imported xml file if the job was created using the
|
@@ -64,6 +65,16 @@ module SequenceServer
|
|
64
65
|
error = IO.foreach(stderr).grep(ERROR_LINE).join
|
65
66
|
error = File.read(stderr) if error.empty?
|
66
67
|
fail InputError, error
|
68
|
+
when 2
|
69
|
+
fail InputError, <<~MSG
|
70
|
+
BLAST signalled a problem with the databases that you searched.
|
71
|
+
|
72
|
+
Most likely one or more of your databases were created using an
|
73
|
+
older version of BLAST. Please consider recreating the databases
|
74
|
+
using BLAST #{BLAST_VERSION}.
|
75
|
+
|
76
|
+
As a temporary solution, you can try searching one database at a time.
|
77
|
+
MSG
|
67
78
|
when 4
|
68
79
|
# Out of memory. User can retry with a shorter search, so raising
|
69
80
|
# InputError here instead of SystemError.
|
@@ -78,7 +89,7 @@ module SequenceServer
|
|
78
89
|
# the job. This is a SystemError.
|
79
90
|
fail SystemError, 'Ran out of disk space.'
|
80
91
|
else
|
81
|
-
# I am not sure what the exit codes
|
92
|
+
# I am not sure what the exit codes 3 means and we should not
|
82
93
|
# encounter exit code 5. The only other error that I know can happen
|
83
94
|
# but is not yet handled is when BLAST+ binaries break such as after
|
84
95
|
# macOS updates. So raise SystemError, include the exit status in the
|
@@ -94,24 +105,6 @@ module SequenceServer
|
|
94
105
|
|
95
106
|
private
|
96
107
|
|
97
|
-
def parse_advanced(param_line)
|
98
|
-
param_list = (param_line || '').split(' ')
|
99
|
-
res = {}
|
100
|
-
|
101
|
-
param_list.each_with_index do |word, i|
|
102
|
-
nxt = param_list[i + 1]
|
103
|
-
if word.start_with? '-'
|
104
|
-
word.sub!('-', '')
|
105
|
-
unless nxt.nil? || nxt.start_with?('-')
|
106
|
-
res[word] = nxt
|
107
|
-
else
|
108
|
-
res[word] = 'True'
|
109
|
-
end
|
110
|
-
end
|
111
|
-
end
|
112
|
-
res
|
113
|
-
end
|
114
|
-
|
115
108
|
def validate(params)
|
116
109
|
validate_method params[:method]
|
117
110
|
validate_sequences params[:sequence]
|
@@ -24,34 +24,15 @@ module SequenceServer
|
|
24
24
|
class Report < Report
|
25
25
|
def initialize(job)
|
26
26
|
super do
|
27
|
-
@querydb = job.databases
|
28
27
|
@queries = []
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
32
|
-
# Attributes parsed out from
|
33
|
-
attr_reader :program, :program_version, :
|
34
|
-
|
35
|
-
# This is obtained from the job object.
|
36
|
-
attr_reader :querydb
|
31
|
+
# Attributes parsed out from BLAST output.
|
32
|
+
attr_reader :program, :program_version, :stats, :queries
|
37
33
|
|
38
|
-
#
|
39
|
-
|
40
|
-
# from Job#databases. For imported XML, this is inferred from
|
41
|
-
# Report#program (i.e., the BLAST algorithm)
|
42
|
-
def dbtype
|
43
|
-
return @dbtype if @dbtype
|
44
|
-
@dbtype = if @querydb.empty?
|
45
|
-
case program
|
46
|
-
when /blastn|tblastn|tblastx/
|
47
|
-
'nucleotide'
|
48
|
-
when /blastp|blastx/
|
49
|
-
'protein'
|
50
|
-
end
|
51
|
-
else
|
52
|
-
@querydb.first.type
|
53
|
-
end
|
54
|
-
end
|
34
|
+
# Attributes parsed from job metadata and BLAST output.
|
35
|
+
attr_reader :querydb, :dbtype, :params
|
55
36
|
|
56
37
|
def to_json
|
57
38
|
[:querydb, :program, :program_version, :params, :stats,
|
@@ -60,7 +41,8 @@ module SequenceServer
|
|
60
41
|
h
|
61
42
|
}.update(search_id: job.id,
|
62
43
|
submitted_at: job.submitted_at.utc,
|
63
|
-
imported_xml: !!job.imported_xml_file
|
44
|
+
imported_xml: !!job.imported_xml_file,
|
45
|
+
seqserv_version: SequenceServer::VERSION).to_json
|
64
46
|
end
|
65
47
|
|
66
48
|
private
|
@@ -68,6 +50,8 @@ module SequenceServer
|
|
68
50
|
# Generate report.
|
69
51
|
def generate
|
70
52
|
job.raise!
|
53
|
+
xml_ir = nil
|
54
|
+
tsv_ir = nil
|
71
55
|
if job.imported_xml_file
|
72
56
|
xml_ir = parse_xml File.read(job.imported_xml_file)
|
73
57
|
tsv_ir = Hash.new do |h1,k1|
|
@@ -75,18 +59,15 @@ module SequenceServer
|
|
75
59
|
h2[k2]=['','',[]]
|
76
60
|
end
|
77
61
|
end
|
78
|
-
extract_program_info xml_ir
|
79
|
-
extract_params xml_ir
|
80
|
-
extract_stats xml_ir
|
81
|
-
extract_queries xml_ir, tsv_ir
|
82
62
|
else
|
83
63
|
xml_ir = parse_xml File.read(Formatter.run(job, 'xml').file)
|
84
|
-
tsv_ir = parse_tsv File.read(Formatter.run(job, 'custom_tsv').file
|
85
|
-
extract_program_info xml_ir
|
86
|
-
extract_params xml_ir
|
87
|
-
extract_stats xml_ir
|
88
|
-
extract_queries xml_ir, tsv_ir
|
64
|
+
tsv_ir = parse_tsv File.read(Formatter.run(job, 'custom_tsv').file)
|
89
65
|
end
|
66
|
+
extract_program_info xml_ir
|
67
|
+
extract_db_info xml_ir
|
68
|
+
extract_params xml_ir
|
69
|
+
extract_stats xml_ir
|
70
|
+
extract_queries xml_ir, tsv_ir
|
90
71
|
end
|
91
72
|
|
92
73
|
# Make program name and program name + version available via `program`
|
@@ -96,6 +77,20 @@ module SequenceServer
|
|
96
77
|
@program_version = ir[1]
|
97
78
|
end
|
98
79
|
|
80
|
+
# Get database information (title and type) from job yaml or from XML.
|
81
|
+
# Sets `querydb` and `dbtype` attributes.
|
82
|
+
def extract_db_info(ir)
|
83
|
+
if job.databases.empty?
|
84
|
+
@querydb = ir[3].split.map do |path|
|
85
|
+
{ title: File.basename(path) }
|
86
|
+
end
|
87
|
+
@dbtype = dbtype_from_program
|
88
|
+
else
|
89
|
+
@querydb = job.databases
|
90
|
+
@dbtype = @querydb.first.type
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
99
94
|
# Make search params available via `params` attribute.
|
100
95
|
#
|
101
96
|
# Search params tweak the results. Like evalue cutoff or penalty to open
|
@@ -103,11 +98,20 @@ module SequenceServer
|
|
103
98
|
# matrix, evalue, gapopen, gapextend, and filters are available from XML
|
104
99
|
# output.
|
105
100
|
def extract_params(ir)
|
101
|
+
# Parse/get params from the job first.
|
102
|
+
job_params = parse_advanced(job.advanced)
|
103
|
+
# Old jobs from beta releases may not have the advanced key but they
|
104
|
+
# will have the deprecated advanced_params key.
|
105
|
+
job_params.update(job.advanced_params) if job.advanced_params
|
106
|
+
|
107
|
+
# Parse params from BLAST XML.
|
106
108
|
@params = Hash[
|
107
109
|
*ir[7].first.map { |k, v| [k.gsub('Parameters_', ''), v] }.flatten
|
108
110
|
]
|
109
111
|
@params['evalue'] = @params.delete('expect')
|
110
|
-
|
112
|
+
|
113
|
+
# Merge into job_params.
|
114
|
+
@params = job_params.merge(@params)
|
111
115
|
end
|
112
116
|
|
113
117
|
# Make search stats available via `stats` attribute.
|
@@ -232,6 +236,36 @@ module SequenceServer
|
|
232
236
|
end
|
233
237
|
ir
|
234
238
|
end
|
239
|
+
|
240
|
+
# Parse BLAST CLI string from job.advanced.
|
241
|
+
def parse_advanced(param_line)
|
242
|
+
param_list = (param_line || '').split(' ')
|
243
|
+
res = {}
|
244
|
+
|
245
|
+
param_list.each_with_index do |word, i|
|
246
|
+
nxt = param_list[i + 1]
|
247
|
+
if word.start_with? '-'
|
248
|
+
word.sub!('-', '')
|
249
|
+
unless nxt.nil? || nxt.start_with?('-')
|
250
|
+
res[word] = nxt
|
251
|
+
else
|
252
|
+
res[word] = 'True'
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
res
|
257
|
+
end
|
258
|
+
|
259
|
+
# Returns database type (nucleotide or protein) inferred from
|
260
|
+
# Report#program (i.e., the BLAST algorithm)
|
261
|
+
def dbtype_from_program
|
262
|
+
case program
|
263
|
+
when /blastn|tblastn|tblastx/
|
264
|
+
'nucleotide'
|
265
|
+
when /blastp|blastx/
|
266
|
+
'protein'
|
267
|
+
end
|
268
|
+
end
|
235
269
|
end
|
236
270
|
end
|
237
271
|
end
|