sequenceserver 2.0.0.beta4 → 2.0.0.rc5
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.
- 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
|