rbbt-util 5.26.139 → 5.26.140
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/hpc.rb +12 -4
- data/lib/rbbt/util/R/plot.rb +5 -1
- data/lib/rbbt/util/log.rb +9 -0
- data/lib/rbbt/util/misc/format.rb +1 -0
- data/lib/rbbt/util/simpleopt/parse.rb +5 -6
- data/lib/rbbt/workflow/integration/cromwell.rb +71 -0
- data/lib/rbbt/workflow/step/run.rb +1 -1
- data/lib/rbbt/workflow/usage.rb +130 -24
- data/share/rbbt_commands/workflow/cmd +2 -2
- data/share/rbbt_commands/workflow/forget_deps +36 -0
- data/share/rbbt_commands/workflow/task +7 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17c32c77d5d49d16533f6b7454312698a17b58f46c3b6c0fab860da939ecbacc
|
4
|
+
data.tar.gz: fa257ea2c8605343387cc7ac8c114cec37a5d65083886fb681d004a12c407975
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4af9fec39133714dad6c3ebcb604d80e02984ba6bb3e2ced53e898e9a0624001161c8f2e7192d4ac0219994f86fcface0a934c0758368029edc0178111a2b8f
|
7
|
+
data.tar.gz: c27f66921cc667ae476ed3ed2b68a6914d76177258178075af8effb03fb390f6a3102742cf34aad9c0b4c89cbe64792f9ce29ad016500f7901699b9aa6fa7c67
|
data/lib/rbbt/hpc.rb
CHANGED
@@ -221,13 +221,13 @@ EOF
|
|
221
221
|
if contain
|
222
222
|
singularity_exec << %( -C -H "$CONTAINER_DIR" \
|
223
223
|
-B /scratch/tmp \
|
224
|
+
#{ group != user_group ? "-B /gpfs/projects/#{user_group}" : "" } \
|
225
|
+
-B #{scratch_group_dir} \
|
226
|
+
-B #{projects_group_dir} \
|
224
227
|
-B "$SINGULARITY_RUBY_INLINE":"$CONTAINER_DIR/.ruby_inline":rw \
|
225
228
|
-B ~/git:"$CONTAINER_DIR/git":ro \
|
226
229
|
#{Open.exists?('~/.rbbt/software/opt/')? '-B ~/.rbbt/software/opt/:"/opt/":ro' : '' } \
|
227
230
|
-B ~/.rbbt:"$CONTAINER_DIR/home/":ro \
|
228
|
-
#{ group != user_group ? "-B /gpfs/projects/#{user_group}" : "" } \
|
229
|
-
-B #{scratch_group_dir} \
|
230
|
-
-B #{projects_group_dir} \
|
231
231
|
"$SINGULARITY_IMG")
|
232
232
|
exec_cmd << ' TMPDIR="$CONTAINER_DIR/.rbbt/tmp" '
|
233
233
|
else
|
@@ -341,13 +341,21 @@ EOF
|
|
341
341
|
|
342
342
|
# Write exit status to file
|
343
343
|
echo $exit_status > #{fexit}
|
344
|
-
|
344
|
+
EOF
|
345
|
+
if sync
|
346
|
+
coda +=<<-EOF
|
347
|
+
if [ "$sync_es" == '0' ]; then
|
345
348
|
unset sync_es
|
346
349
|
exit $exit_status
|
347
350
|
else
|
348
351
|
exit $sync_es
|
349
352
|
fi
|
350
353
|
EOF
|
354
|
+
else
|
355
|
+
coda +=<<-EOF
|
356
|
+
exit $exit_status
|
357
|
+
EOF
|
358
|
+
end
|
351
359
|
|
352
360
|
template = [header, env, prep, run, coda] * "\n"
|
353
361
|
|
data/lib/rbbt/util/R/plot.rb
CHANGED
@@ -15,6 +15,8 @@ module R
|
|
15
15
|
sources = [:plot, :svg, options[:source]].flatten.compact
|
16
16
|
options.delete :source
|
17
17
|
|
18
|
+
field_classes = options[:field_classes]
|
19
|
+
|
18
20
|
fast = options[:fast]
|
19
21
|
|
20
22
|
if fast
|
@@ -31,6 +33,7 @@ module R
|
|
31
33
|
break
|
32
34
|
end
|
33
35
|
values = [values] unless Array === values
|
36
|
+
|
34
37
|
field_classes = values.collect do |v|
|
35
38
|
v = v.first if Array === v
|
36
39
|
case v
|
@@ -49,7 +52,8 @@ module R
|
|
49
52
|
else
|
50
53
|
":NA"
|
51
54
|
end
|
52
|
-
end
|
55
|
+
end if field_classes.nil?
|
56
|
+
|
53
57
|
if field_classes.any?
|
54
58
|
options[:R_open] ||= "colClasses=c('character'," + field_classes * ", " + ')'
|
55
59
|
else
|
data/lib/rbbt/util/log.rb
CHANGED
@@ -23,12 +23,11 @@ module SOPT
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
while shortcuts.include?(short)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
end
|
26
|
+
while shortcuts.include?(short) && shortcuts[short] != long
|
27
|
+
next_letter = chars.shift
|
28
|
+
next_letter = chars.shift while %w(. - _).include?(next_letter)
|
29
|
+
return nil if next_letter.nil?
|
30
|
+
current << next_letter
|
32
31
|
short = current * ""
|
33
32
|
end
|
34
33
|
|
@@ -0,0 +1,71 @@
|
|
1
|
+
module Workflow
|
2
|
+
|
3
|
+
Rbbt.claim Rbbt.software.opt.jar["cromwell.jar"], :url, "https://github.com/broadinstitute/cromwell/releases/download/48/cromwell-48.jar"
|
4
|
+
Rbbt.claim Rbbt.software.opt.jar["wdltool.jar"], :url, "https://github.com/broadinstitute/wdltool/releases/download/0.14/wdltool-0.14.jar"
|
5
|
+
|
6
|
+
def run_cromwell(file, work_dir, options = {})
|
7
|
+
jar = Rbbt.software.opt.jar["cromwell.jar"].produce.find
|
8
|
+
CMD.cmd_log("java -jar '#{jar}' run '#{file}' --workflow-root='#{work_dir}'", options.merge("add_option_dashes" => true))
|
9
|
+
end
|
10
|
+
|
11
|
+
def load_cromwell(file)
|
12
|
+
jar = Rbbt.software.opt.jar["wdltool.jar"].produce.find
|
13
|
+
inputs = JSON.load(CMD.cmd("java -jar '#{jar}' inputs '#{file}'"))
|
14
|
+
|
15
|
+
workflow_inputs = {}
|
16
|
+
inputs.each do |input,input_type|
|
17
|
+
workflow, task, input_name = input.split(".")
|
18
|
+
workflow_inputs[workflow] ||= {}
|
19
|
+
|
20
|
+
if input_name.nil?
|
21
|
+
input_name = task
|
22
|
+
else
|
23
|
+
input_name = [task, input_name] * "."
|
24
|
+
end
|
25
|
+
|
26
|
+
workflow_inputs[workflow][input_name] = input_type
|
27
|
+
end
|
28
|
+
|
29
|
+
workflow_inputs.each do |workflow,input_list|
|
30
|
+
input_list.each do |input_name,input_type|
|
31
|
+
|
32
|
+
input_type = input_type.split(" ").last.sub('?','')
|
33
|
+
input_type_fixed = case input_type
|
34
|
+
when "File", "file"
|
35
|
+
:file
|
36
|
+
when "Int"
|
37
|
+
:integer
|
38
|
+
when /Array/
|
39
|
+
:array
|
40
|
+
else
|
41
|
+
input_type.downcase.to_sym
|
42
|
+
end
|
43
|
+
|
44
|
+
desc = [workflow, input_name] * "."
|
45
|
+
default = nil
|
46
|
+
input input_name, input_type_fixed, desc, default, :nofile => true
|
47
|
+
end
|
48
|
+
|
49
|
+
task workflow => :string do |*args|
|
50
|
+
cromwell = file
|
51
|
+
options = {}
|
52
|
+
Misc.in_dir(self.files_dir) do
|
53
|
+
options["metadata-output"] = file('metadata.json')
|
54
|
+
options["inputs"] = file('inputs')
|
55
|
+
|
56
|
+
cromwell_inputs = {}
|
57
|
+
self.inputs.to_hash.each do |input, value|
|
58
|
+
next if value.nil?
|
59
|
+
key = [workflow.to_s, input] * "."
|
60
|
+
cromwell_inputs[key] = value
|
61
|
+
end
|
62
|
+
|
63
|
+
Open.write(file('inputs'), cromwell_inputs.to_json )
|
64
|
+
Cromwell.run_cromwell(cromwell, self.files_dir, options)
|
65
|
+
end
|
66
|
+
Open.read(Dir.glob(File.join(files_dir, "/cromwell-executions/#{workflow}/*/call-*/execution/stdout")).first)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/rbbt/workflow/usage.rb
CHANGED
@@ -43,28 +43,100 @@ module Task
|
|
43
43
|
else
|
44
44
|
puts " #{Log.color :yellow, task.name.to_s}:"
|
45
45
|
end
|
46
|
-
puts
|
46
|
+
puts unless Log.compact
|
47
47
|
puts SOPT.input_doc(new_inputs, task.input_types, task.input_descriptions, task.input_defaults, true)
|
48
|
-
puts
|
48
|
+
puts unless Log.compact
|
49
49
|
end
|
50
|
+
puts
|
50
51
|
end
|
51
52
|
|
52
53
|
puts Log.color(:magenta, "Returns: ") << Log.color(:blue, result_type.to_s) << "\n"
|
53
54
|
puts
|
54
|
-
|
55
|
+
|
55
56
|
if selects.any?
|
56
57
|
puts Log.color(:magenta, "Input select options")
|
57
58
|
puts
|
58
59
|
selects.collect{|p| p}.uniq.each do |input,options|
|
59
60
|
puts Log.color(:blue, input.to_s + ": ") << Misc.format_paragraph(options.collect{|o| o.to_s} * ", ") << "\n"
|
60
|
-
puts
|
61
|
+
puts unless Log.compact
|
61
62
|
end
|
63
|
+
puts
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
66
68
|
module Workflow
|
67
|
-
|
69
|
+
|
70
|
+
def dep_tree(name)
|
71
|
+
@dep_tree ||= {}
|
72
|
+
@dep_tree[name] ||= begin
|
73
|
+
dep_tree = {}
|
74
|
+
self.rec_dependencies(name).each do |dep|
|
75
|
+
dep = dep.first if Array === dep && dep.length == 1
|
76
|
+
|
77
|
+
workflow, task = case dep
|
78
|
+
when Array
|
79
|
+
dep.values_at 0, 1
|
80
|
+
when Symbol, String
|
81
|
+
[self, dep]
|
82
|
+
else
|
83
|
+
next
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
key = [workflow, task]
|
88
|
+
|
89
|
+
dep_tree[key] = workflow.dep_tree(task)
|
90
|
+
end
|
91
|
+
dep_tree
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def prov_string(tree)
|
96
|
+
description = ""
|
97
|
+
|
98
|
+
last = nil
|
99
|
+
seen = Set.new
|
100
|
+
tree.collect.to_a.flatten.select{|e| Symbol === e }.each do |task_name|
|
101
|
+
|
102
|
+
child = last && last.include?(task_name)
|
103
|
+
first = last.nil?
|
104
|
+
last = dep_tree(task_name).collect.to_a.flatten.select{|e| Symbol === e}
|
105
|
+
|
106
|
+
next if seen.include?(task_name)
|
107
|
+
|
108
|
+
if child
|
109
|
+
description << "->" << task_name.to_s
|
110
|
+
elsif first
|
111
|
+
description << "" << task_name.to_s
|
112
|
+
else
|
113
|
+
description << ";" << task_name.to_s
|
114
|
+
end
|
115
|
+
end
|
116
|
+
description
|
117
|
+
end
|
118
|
+
|
119
|
+
def prov_tree(tree, offset = 0, seen = [])
|
120
|
+
|
121
|
+
return "" if tree.empty?
|
122
|
+
|
123
|
+
lines = []
|
124
|
+
|
125
|
+
offset_str = " " * offset
|
126
|
+
|
127
|
+
lines << offset_str
|
128
|
+
|
129
|
+
tree.each do |p,dtree|
|
130
|
+
next if seen.include?(p)
|
131
|
+
seen.push(p)
|
132
|
+
workflow, task = p
|
133
|
+
lines << offset_str + [workflow.to_s, task.to_s] * "#" + "\n" + workflow.prov_tree(dtree, offset + 1, seen)
|
134
|
+
end
|
135
|
+
|
136
|
+
lines * "\n"
|
137
|
+
end
|
138
|
+
|
139
|
+
def doc(task = nil, abridge = false)
|
68
140
|
|
69
141
|
if task.nil?
|
70
142
|
puts Log.color :magenta, self.to_s
|
@@ -88,10 +160,27 @@ module Workflow
|
|
88
160
|
end
|
89
161
|
puts
|
90
162
|
|
163
|
+
final = Set.new
|
164
|
+
not_final = Set.new
|
165
|
+
tasks.each do |name,task|
|
166
|
+
tree = dep_tree(name)
|
167
|
+
not_final += tree.keys
|
168
|
+
final << name unless not_final.include?(name)
|
169
|
+
end
|
170
|
+
|
171
|
+
not_final.each do |p|
|
172
|
+
final -= [p.last]
|
173
|
+
end
|
174
|
+
|
91
175
|
tasks.each do |name,task|
|
92
176
|
description = task.description || ""
|
93
177
|
description = description.split("\n\n").first
|
94
|
-
|
178
|
+
|
179
|
+
next if abridge and ! final.include?(name)
|
180
|
+
puts Misc.format_definition_list_item(name.to_s, description, Log.terminal_width, 20, :yellow)
|
181
|
+
|
182
|
+
prov_string = prov_string(dep_tree(name))
|
183
|
+
puts Log.color :blue, " ->" + prov_string if prov_string && ! prov_string.empty?
|
95
184
|
end
|
96
185
|
|
97
186
|
else
|
@@ -106,29 +195,46 @@ module Workflow
|
|
106
195
|
#dependencies = self.rec_dependencies(task_name).collect{|dep_name| Array === dep_name ? dep_name.first.tasks[dep_name[1].to_sym] : self.tasks[dep_name.to_sym]}
|
107
196
|
task.doc(self, self.rec_dependencies(task_name))
|
108
197
|
|
198
|
+
prov_tree = prov_tree(dep_tree(task_name))
|
199
|
+
if prov_tree && ! prov_tree.empty?
|
200
|
+
|
201
|
+
puts Log.color :magenta, "## DEPENDENCY GRAPH (abridged)"
|
202
|
+
puts
|
203
|
+
prov_tree.split("\n").each do |line|
|
204
|
+
next if line.strip.empty?
|
205
|
+
if m = line.match(/^( *)(\w+?)#(\w*)/i)
|
206
|
+
offset, workflow, task_name = m.values_at 1, 2, 3
|
207
|
+
puts [offset, Log.color(:magenta, workflow), "#", Log.color(:yellow, task_name)] * ""
|
208
|
+
else
|
209
|
+
puts Log.color :blue, line
|
210
|
+
end
|
211
|
+
end
|
212
|
+
puts
|
213
|
+
end
|
214
|
+
|
109
215
|
if self.examples.include? task_name
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
end
|
216
|
+
self.examples[task_name].each do |example|
|
217
|
+
|
218
|
+
puts Log.color(:magenta, "Example ") << Log.color(:green, example) + " -- " + Log.color(:blue, example_dir[task_name][example])
|
219
|
+
|
220
|
+
inputs = self.example(task_name, example)
|
221
|
+
|
222
|
+
inputs.each do |input, type, file|
|
223
|
+
case type
|
224
|
+
when :tsv, :array, :text
|
225
|
+
lines = file.read.split("\n")
|
226
|
+
head = lines[0..5].compact * "\n\n"
|
227
|
+
head = head[0..500]
|
228
|
+
puts Misc.format_definition_list_item(input, head, 1000, -1, :blue).gsub(/\n\s*\n/,"\n")
|
229
|
+
puts '...' if lines.length > 6
|
230
|
+
else
|
231
|
+
puts Misc.format_definition_list_item(input, file.read, Log.terminal_width, 20, :blue)
|
127
232
|
end
|
128
|
-
puts
|
129
233
|
end
|
234
|
+
puts
|
130
235
|
end
|
131
236
|
end
|
237
|
+
end
|
132
238
|
end
|
133
239
|
|
134
240
|
def SOPT_str(task)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rbbt-util'
|
4
|
+
require 'rbbt/util/simpleopt'
|
5
|
+
require 'rbbt/workflow'
|
6
|
+
|
7
|
+
$0 = "rbbt #{$previous_commands*" "} #{ File.basename(__FILE__) }" if $previous_commands
|
8
|
+
|
9
|
+
options = SOPT.setup <<EOF
|
10
|
+
|
11
|
+
Make a job forget all its dependencies and archive their meta-data
|
12
|
+
|
13
|
+
$ #{$0} [options] <job_path>
|
14
|
+
|
15
|
+
-h--help Print this help
|
16
|
+
|
17
|
+
EOF
|
18
|
+
if options[:help]
|
19
|
+
if defined? rbbt_usage
|
20
|
+
rbbt_usage
|
21
|
+
else
|
22
|
+
puts SOPT.doc
|
23
|
+
end
|
24
|
+
exit 0
|
25
|
+
end
|
26
|
+
|
27
|
+
path = ARGV[0]
|
28
|
+
|
29
|
+
raise ParameterException, "No path given" if path.nil?
|
30
|
+
step = Workflow.load_step path
|
31
|
+
|
32
|
+
|
33
|
+
iif step.rec_dependencies
|
34
|
+
|
35
|
+
step.archive_deps
|
36
|
+
step.set_info :dependencies, []
|
@@ -15,7 +15,7 @@ def report_options(options)
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def usage(workflow = nil, task = nil, exception=nil)
|
18
|
+
def usage(workflow = nil, task = nil, exception=nil, abridge = false)
|
19
19
|
puts SOPT.doc
|
20
20
|
puts
|
21
21
|
if workflow.nil?
|
@@ -25,7 +25,7 @@ def usage(workflow = nil, task = nil, exception=nil)
|
|
25
25
|
|
26
26
|
if task.nil?
|
27
27
|
workflow.load_tasks if workflow.respond_to? :load_tasks
|
28
|
-
workflow.doc
|
28
|
+
workflow.doc nil, abridge
|
29
29
|
puts
|
30
30
|
puts "E.g. rbbt workflow task #{workflow.to_s} #{workflow.tasks.keys.first.to_s} -h"
|
31
31
|
else
|
@@ -40,7 +40,7 @@ def usage(workflow = nil, task = nil, exception=nil)
|
|
40
40
|
puts Misc.format_paragraph workflow.documentation[:description]
|
41
41
|
end
|
42
42
|
puts
|
43
|
-
workflow.doc(task)
|
43
|
+
workflow.doc(task, abridge)
|
44
44
|
end
|
45
45
|
|
46
46
|
print_error(exception.message, exception.backtrace) if exception
|
@@ -171,6 +171,7 @@ can redo it using the `clean` parameter, this cleans the last step of the task.
|
|
171
171
|
The `recursive_clean` cleans all the job dependency steps recursively.
|
172
172
|
|
173
173
|
-h--help Show this help
|
174
|
+
-ha--abridge Abridge help
|
174
175
|
-wd--workdir* Change the working directory of the workflow
|
175
176
|
-wda--workdir_all* Change the working directory of ALL workflow
|
176
177
|
-as--array_separator* Change the character that separates elements of Arrays, ',', '|', or '\\n' by default
|
@@ -265,14 +266,14 @@ namespace = nil, nil
|
|
265
266
|
|
266
267
|
case
|
267
268
|
when task.nil?
|
268
|
-
usage workflow and exit 0
|
269
|
+
usage workflow, nil, nil, options[:abridge] and exit 0
|
269
270
|
else
|
270
271
|
task_name = task.to_sym
|
271
272
|
begin
|
272
273
|
task = workflow.tasks[task_name]
|
273
274
|
raise Workflow::TaskNotFoundException.new workflow, task_name if task.nil?
|
274
275
|
rescue Workflow::TaskNotFoundException
|
275
|
-
usage workflow
|
276
|
+
usage workflow, nil, nil, options[:abridge]
|
276
277
|
|
277
278
|
puts
|
278
279
|
puts Log.color :magenta, "## Error"
|
@@ -284,7 +285,7 @@ else
|
|
284
285
|
end
|
285
286
|
end
|
286
287
|
|
287
|
-
usage workflow, task and exit 0 if help
|
288
|
+
usage workflow, task, nil, options[:abridge] and exit 0 if help
|
288
289
|
|
289
290
|
name = options.delete(:jobname)
|
290
291
|
|
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.26.
|
4
|
+
version: 5.26.140
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02-
|
11
|
+
date: 2020-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -322,6 +322,7 @@ files:
|
|
322
322
|
- lib/rbbt/workflow/definition.rb
|
323
323
|
- lib/rbbt/workflow/doc.rb
|
324
324
|
- lib/rbbt/workflow/examples.rb
|
325
|
+
- lib/rbbt/workflow/integration/cromwell.rb
|
325
326
|
- lib/rbbt/workflow/integration/nextflow.rb
|
326
327
|
- lib/rbbt/workflow/remote/client.rb
|
327
328
|
- lib/rbbt/workflow/remote/remote_step.rb
|
@@ -414,6 +415,7 @@ files:
|
|
414
415
|
- share/rbbt_commands/workflow/archive_all
|
415
416
|
- share/rbbt_commands/workflow/cmd
|
416
417
|
- share/rbbt_commands/workflow/example
|
418
|
+
- share/rbbt_commands/workflow/forget_deps
|
417
419
|
- share/rbbt_commands/workflow/info
|
418
420
|
- share/rbbt_commands/workflow/init
|
419
421
|
- share/rbbt_commands/workflow/install
|