rbbt-util 5.30.4 → 5.30.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d45adac7949e3fea0d710418d93837cf0aa715bcedb2212c6e68f8dd749382ae
4
- data.tar.gz: 9a9857c6b1565b9ed55f18f50fb1b242a1477dd6868111e10252ecc0c286ca44
3
+ metadata.gz: 8985df2e0e2353224b5b075acb1bb04243d12351b8d904441009b93ccf490288
4
+ data.tar.gz: 3a1e7d8561fcc72a83c2b0006c49cf50f35a87cfa037c0186bdc3563435a0e8f
5
5
  SHA512:
6
- metadata.gz: 9dac4b1211fd40894f00b1a84f4f10abad83f2169579ec327a8da86f05b4274cc11e2192902638eb78b9de8f39351993f17a3b08dd5390a0f2c04ef385a0e1a2
7
- data.tar.gz: 01b9d69b003088e78f2665b57e9ed8acc8104143bc826aabe49059e77fd0e20279d9393245f7bb20efcab807180273f31d2285a62113947cf151571a96f2d949
6
+ metadata.gz: baae9121f3d757bcda2add9f666c740e5647f38d4bbc511d3456e36d466fc443c8a04b0ae12431bbf226e4e0c75eec5700b28720c117954005fe836ad74b76e8
7
+ data.tar.gz: ea61b36cec82f6634546aecf5de356d7d3b3c9d28eccfad52282f309e5ad6e1e28c2bfb627a100970d6a553fdc90b3900a4247101210cfbaae461c35d8e0399a
@@ -5,7 +5,10 @@ module HPC
5
5
  def self.job_rules(rules, job)
6
6
  workflow = job.workflow.to_s
7
7
  task_name = job.task_name.to_s
8
+ task_name = job.overriden.to_s if Symbol === job.overriden
9
+
8
10
  defaults = rules["defaults"] || {}
11
+ defaults = defaults.merge(rules[workflow]["defaults"] || {}) if rules[workflow]
9
12
 
10
13
  job_rules = IndiferentHash.setup(defaults.dup)
11
14
 
@@ -50,62 +53,155 @@ module HPC
50
53
  job_rules
51
54
  end
52
55
 
53
- def self.get_job_dependencies(job, job_rules)
56
+ def self.get_job_dependencies(job, job_rules = nil)
54
57
  deps = job.dependencies || []
55
58
  deps += job.input_dependencies || []
56
59
  deps
57
60
  end
58
61
 
59
- def self.orchestrate_job(job, options, skip = false, seen = {})
60
- return if job.done?
61
- return unless job.path.split("/")[-4] == "jobs"
62
- seen[:orchestration_target_job] ||= job
63
-
64
- options.delete "recursive_clean"
65
- options.delete "clean_task"
66
- options.delete "clean"
67
- options.delete "tail"
68
- options.delete "printfile"
69
- options.delete "detach"
62
+ def self.get_recursive_job_dependencies(job)
63
+ deps = get_job_dependencies(job)
64
+ (deps + deps.collect{|dep| get_recursive_job_dependencies(dep) }).flatten
65
+ end
70
66
 
71
- rules = YAML.load(Open.read(options[:orchestration_rules])) if options[:orchestration_rules]
72
- rules ||= {}
73
- IndiferentHash.setup(rules)
67
+ def self.piggyback(job, job_rules, job_deps)
68
+ return false unless job_rules["skip"]
69
+ final_deps = job_deps - job_deps.collect{|dep| get_recursive_job_dependencies(dep)}.flatten.uniq
70
+ return final_deps.first if final_deps.length == 1
71
+ return false
72
+ end
74
73
 
74
+ def self.get_chains(job, rules, chains = {})
75
75
  job_rules = self.job_rules(rules, job)
76
+ job_deps = get_job_dependencies(job)
76
77
 
77
- deps = get_job_dependencies(job, job_rules)
78
+ input_deps = []
79
+ job.rec_dependencies.each do |dep|
80
+ input_deps.concat dep.input_dependencies
81
+ end
78
82
 
79
- dep_ids = deps.collect do |dep|
80
- skip_dep = job_rules["chain_tasks"] &&
83
+ job_deps.each do |dep|
84
+ input_deps.concat dep.input_dependencies
85
+ get_chains(dep, rules, chains)
86
+ end
87
+
88
+ job_deps.select do |dep|
89
+ chained = job_rules["chain_tasks"] &&
81
90
  job_rules["chain_tasks"][job.workflow.to_s] && job_rules["chain_tasks"][job.workflow.to_s].include?(job.task_name.to_s) &&
82
91
  job_rules["chain_tasks"][dep.workflow.to_s] && job_rules["chain_tasks"][dep.workflow.to_s].include?(dep.task_name.to_s)
83
92
 
84
- deps = seen[dep.path] ||= self.orchestrate_job(dep, options, skip_dep, seen)
85
- if job.canfail_paths.include? dep.path
86
- [deps].flatten.compact.collect{|id| ['canfail', id] * ":"}
93
+ dep_skip = dep.done? && ! input_deps.include?(dep) && self.job_rules(rules, dep)["skip"]
94
+ chained || dep_skip
95
+ end.each do |dep|
96
+ chains[job] ||= []
97
+ chains[job] << dep
98
+ chains[job].concat chains[dep] if chains[dep]
99
+ end
100
+
101
+ chains
102
+ end
103
+
104
+ def self.workload(job, rules, chains, options, seen = nil)
105
+ return [] if job.done?
106
+ if seen.nil?
107
+ seen = {}
108
+ target_job = true
109
+ end
110
+
111
+ job_rules = self.job_rules(rules, job)
112
+ job_deps = get_job_dependencies(job)
113
+
114
+
115
+ chain = chains[job]
116
+ chain -= seen.keys if chain
117
+ piggyback = piggyback(job, job_rules, job_deps)
118
+ dep_ids = job_deps.collect do |dep|
119
+ seen[dep] = nil if chain && chain.include?(dep) #&& ! job.input_dependencies.include?(dep)
120
+ next_options = IndiferentHash.setup(options.dup)
121
+ if piggyback and piggyback == dep
122
+ next_options[:piggyback] ||= []
123
+ next_options[:piggyback].push job
124
+ ids = workload(dep, rules, chains, next_options, seen)
87
125
  else
88
- deps
126
+ next_options.delete :piggyback
127
+ ids = workload(dep, rules, chains, next_options, seen)
89
128
  end
90
- end.flatten.compact.uniq
91
129
 
92
- skip = true if job_rules[:skip]
93
- return dep_ids if skip and seen[:orchestration_target_job] != job
130
+ ids = [ids].flatten.compact.collect{|id| ['canfail', id] * ":"} if job.canfail_paths.include? dep.path
131
+
132
+ seen[dep] = ids
133
+ ids
134
+ end.compact.flatten.uniq
135
+
136
+ return seen[job] || dep_ids if seen.include?(job)
137
+ return seen[piggyback] if piggyback
94
138
 
95
139
  job_rules.delete :chain_tasks
96
140
  job_rules.delete :tasks
97
141
  job_rules.delete :workflow
98
142
 
99
- config_keys = job_rules.delete(:config_keys)
100
143
 
101
144
  job_options = IndiferentHash.setup(options.merge(job_rules).merge(:slurm_dependencies => dep_ids))
102
145
  job_options.delete :orchestration_rules
146
+
147
+ config_keys = job_rules.delete(:config_keys)
103
148
  if config_keys
104
149
  config_keys.gsub!(/,\s+/,',')
105
150
  job_options[:config_keys] = job_options[:config_keys] ? config_keys + "," + job_options[:config_keys] : config_keys
106
151
  end
107
152
 
108
- run_job(job, job_options)
153
+ if options[:piggyback]
154
+ manifest = options[:piggyback].uniq
155
+ manifest += [job]
156
+ manifest.concat chain if chain
157
+
158
+ job = options[:piggyback].first
159
+
160
+ job_rules = self.job_rules(rules, job)
161
+ new_config_keys = self.job_rules(rules, job)[:config_keys]
162
+ if new_config_keys
163
+ new_config_keys = new_config_keys.gsub(/,\s+/,',')
164
+ job_options[:config_keys] = job_options[:config_keys] ? new_config_keys + "," + job_options[:config_keys] : new_config_keys
165
+ end
166
+
167
+ job_options.delete :piggyback
168
+ else
169
+ manifest = [job]
170
+ manifest.concat chain if chain
171
+ end
172
+
173
+ manifest.uniq!
174
+
175
+ job_options[:manifest] = manifest.collect{|j| j.workflow_short_path }
176
+
177
+ job_options[:config_keys] = job_options[:config_keys].split(",").uniq * "," if job_options[:config_keys]
178
+
179
+ if options[:dry_run]
180
+ puts Log.color(:magenta, "Manifest: ") + Log.color(:blue, job_options[:manifest] * ", ") + " - tasks: #{job_options[:task_cpus] || 1} - time: #{job_options[:time]} - config: #{job_options[:config_keys]}"
181
+ puts Log.color(:yellow, "Deps: ") + Log.color(:blue, job_options[:slurm_dependencies]*", ")
182
+ job_options[:manifest].first
183
+ else
184
+ run_job(job, job_options)
185
+ end
109
186
  end
187
+
188
+
189
+ def self.orchestrate_job(job, options)
190
+ options.delete "recursive_clean"
191
+ options.delete "clean_task"
192
+ options.delete "clean"
193
+ options.delete "tail"
194
+ options.delete "printfile"
195
+ options.delete "detach"
196
+
197
+ rules = YAML.load(Open.read(options[:orchestration_rules])) if options[:orchestration_rules]
198
+ rules ||= {}
199
+ IndiferentHash.setup(rules)
200
+
201
+ chains = get_chains(job, rules)
202
+
203
+ workload(job, rules, chains, options)
204
+ end
205
+
110
206
  end
111
207
  end
@@ -21,10 +21,12 @@ module HPC
21
21
  exclusive = options.delete :exclusive
22
22
  highmem = options.delete :highmem
23
23
 
24
- queue = options.delete(:queue) || 'bsc_ls'
24
+ manifest = options.delete :manifest
25
+
26
+ queue = options.delete(:queue) || Rbbt::Config.get('queue', :slurm_queue, :slurm, :SLURM, :default => 'bsc_ls')
25
27
  task_cpus = options.delete(:task_cpus) || 1
26
28
  nodes = options.delete(:nodes) || 1
27
- time = options.delete(:time) || "0:00:10"
29
+ time = options.delete(:time) || "0:02:00"
28
30
 
29
31
  inputs_dir = options.delete :inputs_dir
30
32
  config_keys = options.delete :config_keys
@@ -258,6 +260,10 @@ EOF
258
260
  workflow write_info --recursive --force=false --check_pid "$step_path" slurm_job $SLURM_JOB_ID
259
261
  EOF
260
262
 
263
+ header +=<<-EOF if manifest
264
+ #MANIFEST: #{manifest * ", "}
265
+ EOF
266
+
261
267
  header +=<<-EOF
262
268
  #CMD: #{rbbt_cmd}
263
269
  EOF
@@ -301,11 +307,15 @@ EOF
301
307
  coda +=<<-EOF
302
308
 
303
309
  # Sync data to target location
304
- mkdir -p "$(dirname '#{target}')"
305
- rsync -avztAXHP --copy-unsafe-links "#{source}/" "#{target}/" &>> #{fsync}
306
- sync_es="$?"
307
- echo $sync_es > #{fsyncexit}
308
- find '#{target}' -type l -ls | awk '$13 ~ /^#{target.gsub('/','\/')}/ { sub("#{source}", "#{target}", $13); print $11, $13 }' | while read A B; do rm $A; ln -s $B $A; done
310
+ if [ $exit_status == '0' ]; then
311
+ mkdir -p "$(dirname '#{target}')"
312
+ rsync -avztAXHP --copy-unsafe-links "#{source}/" "#{target}/" &>> #{fsync}
313
+ sync_es="$?"
314
+ echo $sync_es > #{fsyncexit}
315
+ find '#{target}' -type l -ls | awk '$13 ~ /^#{target.gsub('/','\/')}/ { sub("#{source}", "#{target}", $13); print $11, $13 }' | while read A B; do rm $A; ln -s $B $A; done
316
+ else
317
+ sync_es="$exit_status"
318
+ fi
309
319
  EOF
310
320
 
311
321
  if contain && (wipe_container == "post" || wipe_container == "both")
@@ -331,11 +341,11 @@ EOF
331
341
  else
332
342
  coda +=<<-EOF
333
343
  ##{exec_cmd} system clean
334
- if [ $exit_status == '0' -a $sync_es == '0' ]; then
344
+ #if [ $exit_status == '0' -a $sync_es == '0' ]; then
335
345
  rm -Rfv #{contain} &>> #{fsync}
336
- else
337
- echo "ERROR: Process failed or results could not sync correctly. Contain directory not purged" &>> #{fsync}
338
- fi
346
+ #else
347
+ # echo "ERROR: Process failed or results could not sync correctly. Contain directory not purged" &>> #{fsync}
348
+ #fi
339
349
  EOF
340
350
 
341
351
  end
data/lib/rbbt/persist.rb CHANGED
@@ -349,7 +349,7 @@ module Persist
349
349
 
350
350
  Open.notify_write(path)
351
351
 
352
- return path if persist_options[:no_load]
352
+ return path if persist_options[:no_load] || type == :path
353
353
 
354
354
  res
355
355
  end
@@ -218,7 +218,14 @@ module Path
218
218
 
219
219
  else
220
220
  where = where.to_sym
221
- raise "Did not recognize the 'where' tag: #{where}. Options: #{paths.keys}" unless paths.include? where
221
+
222
+ if paths.include? where
223
+ path = paths[where]
224
+ elsif where.to_s.include?("/")
225
+ path = where.to_s
226
+ else
227
+ raise "Did not recognize the 'where' tag: #{where}. Options: #{paths.keys}" unless paths.include? where
228
+ end
222
229
 
223
230
  if where == :lib
224
231
  libdir = @libdir || Path.caller_lib_dir(caller_lib) || "NOLIBDIR"
@@ -227,7 +234,6 @@ module Path
227
234
  end
228
235
 
229
236
  pwd = FileUtils.pwd
230
- path = paths[where]
231
237
  path = File.join(path, "{PATH}") unless path.include? "PATH}" or path.include? "{BASENAME}"
232
238
  path = path.
233
239
  sub('{PKGDIR}', pkgdir).
@@ -717,7 +717,7 @@ module TSV
717
717
  def transpose(key_field = "Unkown ID")
718
718
  case type
719
719
  when :single, :flat
720
- transpose_list self.to_list, key_field
720
+ self.to_list.transpose_list key_field
721
721
  when :list
722
722
  transpose_list key_field
723
723
  when :double
@@ -748,7 +748,9 @@ module Open
748
748
  if (dir_sub_path = find_repo_dir(path))
749
749
  writable_repo?(*dir_sub_path)
750
750
  else
751
- if File.exist?(path)
751
+ if File.symlink?(path)
752
+ File.writable?(File.dirname(path))
753
+ elsif File.exist?(path)
752
754
  File.writable?(path)
753
755
  else
754
756
  File.writable?(File.dirname(File.expand_path(path)))
data/lib/rbbt/workflow.rb CHANGED
@@ -379,7 +379,7 @@ module Workflow
379
379
  has_overriden_inputs = false
380
380
 
381
381
  inputs.each do |k,v|
382
- has_overriden_inputs = true if String === k and k.include? "#"
382
+ #has_overriden_inputs = true if String === k and k.include? "#"
383
383
  next unless (task_inputs.include?(k.to_sym) or task_inputs.include?(k.to_s))
384
384
  default = all_defaults[k]
385
385
  next if default == v
@@ -382,8 +382,8 @@ module Workflow
382
382
  else
383
383
  task_info = d[:workflow].task_info(d[:task])
384
384
 
385
- inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
386
- d[:workflow]._job(d[:task], d[:jobname], inputs)
385
+ _inputs = assign_dep_inputs({}, options.merge(d[:inputs] || {}), real_dependencies, task_info)
386
+ d[:workflow]._job(d[:task], d[:jobname], _inputs)
387
387
  end
388
388
  end
389
389
  ComputeDependency.setup(d, compute) if compute
@@ -400,8 +400,8 @@ module Workflow
400
400
  setup_override_dependency(value, dep[:workflow], dep[:task])
401
401
  else
402
402
  task_info = (dep[:task] && dep[:workflow]) ? dep[:workflow].task_info(dep[:task]) : nil
403
- inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
404
- dep = dep[:workflow]._job(dep[:task], dep[:jobname], inputs)
403
+ _inputs = assign_dep_inputs({}, dep[:inputs], real_dependencies, task_info)
404
+ dep = dep[:workflow]._job(dep[:task], dep[:jobname], _inputs)
405
405
  end
406
406
  end
407
407
  end
@@ -53,7 +53,11 @@ module Workflow
53
53
  if file =~ /\.yaml/
54
54
  inputs[input.to_sym] = YAML.load(Open.read(file))
55
55
  else
56
- inputs[input.to_sym] = Open.realpath(file)
56
+ if File.symlink?(file)
57
+ inputs[input.to_sym] = File.readlink(file)
58
+ else
59
+ inputs[input.to_sym] = Open.realpath(file)
60
+ end
57
61
  end
58
62
  when :text
59
63
  Log.debug "Reading #{ input } from #{file}"
@@ -315,6 +315,11 @@ class RemoteStep < Step
315
315
  end
316
316
  end
317
317
 
318
+ def workflow_short_path
319
+ init_job unless @url
320
+ [@base_url, @task, @name] * "/"
321
+ end
322
+
318
323
  def short_path
319
324
  init_job unless @url
320
325
  [@task, @name] * "/"
@@ -114,9 +114,13 @@ class Step
114
114
 
115
115
  def copy_files_dir
116
116
  if File.symlink?(self.files_dir)
117
- realpath = Open.realpath(self.files_dir)
118
- Open.rm self.files_dir
119
- Open.cp realpath, self.files_dir
117
+ begin
118
+ realpath = Open.realpath(self.files_dir)
119
+ Open.rm self.files_dir
120
+ Open.cp realpath, self.files_dir
121
+ rescue
122
+ Log.warn "Copy files_dir for #{self.workflow_short_path}: " + $!.message
123
+ end
120
124
  end
121
125
  end
122
126
 
@@ -465,7 +469,10 @@ class Step
465
469
  self
466
470
  end
467
471
 
468
- def rec_dependencies(need_run = false, seen = [])
472
+ #connected = true means that dependency searching ends when a result is done
473
+ #but dependencies are absent, meanining that the file could have been dropped
474
+ #in
475
+ def rec_dependencies(connected = false, seen = [])
469
476
 
470
477
  # A step result with no info_file means that it was manually
471
478
  # placed. In that case, do not consider its dependencies
@@ -480,9 +487,9 @@ class Step
480
487
  #next if self.done? && Open.exists?(info_file) && info[:dependencies] && info[:dependencies].select{|task,name,path| path == step.path }.empty?
481
488
  next if archived_deps.include? step.path
482
489
  next if seen.include? step.path
483
- next if self.done? && need_run && ! updatable?
490
+ next if self.done? && connected && ! updatable?
484
491
 
485
- r = step.rec_dependencies(need_run, new_dependencies.collect{|d| d.path})
492
+ r = step.rec_dependencies(connected, new_dependencies.collect{|d| d.path})
486
493
  new_dependencies.concat r
487
494
  new_dependencies << step
488
495
  }
@@ -154,14 +154,24 @@ class Step
154
154
  @name ||= path.sub(/.*\/#{Regexp.quote task_name.to_s}\/(.*)/, '\1')
155
155
  end
156
156
 
157
+
157
158
  def short_path
158
159
  [task_name, name] * "/"
159
160
  end
160
161
 
162
+ def workflow_short_path
163
+ return short_path unless workflow
164
+ workflow.to_s + "#" + short_path
165
+ end
166
+
161
167
  def task_name
162
168
  @task_name ||= task.name
163
169
  end
164
170
 
171
+ def task_signature
172
+ [workflow.to_s, task_name] * "#"
173
+ end
174
+
165
175
  # {{{ INFO
166
176
 
167
177
  def info_file
@@ -456,7 +466,7 @@ class Step
456
466
  end
457
467
 
458
468
  def dirty_files
459
- rec_dependencies = self.rec_dependencies
469
+ rec_dependencies = self.rec_dependencies(true)
460
470
  return [] if rec_dependencies.empty?
461
471
  canfail_paths = self.canfail_paths
462
472
 
@@ -112,23 +112,27 @@ class Step
112
112
  end
113
113
 
114
114
  def updatable?
115
- (ENV["RBBT_UPDATE_ALL_JOBS"] == 'true' || ( ENV["RBBT_UPDATE"] == "true" && Open.exists?(info_file)) && status != :noinfo && ! (relocated? && done?)) || (ENV["RBBT_UPDATE"] && ! (done? && ! Open.exists?(info_file)))
115
+ return true if ENV["RBBT_UPDATE_ALL_JOBS"] == 'true'
116
+ return false unless ENV["RBBT_UPDATE"] == "true"
117
+ return false unless Open.exists?(info_file)
118
+ return true if status != :noinfo && ! (relocated? && done?)
119
+ false
116
120
  end
117
121
 
118
122
  def dependency_checks
119
123
  return [] if ENV["RBBT_UPDATE"] != "true"
120
124
 
121
- rec_dependencies.
125
+ rec_dependencies(true).
122
126
  reject{|dependency| (defined?(WorkflowRemoteClient) && WorkflowRemoteClient::RemoteStep === dependency) || Open.remote?(dependency.path) }.
123
127
  reject{|dependency| dependency.error? }.
124
128
  #select{|dependency| Open.exists?(dependency.path) || ((Open.exists?(dependency.info_file) && (dependency.status == :cleaned) || dependency.status == :waiting)) }.
125
- select{|dependency| dependency.updatable? }.
129
+ #select{|dependency| dependency.updatable? }.
126
130
  collect{|dependency| Workflow.relocate_dependency(self, dependency)}
127
131
  end
128
132
 
129
133
  def input_checks
130
- (inputs.select{|i| Step === i } + inputs.select{|i| Path === i && Step === i.resource}.collect{|i| i.resource}).
131
- select{|dependency| dependency.updatable? }
134
+ (inputs.select{|i| Step === i } + inputs.select{|i| Path === i && Step === i.resource}.collect{|i| i.resource})
135
+ #select{|dependency| dependency.updatable? }
132
136
  end
133
137
 
134
138
  def checks
@@ -153,7 +157,8 @@ class Step
153
157
  canfail_paths = self.canfail_paths
154
158
  this_mtime = Open.mtime(self.path) if Open.exists?(self.path)
155
159
 
156
- outdated_time = checks.select{|dep| dep.updatable? && dep.done? && Persist.newer?(path, dep.path) }
160
+ #outdated_time = checks.select{|dep| dep.updatable? && dep.done? && Persist.newer?(path, dep.path) }
161
+ outdated_time = checks.select{|dep| dep.done? && Persist.newer?(path, dep.path) }
157
162
  outdated_dep = checks.reject{|dep| dep.done? || (dep.error? && ! dep.recoverable_error? && canfail_paths.include?(dep.path)) }
158
163
 
159
164
  #checks.each do |dep|
@@ -21,7 +21,7 @@ module Task
21
21
 
22
22
  selects = []
23
23
  if inputs.any?
24
- inputs.zip(input_types.values_at(*inputs)).select{|i,t| t.to_sym == :select and input_options[i][:select_options] }.each{|i,t| selects << [i, input_options[i][:select_options]] }
24
+ inputs.zip(input_types.values_at(*inputs)).select{|i,t| t.to_sym == :select && input_options[i] && input_options[i][:select_options] }.each{|i,t| selects << [i, input_options[i][:select_options]] }
25
25
  puts SOPT.input_doc(inputs, input_types, input_descriptions, input_defaults, true)
26
26
  puts
27
27
  end
@@ -91,7 +91,14 @@ class Step
91
91
  if expand_repeats
92
92
  str << Log.color(:green, Log.uncolor(prov_report(dep, offset+1, task)))
93
93
  else
94
- str << Log.color(:green, " " * (offset + 1) + Log.uncolor(prov_report_msg(dep.status, dep.info[:name], dep.path, dep.info)))
94
+ info = dep.info || {}
95
+ status = info[:status] || :missing
96
+ status = "remote" if Open.remote?(path) || Open.ssh?(path)
97
+ name = info[:name] || File.basename(path)
98
+ status = :unsync if status == :done and not Open.exist?(path)
99
+ status = :notfound if status == :noinfo and not Open.exist?(path)
100
+
101
+ str << Log.color(status == :notfound ? :blue : :green, " " * (offset + 1) + Log.uncolor(prov_report_msg(status, name, path, info)))
95
102
  end
96
103
  end
97
104
  end if step.dependencies
data/share/Rlib/util.R CHANGED
@@ -484,7 +484,7 @@ rbbt.model.inpute <- function(data, formula, ...){
484
484
  data
485
485
  }
486
486
 
487
- rbbt.tsv.melt <- function(tsv, variable = NULL, value = NULL, key.field = NULL){
487
+ rbbt.tsv.melt <- function(tsv, variable = NULL, value = NULL, key.field = NULL, ...){
488
488
  rbbt.require('reshape2')
489
489
  if (is.null(key.field)){ key.field = attributes(data)$key.field;}
490
490
  if (is.null(key.field)){ key.field = "ID" }
@@ -494,7 +494,7 @@ rbbt.tsv.melt <- function(tsv, variable = NULL, value = NULL, key.field = NULL){
494
494
 
495
495
  tsv[key.field] = rownames(tsv)
496
496
 
497
- m <- melt(tsv)
497
+ m <- melt(tsv, id.vars=c(key.field), ...)
498
498
 
499
499
  names(m) <- c(key.field, variable, value)
500
500
 
@@ -784,6 +784,12 @@ rbbt.plot.venn <- function(data, a=NULL, category=NULL, fill=NULL, ...) {
784
784
  return(out)
785
785
  }
786
786
 
787
+ rbbt.plot.upset <- function(data, variable = NULL, ...){
788
+ rbbt.require('UpSetR')
789
+ data[data == TRUE] = 1
790
+ return(upset(data, ...))
791
+ }
792
+
787
793
  rbbt.plot.pca <- function(data, center = TRUE, scale. = TRUE, ...) {
788
794
  rbbt.require('vqv/ggbiplot')
789
795
  data <- rbbt.impute(data)
@@ -70,6 +70,13 @@ workdir.glob("**/command.slurm").sort_by{|f| File.mtime(f)}.each do |fcmd|
70
70
  cmd = nil
71
71
  end
72
72
 
73
+ if m = Open.read(fcmd).match(/#MANIFEST: (.*)/)
74
+ manifest = m[1]
75
+ else
76
+ manifest = nil
77
+ end
78
+
79
+
73
80
  if m = Open.read(fcmd).match(/# Run command\n(.*?)\n/im)
74
81
  exe = m[1].sub('step_path=$(','')
75
82
  else
@@ -133,7 +140,7 @@ workdir.glob("**/command.slurm").sort_by{|f| File.mtime(f)}.each do |fcmd|
133
140
  select = true if queued && deps && (running_jobs & deps).any? || queued && is_running && nodes.empty?
134
141
  select = true if running && nodes.any? && (exit_status.nil? && running_jobs.include?(id)) && (!deps || (running_jobs & deps).empty?)
135
142
  select = true if jobid && jobid.split(",").include?(id)
136
- select &= search && cmd.match(/#{search}/) if search
143
+ select = select && cmd.match(/#{search}/) if search
137
144
  next unless select
138
145
  elsif search
139
146
  select = false
@@ -145,6 +152,7 @@ workdir.glob("**/command.slurm").sort_by{|f| File.mtime(f)}.each do |fcmd|
145
152
  puts Log.color :blue, dir
146
153
  puts Log.color(:magenta, "Creation: ") << File.mtime(File.join(dir, 'command.slurm')).to_s
147
154
  puts Log.color(:magenta, "Started: ") << File.ctime(File.join(dir, 'std.err')).to_s if File.exist?(File.join(dir, 'std.err'))
155
+ puts Log.color(:magenta, "Manifest: ") << Log.color(:yellow, manifest)
148
156
  puts Log.color(:magenta, "Done: ") << File.mtime(File.join(dir, 'exit.status')).to_s if File.exist?(File.join(dir, 'exit.status'))
149
157
  puts Log.color(:magenta, "Exec: ") << (exe || "Missing")
150
158
  puts Log.color(:magenta, "CMD: ") << (Log.color(:yellow, cmd) || "Missing")
@@ -16,6 +16,8 @@ $ rbbt workflow server [options] <Workflow>
16
16
  -B--Bind* Bind IP
17
17
  -p--port* TCP port
18
18
  -s--server* Server type: thin, webrick, unicorn, etc
19
+ -w--workers* Number of workers for cluster mode (puma)
20
+ -so--server_options* Additional options for server (e.g. option1=value1;option2=value2)
19
21
  -f--finder Start server with finder functionality
20
22
  -RS--Rserve_session* Rserve session to use, otherwise start new one
21
23
  -wd--workdir* Change the working directory of the workflow
@@ -32,7 +34,6 @@ $ rbbt workflow server [options] <Workflow>
32
34
  --export_synchronous* Export workflow tasks as synchronous
33
35
  --export_exec* Export workflow tasks as exec
34
36
  --export_stream* Export workflow tasks as stream
35
- --options* Additional options for server (e.g. option1=value1;option2=value2)
36
37
  EOF
37
38
 
38
39
  if options[:help]
@@ -108,20 +109,24 @@ TmpFile.with_file do |app_dir|
108
109
  config_ru_file = File.exist?('./workflow_config.ru') ? './workflow_config.ru' : Rbbt.share['workflow_config.ru'].find
109
110
 
110
111
 
111
- if options[:options]
112
- options[:options].split(";").each do |pair|
112
+ if options[:server_options]
113
+ options[:server_options].split(";").each do |pair|
113
114
  name, _sep, value = pair.partition("=")
114
115
  name = name[1..-1].to_sym if name[0] == ':'
116
+ value = value.to_i if value =~ /^\d+$/
117
+ value = true if value == "true"
118
+ value = false if value == "false"
115
119
  options[name] = value
116
120
  end
121
+ options.delete :server_options
117
122
  end
118
123
 
119
124
  case server
120
125
  when 'unicorn'
121
126
  `env RBBT_LOG=#{Log.severity.to_s} unicorn -c #{ Rbbt.share['unicorn.rb'].find } '#{config_ru_file}' -p #{options[:Port] || "2887"}`
122
- when 'puma_alt'
127
+ when 'puma_production'
123
128
  #`puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 3 -t 8:32 --preload`
124
- `env RBBT_LOG=#{Log.severity.to_s} puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 20 -t 10:160 --preload`
129
+ CMD.cmd_log("env RBBT_LOG=#{Log.severity.to_s} puma '#{config_ru_file}' -p #{options[:Port] || "2887"} -w 20 -t 10:160 --preload")
125
130
  else
126
131
  options[:config] = config_ru_file
127
132
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rbbt-util
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.30.4
4
+ version: 5.30.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-02-04 00:00:00.000000000 Z
11
+ date: 2021-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake