miga-base 0.2.5.2 → 0.2.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6ad4344d34f36a3ec81feaa2dd60d7e4b0e9f0ee
4
- data.tar.gz: fc4cb3a9ff09769199bd24d22aecdd3622f8ea38
3
+ metadata.gz: 86777e753b2985fdceae0ee27c2d6270baf23e0e
4
+ data.tar.gz: bc5353979542701b28f35ad0fdc6bc68ee4d0c08
5
5
  SHA512:
6
- metadata.gz: 02dee40c0c7bc3c6cd7bab93a09317a991a0fbaed66c9b73acf2d605b624fd4035ed76a1e42f4954ed0edc5e6c12002f6a499a898f1c05d855060a04a5c59e92
7
- data.tar.gz: 3a255fc1af9aefec2e90ba49ba09640891372cd6bcec4b2c9c91d7ab2e0244ee0be94063e4db7c01a52c229dc7605d7ccf636b1acac0434a179d6da0e0b9fdc9
6
+ metadata.gz: 9493d3aec9de2f8ba8131ca475bc9d982686168cf64c8c565c64215ecdb34978235419e5134674c9e4d625edf000868f9bd140b7df00cd29aa16f8120d2e27b3
7
+ data.tar.gz: 9f9125548016a2b29f840c8b8e120527eb3e9dcbbf7cc5a9c464e1bfcbc4e223bca4a3dce3c1e820afe0e7b45cca3307ec53241f5fd3cdb390112714c4353f87
@@ -44,6 +44,8 @@ end.parse!
44
44
  ##=> Main <=
45
45
  opt_require(o)
46
46
  opt_require(o, type:"-t") unless o[:update]
47
+ raise "Unrecognized dataset type: #{o[:type]}." if
48
+ (not o[:update]) and MiGA::Dataset.KNOWN_TYPES[o[:type]].nil?
47
49
 
48
50
  $stderr.puts "Loading project." unless o[:q]
49
51
  p = MiGA::Project.load(o[:project])
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # @package MiGA
4
+ # @license Artistic-2.0
5
+
6
+ require "shellwords"
7
+
8
+ o = {q:true, try_load:false, thr:1}
9
+ opts = OptionParser.new do |opt|
10
+ opt_banner(opt)
11
+ opt_object(opt, o, [:project, :dataset_opt, :result])
12
+ opt.on("-t", "--threads INT",
13
+ "Threads to use in the local run (by default: #{o[:thr]})."
14
+ ){ |v| o[:thr] = v.to_i }
15
+ opt_common(opt, o)
16
+ end.parse!
17
+
18
+ ##=> Main <=
19
+ opts.parse!
20
+ opt_require(o, project:"-P", name:"-r")
21
+
22
+ $stderr.puts "Loading project." unless o[:q]
23
+ p = MiGA::Project.load(o[:project])
24
+ raise "Impossible to load project: #{o[:project]}" if p.nil?
25
+
26
+ miga = File.expand_path("../..", __FILE__)
27
+ cmd = ["PROJECT=#{p.path.shellescape}", "RUNTYPE=bash",
28
+ "MIGA=#{miga.shellescape}", "CORES=#{o[:thr]}"]
29
+ if o[:dataset].nil?
30
+ type = MiGA::Project
31
+ else
32
+ d = p.dataset(o[:dataset])
33
+ raise "Cannot load dataset." if d.nil?
34
+ cmd << "DATASET=#{d.name.shellescape}"
35
+ type = MiGA::Dataset
36
+ end
37
+ raise "Unsupported #{type.to_s.gsub(/.*::/,"")} result: #{o[:name]}." if
38
+ type.RESULT_DIRS[o[:name].to_sym].nil?
39
+ cmd << "#{miga}/scripts/#{o[:name]}.bash".shellescape
40
+ pid = spawn cmd.join(" ")
41
+ Process.wait pid
42
+
43
+ $stderr.puts "Done." unless o[:q]
data/bin/miga CHANGED
@@ -28,6 +28,7 @@ $task_desc = {
28
28
  result_stats: "Extracts statistics for the given result.",
29
29
  list_files: "Lists all registered files from the results of a dataset or a "+
30
30
  "project.",
31
+ run_local: "Executes locally one step analysis producing the given result.",
31
32
  # System
32
33
  daemon: "Controls the daemon of a MiGA project.",
33
34
  date: "Returns the current date in standard MiGA format.",
data/lib/miga/common.rb CHANGED
@@ -91,7 +91,7 @@ class MiGA::MiGA
91
91
  buffer = ""
92
92
  tmp.puts ">#{id.gsub(/[^A-Za-z0-9_\|\.]/, "_")}#{df}"
93
93
  else
94
- buffer += ln.gsub(/[^A-Za-z\.\-]/, "")
94
+ buffer << ln.gsub(/[^A-Za-z\.\-]/, "")
95
95
  end
96
96
  end
97
97
  tmp.print buffer.wrap_width(80)
@@ -111,7 +111,7 @@ class MiGA::MiGA
111
111
  def result_files_exist?(base, ext)
112
112
  ext = [ext] unless ext.kind_of? Array
113
113
  ext.all? do |f|
114
- File.exist?(base + f) or File.exist?(base + f + ".gz")
114
+ File.exist?(base + f) or File.exist?("#{base}#{f}.gz")
115
115
  end
116
116
  end
117
117
 
@@ -156,7 +156,7 @@ class String
156
156
  def miga_name? ; not(self !~ /^[A-Za-z0-9_]+$/) ; end
157
157
 
158
158
  ##
159
- # Replace underscores by spaces.
159
+ # Replace underscores by spaces or dots (depending on context).
160
160
  def unmiga_name ; gsub(/_(str|sp|subsp|pv)__/,"_\\1._").tr("_", " ") ; end
161
161
 
162
162
  ##
data/lib/miga/daemon.rb CHANGED
@@ -14,7 +14,7 @@ class MiGA::Daemon < MiGA::MiGA
14
14
  # active? Returns DateTime.
15
15
  def self.last_alive(project)
16
16
  f = File.expand_path("daemon/alive", project.path)
17
- return nil unless File.size? f
17
+ return nil unless File.exist? f
18
18
  DateTime.parse(File.read(f))
19
19
  end
20
20
 
@@ -63,10 +63,9 @@ class MiGA::Daemon < MiGA::MiGA
63
63
  def runopts(k, v=nil, force=false)
64
64
  k = k.to_sym
65
65
  unless v.nil?
66
- v = v.to_i if [:latency, :maxjobs, :ppn].include? k
67
- raise "Daemon's #{k} cannot be set to zero." if
68
- !force and v.is_a? Integer and v==0
69
- v = !!v if [:shutdown_when_done].include? k
66
+ v = [:latency, :maxjobs, :ppn].include?(k) ? v.to_i :
67
+ [:shutdown_when_done].include?(k) ? !!v : v
68
+ raise "Daemon's #{k} cannot be set to zero." if !force and v==0
70
69
  @runopts[k] = v
71
70
  end
72
71
  @runopts[k]
@@ -209,23 +208,7 @@ class MiGA::Daemon < MiGA::MiGA
209
208
  # Launch as many +jobs_to_run+ as possible
210
209
  while jobs_running.size < maxjobs
211
210
  break if jobs_to_run.empty?
212
- job = @jobs_to_run.shift
213
- # Launch job
214
- if runopts(:type) == "bash"
215
- job[:pid] = spawn job[:cmd]
216
- Process.detach job[:pid] unless [nil, "", 0].include? job[:pid]
217
- else
218
- job[:pid] = `#{job[:cmd]}`.chomp
219
- end
220
- # Check if registered
221
- if [nil, "", 0].include? job[:pid].nil?
222
- job[:pid] = nil
223
- @jobs_to_run << job
224
- say "Unsuccessful #{job[:task_name]}, rescheduling."
225
- else
226
- @jobs_running << job
227
- say "Spawned pid:#{job[:pid]} for #{job[:task_name]}."
228
- end
211
+ launch_job @jobs_to_run.shift
229
212
  end
230
213
  end
231
214
 
@@ -270,4 +253,28 @@ class MiGA::Daemon < MiGA::MiGA
270
253
  print "[#{Time.new.inspect}] ", *opts, "\n"
271
254
  end
272
255
 
256
+ private
257
+
258
+ def launch_job(job)
259
+ # Execute job
260
+ if runopts(:type) == "bash"
261
+ # Local job
262
+ job[:pid] = spawn job[:cmd]
263
+ Process.detach job[:pid] unless [nil, "", 0].include?(job[:pid])
264
+ else
265
+ # Schedule cluster job
266
+ job[:pid] = `#{job[:cmd]}`.chomp
267
+ end
268
+
269
+ # Check if registered
270
+ if [nil, "", 0].include?(job[:pid])
271
+ job[:pid] = nil
272
+ @jobs_to_run << job
273
+ say "Unsuccessful #{job[:task_name]}, rescheduling."
274
+ else
275
+ @jobs_running << job
276
+ say "Spawned pid:#{job[:pid]} for #{job[:task_name]}."
277
+ end
278
+ end
279
+
273
280
  end
data/lib/miga/dataset.rb CHANGED
@@ -26,9 +26,6 @@ class MiGA::Dataset < MiGA::MiGA
26
26
  ssu: "07.annotation/01.function/02.ssu",
27
27
  mytaxa: "07.annotation/02.taxonomy/01.mytaxa",
28
28
  mytaxa_scan: "07.annotation/03.qa/02.mytaxa_scan",
29
- # Mapping
30
- mapping_on_contigs: "08.mapping/01.read-ctg",
31
- mapping_on_genes: "08.mapping/02.read-gene",
32
29
  # Distances (for single-species datasets)
33
30
  distances: "09.distances",
34
31
  # General statistics
@@ -59,21 +56,24 @@ class MiGA::Dataset < MiGA::MiGA
59
56
  ##
60
57
  # Tasks to be excluded from query datasets.
61
58
  @@EXCLUDE_NOREF_TASKS = [:mytaxa_scan]
59
+ @@_EXCLUDE_NOREF_TASKS_H = Hash[@@EXCLUDE_NOREF_TASKS.map{ |i| [i,true] }]
62
60
 
63
61
  ##
64
62
  # Tasks to be executed only in datasets that are not multi-organism. These
65
63
  # tasks are ignored for multi-organism datasets or for unknown types.
66
64
  @@ONLY_NONMULTI_TASKS = [:mytaxa_scan, :distances]
65
+ @@_ONLY_NONMULTI_TASKS_H = Hash[@@ONLY_NONMULTI_TASKS.map{ |i| [i,true] }]
67
66
 
68
67
  ##
69
68
  # Tasks to be executed only in datasets that are multi-organism. These
70
69
  # tasks are ignored for single-organism datasets or for unknwon types.
71
70
  @@ONLY_MULTI_TASKS = [:mytaxa]
71
+ @@_ONLY_MULTI_TASKS_H = Hash[@@ONLY_MULTI_TASKS.map{ |i| [i,true] }]
72
72
 
73
73
  ##
74
74
  # Does the +project+ already have a dataset with that +name+?
75
75
  def self.exist?(project, name)
76
- File.exist? project.path + "/metadata/" + name + ".json"
76
+ File.exist? "#{project.path}/metadata/#{name}.json"
77
77
  end
78
78
 
79
79
  ##
@@ -109,8 +109,6 @@ class MiGA::Dataset < MiGA::MiGA
109
109
  metadata[:ref] = is_ref
110
110
  @metadata = MiGA::Metadata.new(
111
111
  File.expand_path("metadata/#{name}.json", project.path), metadata )
112
- warn "Warning: Unrecognized dataset type: #{type}." if
113
- !type.nil? and @@KNOWN_TYPES[type].nil?
114
112
  end
115
113
 
116
114
  ##
@@ -165,8 +163,8 @@ class MiGA::Dataset < MiGA::MiGA
165
163
  # Get the result MiGA::Result in this dataset identified by the symbol +k+.
166
164
  def result(k)
167
165
  return nil if @@RESULT_DIRS[k.to_sym].nil?
168
- MiGA::Result.load(project.path + "/data/" + @@RESULT_DIRS[k.to_sym] +
169
- "/" + name + ".json")
166
+ MiGA::Result.load(
167
+ "#{project.path}/data/#{@@RESULT_DIRS[k.to_sym]}/#{name}.json" )
170
168
  end
171
169
 
172
170
  ##
@@ -184,16 +182,18 @@ class MiGA::Dataset < MiGA::MiGA
184
182
  ##
185
183
  # Look for the result with symbol key +result_type+ and register it in the
186
184
  # dataset. If +save+ is false, it doesn't register the result, but it still
187
- # returns a result if the expected files are complete. Returns MiGA::Result
188
- # or nil.
189
- def add_result(result_type, save=true)
190
- return nil if @@RESULT_DIRS[result_type].nil?
191
- base = File.expand_path("data/#{@@RESULT_DIRS[result_type]}/#{name}",
192
- project.path)
185
+ # returns a result if the expected files are complete. The +opts+ array
186
+ # controls result creation (if necessary). Supported values include:
187
+ # - +is_clean+: A Boolean indicating if the input files are clean.
188
+ # Returns MiGA::Result or nil.
189
+ def add_result(result_type, save=true, opts={})
190
+ dir = @@RESULT_DIRS[result_type]
191
+ return nil if dir.nil?
192
+ base = File.expand_path("data/#{dir}/#{name}", project.path)
193
193
  r_pre = MiGA::Result.load("#{base}.json")
194
194
  return r_pre if (r_pre.nil? and not save) or not r_pre.nil?
195
- return nil unless result_files_exist?(base, ".done")
196
- r = self.send("add_result_#{result_type}", base)
195
+ r = File.exist?("#{base}.done") ?
196
+ self.send("add_result_#{result_type}", base, opts) : nil
197
197
  r.save unless r.nil?
198
198
  r
199
199
  end
@@ -232,11 +232,12 @@ class MiGA::Dataset < MiGA::MiGA
232
232
  # Should I ignore +task+ for this dataset?
233
233
  def ignore_task?(task)
234
234
  return !metadata["run_#{task}"] unless metadata["run_#{task}"].nil?
235
- ( (@@EXCLUDE_NOREF_TASKS.include?(task) and not is_ref?) or
236
- (@@ONLY_MULTI_TASKS.include?(task) and not is_multi?) or
237
- (@@ONLY_NONMULTI_TASKS.include?(task) and not is_nonmulti?))
235
+ pattern = [true, false]
236
+ ( [@@_EXCLUDE_NOREF_TASKS_H[task], is_ref? ]==pattern or
237
+ [@@_ONLY_MULTI_TASKS_H[task], is_multi? ]==pattern or
238
+ [@@_ONLY_NONMULTI_TASKS_H[task], is_nonmulti?]==pattern )
238
239
  end
239
-
240
+
240
241
  ##
241
242
  # Are all the dataset-specific tasks done? Passes +save+ to #add_result.
242
243
  def done_preprocessing?(save=false)
@@ -27,10 +27,10 @@ module MiGA::DatasetResult
27
27
  private
28
28
 
29
29
  ##
30
- # Add result type +:raw_reads+ at +base+.
31
- def add_result_raw_reads(base)
30
+ # Add result type +:raw_reads+ at +base+ (no +opts+ supported).
31
+ def add_result_raw_reads(base, opts)
32
32
  return nil unless result_files_exist?(base, ".1.fastq")
33
- r = MiGA::Result.new(base + ".json")
33
+ r = MiGA::Result.new("#{base}.json")
34
34
  r = add_files_to_ds_result(r, name,
35
35
  ( result_files_exist?(base, ".2.fastq") ?
36
36
  {:pair1=>".1.fastq", :pair2=>".2.fastq"} :
@@ -38,24 +38,24 @@ module MiGA::DatasetResult
38
38
  end
39
39
 
40
40
  ##
41
- # Add result type +:trimmed_reads+ at +base+.
42
- def add_result_trimmed_reads(base)
41
+ # Add result type +:trimmed_reads+ at +base+ (no +opts+ supported).
42
+ def add_result_trimmed_reads(base, opts)
43
43
  return nil unless result_files_exist?(base, ".1.clipped.fastq")
44
- r = MiGA::Result.new base + ".json"
44
+ r = MiGA::Result.new("#{base}.json")
45
45
  r = add_files_to_ds_result(r, name,
46
46
  {:pair1=>".1.clipped.fastq", :pair2=>".2.clipped.fastq"}) if
47
47
  result_files_exist?(base, ".2.clipped.fastq")
48
- r.add_file(:single, name + ".1.clipped.single.fastq")
49
- r.add_file(:trimming_sumary, name + ".1.fastq.trimmed.summary.txt")
48
+ r.add_file(:single, "#{name}.1.clipped.single.fastq")
49
+ r.add_file(:trimming_sumary, "#{name}.1.fastq.trimmed.summary.txt")
50
50
  add_result(:raw_reads) #-> Post gunzip
51
51
  r
52
52
  end
53
53
 
54
54
  ##
55
- # Add result type +:read_quality+ at +base+.
56
- def add_result_read_quality(base)
55
+ # Add result type +:read_quality+ at +base+ (no +opts+ supported).
56
+ def add_result_read_quality(base, opts)
57
57
  return nil unless result_files_exist?(base, %w[.solexaqa .fastqc])
58
- r = MiGA::Result.new(base + ".json")
58
+ r = MiGA::Result.new("#{base}.json")
59
59
  r = add_files_to_ds_result(r, name,
60
60
  {:solexaqa=>".solexaqa", :fastqc=>".fastqc"})
61
61
  add_result(:trimmed_reads) #-> Post cleaning
@@ -63,13 +63,13 @@ module MiGA::DatasetResult
63
63
  end
64
64
 
65
65
  ##
66
- # Add result type +:trimmed_fasta+ at +base+.
67
- def add_result_trimmed_fasta(base)
66
+ # Add result type +:trimmed_fasta+ at +base+ (no +opts+ supported).
67
+ def add_result_trimmed_fasta(base, opts)
68
68
  return nil unless
69
69
  result_files_exist?(base, ".CoupledReads.fa") or
70
70
  result_files_exist?(base, ".SingleReads.fa") or
71
71
  result_files_exist?(base, %w[.1.fasta .2.fasta])
72
- r = MiGA::Result.new base + ".json"
72
+ r = MiGA::Result.new("#{base}.json")
73
73
  r = add_files_to_ds_result(r, name, {:coupled=>".CoupledReads.fa",
74
74
  :single=>".SingleReads.fa", :pair1=>".1.fasta", :pair2=>".2.fasta"})
75
75
  add_result(:raw_reads) #-> Post gzip
@@ -77,12 +77,15 @@ module MiGA::DatasetResult
77
77
  end
78
78
 
79
79
  ##
80
- # Add result type +:assembly+ at +base+.
81
- def add_result_assembly(base)
80
+ # Add result type +:assembly+ at +base+. Hash +opts+ supports
81
+ # +is_clean: Boolean+.
82
+ def add_result_assembly(base, opts)
82
83
  return nil unless result_files_exist?(base, ".LargeContigs.fna")
83
- r = MiGA::Result.new(base + ".json")
84
+ r = MiGA::Result.new("#{base}.json")
84
85
  r = add_files_to_ds_result(r, name, {:largecontigs=>".LargeContigs.fna",
85
86
  :allcontigs=>".AllContigs.fna", :assembly_data=>""})
87
+ opts[:is_clean] ||= false
88
+ r.clean! if opts[:is_clean]
86
89
  unless r.clean?
87
90
  MiGA::MiGA.clean_fasta_file(r.file_path :largecontigs)
88
91
  r.clean!
@@ -92,12 +95,14 @@ module MiGA::DatasetResult
92
95
  end
93
96
 
94
97
  ##
95
- # Add result type +:cds+ at +base+.
96
- def add_result_cds(base)
98
+ # Add result type +:cds+ at +base+. Hash +opts+ supports +is_clean: Boolean+
99
+ def add_result_cds(base, opts)
97
100
  return nil unless result_files_exist?(base, %w[.faa .fna])
98
- r = MiGA::Result.new(base + ".json")
101
+ r = MiGA::Result.new("#{base}.json")
99
102
  r = add_files_to_ds_result(r, name, {:proteins=>".faa", :genes=>".fna",
100
103
  :gff2=>".gff2", :gff3=>".gff3", :tab=>".tab"})
104
+ opts[:is_clean] ||= false
105
+ r.clean! if opts[:is_clean]
101
106
  unless r.clean?
102
107
  MiGA::MiGA.clean_fasta_file(r.file_path :proteins)
103
108
  MiGA::MiGA.clean_fasta_file(r.file_path :genes)
@@ -107,22 +112,24 @@ module MiGA::DatasetResult
107
112
  end
108
113
 
109
114
  ##
110
- # Add result type +:essential_genes+ at +base+.
111
- def add_result_essential_genes(base)
115
+ # Add result type +:essential_genes+ at +base+ (no +opts+ supported).
116
+ def add_result_essential_genes(base, opts)
112
117
  return nil unless result_files_exist?(base, %w[.ess.faa .ess .ess/log])
113
- r = MiGA::Result.new(base + ".json")
118
+ r = MiGA::Result.new("#{base}.json")
114
119
  r = add_files_to_ds_result(r, name, {:ess_genes=>".ess.faa",
115
120
  :collection=>".ess", :report=>".ess/log"})
116
121
  end
117
122
 
118
123
  ##
119
- # Add result type +:ssu+ at +base+.
120
- def add_result_ssu(base)
121
- return MiGA::Result.new(base + ".json") if result(:assembly).nil?
124
+ # Add result type +:ssu+ at +base+. Hash +opts+ supports +is_clean: Boolean+
125
+ def add_result_ssu(base, opts)
126
+ return MiGA::Result.new("#{base}.json") if result(:assembly).nil?
122
127
  return nil unless result_files_exist?(base, ".ssu.fa")
123
- r = MiGA::Result.new(base + ".json")
128
+ r = MiGA::Result.new("#{base}.json")
124
129
  r = add_files_to_ds_result(r, name, {:longest_ssu_gene=>".ssu.fa",
125
130
  :gff=>".ssu.gff", :all_ssu_genes=>".ssu.all.fa"})
131
+ opts[:is_clean] ||= false
132
+ r.clean! if opts[:is_clean]
126
133
  unless r.clean?
127
134
  MiGA::MiGA.clean_fasta_file(r.file_path :longest_ssu_gene)
128
135
  r.clean!
@@ -131,37 +138,37 @@ module MiGA::DatasetResult
131
138
  end
132
139
 
133
140
  ##
134
- # Add result type +:mytaxa+ at +base+.
135
- def add_result_mytaxa(base)
141
+ # Add result type +:mytaxa+ at +base+ (no +opts+ supported).
142
+ def add_result_mytaxa(base, opts)
136
143
  if is_multi?
137
144
  return nil unless result_files_exist?(base, ".mytaxa")
138
- r = MiGA::Result.new(base + ".json")
145
+ r = MiGA::Result.new("#{base}.json")
139
146
  add_files_to_ds_result(r, name, {:mytaxa=>".mytaxa", :blast=>".blast",
140
147
  :mytaxain=>".mytaxain"})
141
148
  else
142
- MiGA::Result.new(base + ".json")
149
+ MiGA::Result.new("#{base}.json")
143
150
  end
144
151
  end
145
152
 
146
153
  ##
147
- # Add result type +:mytaxa_scan+ at +base+.
148
- def add_result_mytaxa_scan(base)
154
+ # Add result type +:mytaxa_scan+ at +base+ (no +opts+ supported).
155
+ def add_result_mytaxa_scan(base, opts)
149
156
  if is_nonmulti?
150
157
  return nil unless
151
158
  result_files_exist?(base, %w[.pdf .wintax .mytaxa .reg])
152
- r = MiGA::Result.new(base + ".json")
159
+ r = MiGA::Result.new("#{base}.json")
153
160
  add_files_to_ds_result(r, name, {:mytaxa=>".mytaxa", :wintax=>".wintax",
154
161
  :blast=>".blast", :mytaxain=>".mytaxain", :report=>".pdf",
155
162
  :regions=>".reg", :gene_ids=>".wintax.genes",
156
163
  :region_ids=>".wintax.regions"})
157
164
  else
158
- MiGA::Result.new base + ".json"
165
+ MiGA::Result.new("#{base}.json")
159
166
  end
160
167
  end
161
168
 
162
169
  ##
163
- # Add result type +:distances+ at +base+.
164
- def add_result_distances(base)
170
+ # Add result type +:distances+ at +base+ (no +opts+ supported).
171
+ def add_result_distances(base, opts)
165
172
  if is_nonmulti?
166
173
  if is_ref?
167
174
  add_result_distances_ref(base)
@@ -174,15 +181,15 @@ module MiGA::DatasetResult
174
181
  end
175
182
 
176
183
  ##
177
- # Add result type +:stats+ at +base+.
178
- def add_result_stats(base)
179
- MiGA::Result.new "#{base}.json"
184
+ # Add result type +:stats+ at +base+ (no +opts+ supported).
185
+ def add_result_stats(base, opts)
186
+ MiGA::Result.new("#{base}.json")
180
187
  end
181
188
 
182
189
  ##
183
190
  # Add result type +:distances+ for _multi_ datasets at +base+.
184
191
  def add_result_distances_multi(base)
185
- MiGA::Result.new "#{base}.json"
192
+ MiGA::Result.new("#{base}.json")
186
193
  end
187
194
 
188
195
  ##
@@ -191,7 +198,7 @@ module MiGA::DatasetResult
191
198
  pref = File.dirname(base)
192
199
  return nil unless
193
200
  File.exist?("#{pref}/01.haai/#{name}.db")
194
- r = MiGA::Result.new(base + ".json")
201
+ r = MiGA::Result.new("#{base}.json")
195
202
  r.add_files({:haai_db=>"01.haai/#{name}.db",
196
203
  :aai_db=>"02.aai/#{name}.db", :ani_db=>"03.ani/#{name}.db"})
197
204
  r
@@ -203,7 +210,7 @@ module MiGA::DatasetResult
203
210
  return nil unless
204
211
  result_files_exist?(base, %w[.aai-medoids.tsv .aai.db]) or
205
212
  result_files_exist?(base, %w[.ani-medoids.tsv .ani.db])
206
- r = MiGA::Result.new(base + ".json")
213
+ r = MiGA::Result.new("#{base}.json")
207
214
  r = add_files_to_ds_result(r, name, {
208
215
  :aai_medoids=>".aai-medoids.tsv",
209
216
  :haai_db=>".haai.db", :aai_db=>".aai.db",
data/lib/miga/metadata.rb CHANGED
@@ -9,7 +9,7 @@ class MiGA::Metadata < MiGA::MiGA
9
9
 
10
10
  ##
11
11
  # Does the metadata described in +path+ already exist?
12
- def self.exist?(path) File.size? path end
12
+ def self.exist?(path) File.exist? path end
13
13
 
14
14
  ##
15
15
  # Load the metadata described in +path+ and return MiGA::Metadata if it
@@ -24,34 +24,39 @@ class MiGA::Metadata < MiGA::MiGA
24
24
  ##
25
25
  # Path to the JSON file describing the metadata.
26
26
  attr_reader :path
27
-
28
- ##
29
- # Parsed data as a Hash.
30
- attr_reader :data
31
27
 
32
28
  ##
33
29
  # Initiate a MiGA::Metadata object with description in +path+. It will create
34
30
  # it if it doesn't exist.
35
31
  def initialize(path, defaults={})
32
+ @data = nil
36
33
  @path = File.absolute_path(path)
37
- @data = {}
38
- defaults.each_pair{ |k,v| self[k]=v }
39
- self.create unless File.size? self.path
40
- self.load
34
+ unless File.exist? path
35
+ @data = {}
36
+ defaults.each_pair{ |k,v| self[k]=v }
37
+ create
38
+ end
39
+ end
40
+
41
+ ##
42
+ # Parsed data as a Hash.
43
+ def data
44
+ self.load if @data.nil?
45
+ @data
41
46
  end
42
47
 
43
48
  ##
44
49
  # Reset :created field and save the current data.
45
50
  def create
46
- @data[:created] = Time.now.to_s
47
- self.save
51
+ self[:created] = Time.now.to_s
52
+ save
48
53
  end
49
54
 
50
55
  ##
51
56
  # Save the metadata into #path.
52
57
  def save
53
58
  MiGA.DEBUG "Metadata.save #{path}"
54
- @data[:updated] = Time.now.to_s
59
+ self[:updated] = Time.now.to_s
55
60
  json = JSON.pretty_generate(data)
56
61
  sleeper = 0.0
57
62
  while File.exist?(lock_file)
@@ -59,12 +64,12 @@ class MiGA::Metadata < MiGA::MiGA
59
64
  sleep(sleeper.to_i)
60
65
  end
61
66
  FileUtils.touch lock_file
62
- ofh = File.open(path + ".tmp", "w")
67
+ ofh = File.open("#{path}.tmp", "w")
63
68
  ofh.puts json
64
69
  ofh.close
65
70
  raise "Lock-racing detected for #{path}." unless
66
- File.exist?(path + ".tmp") and File.exist?(lock_file)
67
- File.rename(path + ".tmp", path)
71
+ File.exist?("#{path}.tmp") and File.exist?(lock_file)
72
+ File.rename("#{path}.tmp", path)
68
73
  File.unlink(lock_file)
69
74
  end
70
75
 
@@ -86,14 +91,14 @@ class MiGA::Metadata < MiGA::MiGA
86
91
  ##
87
92
  # Delete file at #path.
88
93
  def remove!
89
- MiGA.DEBUG "Metadata.remove! #{self.path}"
90
- File.unlink(self.path)
94
+ MiGA.DEBUG "Metadata.remove! #{path}"
95
+ File.unlink(path)
91
96
  nil
92
97
  end
93
98
 
94
99
  ##
95
100
  # Lock file for the metadata.
96
- def lock_file ; path + ".lock" ; end
101
+ def lock_file ; "#{path}.lock" ; end
97
102
 
98
103
  ##
99
104
  # Return the value of +k+ in #data.
@@ -102,6 +107,7 @@ class MiGA::Metadata < MiGA::MiGA
102
107
  ##
103
108
  # Set the value of +k+ to +v+.
104
109
  def []=(k,v)
110
+ self.load if @data.nil?
105
111
  k = k.to_sym
106
112
  # Protect the special field :name
107
113
  v=v.miga_name if k==:name
data/lib/miga/project.rb CHANGED
@@ -49,11 +49,11 @@ class MiGA::Project < MiGA::MiGA
49
49
  clade_finding: "10.clades/01.find",
50
50
  # Clade analysis
51
51
  subclades: "10.clades/02.ani",
52
- ogs: "10.clades/03.ogs"
52
+ ogs: "10.clades/03.ogs",
53
53
  #ess_phylogeny: "10.clades/04.phylogeny/01.essential",
54
54
  #core_phylogeny: "10.clades/04.phylogeny/02.core",
55
55
  #clade_metadata: "10.clades/05.metadata"
56
- #project_stats: "90.stats"
56
+ project_stats: "90.stats"
57
57
  }
58
58
 
59
59
  ##
@@ -85,7 +85,7 @@ class MiGA::Project < MiGA::MiGA
85
85
  ##
86
86
  # Does the project at +path+ exist?
87
87
  def self.exist?(path)
88
- Dir.exist?(path) and File.exist?(path + "/miga.project.json")
88
+ Dir.exist?(path) and File.exist?("#{path}/miga.project.json")
89
89
  end
90
90
 
91
91
  ##
@@ -130,7 +130,7 @@ class MiGA::Project < MiGA::MiGA
130
130
  dirs.each{ |d| Dir.mkdir(d) unless Dir.exist? d }
131
131
  @metadata = MiGA::Metadata.new(self.path + "/miga.project.json",
132
132
  {datasets: [], name: File.basename(path)})
133
- FileUtils.cp(ENV["MIGA_HOME"] + "/.miga_daemon.json",
133
+ FileUtils.cp("#{ENV["MIGA_HOME"]}/.miga_daemon.json",
134
134
  "#{path}/daemon/daemon.json") unless
135
135
  File.exist? "#{path}/daemon/daemon.json"
136
136
  self.load
@@ -252,9 +252,9 @@ class MiGA::Project < MiGA::MiGA
252
252
  ##
253
253
  # Get result identified by Symbol +name+, returns MiGA::Result.
254
254
  def result(name)
255
- return nil if @@RESULT_DIRS[name.to_sym].nil?
256
- MiGA::Result.load "#{path}/data/" + @@RESULT_DIRS[name.to_sym] +
257
- "/miga-project.json"
255
+ dir = @@RESULT_DIRS[name.to_sym]
256
+ return nil if dir.nil?
257
+ MiGA::Result.load("#{path}/data/#{dir}/miga-project.json")
258
258
  end
259
259
 
260
260
  ##
@@ -269,7 +269,7 @@ class MiGA::Project < MiGA::MiGA
269
269
  def add_result(name, save=true)
270
270
  return nil if @@RESULT_DIRS[name].nil?
271
271
  base = "#{path}/data/#{@@RESULT_DIRS[name]}/miga-project"
272
- return MiGA::Result.load(base + ".json") unless save
272
+ return MiGA::Result.load("#{base}.json") unless save
273
273
  return nil unless result_files_exist?(base, ".done")
274
274
  r = send("add_result_#{name}", base)
275
275
  r.save unless r.nil?
@@ -11,7 +11,7 @@ module MiGA::ProjectResult
11
11
  # Internal alias for all add_result_*_distances.
12
12
  def add_result_distances(base)
13
13
  return nil unless result_files_exist?(base, %w[.Rdata .log .txt])
14
- r = MiGA::Result.new(base + ".json")
14
+ r = MiGA::Result.new("#{base}.json")
15
15
  r.add_file(:rdata, "miga-project.Rdata")
16
16
  r.add_file(:matrix, "miga-project.txt")
17
17
  r.add_file(:log, "miga-project.log")
@@ -40,7 +40,7 @@ module MiGA::ProjectResult
40
40
  end
41
41
 
42
42
  def add_result_iter_clades(base)
43
- r = MiGA::Result.new(base + ".json")
43
+ r = MiGA::Result.new("#{base}.json")
44
44
  r.add_file(:report, "miga-project.pdf")
45
45
  r.add_file(:class_table, "miga-project.class.tsv")
46
46
  r.add_file(:class_tree, "miga-project.class.nwk")
@@ -51,13 +51,22 @@ module MiGA::ProjectResult
51
51
 
52
52
  def add_result_ogs(base)
53
53
  return nil unless result_files_exist?(base, %w[.ogs .stats])
54
- r = MiGA::Result.new(base + ".json")
54
+ r = MiGA::Result.new("#{base}.json")
55
55
  r.add_file(:ogs, "miga-project.ogs")
56
56
  r.add_file(:stats, "miga-project.stats")
57
57
  r.add_file(:rbm, "miga-project.rbm")
58
58
  r
59
59
  end
60
60
 
61
+ def add_result_project_stats(base)
62
+ return nil unless
63
+ result_files_exist?(base, %w[.taxonomy.json .metadata.db])
64
+ r = MiGA::Result.new("#{base}.json")
65
+ r.add_file(:taxonomy_index, "miga-project.taxonomy.json")
66
+ r.add_file(:metadata_index, "miga-project.metadata.db")
67
+ r
68
+ end
69
+
61
70
  alias add_result_haai_distances add_result_distances
62
71
  alias add_result_aai_distances add_result_distances
63
72
  alias add_result_ani_distances add_result_distances
@@ -9,6 +9,7 @@ require "open-uri"
9
9
  class MiGA::RemoteDataset < MiGA::MiGA
10
10
  # Class-level
11
11
 
12
+ @@_EUTILS = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/"
12
13
  ##
13
14
  # Structure of the different database Universes or containers. The structure
14
15
  # is a Hash with universe names as keys as Symbol and values being a Hash with
@@ -37,16 +38,14 @@ class MiGA::RemoteDataset < MiGA::MiGA
37
38
  },
38
39
  ncbi:{
39
40
  dbs: { nuccore:{stage: :assembly, format: :fasta} },
40
- url: "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/" +
41
- "efetch.fcgi?db=%1$s&id=%2$s&rettype=%3$s&retmode=text",
41
+ url: "#{@@_EUTILS}efetch.fcgi?db=%1$s&id=%2$s&rettype=%3$s&retmode=text",
42
42
  method: :rest
43
43
  },
44
44
  ncbi_map:{
45
45
  dbs: { assembly:{map_to: :nuccore, format: :text} },
46
- url: "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/" +
47
46
  # FIXME ncbi_map is intended to do internal NCBI mapping between
48
47
  # databases.
49
- "elink.fcgi?dbfrom=%1$s&id=%2$s&db=%3$s - - - - -",
48
+ url: "#{@@_EUTILS}elink.fcgi?dbfrom=%1$s&id=%2$s&db=%3$s - - - - -",
50
49
  method: :rest,
51
50
  map_to_universe: :ncbi
52
51
  }
@@ -127,8 +126,8 @@ class MiGA::RemoteDataset < MiGA::MiGA
127
126
  metadata = get_metadata(metadata)
128
127
  case @@UNIVERSE[universe][:dbs][db][:stage]
129
128
  when :assembly
130
- base = project.path + "/data/" + MiGA::Dataset.RESULT_DIRS[:assembly] +
131
- "/" + name
129
+ dir = MiGA::Dataset.RESULT_DIRS[:assembly]
130
+ base = "#{project.path}/data/#{dir}/#{name}"
132
131
  File.open("#{base}.start", "w") { |ofh| ofh.puts Time.now.to_s }
133
132
  if @@UNIVERSE[universe][:dbs][db][:format] == :fasta_gz
134
133
  download("#{base}.LargeContigs.fna.gz")
@@ -144,9 +143,12 @@ class MiGA::RemoteDataset < MiGA::MiGA
144
143
  end
145
144
  dataset = MiGA::Dataset.new(project, name, is_ref, metadata)
146
145
  project.add_dataset(dataset.name)
147
- result = dataset.add_result @@UNIVERSE[universe][:dbs][db][:stage]
146
+ result = dataset.add_result(@@UNIVERSE[universe][:dbs][db][:stage],
147
+ true, is_clean:true)
148
148
  raise "Empty dataset created: seed result was not added due to "+
149
149
  "incomplete files." if result.nil?
150
+ result.clean!
151
+ result.save
150
152
  dataset
151
153
  end
152
154
 
data/lib/miga/result.rb CHANGED
@@ -9,9 +9,7 @@ class MiGA::Result < MiGA::MiGA
9
9
 
10
10
  ##
11
11
  # Check if the result described by the JSON in +path+ already exists.
12
- def self.exist?(path)
13
- !!(File.size? path)
14
- end
12
+ def self.exist?(path) File.exist? path end
15
13
 
16
14
  ##
17
15
  # Load the result described by the JSON in +path+. Returns MiGA::Result if it
@@ -82,8 +80,8 @@ class MiGA::Result < MiGA::MiGA
82
80
  k = k.to_sym
83
81
  @data[:files] ||= {}
84
82
  @data[:files][k] = file if File.exist? File.expand_path(file, dir)
85
- @data[:files][k] = file + ".gz" if
86
- File.exist? File.expand_path(file + ".gz", dir)
83
+ @data[:files][k] = "#{file}.gz" if
84
+ File.exist? File.expand_path("#{file}.gz", dir)
87
85
  end
88
86
 
89
87
  ##
@@ -115,13 +115,13 @@ class MiGA::TaxIndexTaxon < MiGA::MiGA
115
115
  ##
116
116
  # Get the number of datasets in the taxon (including children).
117
117
  def datasets_count
118
- datasets.size + children.map{ |it| it.datasets_count }.reduce(0, :+)
118
+ children.map{ |it| it.datasets_count }.reduce(datasets.size, :+)
119
119
  end
120
120
 
121
121
  ##
122
122
  # Get all the datasets in the taxon (including children).
123
123
  def all_datasets
124
- datasets + children.map{ |it| it.datasets }.reduce([], :+)
124
+ children.map{ |it| it.datasets }.reduce(datasets, :+)
125
125
  end
126
126
 
127
127
  ##
@@ -142,11 +142,11 @@ class MiGA::TaxIndexTaxon < MiGA::MiGA
142
142
  # Tabular String of the taxon.
143
143
  def to_tab(unknown, indent=0)
144
144
  o = ""
145
- o = (" " * indent) + tax_str + ": " + datasets_count.to_s + "\n" if
145
+ o = "#{" " * indent}#{tax_str}: #{datasets_count}\n" if
146
146
  unknown or not datasets.empty? or not name.nil?
147
147
  indent += 2
148
- datasets.each{ |ds| o += (" " * indent) + "# " + ds.name + "\n" }
149
- children.each{ |it| o += it.to_tab(unknown, indent) }
148
+ datasets.each{ |ds| o << "#{" " * indent}# #{ds.name}\n" }
149
+ children.each{ |it| o << it.to_tab(unknown, indent) }
150
150
  o
151
151
  end
152
152
 
data/lib/miga/taxonomy.rb CHANGED
@@ -10,6 +10,7 @@ class MiGA::Taxonomy < MiGA::MiGA
10
10
  # Cannonical ranks.
11
11
  def self.KNOWN_RANKS() @@KNOWN_RANKS ; end
12
12
  @@KNOWN_RANKS = %w{ns d k p c o f g s ssp str ds}.map{|r| r.to_sym}
13
+ @@_KNOWN_RANKS_H = Hash[ @@KNOWN_RANKS.map{ |i| [i,true] } ]
13
14
 
14
15
  ##
15
16
  # Long names of the cannonical ranks.
@@ -42,11 +43,12 @@ class MiGA::Taxonomy < MiGA::MiGA
42
43
  ##
43
44
  # Returns cannonical rank (Symbol) for the +rank+ String.
44
45
  def self.normalize_rank(rank)
46
+ return rank.to_sym if @@_KNOWN_RANKS_H[rank.to_sym]
45
47
  rank = rank.to_s.downcase
46
48
  return nil if rank=="no rank"
47
49
  rank = @@RANK_SYNONYMS[rank] unless @@RANK_SYNONYMS[rank].nil?
48
50
  rank = rank.to_sym
49
- return nil unless @@KNOWN_RANKS.include? rank
51
+ return nil unless @@_KNOWN_RANKS_H[rank]
50
52
  rank
51
53
  end
52
54
 
@@ -84,16 +86,16 @@ class MiGA::Taxonomy < MiGA::MiGA
84
86
  # Add +value+ to the hierarchy, that can be an Array, a String, or a Hash, as
85
87
  # described in #initialize.
86
88
  def <<(value)
87
- if value.is_a? Array
88
- value.each{ |v| self << v }
89
- elsif value.is_a? String
90
- (rank, name) = value.split(/:/)
91
- self << { rank => name }
92
- elsif value.is_a? Hash
89
+ if value.is_a? Hash
93
90
  value.each_pair do |rank_i, name_i|
94
91
  next if name_i.nil? or name_i == ""
95
92
  @ranks[ Taxonomy.normalize_rank rank_i ] = name_i.tr("_"," ")
96
93
  end
94
+ elsif value.is_a? Array
95
+ value.each{ |v| self << v }
96
+ elsif value.is_a? String
97
+ (rank, name) = value.split(/:/)
98
+ self << { rank => name }
97
99
  else
98
100
  raise "Unsupported class: #{value.class.name}."
99
101
  end
data/lib/miga/version.rb CHANGED
@@ -10,7 +10,7 @@ module MiGA
10
10
  # - Float representing the major.minor version.
11
11
  # - Integer representing gem releases of the current version.
12
12
  # - Integer representing minor changes that require new version number.
13
- VERSION = [0.2, 5, 2]
13
+ VERSION = [0.2, 6, 0]
14
14
 
15
15
  ##
16
16
  # Nickname for the current major.minor version.
@@ -18,7 +18,7 @@ module MiGA
18
18
 
19
19
  ##
20
20
  # Date of the current gem release.
21
- VERSION_DATE = Date.new(2017, 4, 3)
21
+ VERSION_DATE = Date.new(2017, 4, 14)
22
22
 
23
23
  ##
24
24
  # Reference of MiGA.
@@ -42,8 +42,7 @@ class MiGA::MiGA
42
42
  ##
43
43
  # Complete version with nickname and date as string.
44
44
  def self.LONG_VERSION
45
- "MiGA " + VERSION.join(".") + " - " + VERSION_NAME + " - " +
46
- VERSION_DATE.to_s
45
+ "MiGA #{VERSION.join(".")} - #{VERSION_NAME} - #{VERSION_DATE}"
47
46
  end
48
47
 
49
48
  ##
@@ -1,7 +1,7 @@
1
1
  #!/bin/bash
2
2
  # Available variables: $PROJECT, $RUNTYPE, $MIGA, $CORES
3
3
  set -e
4
- SCRIPT="essential"
4
+ SCRIPT="essential_genes"
5
5
  echo "MiGA: $MIGA"
6
6
  echo "Project: $PROJECT"
7
7
  source "$MIGA/scripts/miga.bash" || exit 1
@@ -0,0 +1,24 @@
1
+ #!/bin/bash
2
+ # Available variables: $PROJECT, $RUNTYPE, $MIGA, $CORES
3
+ set -e
4
+ SCRIPT="project_stats"
5
+ echo "MiGA: $MIGA"
6
+ echo "Project: $PROJECT"
7
+ source "$MIGA/scripts/miga.bash" || exit 1
8
+ DIR="$PROJECT/data/90.stats"
9
+ [[ -d "$DIR" ]] || mkdir -p "$DIR"
10
+ cd "$DIR"
11
+
12
+ # Initialize
13
+ miga date > "miga-project.start"
14
+
15
+ # Index taxonomy
16
+ miga index_taxonomy -P "$PROJECT" -i "miga-project.taxonomy.json" --ref
17
+
18
+ # Index metadata
19
+ ruby -I "$MIGA/lib"
20
+ "$MIGA/utils/index_metadata.rb" "$PROJECT" "miga-project.metadata.db"
21
+
22
+ # Finalize
23
+ miga date > "miga-project.done"
24
+ miga add_result -P "$PROJECT" -r "$SCRIPT"
data/test/dataset_test.rb CHANGED
@@ -92,13 +92,24 @@ class DatasetTest < Test::Unit::TestCase
92
92
  assert_equal(:trimmed_reads, d2.first_preprocessing(true))
93
93
  assert_equal(:read_quality, d2.next_preprocessing(true))
94
94
  assert(! d2.done_preprocessing?(true))
95
+ # Ref and undeclared multi
95
96
  assert(d2.ignore_task?(:mytaxa))
97
+ assert(d2.ignore_task?(:mytaxa_scan))
96
98
  assert(d2.ignore_task?(:distances))
99
+ # Ref and multi
97
100
  d2.metadata[:type] = :metagenome
98
101
  assert(! d2.ignore_task?(:mytaxa))
102
+ assert(d2.ignore_task?(:mytaxa_scan))
99
103
  assert(d2.ignore_task?(:distances))
104
+ # Ref and nonmulti
100
105
  d2.metadata[:type] = :genome
101
106
  assert(d2.ignore_task?(:mytaxa))
107
+ assert(! d2.ignore_task?(:mytaxa_scan))
108
+ assert(! d2.ignore_task?(:distances))
109
+ # Qry and nonmulti
110
+ d2.metadata[:ref] = false
111
+ assert(d2.ignore_task?(:mytaxa))
112
+ assert(d2.ignore_task?(:mytaxa_scan))
102
113
  assert(! d2.ignore_task?(:distances))
103
114
  end
104
115
 
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "miga"
4
+ require "sqlite3"
5
+
6
+ p = MiGA::Project.load(ARGV[0])
7
+ raise "Impossible to load project: #{ARGV[0]}." if p.nil?
8
+
9
+ File.unlink(ARGV[1]) if File.exist? ARGV[1]
10
+ db = SQLite3::Database.new(ARGV[1])
11
+ db.execute "create table metadata(" +
12
+ "`name` varchar(256), `field` varchar(256), `value` text)"
13
+
14
+ def searchable(db, k, v)
15
+ db.execute "insert into metadata values(?,?,?)",
16
+ k.to_s, " #{v.to_s.downcase.gsub(/[^A-Za-z0-9\-]+/, " ")} "
17
+ end
18
+
19
+ p.each_dataset do |name, d|
20
+ next unless d.is_ref?
21
+ searchable(db, :name, d.name)
22
+ d.metadata.each do |k, v|
23
+ next if [:created, :updated].include? k
24
+ v = v.sorted_ranks.map{ |r| r[1] }.join(" ") if k==:tax
25
+ searchable(db, k, v)
26
+ end
27
+ end
28
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miga-base
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5.2
4
+ version: 0.2.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Luis M. Rodriguez-R
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-03 00:00:00.000000000 Z
11
+ date: 2017-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -149,6 +149,7 @@ files:
149
149
  - scripts/mytaxa.bash
150
150
  - scripts/mytaxa_scan.bash
151
151
  - scripts/ogs.bash
152
+ - scripts/project_stats.bash
152
153
  - scripts/read_quality.bash
153
154
  - scripts/ssu.bash
154
155
  - scripts/stats.bash
@@ -156,6 +157,7 @@ files:
156
157
  - scripts/trimmed_fasta.bash
157
158
  - scripts/trimmed_reads.bash
158
159
  - utils/adapters.fa
160
+ - utils/index_metadata.rb
159
161
  - utils/mytaxa_scan.R
160
162
  - utils/mytaxa_scan.rb
161
163
  - utils/plot-taxdist.R
@@ -179,6 +181,7 @@ files:
179
181
  - actions/plugins.rb
180
182
  - actions/project_info.rb
181
183
  - actions/result_stats.rb
184
+ - actions/run_local.rb
182
185
  - actions/tax_distributions.rb
183
186
  - actions/unlink_dataset.rb
184
187
  - Gemfile