rbbt-util 5.32.9 → 5.32.15

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rbbt +1 -0
  3. data/lib/rbbt/annotations/util.rb +1 -0
  4. data/lib/rbbt/entity.rb +6 -1
  5. data/lib/rbbt/hpc/batch.rb +26 -9
  6. data/lib/rbbt/hpc/orchestrate.rb +1 -0
  7. data/lib/rbbt/hpc/slurm.rb +31 -10
  8. data/lib/rbbt/persist/tsv/adapter.rb +1 -5
  9. data/lib/rbbt/resource.rb +22 -9
  10. data/lib/rbbt/tsv/csv.rb +2 -2
  11. data/lib/rbbt/tsv/manipulate.rb +2 -0
  12. data/lib/rbbt/tsv/parallel/traverse.rb +7 -10
  13. data/lib/rbbt/util/R.rb +2 -2
  14. data/lib/rbbt/util/cmd.rb +39 -18
  15. data/lib/rbbt/util/log/progress/report.rb +20 -17
  16. data/lib/rbbt/util/log/progress/util.rb +2 -1
  17. data/lib/rbbt/util/misc/omics.rb +2 -2
  18. data/lib/rbbt/util/misc/system.rb +2 -2
  19. data/lib/rbbt/util/python.rb +63 -3
  20. data/lib/rbbt/util/simpleDSL.rb +4 -4
  21. data/lib/rbbt/workflow.rb +20 -2
  22. data/lib/rbbt/workflow/step.rb +37 -6
  23. data/lib/rbbt/workflow/step/accessor.rb +2 -2
  24. data/lib/rbbt/workflow/util/data.rb +35 -0
  25. data/lib/rbbt/workflow/util/trace.rb +2 -1
  26. data/python/rbbt.py +7 -0
  27. data/share/install/software/lib/install_helpers +1 -1
  28. data/share/rbbt_commands/hpc/list +11 -7
  29. data/share/rbbt_commands/hpc/orchestrate +10 -2
  30. data/share/rbbt_commands/hpc/task +8 -1
  31. data/share/rbbt_commands/lsf/list +11 -7
  32. data/share/rbbt_commands/lsf/orchestrate +10 -2
  33. data/share/rbbt_commands/lsf/task +8 -1
  34. data/share/rbbt_commands/slurm/list +11 -7
  35. data/share/rbbt_commands/slurm/orchestrate +10 -2
  36. data/share/rbbt_commands/slurm/task +8 -1
  37. data/share/rbbt_commands/workflow/forget_deps +5 -4
  38. data/test/rbbt/util/test_python.rb +3 -2
  39. data/test/rbbt/util/test_simpleDSL.rb +3 -3
  40. data/test/rbbt/workflow/util/test_data.rb +48 -0
  41. metadata +86 -83
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b9d236294c4bdcc32e517eadcffa4d103e5a99a220096497a50f8baa26f746d
4
- data.tar.gz: 6370930ac76bd8b86666fa59556d2d8648789c3e3dda56bb71c71c2ff65b88d3
3
+ metadata.gz: 54a6869616f33a2c526e35ddddf90c1e7c29e79c5df9fabaa51d9711e0aba249
4
+ data.tar.gz: 7a6c7290ff27c00ba5911a609897eb9104b357adec7a38b892ad5a8c01267e26
5
5
  SHA512:
6
- metadata.gz: 7dcd6fadf6424add27b6773d16ef0b794183c4b2f52616498d8c2ec21a77c5b5ad8f3fed65ca69ce5111c71e0942f84be79c107b40156c331919533f3fc5bea7
7
- data.tar.gz: ea294d8aa5f8ff04a9e902fdd2d7d2287a34934f7288a11234996d06fb72dba4f333e655d591d9b78c5bc00104036356625088f9aa4c7e808ae2d42d0b253781
6
+ metadata.gz: 1d7f69b1680ffc9cc8d30435da870ed50411d02ac285ab8b98f98f4fd8f9b3e07bf3b228904f5dc5ea03a987e4b37de398e99d50e8679f833682a0ecba8f632a
7
+ data.tar.gz: 35ff2212eccbb3fbb2141f7aa7ec1c6d6de4ae77f3e2289ce8d99b11ff5d657d967a25367e5710e0f1fa13f0e7cff2a6f525b13ce68b82b933a7113b16146b10
data/bin/rbbt CHANGED
@@ -102,6 +102,7 @@ end
102
102
 
103
103
  if options[:config_keys]
104
104
  options[:config_keys].split(",").each do |config|
105
+ config = config.strip
105
106
  Rbbt::Config.process_config config
106
107
  end
107
108
  end
@@ -152,6 +152,7 @@ module Annotated
152
152
  tsv = TSV.setup({}, :key_field => "List", :fields => fields, :type => :list, :unnamed => true)
153
153
 
154
154
  annot_id = annotations.id
155
+ annot_id = annot_id * "," if Array === annot_id
155
156
  tsv[annot_id] = annotations.tsv_values(*fields).dup
156
157
 
157
158
  when Array === annotations
data/lib/rbbt/entity.rb CHANGED
@@ -197,7 +197,7 @@ module Entity
197
197
  if self.instance_variable_get("@multiple_result_" + name.to_s)
198
198
  return self.instance_variable_get("@multiple_result_" + name.to_s)
199
199
  end
200
- raise MultipleEntity, "Entity #{name} runs with multiple entities"
200
+ raise MultipleEntity, "Entity property #{name} runs with multiple entities"
201
201
  end
202
202
 
203
203
  define_method name do |*args|
@@ -225,10 +225,12 @@ module Entity
225
225
  case res
226
226
  when Array
227
227
  missing.zip(res).each do |o,res|
228
+ raise "Multiple function #{name} result nil for element #{o}" if res.nil?
228
229
  o.instance_variable_set("@multiple_result_" + name.to_s, res)
229
230
  end
230
231
  when Hash
231
232
  res.each do |o,res|
233
+ raise "Multiple function #{name} result nil for element #{o}" if res.nil?
232
234
  o.instance_variable_set("@multiple_result_" + name.to_s, res)
233
235
  end
234
236
  end
@@ -254,7 +256,10 @@ module Entity
254
256
 
255
257
  orig_method_name = method_name
256
258
  multi_name = "_multiple_" + method_name.to_s
259
+ single_name = "_single_" + method_name.to_s
260
+
257
261
  method_name = multi_name if self.instance_methods.include?(multi_name.to_sym)
262
+ method_name = single_name if self.instance_methods.include?(single_name.to_sym)
258
263
 
259
264
  orig_name = UNPERSISTED_PREFIX + method_name.to_s
260
265
  alias_method orig_name, method_name unless self.instance_methods.include? orig_name.to_sym
@@ -95,14 +95,15 @@ module HPC
95
95
 
96
96
  task = Symbol === job.overriden ? job.overriden : job.task_name
97
97
 
98
- if job.overriden
99
- override_deps = job.rec_dependencies.
100
- select{|dep| Symbol === dep.overriden }.
98
+ if job.overriden?
99
+ #override_deps = job.rec_dependencies.
100
+ # select{|dep| Symbol === dep.overriden }.
101
+
102
+ override_deps = job.overriden_deps.
101
103
  collect do |dep|
102
-
103
104
  name = [dep.workflow.to_s, dep.task_name] * "#"
104
105
  [name, dep.path] * "="
105
- end * ","
106
+ end.uniq * ","
106
107
 
107
108
  options[:override_deps] = override_deps unless override_deps.empty?
108
109
  end
@@ -138,7 +139,7 @@ EOF
138
139
 
139
140
  keys = [
140
141
  :batch_dir,
141
- :batch_modules,
142
+ :lua_modules,
142
143
  :batch_name,
143
144
  :contain,
144
145
  :contain_and_sync,
@@ -156,10 +157,16 @@ EOF
156
157
  :singularity_ruby_inline,
157
158
  :sync,
158
159
  :task_cpus,
160
+ :gres,
161
+ :mem,
162
+ :mem_per_cpu,
163
+ :licenses,
164
+ :contraints,
159
165
  :time,
160
166
  :user_group,
161
167
  :wipe_container,
162
168
  :workdir,
169
+ :purge_deps
163
170
  ]
164
171
 
165
172
  keys.each do |key|
@@ -283,7 +290,7 @@ let MAX_MEMORY="$(grep MemTotal /proc/meminfo|grep -o "[[:digit:]]*") / 1024"
283
290
  end
284
291
 
285
292
  def prepare_environment(options = {})
286
- modules = options[:batch_modules]
293
+ modules = options[:lua_modules]
287
294
 
288
295
  prepare_environment = ""
289
296
 
@@ -378,9 +385,9 @@ echo "user_scratch: #{scratch_group_dir}/#{user}/{PKGDIR}/{TOPLEVEL}/{SUBPATH}"
378
385
  end
379
386
 
380
387
  def execute(options)
381
- exec_cmd, job_cmd = options.values_at :exec_cmd, :rbbt_cmd
388
+ exec_cmd, job_cmd, task_cpus = options.values_at :exec_cmd, :rbbt_cmd, :task_cpus
382
389
 
383
- <<-EOF
390
+ script=<<-EOF
384
391
  step_path=$(
385
392
  #{exec_cmd} #{job_cmd} --printpath
386
393
  )
@@ -388,7 +395,10 @@ exit_status=$?
388
395
 
389
396
  [[ -z $BATCH_JOB_ID ]] || #{exec_cmd} workflow write_info --recursive --force=false --check_pid "$step_path" batch_job $BATCH_JOB_ID
390
397
  [[ -z $BATCH_SYSTEM ]] || #{exec_cmd} workflow write_info --recursive --force=false --check_pid "$step_path" batch_system $BATCH_SYSTEM
398
+ #{exec_cmd} workflow write_info --recursive --force=false --check_pid "$step_path" batch_cpus #{task_cpus}
391
399
  EOF
400
+
401
+ script
392
402
  end
393
403
 
394
404
  def sync_environment(options = {})
@@ -409,6 +419,13 @@ fi
409
419
 
410
420
  def cleanup_environment(options = {})
411
421
  cleanup_environment = ""
422
+
423
+ cleanup_environment +=<<-EOF if options[:purge_deps]
424
+ if [ $exit_status == '0' ]; then
425
+ #{options[:exec_cmd]} workflow forget_deps --purge --recursive_purge "$step_path" 2>1 >> '#{options[:fsync]}'
426
+ fi
427
+ EOF
428
+
412
429
  if options[:sync]
413
430
  if options[:wipe_container] == 'force'
414
431
  cleanup_environment +=<<-EOF
@@ -97,6 +97,7 @@ module HPC
97
97
  chains[job] ||= []
98
98
  chains[job] << dep
99
99
  chains[job].concat chains[dep] if chains[dep]
100
+ chains[job].uniq!
100
101
  end
101
102
 
102
103
  chains
@@ -28,6 +28,12 @@ export BATCH_SYSTEM=SLURM
28
28
  workdir = Misc.process_options options, :workdir
29
29
  exclusive = Misc.process_options options, :exclusive
30
30
  highmem = Misc.process_options options, :highmem
31
+ licenses = Misc.process_options options, :licenses
32
+ constraint = Misc.process_options options, :constraint
33
+ gres = Misc.process_options options, :gres
34
+
35
+ mem = Misc.process_options options, :mem
36
+ mem_per_cpu = Misc.process_options options, :mem_per_cpu
31
37
 
32
38
  batch_dir = Misc.process_options options, :batch_dir
33
39
  batch_name = Misc.process_options options, :batch_name
@@ -37,20 +43,35 @@ export BATCH_SYSTEM=SLURM
37
43
 
38
44
  time = Misc.format_seconds Misc.timespan(time) unless time.include? ":"
39
45
 
46
+ sbatch_params = {"job-name" => batch_name,
47
+ "output" => fout,
48
+ "error" => ferr,
49
+ "cpus-per-task" => task_cpus,
50
+ "nodes" => nodes,
51
+ "time" => time,
52
+ "exclusive" => exclusive,
53
+ "licenses" => licenses,
54
+ "gres" => gres,
55
+ "mem" => mem,
56
+ "mem-per-cpu" => mem_per_cpu,
57
+ }
58
+
40
59
  header =<<-EOF
41
60
  #!/bin/bash
42
- #SBATCH --job-name="#{batch_name}"
43
- #SBATCH --workdir="#{workdir}"
44
- #SBATCH --output="#{fout}"
45
- #SBATCH --error="#{ferr}"
46
- #SBATCH --qos="#{queue}"
47
- #SBATCH --cpus-per-task="#{task_cpus}"
48
- #SBATCH --time="#{time}"
49
- #SBATCH --nodes="#{nodes}"
50
61
  EOF
51
62
 
52
- header << "#SBATCH --exclusive" << "\n" if exclusive
53
- header << "#SBATCH --constraint=highmem" << "\n" if highmem
63
+ sbatch_params.each do |name,value|
64
+ next if value.nil? || value == ""
65
+ if TrueClass === value
66
+ header << "#SBATCH --#{name}" << "\n"
67
+ elsif Array === value
68
+ value.each do |v|
69
+ header << "#SBATCH --#{name}=\"#{v}\"" << "\n"
70
+ end
71
+ else
72
+ header << "#SBATCH --#{name}=\"#{value}\"" << "\n"
73
+ end
74
+ end
54
75
 
55
76
  header
56
77
  end
@@ -148,11 +148,7 @@ module Persist
148
148
  def write_lock
149
149
  write if closed?
150
150
  if write?
151
- begin
152
- return yield
153
- ensure
154
- close
155
- end
151
+ return yield
156
152
  end
157
153
 
158
154
  lock do
data/lib/rbbt/resource.rb CHANGED
@@ -4,10 +4,10 @@ require 'rbbt/resource/path'
4
4
  require 'net/http'
5
5
  require 'set'
6
6
 
7
-
8
7
  module Resource
9
8
  class ResourceNotFound < RbbtException; end
10
9
 
10
+
11
11
  class << self
12
12
  attr_accessor :lock_dir
13
13
 
@@ -87,12 +87,21 @@ module Resource
87
87
  lock_filename = nil # it seems like this was locked already.
88
88
 
89
89
  Misc.lock lock_filename do
90
- uri = URI(url)
90
+ begin
91
+ uri = URI(url)
92
+
93
+ http = Net::HTTP.new(uri.host, uri.port)
91
94
 
92
- http = Net::HTTP.new(uri.host, uri.port)
93
- request = Net::HTTP::Get.new(uri.request_uri)
94
- timeout = 60 * 10
95
- Net::HTTP.start(uri.host, uri.port, :timeout => timeout, :read_timeout => timeout, :open_timeout => timeout) do |http|
95
+ if uri.scheme == "https"
96
+ http.use_ssl = true
97
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
98
+ http.instance_variable_set("@ssl_options", OpenSSL::SSL::OP_NO_SSLv2 + OpenSSL::SSL::OP_NO_SSLv3 + OpenSSL::SSL::OP_NO_COMPRESSION)
99
+ end
100
+
101
+ timeout = 60 * 10
102
+ http.read_timeout = timeout
103
+ http.open_timeout = timeout
104
+ request = Net::HTTP::Get.new(uri.request_uri)
96
105
  http.request request do |response|
97
106
  filename = if response["Content-Disposition"]
98
107
  response["Content-Disposition"].split(";").select{|f| f.include? "filename"}.collect{|f| f.split("=").last.gsub('"','')}.first
@@ -123,9 +132,11 @@ module Resource
123
132
  FileUtils.mv tmp_dir, final_path
124
133
  end
125
134
  else
126
- Open.open(location, :nocache => true) do |s|
127
- Misc.sensiblewrite(final_path, s)
128
- end
135
+ url = location
136
+ raise TryAgain
137
+ #Open.open(location, :nocache => true) do |s|
138
+ # Misc.sensiblewrite(final_path, s)
139
+ #end
129
140
  end
130
141
  when Net::HTTPInternalServerError
131
142
  @server_missing_resource_cache << url
@@ -134,6 +145,8 @@ module Resource
134
145
  raise "Response not understood: #{response.inspect}"
135
146
  end
136
147
  end
148
+ rescue TryAgain
149
+ retry
137
150
  end
138
151
  end
139
152
  rescue
data/lib/rbbt/tsv/csv.rb CHANGED
@@ -28,10 +28,10 @@ module TSV
28
28
  if Misc.is_filename?(obj)
29
29
  CSV.read obj, options
30
30
  else
31
- CSV.new obj, options
31
+ CSV.new obj, **options
32
32
  end
33
33
  else
34
- CSV.new obj, options
34
+ CSV.new obj, **options
35
35
  end
36
36
 
37
37
  tsv = if noheaders
@@ -174,6 +174,8 @@ module TSV
174
174
  if Hash === @monitor
175
175
  desc = @monitor[:desc] if @monitor.include? :desc
176
176
  step = @monitor[:step] if @monitor.include? :step
177
+ elsif String === @monitor
178
+ desc = @monitor
177
179
  end
178
180
  progress_monitor = Log::ProgressBar.new_bar(size, :desc => desc)
179
181
  end
@@ -97,12 +97,11 @@ module TSV
97
97
  end
98
98
  end
99
99
  rescue
100
- Log.exception $!
101
100
  error = true
102
101
  raise $!
103
102
  ensure
104
103
  join.call(error) if join
105
- Log::ProgressBar.remove_bar(bar) if bar
104
+ Log::ProgressBar.remove_bar(bar, error) if bar
106
105
  end
107
106
  end
108
107
 
@@ -138,7 +137,7 @@ module TSV
138
137
  raise $!
139
138
  ensure
140
139
  join.call(error) if join
141
- Log::ProgressBar.remove_bar(bar) if bar
140
+ Log::ProgressBar.remove_bar(bar, error) if bar
142
141
  end
143
142
  end
144
143
 
@@ -178,7 +177,7 @@ module TSV
178
177
  raise $!
179
178
  ensure
180
179
  join.call(error) if join
181
- Log::ProgressBar.remove_bar(bar) if bar
180
+ Log::ProgressBar.remove_bar(bar, error) if bar
182
181
  end
183
182
  end
184
183
 
@@ -220,7 +219,7 @@ module TSV
220
219
  raise $!
221
220
  ensure
222
221
  join.call(error) if join
223
- Log::ProgressBar.remove_bar(bar) if bar
222
+ Log::ProgressBar.remove_bar(bar, error) if bar
224
223
  end
225
224
  end
226
225
 
@@ -274,7 +273,7 @@ module TSV
274
273
  raise $!
275
274
  ensure
276
275
  join.call(error) if join
277
- Log::ProgressBar.remove_bar(bar) if bar
276
+ Log::ProgressBar.remove_bar(bar, error) if bar
278
277
  end
279
278
  end
280
279
 
@@ -319,7 +318,7 @@ module TSV
319
318
  raise $!
320
319
  ensure
321
320
  join.call(error) if join
322
- Log::ProgressBar.remove_bar(bar) if bar
321
+ Log::ProgressBar.remove_bar(bar, error) if bar
323
322
  end
324
323
  end
325
324
 
@@ -491,9 +490,7 @@ module TSV
491
490
  q.join
492
491
  raise $!
493
492
  ensure
494
- if bar
495
- Log::ProgressBar.remove_bar(bar, error)
496
- end
493
+ Log::ProgressBar.remove_bar(bar, error) if bar
497
494
  end
498
495
  end
499
496
 
data/lib/rbbt/util/R.rb CHANGED
@@ -41,7 +41,7 @@ source('#{UTIL}');
41
41
 
42
42
  if monitor
43
43
  #io = CMD.cmd('R --no-save --quiet', options.merge(:in => cmd, :pipe => true, :log => true))
44
- io = CMD.cmd('R --no-save --quiet', options.merge(:in => cmd, :pipe => true, :log => true, :xvfb => true))
44
+ io = CMD.cmd('R --no-save --quiet', options.merge(:in => cmd, :pipe => true, :log => true, :xvfb => options[:xvfb]))
45
45
  while line = io.gets
46
46
  case monitor
47
47
  when Proc
@@ -52,7 +52,7 @@ source('#{UTIL}');
52
52
  end
53
53
  nil
54
54
  else
55
- CMD.cmd('R --no-save --slave --quiet', options.merge(:in => cmd, :xvfb => true))
55
+ CMD.cmd('R --no-save --slave --quiet', options.merge(:in => cmd, :xvfb => options[:xvfb]))
56
56
  end
57
57
  end
58
58
 
data/lib/rbbt/util/cmd.rb CHANGED
@@ -192,25 +192,47 @@ module CMD
192
192
 
193
193
  ConcurrentStream.setup sout, :pids => pids, :autojoin => no_wait, :no_fail => no_fail
194
194
 
195
- err_thread = Thread.new do
196
- while line = serr.gets
197
- bar.process(line) if bar
198
- sout.log = line
199
- Log.log "STDERR [#{pid}]: " + line, stderr
200
- end if Integer === stderr and log
201
- serr.close
195
+ if (Integer === stderr and log) || bar
196
+ err_thread = Thread.new do
197
+ while line = serr.gets
198
+ bar.process(line) if bar
199
+ sout.log = line
200
+ Log.log "STDERR [#{pid}]: " + line, stderr if log
201
+ end
202
+ serr.close
203
+ end
204
+ else
205
+ err_thread = Misc.consume_stream(serr, true)
202
206
  end
203
207
 
204
208
  sout.threads = [in_thread, err_thread, wait_thr].compact
205
209
 
206
210
  sout
207
211
  else
208
- err = ""
209
- err_thread = Thread.new do
210
- while not serr.eof?
211
- err << serr.gets if Integer === stderr
212
+
213
+ if bar
214
+ err = ""
215
+ err_thread = Thread.new do
216
+ while not serr.eof?
217
+ line = serr.gets
218
+ bar.process(line)
219
+ err << line if Integer === stderr and log
220
+ end
221
+ serr.close
212
222
  end
213
- serr.close
223
+ elsif log and Integer === stderr
224
+ err = ""
225
+ err_thread = Thread.new do
226
+ while not serr.eof?
227
+ err << serr.gets
228
+ end
229
+ serr.close
230
+ end
231
+ else
232
+ Misc.consume_stream(serr, true)
233
+ #serr.close
234
+ err_thread = nil
235
+ err = ""
214
236
  end
215
237
 
216
238
  ConcurrentStream.setup sout, :pids => pids, :threads => [in_thread, err_thread].compact, :autojoin => no_wait, :no_fail => no_fail
@@ -220,7 +242,11 @@ module CMD
220
242
 
221
243
  status = wait_thr.value
222
244
  if not status.success? and not no_fail
223
- raise ProcessFailed.new "Command [#{pid}] #{cmd} failed with error status #{status.exitstatus}.\n#{err}"
245
+ if !err.empty?
246
+ raise ProcessFailed.new "Command [#{pid}] #{cmd} failed with error status #{status.exitstatus}.\n#{err}"
247
+ else
248
+ raise ProcessFailed.new "Command [#{pid}] #{cmd} failed with error status #{status.exitstatus}"
249
+ end
224
250
  else
225
251
  Log.log err, stderr if Integer === stderr and log
226
252
  end
@@ -263,11 +289,6 @@ module CMD
263
289
  if c == "\n"
264
290
  bar.process(line) if bar
265
291
  starting = true
266
- #if pid
267
- # Log.logn "STDOUT [#{pid}]: ", level
268
- #else
269
- # Log.logn "STDOUT: ", level
270
- #end
271
292
  line = "" if bar
272
293
  end
273
294
  end