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.
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