miga-base 0.7.22.0 → 0.7.25.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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/README.md +1 -1
- data/Rakefile +1 -0
- data/lib/miga/cli/action/add.rb +10 -8
- data/lib/miga/cli/action/classify_wf.rb +12 -11
- data/lib/miga/cli/action/derep_wf.rb +3 -9
- data/lib/miga/cli/action/edit.rb +0 -1
- data/lib/miga/cli/action/find.rb +1 -1
- data/lib/miga/cli/action/generic.rb +1 -1
- data/lib/miga/cli/action/get.rb +7 -2
- data/lib/miga/cli/action/get_db.rb +16 -21
- data/lib/miga/cli/action/index_wf.rb +4 -2
- data/lib/miga/cli/action/init.rb +93 -144
- data/lib/miga/cli/action/init/daemon_helper.rb +1 -2
- data/lib/miga/cli/action/init/files_helper.rb +119 -0
- data/lib/miga/cli/action/ncbi_get.rb +1 -1
- data/lib/miga/cli/action/new.rb +15 -9
- data/lib/miga/cli/action/option.rb +44 -0
- data/lib/miga/cli/action/preproc_wf.rb +7 -5
- data/lib/miga/cli/action/quality_wf.rb +3 -3
- data/lib/miga/cli/action/tax_dist.rb +1 -1
- data/lib/miga/cli/action/tax_test.rb +1 -1
- data/lib/miga/cli/action/wf.rb +71 -53
- data/lib/miga/cli/base.rb +17 -5
- data/lib/miga/cli/objects_helper.rb +23 -18
- data/lib/miga/common.rb +4 -2
- data/lib/miga/common/net.rb +74 -0
- data/lib/miga/common/with_option.rb +83 -0
- data/lib/miga/common/with_result.rb +3 -2
- data/lib/miga/dataset/base.rb +20 -2
- data/lib/miga/dataset/result.rb +5 -3
- data/lib/miga/metadata.rb +25 -13
- data/lib/miga/project/base.rb +82 -2
- data/lib/miga/project/result.rb +4 -4
- data/lib/miga/remote_dataset.rb +2 -0
- data/lib/miga/result/stats.rb +2 -2
- data/lib/miga/version.rb +4 -2
- data/scripts/essential_genes.bash +18 -3
- data/scripts/miga.bash +8 -2
- data/scripts/mytaxa.bash +6 -5
- data/scripts/mytaxa_scan.bash +8 -7
- data/scripts/ogs.bash +2 -3
- data/scripts/ssu.bash +16 -2
- data/test/dataset_test.rb +5 -5
- data/test/lair_test.rb +1 -2
- data/test/net_test.rb +34 -0
- data/test/with_option_test.rb +115 -0
- data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Archaea_SCG.hmm +41964 -0
- data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Bacteria_SCG.hmm +32439 -0
- data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Complete_SCG_DB.hmm +62056 -0
- data/utils/FastAAI/FastAAI/FastAAI +1336 -0
- data/utils/FastAAI/README.md +84 -0
- data/utils/FastAAI/kAAI_v1.0_virus.py +1296 -0
- data/utils/cleanup-databases.rb +2 -3
- data/utils/distance/base.rb +9 -0
- data/utils/distance/commands.rb +183 -81
- data/utils/distance/database.rb +69 -10
- data/utils/distance/pipeline.rb +15 -21
- data/utils/distance/runner.rb +27 -49
- data/utils/distance/temporal.rb +4 -2
- data/utils/distances.rb +2 -2
- data/utils/index_metadata.rb +1 -2
- data/utils/requirements.txt +6 -5
- data/utils/subclade/runner.rb +10 -11
- metadata +18 -6
data/lib/miga/cli/base.rb
CHANGED
@@ -34,6 +34,7 @@ module MiGA::Cli::Base
|
|
34
34
|
next_step: 'Return the next task to run in a dataset or project',
|
35
35
|
# Objects (Datasets or Projects)
|
36
36
|
edit: 'Edit the metadata of a dataset or project',
|
37
|
+
option: 'Get or set options of a dataset or project',
|
37
38
|
# System
|
38
39
|
init: 'Initialize MiGA to process new projects',
|
39
40
|
daemon: 'Control the daemon of a MiGA project',
|
@@ -87,19 +88,30 @@ module MiGA::Cli::Base
|
|
87
88
|
@@EXECS = @@TASK_DESC.keys
|
88
89
|
|
89
90
|
@@FILE_REGEXP =
|
90
|
-
%r{^(?:.*/)?(.+?)(\.[A-Z]*(
|
91
|
+
%r{^(?:.*/)?(.+?)(\.[A-Z]*(Reads|Contigs))?(\.f[nastq]+)?(\.gz)?$}i
|
92
|
+
|
93
|
+
@@PAIRED_FILE_REGEXP =
|
94
|
+
%r{^(?:.*/)?(.+?)(\.[A-Z]*([12]|Reads))?(\.f[nastq]+)?(\.gz)?$}i
|
91
95
|
end
|
92
96
|
|
93
97
|
class MiGA::Cli < MiGA::MiGA
|
94
98
|
include MiGA::Cli::Base
|
95
99
|
|
96
100
|
class << self
|
97
|
-
def TASK_DESC
|
101
|
+
def TASK_DESC
|
102
|
+
@@TASK_DESC
|
103
|
+
end
|
98
104
|
|
99
|
-
def TASK_ALIAS
|
105
|
+
def TASK_ALIAS
|
106
|
+
@@TASK_ALIAS
|
107
|
+
end
|
100
108
|
|
101
|
-
def EXECS
|
109
|
+
def EXECS
|
110
|
+
@@EXECS
|
111
|
+
end
|
102
112
|
|
103
|
-
def FILE_REGEXP
|
113
|
+
def FILE_REGEXP(paired = false)
|
114
|
+
paired ? @@PAIRED_FILE_REGEXP : @@FILE_REGEXP
|
115
|
+
end
|
104
116
|
end
|
105
117
|
end
|
@@ -57,12 +57,12 @@ module MiGA::Cli::ObjectsHelper
|
|
57
57
|
ds.select! do |d|
|
58
58
|
advance('Datasets:', k += 1, n, false)
|
59
59
|
o = true
|
60
|
-
o &&= (d.
|
61
|
-
o &&= (d.
|
62
|
-
o &&= (self[:multi] ? d.
|
63
|
-
|
64
|
-
|
65
|
-
|
60
|
+
o &&= (d.ref? == self[:ref]) unless self[:ref].nil?
|
61
|
+
o &&= (d.active? == self[:active]) unless self[:active].nil?
|
62
|
+
o &&= (self[:multi] ? d.multi? : d.nonmulti?) unless self[:multi].nil?
|
63
|
+
unless self[:taxonomy].nil?
|
64
|
+
o &&= !d.metadata[:tax].nil? && d.metadata[:tax].in?(self[:taxonomy])
|
65
|
+
end
|
66
66
|
o
|
67
67
|
end
|
68
68
|
say ''
|
@@ -90,22 +90,27 @@ module MiGA::Cli::ObjectsHelper
|
|
90
90
|
def add_metadata(obj, cli = self)
|
91
91
|
raise "Unsupported object: #{obj.class}" unless obj.respond_to? :metadata
|
92
92
|
|
93
|
-
cli[:metadata].split(',').each do |pair|
|
93
|
+
(cli[:metadata] || '').split(',').each do |pair|
|
94
94
|
(k, v) = pair.split('=')
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
95
|
+
if obj.option?(k)
|
96
|
+
obj.set_option(k, v, true)
|
97
|
+
else
|
98
|
+
case v
|
99
|
+
when 'true'; v = true
|
100
|
+
when 'false'; v = false
|
101
|
+
when 'nil'; v = nil
|
102
|
+
end
|
103
|
+
if k == '_step'
|
104
|
+
obj.metadata["_try_#{v}"] ||= 0
|
105
|
+
obj.metadata["_try_#{v}"] += 1
|
106
|
+
end
|
107
|
+
obj.metadata[k] = v
|
103
108
|
end
|
104
|
-
|
105
|
-
|
106
|
-
[:type, :name, :user, :description, :comments].each do |k|
|
109
|
+
end
|
110
|
+
%i[type name user description comments].each do |k|
|
107
111
|
obj.metadata[k] = cli[k] unless cli[k].nil?
|
108
112
|
end
|
113
|
+
obj.save
|
109
114
|
obj
|
110
115
|
end
|
111
116
|
end
|
data/lib/miga/common.rb
CHANGED
@@ -6,6 +6,7 @@ require 'miga/json'
|
|
6
6
|
require 'miga/common/base'
|
7
7
|
require 'miga/common/path'
|
8
8
|
require 'miga/common/format'
|
9
|
+
require 'miga/common/net'
|
9
10
|
require 'stringio'
|
10
11
|
|
11
12
|
##
|
@@ -16,13 +17,14 @@ class MiGA::MiGA
|
|
16
17
|
|
17
18
|
extend MiGA::Common::Path
|
18
19
|
extend MiGA::Common::Format
|
20
|
+
extend MiGA::Common::Net
|
19
21
|
|
20
22
|
ENV['MIGA_HOME'] ||= ENV['HOME']
|
21
23
|
|
22
24
|
##
|
23
25
|
# Has MiGA been initialized?
|
24
26
|
def self.initialized?
|
25
|
-
File.exist?(File.expand_path('.miga_rc', ENV['MIGA_HOME']))
|
27
|
+
File.exist?(File.expand_path('.miga_rc', ENV['MIGA_HOME'])) &&
|
26
28
|
File.exist?(File.expand_path('.miga_daemon.json', ENV['MIGA_HOME']))
|
27
29
|
end
|
28
30
|
|
@@ -64,7 +66,7 @@ class MiGA::MiGA
|
|
64
66
|
adv_n = n - @_advance_time[:n]
|
65
67
|
unless total.nil? || @_advance_time[:last].nil? || adv_n <= 0
|
66
68
|
if adv_n.to_f/n > 0.001
|
67
|
-
this_time = Time.now - @_advance_time[:last]
|
69
|
+
this_time = (Time.now - @_advance_time[:last]).to_f
|
68
70
|
this_avg = this_time / adv_n
|
69
71
|
@_advance_time[:avg] ||= this_avg
|
70
72
|
@_advance_time[:avg] = 0.9 * @_advance_time[:avg] + 0.1 * this_avg
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/ftp'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'fileutils'
|
6
|
+
|
7
|
+
Net::FTP.send(:remove_const, 'FTP_PORT') # just to avoid warnings
|
8
|
+
Net::FTP.const_set('FTP_PORT', 21)
|
9
|
+
|
10
|
+
##
|
11
|
+
# General web-access functions shared throughout MiGA.
|
12
|
+
module MiGA::Common::Net
|
13
|
+
##
|
14
|
+
# Returns the URL of the host +name+ (Symbol)
|
15
|
+
def known_hosts(name)
|
16
|
+
case name.to_sym
|
17
|
+
when :miga_online_ftp
|
18
|
+
'ftp://microbial-genomes.org//' # <- // to simplify chdir in connection
|
19
|
+
when :miga_db
|
20
|
+
'ftp://microbial-genomes.org/db'
|
21
|
+
when :miga_dist
|
22
|
+
'ftp://microbial-genomes.org/dist'
|
23
|
+
else
|
24
|
+
raise "Unrecognized server name: #{host}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Connect to an FTP +host+ (String) or a known host name (Symbol, see
|
30
|
+
# +.known_hosts+)
|
31
|
+
def remote_connection(host)
|
32
|
+
host = known_hosts(host) if host.is_a?(Symbol)
|
33
|
+
uri = URI.parse(host)
|
34
|
+
raise 'Only FTP hosts are currently supported' unless uri.scheme == 'ftp'
|
35
|
+
|
36
|
+
ftp = Net::FTP.new(uri.host)
|
37
|
+
ftp.passive = true
|
38
|
+
ftp.login
|
39
|
+
ftp.chdir(uri.path)
|
40
|
+
ftp
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Download a file via FTP using the +connection+ (returned by
|
45
|
+
# +.remote_connection+) with remote name +file+ into local +target+.
|
46
|
+
#
|
47
|
+
# Alternatively, +connection+ can simply be the host (String) or a recognized
|
48
|
+
# Symbol (see +.remote_connection+), in which case the function opens the
|
49
|
+
# connection automatically
|
50
|
+
#
|
51
|
+
# Reports progress to the function block with two arguments: the
|
52
|
+
# currently transferred size and the total file size
|
53
|
+
def download_file_ftp(connection, file, target)
|
54
|
+
# Open connection unless passed
|
55
|
+
close_conn = false
|
56
|
+
if connection.is_a?(String) || connection.is_a?(Symbol)
|
57
|
+
connection = remote_connection(connection)
|
58
|
+
close_conn = true
|
59
|
+
end
|
60
|
+
|
61
|
+
# Prepare download
|
62
|
+
FileUtils.mkdir_p(File.dirname(target))
|
63
|
+
filesize = connection.size(file)
|
64
|
+
transferred = 0
|
65
|
+
|
66
|
+
# Get in chunks of 1KiB
|
67
|
+
connection.getbinaryfile(file, target, 1024) do |data|
|
68
|
+
yield(transferred += data.size, filesize) if block_given?
|
69
|
+
end
|
70
|
+
|
71
|
+
# Close connection if automatically opened
|
72
|
+
connection.close if close_conn
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
##
|
4
|
+
# Helper module including specific functions to handle objects that
|
5
|
+
# have configurable options. The class including this module must implement
|
6
|
+
# the methods +.OPTIONS+, +#metadata+, and +#save+.
|
7
|
+
module MiGA::Common::WithOption
|
8
|
+
def option(key)
|
9
|
+
assert_has_option(key)
|
10
|
+
opt = option_by_metadata(key)
|
11
|
+
value = opt.nil? ? option_by_default(key) : opt
|
12
|
+
value = value[self] if value.is_a?(Proc)
|
13
|
+
value
|
14
|
+
end
|
15
|
+
|
16
|
+
def set_option(key, value, from_string = false)
|
17
|
+
metadata[key] = assert_valid_option_value(key, value, from_string)
|
18
|
+
save
|
19
|
+
option(key)
|
20
|
+
end
|
21
|
+
|
22
|
+
def all_options
|
23
|
+
Hash[self.class.OPTIONS.each_key.map { |key| [key, option(key)] }]
|
24
|
+
end
|
25
|
+
|
26
|
+
def option?(key)
|
27
|
+
!self.class.OPTIONS[key.to_sym].nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
def option_by_metadata(key)
|
31
|
+
metadata[key]
|
32
|
+
end
|
33
|
+
|
34
|
+
def option_by_default(key)
|
35
|
+
self.class.OPTIONS[key.to_sym][:default]
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_has_option(key)
|
39
|
+
opt = self.class.OPTIONS[key.to_sym]
|
40
|
+
raise "Unrecognized option: #{key}" if opt.nil?
|
41
|
+
opt
|
42
|
+
end
|
43
|
+
|
44
|
+
def assert_valid_option_value(key, value, from_string = false)
|
45
|
+
opt = assert_has_option(key)
|
46
|
+
value = option_from_string(key, value) if from_string
|
47
|
+
|
48
|
+
# nil is always valid, and so are supported tokens
|
49
|
+
return value if value.nil? || opt[:tokens]&.include?(value)
|
50
|
+
|
51
|
+
if opt[:type] && !value.is_a?(opt[:type])
|
52
|
+
raise "Invalid value type for #{key}: #{value.class}, not #{opt[:type]}"
|
53
|
+
end
|
54
|
+
|
55
|
+
if opt[:in] && !opt[:in].include?(value)
|
56
|
+
raise "Value out of range for #{key}: #{value}, not in #{opt[:in]}"
|
57
|
+
end
|
58
|
+
|
59
|
+
value
|
60
|
+
end
|
61
|
+
|
62
|
+
def option_from_string(key, value)
|
63
|
+
opt = assert_has_option(key)
|
64
|
+
|
65
|
+
if ['', 'nil'].include?(value)
|
66
|
+
nil
|
67
|
+
elsif opt[:tokens]&.include?(value)
|
68
|
+
value
|
69
|
+
elsif opt[:type]&.equal?(Float)
|
70
|
+
raise "Not a float: #{value}" unless value =~ /^-?\.?\d/
|
71
|
+
value.to_f
|
72
|
+
elsif opt[:type]&.equal?(Integer)
|
73
|
+
raise "Not an integer: #{value}" unless value =~ /^-?\d/
|
74
|
+
value.to_i
|
75
|
+
elsif opt[:in]&.include?(true) && value == 'true'
|
76
|
+
true
|
77
|
+
elsif opt[:in]&.include?(false) && value == 'false'
|
78
|
+
false
|
79
|
+
else
|
80
|
+
value
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -86,7 +86,8 @@ module MiGA::Common::WithResult
|
|
86
86
|
if res.nil?
|
87
87
|
# Run if the step has not been calculated,
|
88
88
|
# unless too many attempts were already made
|
89
|
-
|
89
|
+
cur_try = metadata["_try_#{t}"] || 0
|
90
|
+
if cur_try > project.option(:max_try)
|
90
91
|
inactivate! "Too many errors in step #{t}"
|
91
92
|
false
|
92
93
|
else
|
@@ -103,7 +104,7 @@ module MiGA::Common::WithResult
|
|
103
104
|
##
|
104
105
|
# Mark all results for recalculation
|
105
106
|
def recalculate_tasks(reason = nil)
|
106
|
-
each_result { |res| res.recalculate!(reason).save }
|
107
|
+
each_result { |_k, res| res.recalculate!(reason).save }
|
107
108
|
end
|
108
109
|
|
109
110
|
end
|
data/lib/miga/dataset/base.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'miga/common/with_option'
|
3
4
|
|
4
5
|
class MiGA::Dataset < MiGA::MiGA
|
6
|
+
include MiGA::Common::WithOption
|
7
|
+
|
5
8
|
# Class-level
|
6
9
|
class << self
|
7
10
|
def RESULT_DIRS
|
@@ -15,6 +18,10 @@ class MiGA::Dataset < MiGA::MiGA
|
|
15
18
|
def PREPROCESSING_TASKS
|
16
19
|
@@PREPROCESSING_TASKS
|
17
20
|
end
|
21
|
+
|
22
|
+
def OPTIONS
|
23
|
+
@@OPTIONS
|
24
|
+
end
|
18
25
|
end
|
19
26
|
end
|
20
27
|
|
@@ -85,4 +92,15 @@ module MiGA::Dataset::Base
|
|
85
92
|
# tasks are ignored for single-organism datasets or for unknwon types.
|
86
93
|
@@ONLY_MULTI_TASKS = [:mytaxa]
|
87
94
|
@@_ONLY_MULTI_TASKS_H = Hash[@@ONLY_MULTI_TASKS.map { |i| [i, true] }]
|
95
|
+
|
96
|
+
##
|
97
|
+
# Options supported by datasets
|
98
|
+
@@OPTIONS = {
|
99
|
+
db_project: {
|
100
|
+
desc: 'Project to use as database', type: String
|
101
|
+
},
|
102
|
+
dist_req: {
|
103
|
+
desc: 'Run distances against these datasets', type: Array, default: []
|
104
|
+
}
|
105
|
+
}
|
88
106
|
end
|
data/lib/miga/dataset/result.rb
CHANGED
@@ -50,7 +50,7 @@ module MiGA::Dataset::Result
|
|
50
50
|
:upstream
|
51
51
|
elsif !metadata["run_#{task}"].nil?
|
52
52
|
metadata["run_#{task}"] ? :execute : :force
|
53
|
-
elsif task == :taxonomy && project.
|
53
|
+
elsif task == :taxonomy && project.option(:ref_project).nil?
|
54
54
|
:project
|
55
55
|
elsif @@_EXCLUDE_NOREF_TASKS_H[task] && !ref?
|
56
56
|
:noref
|
@@ -276,7 +276,8 @@ module MiGA::Dataset::Result
|
|
276
276
|
ess_genes: '.ess.faa',
|
277
277
|
collection: '.ess',
|
278
278
|
report: '.ess/log',
|
279
|
-
alignments: '.ess/proteins.aln'
|
279
|
+
alignments: '.ess/proteins.aln',
|
280
|
+
fastaai_index: '.faix.db.gz'
|
280
281
|
)
|
281
282
|
end
|
282
283
|
|
@@ -290,7 +291,8 @@ module MiGA::Dataset::Result
|
|
290
291
|
MiGA::Result.new("#{base}.json"), name,
|
291
292
|
longest_ssu_gene: '.ssu.fa',
|
292
293
|
gff: '.ssu.gff',
|
293
|
-
all_ssu_genes: '.ssu.all.fa'
|
294
|
+
all_ssu_genes: '.ssu.all.fa',
|
295
|
+
classification: '.rdp.tsv'
|
294
296
|
)
|
295
297
|
opts[:is_clean] ||= false
|
296
298
|
r.clean! if opts[:is_clean]
|
data/lib/miga/metadata.rb
CHANGED
@@ -56,24 +56,20 @@ class MiGA::Metadata < MiGA::MiGA
|
|
56
56
|
##
|
57
57
|
# Save the metadata into #path
|
58
58
|
def save
|
59
|
-
|
59
|
+
return if self[:never_save]
|
60
|
+
|
61
|
+
MiGA::MiGA.DEBUG "Metadata.save #{path}"
|
60
62
|
self[:updated] = Time.now.to_s
|
61
63
|
json = to_json
|
62
|
-
|
63
|
-
|
64
|
-
while File.exist?(lock_file)
|
65
|
-
MiGA::MiGA.DEBUG "Waiting for lock: #{lock_file}"
|
66
|
-
sleeper += 0.1 if sleeper <= 10.0
|
67
|
-
sleep(sleeper.to_i)
|
68
|
-
slept += sleeper.to_i
|
69
|
-
raise "Lock detected for over 10 minutes: #{lock_file}" if slept > 600
|
70
|
-
end
|
71
|
-
FileUtils.touch lock_file
|
64
|
+
wait_for_lock
|
65
|
+
FileUtils.touch(lock_file)
|
72
66
|
ofh = File.open("#{path}.tmp", 'w')
|
73
67
|
ofh.puts json
|
74
68
|
ofh.close
|
75
|
-
|
76
|
-
|
69
|
+
|
70
|
+
unless File.exist?("#{path}.tmp") && File.exist?(lock_file)
|
71
|
+
raise "Lock-racing detected for #{path}"
|
72
|
+
end
|
77
73
|
|
78
74
|
File.rename("#{path}.tmp", path)
|
79
75
|
File.unlink(lock_file)
|
@@ -154,4 +150,20 @@ class MiGA::Metadata < MiGA::MiGA
|
|
154
150
|
def to_json
|
155
151
|
MiGA::Json.generate(data)
|
156
152
|
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
##
|
157
|
+
# Wait for the lock to go away
|
158
|
+
def wait_for_lock
|
159
|
+
sleeper = 0.0
|
160
|
+
slept = 0.0
|
161
|
+
while File.exist?(lock_file)
|
162
|
+
MiGA::MiGA.DEBUG "Waiting for lock: #{lock_file}"
|
163
|
+
sleeper += 0.1 if sleeper <= 10.0
|
164
|
+
sleep(sleeper)
|
165
|
+
slept += sleeper
|
166
|
+
raise "Lock detected for over 10 minutes: #{lock_file}" if slept > 600
|
167
|
+
end
|
168
|
+
end
|
157
169
|
end
|
data/lib/miga/project/base.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'miga/common/with_option'
|
3
4
|
|
4
5
|
class MiGA::Project < MiGA::MiGA
|
6
|
+
include MiGA::Common::WithOption
|
7
|
+
|
5
8
|
class << self
|
6
9
|
##
|
7
10
|
# Does the project at +path+ exist?
|
@@ -33,6 +36,10 @@ class MiGA::Project < MiGA::MiGA
|
|
33
36
|
def RESULT_DIRS
|
34
37
|
@@RESULT_DIRS
|
35
38
|
end
|
39
|
+
|
40
|
+
def OPTIONS
|
41
|
+
@@OPTIONS
|
42
|
+
end
|
36
43
|
end
|
37
44
|
end
|
38
45
|
|
@@ -108,4 +115,77 @@ module MiGA::Project::Base
|
|
108
115
|
##
|
109
116
|
# Project-wide tasks for :clade projects
|
110
117
|
@@INCLADE_TASKS = [:subclades, :ogs]
|
118
|
+
|
119
|
+
##
|
120
|
+
# Options supported by projects
|
121
|
+
@@OPTIONS = {
|
122
|
+
ref_project: {
|
123
|
+
desc: 'Project with reference taxonomy', type: String
|
124
|
+
},
|
125
|
+
db_proj_dir: {
|
126
|
+
desc: 'Directory containing database projects', type: String
|
127
|
+
},
|
128
|
+
tax_pvalue: {
|
129
|
+
desc: 'Maximum p-value to transfer taxonomy', default: 0.05, type: Float,
|
130
|
+
in: 0.0..1.0
|
131
|
+
},
|
132
|
+
haai_p: {
|
133
|
+
desc: 'Value of aai.rb -p on hAAI', type: String,
|
134
|
+
default: proc { |project| project.clade? ? 'no' : 'blast+' },
|
135
|
+
in: %w[fastaai blast+ blast blat diamond no]
|
136
|
+
},
|
137
|
+
aai_p: {
|
138
|
+
desc: 'Value of aai.rb -p on AAI', default: 'blast+', type: String,
|
139
|
+
in: %w[blast+ blast blat diamond]
|
140
|
+
},
|
141
|
+
ani_p: {
|
142
|
+
desc: 'Value of ani.rb -p on ANI', default: 'blast+', type: String,
|
143
|
+
in: %w[blast+ blast blat fastani]
|
144
|
+
},
|
145
|
+
max_try: {
|
146
|
+
desc: 'Maximum number of task attempts', default: 10, type: Integer,
|
147
|
+
in: (0..1000)
|
148
|
+
},
|
149
|
+
aai_save_rbm: {
|
150
|
+
desc: 'Should RBMs be saved for OGS analysis?',
|
151
|
+
default: proc { |project| project.clade? },
|
152
|
+
in: [true, false]
|
153
|
+
},
|
154
|
+
ogs_identity: {
|
155
|
+
desc: 'Min RBM identity for OGS', default: 80.0, type: Float,
|
156
|
+
in: (0.0..100.0)
|
157
|
+
},
|
158
|
+
clean_ogs: {
|
159
|
+
desc: 'If false, keeps ABC files (clades only)', default: true,
|
160
|
+
in: [true, false]
|
161
|
+
},
|
162
|
+
run_clades: {
|
163
|
+
desc: 'Should clades be estimated from distances?', default: true,
|
164
|
+
in: [true, false]
|
165
|
+
},
|
166
|
+
gsp_ani: {
|
167
|
+
desc: 'ANI limit to propose gsp clades', default: 95.0, type: Float,
|
168
|
+
in: (0.0..100.0)
|
169
|
+
},
|
170
|
+
gsp_aai: {
|
171
|
+
desc: 'AAI limit to propose gsp clades', default: 90.0, type: Float,
|
172
|
+
in: (0.0..100.0)
|
173
|
+
},
|
174
|
+
gsp_metric: {
|
175
|
+
desc: 'Metric to propose clades', default: 'ani', type: String,
|
176
|
+
in: %w[ani aai]
|
177
|
+
},
|
178
|
+
ess_coll: {
|
179
|
+
desc: 'Collection of essential genes to use', default: 'dupont_2012',
|
180
|
+
type: String, in: %w[dupont_2012 lee_2019]
|
181
|
+
},
|
182
|
+
min_qual: {
|
183
|
+
desc: 'Minimum genome quality', default: 25.0, type: Float,
|
184
|
+
in: -Float::INFINITY..100.0, tokens: %w[no]
|
185
|
+
},
|
186
|
+
distances_checkpoint: {
|
187
|
+
desc: 'Number of comparisons before storing data', default: 10,
|
188
|
+
type: Integer, in: 1...Float::INFINITY
|
189
|
+
}
|
190
|
+
}
|
111
191
|
end
|