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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/README.md +1 -1
  4. data/Rakefile +1 -0
  5. data/lib/miga/cli/action/add.rb +10 -8
  6. data/lib/miga/cli/action/classify_wf.rb +12 -11
  7. data/lib/miga/cli/action/derep_wf.rb +3 -9
  8. data/lib/miga/cli/action/edit.rb +0 -1
  9. data/lib/miga/cli/action/find.rb +1 -1
  10. data/lib/miga/cli/action/generic.rb +1 -1
  11. data/lib/miga/cli/action/get.rb +7 -2
  12. data/lib/miga/cli/action/get_db.rb +16 -21
  13. data/lib/miga/cli/action/index_wf.rb +4 -2
  14. data/lib/miga/cli/action/init.rb +93 -144
  15. data/lib/miga/cli/action/init/daemon_helper.rb +1 -2
  16. data/lib/miga/cli/action/init/files_helper.rb +119 -0
  17. data/lib/miga/cli/action/ncbi_get.rb +1 -1
  18. data/lib/miga/cli/action/new.rb +15 -9
  19. data/lib/miga/cli/action/option.rb +44 -0
  20. data/lib/miga/cli/action/preproc_wf.rb +7 -5
  21. data/lib/miga/cli/action/quality_wf.rb +3 -3
  22. data/lib/miga/cli/action/tax_dist.rb +1 -1
  23. data/lib/miga/cli/action/tax_test.rb +1 -1
  24. data/lib/miga/cli/action/wf.rb +71 -53
  25. data/lib/miga/cli/base.rb +17 -5
  26. data/lib/miga/cli/objects_helper.rb +23 -18
  27. data/lib/miga/common.rb +4 -2
  28. data/lib/miga/common/net.rb +74 -0
  29. data/lib/miga/common/with_option.rb +83 -0
  30. data/lib/miga/common/with_result.rb +3 -2
  31. data/lib/miga/dataset/base.rb +20 -2
  32. data/lib/miga/dataset/result.rb +5 -3
  33. data/lib/miga/metadata.rb +25 -13
  34. data/lib/miga/project/base.rb +82 -2
  35. data/lib/miga/project/result.rb +4 -4
  36. data/lib/miga/remote_dataset.rb +2 -0
  37. data/lib/miga/result/stats.rb +2 -2
  38. data/lib/miga/version.rb +4 -2
  39. data/scripts/essential_genes.bash +18 -3
  40. data/scripts/miga.bash +8 -2
  41. data/scripts/mytaxa.bash +6 -5
  42. data/scripts/mytaxa_scan.bash +8 -7
  43. data/scripts/ogs.bash +2 -3
  44. data/scripts/ssu.bash +16 -2
  45. data/test/dataset_test.rb +5 -5
  46. data/test/lair_test.rb +1 -2
  47. data/test/net_test.rb +34 -0
  48. data/test/with_option_test.rb +115 -0
  49. data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Archaea_SCG.hmm +41964 -0
  50. data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Bacteria_SCG.hmm +32439 -0
  51. data/utils/FastAAI/00.Libraries/01.SCG_HMMs/Complete_SCG_DB.hmm +62056 -0
  52. data/utils/FastAAI/FastAAI/FastAAI +1336 -0
  53. data/utils/FastAAI/README.md +84 -0
  54. data/utils/FastAAI/kAAI_v1.0_virus.py +1296 -0
  55. data/utils/cleanup-databases.rb +2 -3
  56. data/utils/distance/base.rb +9 -0
  57. data/utils/distance/commands.rb +183 -81
  58. data/utils/distance/database.rb +69 -10
  59. data/utils/distance/pipeline.rb +15 -21
  60. data/utils/distance/runner.rb +27 -49
  61. data/utils/distance/temporal.rb +4 -2
  62. data/utils/distances.rb +2 -2
  63. data/utils/index_metadata.rb +1 -2
  64. data/utils/requirements.txt +6 -5
  65. data/utils/subclade/runner.rb +10 -11
  66. 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]*([12]|Reads|Contigs))?(\.f[nastq]+)?$}i
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; @@TASK_DESC end
101
+ def TASK_DESC
102
+ @@TASK_DESC
103
+ end
98
104
 
99
- def TASK_ALIAS; @@TASK_ALIAS end
105
+ def TASK_ALIAS
106
+ @@TASK_ALIAS
107
+ end
100
108
 
101
- def EXECS; @@EXECS end
109
+ def EXECS
110
+ @@EXECS
111
+ end
102
112
 
103
- def FILE_REGEXP; @@FILE_REGEXP end
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.is_ref? == self[:ref]) unless self[:ref].nil?
61
- o &&= (d.is_active? == self[:active]) unless self[:active].nil?
62
- o &&= (self[:multi] ? d.is_multi? :
63
- d.is_nonmulti?) unless self[:multi].nil?
64
- o &&= (not d.metadata[:tax].nil?) &&
65
- d.metadata[:tax].in?(self[:taxonomy]) unless self[:taxonomy].nil?
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
- case v
96
- when 'true'; v = true
97
- when 'false'; v = false
98
- when 'nil'; v = nil
99
- end
100
- if k == '_step'
101
- obj.metadata["_try_#{v}"] ||= 0
102
- obj.metadata["_try_#{v}"] += 1
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
- obj.metadata[k] = v
105
- end unless cli[:metadata].nil?
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'])) and
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
- if (metadata["_try_#{t}"] || 0) > (project.metadata[:max_try] || 10)
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
@@ -1,7 +1,10 @@
1
- # @package MiGA
2
- # @license Artistic-2.0
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
@@ -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.metadata[:ref_project].nil?
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
- MiGA.DEBUG "Metadata.save #{path}"
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
- sleeper = 0.0
63
- slept = 0
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
- raise "Lock-racing detected for #{path}" unless
76
- File.exist?("#{path}.tmp") and File.exist?(lock_file)
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
@@ -1,7 +1,10 @@
1
- # @package MiGA
2
- # @license Artistic-2.0
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