miga-base 0.7.22.0 → 0.7.25.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|