rbbt-util 5.22.5 → 5.23.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rbbt/resource/path.rb +2 -2
- data/lib/rbbt/tsv/util.rb +1 -1
- data/lib/rbbt/util/cmd.rb +0 -2
- data/lib/rbbt/util/concurrency/processes.rb +41 -33
- data/lib/rbbt/util/log/progress.rb +5 -0
- data/lib/rbbt/util/misc/concurrent_stream.rb +12 -4
- data/lib/rbbt/util/misc/omics.rb +46 -9
- data/lib/rbbt/util/misc/pipes.rb +45 -9
- data/lib/rbbt/util/open.rb +15 -0
- data/lib/rbbt/workflow.rb +17 -2
- data/lib/rbbt/workflow/accessor.rb +54 -4
- data/lib/rbbt/workflow/step/run.rb +1 -1
- data/share/rbbt_commands/workflow/task +1 -1
- data/test/rbbt/test_resource.rb +0 -1
- data/test/rbbt/test_workflow.rb +15 -0
- data/test/rbbt/util/log/test_progress.rb +16 -0
- data/test/rbbt/util/misc/test_omics.rb +0 -1
- data/test/rbbt/util/misc/test_pipes.rb +24 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7397119676c0da57371a52797ef8a3f4dc2bc0a
|
4
|
+
data.tar.gz: 973e8a7c4e2cb6eb960ed2b7c782dae0a615c0ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26497c36b05b98961b845562930dceb399c720ab399c5a71c16ccbefb6e5b9756c407ca4fd1ca5b679ef1fca5ea1c989fd1cd4b28b33d8ae983d82cdcfa99aa8
|
7
|
+
data.tar.gz: 37a2aa35faac67658a57ef32d2ab662968a4a11ba44a6a1174d79cdfd86a4315f8ee2b57b3f870b928a4e7b1138ceb5f81f12b513beff95bf00171839083bc9b
|
data/lib/rbbt/resource/path.rb
CHANGED
@@ -227,12 +227,12 @@ module Path
|
|
227
227
|
compact.select{|file| file.exists? }.uniq
|
228
228
|
end
|
229
229
|
|
230
|
-
def glob_all(caller_lib = nil, search_paths = nil)
|
230
|
+
def glob_all(pattern = nil, caller_lib = nil, search_paths = nil)
|
231
231
|
search_paths ||= @search_paths || SEARCH_PATHS
|
232
232
|
search_paths = search_paths.dup
|
233
233
|
|
234
234
|
search_paths.keys.
|
235
|
-
collect{|where| Dir.glob(find(where, Path.caller_lib_dir, search_paths))}.
|
235
|
+
collect{|where| pattern ? Dir.glob(File.join(find(where, Path.caller_lib_dir, search_paths), pattern)) : Dir.glob(find(where, Path.caller_lib_dir, search_paths)) }.
|
236
236
|
compact.flatten.collect{|file| File.expand_path(file)}.uniq.collect{|path| Path.setup(path, self.resource, self.pkgdir)}
|
237
237
|
end
|
238
238
|
#{{{ Methods
|
data/lib/rbbt/tsv/util.rb
CHANGED
@@ -128,7 +128,7 @@ module TSV
|
|
128
128
|
file.join
|
129
129
|
raise "Aborted stream from Step #{file.path}" if file.aborted?
|
130
130
|
raise "Exception in stream from Step #{file.path}: #{file.messages.last}" if file.error?
|
131
|
-
get_stream(file.path)
|
131
|
+
get_stream(file.path, open_options)
|
132
132
|
end
|
133
133
|
end
|
134
134
|
when Array
|
data/lib/rbbt/util/cmd.rb
CHANGED
@@ -65,10 +65,8 @@ module CMD
|
|
65
65
|
|
66
66
|
if IO === in_content
|
67
67
|
in_content.close if in_content.respond_to?(:close) and not in_content.closed?
|
68
|
-
in_content.join if in_content.respond_to?(:join) and not in_content.joined?
|
69
68
|
end
|
70
69
|
|
71
|
-
|
72
70
|
STDERR.reopen serr.last
|
73
71
|
serr.last.close
|
74
72
|
|
@@ -15,6 +15,10 @@ class RbbtProcessQueue
|
|
15
15
|
@process_mutex = Mutex.new
|
16
16
|
end
|
17
17
|
|
18
|
+
|
19
|
+
ABORT_SIGNAL = :INT
|
20
|
+
CLOSE_SIGNAL = :PIPE
|
21
|
+
|
18
22
|
attr_accessor :callback, :callback_queue, :callback_thread
|
19
23
|
def callback(&block)
|
20
24
|
if block_given?
|
@@ -64,8 +68,9 @@ class RbbtProcessQueue
|
|
64
68
|
|
65
69
|
@master_pid = Process.fork do
|
66
70
|
@close_up = false
|
67
|
-
|
68
|
-
|
71
|
+
|
72
|
+
Signal.trap(CLOSE_SIGNAL) do
|
73
|
+
@close_up = true unless @closing_thread
|
69
74
|
Misc.insist([0,0.01,0.1,0.2,0.5]) do
|
70
75
|
raise TryAgain unless @manager_thread
|
71
76
|
if @manager_thread.alive?
|
@@ -75,6 +80,25 @@ class RbbtProcessQueue
|
|
75
80
|
end
|
76
81
|
end
|
77
82
|
|
83
|
+
Signal.trap(:USR1) do
|
84
|
+
@count += 1
|
85
|
+
@manager_thread.raise TryAgain
|
86
|
+
end
|
87
|
+
|
88
|
+
Signal.trap(:USR2) do
|
89
|
+
@count -= 1
|
90
|
+
@manager_thread.raise TryAgain
|
91
|
+
end
|
92
|
+
|
93
|
+
Signal.trap(ABORT_SIGNAL) do
|
94
|
+
begin
|
95
|
+
@monitor_thread.raise Aborted
|
96
|
+
rescue Exception
|
97
|
+
Log.exception $!
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
|
78
102
|
if @callback_queue
|
79
103
|
Misc.purge_pipes(@queue.swrite,@queue.sread,@callback_queue.swrite, @callback_queue.sread)
|
80
104
|
else
|
@@ -91,15 +115,16 @@ class RbbtProcessQueue
|
|
91
115
|
begin
|
92
116
|
Thread.current["working"] = true
|
93
117
|
if @close_up
|
118
|
+
@close_up = false
|
94
119
|
Log.debug "Closing up process queue #{Process.pid}"
|
95
120
|
@count = 0
|
96
|
-
Thread.new do
|
121
|
+
@closing_thread = Thread.new do
|
97
122
|
Log.debug "Pushing closed stream #{Process.pid}"
|
98
123
|
while true
|
99
124
|
@queue.push ClosedStream.new unless @queue.cleaned
|
125
|
+
break if @processes.empty?
|
100
126
|
end unless @processes.empty?
|
101
127
|
end
|
102
|
-
@close_up = false
|
103
128
|
end
|
104
129
|
|
105
130
|
begin
|
@@ -141,17 +166,6 @@ class RbbtProcessQueue
|
|
141
166
|
end
|
142
167
|
end
|
143
168
|
|
144
|
-
Signal.trap(:USR1) do
|
145
|
-
@count += 1
|
146
|
-
@manager_thread.raise TryAgain
|
147
|
-
end
|
148
|
-
|
149
|
-
Signal.trap(:USR2) do
|
150
|
-
@count -= 1
|
151
|
-
@manager_thread.raise TryAgain
|
152
|
-
end
|
153
|
-
|
154
|
-
|
155
169
|
@callback_queue.close_read if @callback_queue
|
156
170
|
|
157
171
|
num_processes.times do |i|
|
@@ -183,16 +197,12 @@ class RbbtProcessQueue
|
|
183
197
|
end
|
184
198
|
end
|
185
199
|
|
186
|
-
Signal.trap(20) do
|
187
|
-
begin
|
188
|
-
@monitor_thread.raise Aborted.new
|
189
|
-
rescue Exception
|
190
|
-
Log.exception $!
|
191
|
-
end
|
192
|
-
end
|
193
200
|
|
194
201
|
begin
|
195
|
-
|
202
|
+
|
203
|
+
while @monitor_thread.alive?
|
204
|
+
@monitor_thread.join(1)
|
205
|
+
end
|
196
206
|
rescue Exception
|
197
207
|
Log.exception $!
|
198
208
|
end
|
@@ -222,7 +232,7 @@ class RbbtProcessQueue
|
|
222
232
|
rescue Exception
|
223
233
|
Log.warn "Error closing callback: #{$!.message}"
|
224
234
|
end
|
225
|
-
@callback_thread.join
|
235
|
+
@callback_thread.join if @callback_thread && @callback_thread.alive?
|
226
236
|
t.join
|
227
237
|
end
|
228
238
|
|
@@ -240,6 +250,8 @@ class RbbtProcessQueue
|
|
240
250
|
Log.error "Exception joining queue: #{$!.message}"
|
241
251
|
raise $!
|
242
252
|
ensure
|
253
|
+
close_callback if @callback
|
254
|
+
@callback_thread.join if @callback_thread
|
243
255
|
if @join
|
244
256
|
if @join.arity == 1
|
245
257
|
@join.call(error)
|
@@ -253,7 +265,7 @@ class RbbtProcessQueue
|
|
253
265
|
|
254
266
|
def join
|
255
267
|
begin
|
256
|
-
Process.kill
|
268
|
+
Process.kill CLOSE_SIGNAL, @master_pid
|
257
269
|
rescue Errno::ECHILD, Errno::ESRCH
|
258
270
|
Log.debug "Cannot kill #{@master_pid}: #{$!.message}"
|
259
271
|
end
|
@@ -264,20 +276,16 @@ class RbbtProcessQueue
|
|
264
276
|
close_callback if @callback
|
265
277
|
@queue.swrite.close unless @queue.swrite.closed?
|
266
278
|
end
|
267
|
-
|
279
|
+
#@callback_thread.join if @callback_thread
|
268
280
|
self.clean
|
269
281
|
end
|
270
282
|
|
271
283
|
def _abort
|
272
284
|
begin
|
273
|
-
Process.kill
|
285
|
+
Process.kill ABORT_SIGNAL, @master_pid
|
286
|
+
pid, status = Process.waitpid2 @master_pid
|
274
287
|
rescue Errno::ECHILD, Errno::ESRCH
|
275
|
-
Log.
|
276
|
-
end
|
277
|
-
|
278
|
-
begin
|
279
|
-
_join
|
280
|
-
rescue ProcessFailed
|
288
|
+
Log.warn "Cannot kill #{@master_pid}: #{$!.message}"
|
281
289
|
end
|
282
290
|
end
|
283
291
|
|
@@ -18,10 +18,10 @@ module ConcurrentStream
|
|
18
18
|
stream.pids ||= []
|
19
19
|
stream.threads.concat(Array === threads ? threads : [threads]) unless threads.nil?
|
20
20
|
stream.pids.concat(Array === pids ? pids : [pids]) unless pids.nil? or pids.empty?
|
21
|
-
stream.autojoin = autojoin
|
22
|
-
stream.no_fail = no_fail
|
21
|
+
stream.autojoin = autojoin unless autojoin.nil?
|
22
|
+
stream.no_fail = no_fail unless no_fail.nil?
|
23
23
|
|
24
|
-
stream.pair = pair
|
24
|
+
stream.pair = pair unless pair.nil?
|
25
25
|
|
26
26
|
callback = block if block_given?
|
27
27
|
if callback
|
@@ -50,7 +50,7 @@ module ConcurrentStream
|
|
50
50
|
|
51
51
|
stream.filename = filename unless filename.nil?
|
52
52
|
|
53
|
-
stream.lockfile = lockfile
|
53
|
+
stream.lockfile = lockfile unless lockfile.nil?
|
54
54
|
|
55
55
|
stream.aborted = false
|
56
56
|
|
@@ -219,4 +219,12 @@ module ConcurrentStream
|
|
219
219
|
end
|
220
220
|
end
|
221
221
|
|
222
|
+
def raise(exception)
|
223
|
+
threads.each do |thread|
|
224
|
+
thread.raise exception
|
225
|
+
end
|
226
|
+
|
227
|
+
self.abort
|
228
|
+
end
|
229
|
+
|
222
230
|
end
|
data/lib/rbbt/util/misc/omics.rb
CHANGED
@@ -266,9 +266,9 @@ module Misc
|
|
266
266
|
end
|
267
267
|
|
268
268
|
|
269
|
-
def self.
|
269
|
+
def self.sort_mutations_strict(mutations)
|
270
270
|
mutations.collect do |mutation|
|
271
|
-
chr,pos,mut = mutation.split ":"
|
271
|
+
chr, pos, mut = mutation.split ":"
|
272
272
|
chr.sub!(/^chr/i,'')
|
273
273
|
chr = 22 if chr == "Y"
|
274
274
|
chr = 23 if chr == "X"
|
@@ -293,6 +293,10 @@ module Misc
|
|
293
293
|
end.collect{|p| p.last }
|
294
294
|
end
|
295
295
|
|
296
|
+
class << self
|
297
|
+
alias sort_mutations sort_mutations_strict
|
298
|
+
end
|
299
|
+
|
296
300
|
def self.ensembl_server(organism)
|
297
301
|
date = organism.split("/")[1]
|
298
302
|
if date.nil?
|
@@ -302,8 +306,12 @@ module Misc
|
|
302
306
|
end
|
303
307
|
end
|
304
308
|
|
309
|
+
def self.sort_genomic_locations_strict(stream, sep = ":")
|
310
|
+
sort_stream(stream, '#', "-k1,1V -k2,2n -t#{sep}")
|
311
|
+
end
|
312
|
+
|
305
313
|
def self.sort_genomic_locations(stream)
|
306
|
-
sort_stream(stream, '#',
|
314
|
+
sort_stream(stream, '#', "-k1,1 -k2,2n -t#{sep}")
|
307
315
|
end
|
308
316
|
|
309
317
|
def self.intersect_streams_read(io, sep=":")
|
@@ -319,18 +327,46 @@ module Misc
|
|
319
327
|
[line,chr, start, eend, rest]
|
320
328
|
end
|
321
329
|
|
322
|
-
def self.
|
323
|
-
if
|
324
|
-
|
325
|
-
elsif chr1 =~
|
330
|
+
def self.chr_cmp_strict(chr1, chr2)
|
331
|
+
if (m1 = chr1.match(/(\d+)$/)) && (m2 = chr2.match(/(\d+)$/))
|
332
|
+
m1[1].to_i <=> m2[1].to_i
|
333
|
+
elsif chr1 =~ /\d+$/
|
326
334
|
-1
|
327
|
-
elsif chr2 =~
|
335
|
+
elsif chr2 =~ /\d+$/
|
328
336
|
1
|
329
337
|
else
|
330
338
|
chr1 <=> chr2
|
331
339
|
end
|
332
340
|
end
|
333
341
|
|
342
|
+
def self.genomic_location_cmp(gpos1, gpos2, sep = ":")
|
343
|
+
chr1, _sep, pos1 = gpos1.partition(sep)
|
344
|
+
chr2, _sep, pos2 = gpos2.partition(sep)
|
345
|
+
cmp = chr1 <=> chr2
|
346
|
+
case cmp
|
347
|
+
when 0
|
348
|
+
pos1.to_i <=> pos2.to_i
|
349
|
+
else
|
350
|
+
cmp
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def self.genomic_location_cmp_strict(gpos1, gpos2, sep = ":")
|
355
|
+
chr1, _sep, pos1 = gpos1.partition(sep)
|
356
|
+
chr2, _sep, pos2 = gpos2.partition(sep)
|
357
|
+
cmp = chr_cmp_strict(chr1, chr2)
|
358
|
+
case cmp
|
359
|
+
when 0
|
360
|
+
pos1.to_i <=> pos2.to_i
|
361
|
+
else
|
362
|
+
cmp
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
def self.intersect_streams_cmp_chr(chr1, chr2)
|
367
|
+
chr1 <=> chr2
|
368
|
+
end
|
369
|
+
|
334
370
|
def self.intersect_streams(f1, f2, out, sep=":")
|
335
371
|
finish = false
|
336
372
|
return if f1.eof? or f2.eof?
|
@@ -404,7 +440,7 @@ module Misc
|
|
404
440
|
max_size = 0
|
405
441
|
nio = Misc.open_pipe do |sin|
|
406
442
|
while line = io.gets
|
407
|
-
chr, start, eend, id, *rest = line.split("\t")
|
443
|
+
chr, start, eend, id, *rest = line.chomp.split("\t")
|
408
444
|
l = id.length
|
409
445
|
max_size = l if max_size < l
|
410
446
|
chr = chr.sub('chr','')
|
@@ -422,6 +458,7 @@ module Misc
|
|
422
458
|
end
|
423
459
|
|
424
460
|
TSV.traverse tmpfile, :type => :array, :bar => "Creating BED index for #{Misc.fingerprint source}" do |line|
|
461
|
+
next if line.empty?
|
425
462
|
chr, start, eend, id, *rest = line.split("\t")
|
426
463
|
key = [chr, start, eend] * ":"
|
427
464
|
sharder[key] = id
|
data/lib/rbbt/util/misc/pipes.rb
CHANGED
@@ -197,7 +197,10 @@ module Misc
|
|
197
197
|
rescue IOError
|
198
198
|
end
|
199
199
|
|
200
|
+
stream.close unless stream.closed?
|
201
|
+
stream.join if stream.respond_to? :join
|
200
202
|
in_pipes.first.close
|
203
|
+
#Log.medium "Tee done #{Misc.fingerprint stream}"
|
201
204
|
rescue Aborted, Interrupt
|
202
205
|
stream.abort if stream.respond_to? :abort
|
203
206
|
out_pipes.each do |sout|
|
@@ -219,10 +222,11 @@ module Misc
|
|
219
222
|
ConcurrentStream.setup sout, :threads => splitter_thread, :filename => filename, :_pair => stream
|
220
223
|
end
|
221
224
|
|
222
|
-
out_pipes.first
|
225
|
+
main_pipe = out_pipes.first
|
226
|
+
main_pipe.autojoin = true
|
223
227
|
|
224
|
-
|
225
|
-
stream.join
|
228
|
+
main_pipe.callback = Proc.new do
|
229
|
+
stream.join if stream.respond_to? :join
|
226
230
|
in_pipes[1..-1].each do |sin|
|
227
231
|
sin.close unless sin.closed?
|
228
232
|
end
|
@@ -246,7 +250,7 @@ module Misc
|
|
246
250
|
rest
|
247
251
|
end
|
248
252
|
|
249
|
-
def
|
253
|
+
def self.dup_stream(stream)
|
250
254
|
dup_stream_multiple(stream, 1).first
|
251
255
|
end
|
252
256
|
|
@@ -314,6 +318,8 @@ module Misc
|
|
314
318
|
into.close if into and into_close and not into.closed?
|
315
319
|
into.join if into and into_close and into.respond_to?(:joined?) and not into.joined?
|
316
320
|
block.call if block_given?
|
321
|
+
|
322
|
+
#Log.medium "Done consuming stream #{Misc.fingerprint io}"
|
317
323
|
rescue Aborted
|
318
324
|
Log.medium "Consume stream aborted #{Misc.fingerprint io}"
|
319
325
|
io.abort if io.respond_to? :abort
|
@@ -514,7 +520,7 @@ module Misc
|
|
514
520
|
end
|
515
521
|
end
|
516
522
|
|
517
|
-
def self._paste_streams(streams, output, lines = nil, sep = "\t", header = nil)
|
523
|
+
def self._paste_streams(streams, output, lines = nil, sep = "\t", header = nil, &block)
|
518
524
|
output.puts header if header
|
519
525
|
streams = streams.collect do |stream|
|
520
526
|
if defined? Step and Step === stream
|
@@ -542,7 +548,11 @@ module Misc
|
|
542
548
|
sizes = parts.collect{|p| p.nil? ? 0 : p.length }
|
543
549
|
last_min = nil
|
544
550
|
while lines.compact.any?
|
545
|
-
|
551
|
+
if block_given?
|
552
|
+
min = keys.compact.sort(&block).first
|
553
|
+
else
|
554
|
+
min = keys.compact.sort.first
|
555
|
+
end
|
546
556
|
str = []
|
547
557
|
keys.each_with_index do |key,i|
|
548
558
|
case key
|
@@ -576,11 +586,11 @@ module Misc
|
|
576
586
|
end
|
577
587
|
end
|
578
588
|
|
579
|
-
def self.paste_streams(streams, lines = nil, sep = "\t", header = nil)
|
589
|
+
def self.paste_streams(streams, lines = nil, sep = "\t", header = nil, &block)
|
580
590
|
sep ||= "\t"
|
581
591
|
num_streams = streams.length
|
582
592
|
Misc.open_pipe do |sin|
|
583
|
-
self._paste_streams(streams, sin, lines, sep, header)
|
593
|
+
self._paste_streams(streams, sin, lines, sep, header, &block)
|
584
594
|
end
|
585
595
|
end
|
586
596
|
|
@@ -667,11 +677,14 @@ module Misc
|
|
667
677
|
end
|
668
678
|
end
|
669
679
|
|
680
|
+
def self.sort_mutation_stream_strict(stream, sep=":")
|
681
|
+
CMD.cmd("grep '#{sep}' | sort -u | sed 's/^M:/MT:/' | env LC_ALL=C sort -V -k1,1 -k2,2n -k3,3n -t'#{sep}'", :in => stream, :pipe => true, :no_fail => true)
|
682
|
+
end
|
683
|
+
|
670
684
|
def self.sort_mutation_stream(stream, sep=":")
|
671
685
|
CMD.cmd("grep '#{sep}' | sort -u | sed 's/^M:/MT:/' | env LC_ALL=C sort -k1,1 -k2,2n -k3,3n -t'#{sep}'", :in => stream, :pipe => true, :no_fail => true)
|
672
686
|
end
|
673
687
|
|
674
|
-
|
675
688
|
def self.swap_quoted_character(stream, charout="\n", charin=" ", quote='"')
|
676
689
|
io = Misc.open_pipe do |sin|
|
677
690
|
begin
|
@@ -698,4 +711,27 @@ module Misc
|
|
698
711
|
swap_quoted_character(stream, "\n", " ", quote)
|
699
712
|
end
|
700
713
|
|
714
|
+
def self.line_monitor_stream(stream, &block)
|
715
|
+
monitor, out = tee_stream stream
|
716
|
+
monitor_thread = Thread.new do
|
717
|
+
begin
|
718
|
+
while line = monitor.gets
|
719
|
+
block.call line
|
720
|
+
end
|
721
|
+
rescue
|
722
|
+
Log.exception $!
|
723
|
+
monitor.raise $!
|
724
|
+
monitor.close unless monitor.closed?
|
725
|
+
monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
726
|
+
out.raise $! if out.respond_to?(:raise)
|
727
|
+
ensure
|
728
|
+
monitor.close unless monitor.closed?
|
729
|
+
monitor.join if monitor.respond_to?(:join) && ! monitor.aborted?
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
stream.annotate out if stream.respond_to? :annotate
|
734
|
+
ConcurrentStream.setup out, :threads => monitor_thread
|
735
|
+
end
|
736
|
+
|
701
737
|
end
|
data/lib/rbbt/util/open.rb
CHANGED
@@ -236,6 +236,13 @@ module Open
|
|
236
236
|
end
|
237
237
|
end
|
238
238
|
|
239
|
+
def self.mkdir(target)
|
240
|
+
target = target.find if Path === target
|
241
|
+
if not File.exists?(target)
|
242
|
+
FileUtils.mkdir_p target
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
239
246
|
def self.ln_s(source, target, options = {})
|
240
247
|
source = source.find if Path === source
|
241
248
|
target = target.find if Path === target
|
@@ -346,6 +353,14 @@ module Open
|
|
346
353
|
CMD.cmd('zcat', :in => stream, :pipe => true, :no_fail => true, :no_wait => true)
|
347
354
|
end
|
348
355
|
|
356
|
+
def self.gzip(stream)
|
357
|
+
CMD.cmd('gzip', :in => stream, :pipe => true, :no_fail => true, :no_wait => true)
|
358
|
+
end
|
359
|
+
|
360
|
+
def self.bgzip(stream)
|
361
|
+
CMD.cmd('bgzip', :in => stream, :pipe => true, :no_fail => true, :no_wait => true)
|
362
|
+
end
|
363
|
+
|
349
364
|
def self.unzip(stream)
|
350
365
|
TmpFile.with_file(stream.read) do |filename|
|
351
366
|
StringIO.new(CMD.cmd("unzip '{opt}' #{filename}", "-p" => true, :pipe => true).read)
|
data/lib/rbbt/workflow.rb
CHANGED
@@ -299,7 +299,6 @@ module Workflow
|
|
299
299
|
taskname = taskname.to_sym
|
300
300
|
return remote_tasks[taskname].job(taskname, jobname, inputs) if remote_tasks and remote_tasks.include? taskname
|
301
301
|
|
302
|
-
jobname = DEFAULT_NAME if jobname.nil? or jobname.empty?
|
303
302
|
|
304
303
|
task = tasks[taskname]
|
305
304
|
raise "Task not found: #{ taskname }" if task.nil?
|
@@ -326,7 +325,15 @@ module Workflow
|
|
326
325
|
raise ParameterException, "Inputs #{Misc.humanize_list(missing_inputs)} are required but were not provided or are nil"
|
327
326
|
end
|
328
327
|
|
329
|
-
|
328
|
+
if task.input_options
|
329
|
+
jobname_input = task.input_options.select{|i,o| o[:jobname]}.collect{|i,o| i }.first
|
330
|
+
else
|
331
|
+
jobname_input = nil
|
332
|
+
end
|
333
|
+
|
334
|
+
if jobname_input && jobname && inputs[jobname_input].nil?
|
335
|
+
inputs[jobname_input] = jobname
|
336
|
+
end
|
330
337
|
|
331
338
|
real_inputs = {}
|
332
339
|
|
@@ -339,6 +346,14 @@ module Workflow
|
|
339
346
|
real_inputs[k] = v
|
340
347
|
end
|
341
348
|
|
349
|
+
jobname_input_value = inputs[jobname_input] || defaults[jobname_input]
|
350
|
+
if jobname_input && jobname.nil? && String === jobname_input_value && ! jobname_input_value.include?('/')
|
351
|
+
jobname = jobname_input_value
|
352
|
+
end
|
353
|
+
|
354
|
+
jobname = DEFAULT_NAME if jobname.nil? or jobname.empty?
|
355
|
+
|
356
|
+
dependencies = real_dependencies(task, jobname, defaults.merge(inputs), task_dependencies[taskname] || [])
|
342
357
|
overriden = dependencies.select{|dep| dep.overriden }.any?
|
343
358
|
|
344
359
|
if real_inputs.empty? and not Workflow::TAG == :inputs and not overriden
|
@@ -325,12 +325,14 @@ class Step
|
|
325
325
|
|
326
326
|
def exception(ex, msg = nil)
|
327
327
|
ex_class = ex.class.to_s
|
328
|
-
|
329
|
-
|
328
|
+
backtrace = ex.backtrace if ex.respond_to?(:backtrace)
|
329
|
+
message = ex.message if ex.respond_to?(:message)
|
330
|
+
set_info :backtrace, backtrace
|
331
|
+
set_info :exception, {:class => ex_class, :message => message, :backtrace => backtrace}
|
330
332
|
if msg.nil?
|
331
|
-
log :error, "#{ex_class} -- #{
|
333
|
+
log :error, "#{ex_class} -- #{message}"
|
332
334
|
else
|
333
|
-
log :error, "#{msg} -- #{
|
335
|
+
log :error, "#{msg} -- #{message}"
|
334
336
|
end
|
335
337
|
self._abort
|
336
338
|
end
|
@@ -575,6 +577,53 @@ class Step
|
|
575
577
|
end
|
576
578
|
end
|
577
579
|
|
580
|
+
def monitor_stream(stream, options = {}, &block)
|
581
|
+
case options[:bar]
|
582
|
+
when TrueClass
|
583
|
+
bar = progress_bar
|
584
|
+
when Hash
|
585
|
+
bar = progress_bar options[:bar]
|
586
|
+
when Numeric
|
587
|
+
bar = progress_bar :max => options[:bar]
|
588
|
+
else
|
589
|
+
bar = options[:bar]
|
590
|
+
end
|
591
|
+
|
592
|
+
out = if bar.nil?
|
593
|
+
Misc.line_monitor_stream stream, &block
|
594
|
+
elsif (block.nil? || block.arity == 0)
|
595
|
+
Misc.line_monitor_stream stream do
|
596
|
+
bar.tick
|
597
|
+
end
|
598
|
+
elsif block.arity == 1
|
599
|
+
Misc.line_monitor_stream stream do |line|
|
600
|
+
bar.tick
|
601
|
+
block.call line
|
602
|
+
end
|
603
|
+
elsif block.arity == 2
|
604
|
+
Misc.line_monitor_stream stream do |line|
|
605
|
+
block.call line, bar
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
ConcurrentStream.setup(out, :abort_callback => Proc.new{
|
610
|
+
Log::ProgressBar.remove_bar(bar, true) if bar
|
611
|
+
}, :callback => Proc.new{
|
612
|
+
Log::ProgressBar.remove_bar(bar) if bar
|
613
|
+
})
|
614
|
+
|
615
|
+
bgzip = (options[:compress] || options[:gzip]).to_s == 'bgzip'
|
616
|
+
bgzip = true if options[:bgzip]
|
617
|
+
|
618
|
+
gzip = true if options[:compress] || options[:gzip]
|
619
|
+
if bgzip
|
620
|
+
Open.bgzip(out)
|
621
|
+
elsif gzip
|
622
|
+
Open.gzip(out)
|
623
|
+
else
|
624
|
+
out
|
625
|
+
end
|
626
|
+
end
|
578
627
|
end
|
579
628
|
|
580
629
|
module Workflow
|
@@ -1040,4 +1089,5 @@ module Workflow
|
|
1040
1089
|
[exec_exports, synchronous_exports, asynchronous_exports, stream_exports].compact.flatten.uniq
|
1041
1090
|
end
|
1042
1091
|
|
1092
|
+
|
1043
1093
|
end
|
@@ -354,7 +354,7 @@ class Step
|
|
354
354
|
ConcurrentStream.setup stream, :callback => callback, :abort_callback => abort_callback
|
355
355
|
|
356
356
|
if AbortedStream === stream
|
357
|
-
exception = stream.exception || Aborted
|
357
|
+
exception = stream.exception || Aborted.new("Aborted stream: #{Misc.fingerprint stream}")
|
358
358
|
self.exception exception
|
359
359
|
_clean_finished
|
360
360
|
raise exception
|
data/test/rbbt/test_resource.rb
CHANGED
data/test/rbbt/test_workflow.rb
CHANGED
@@ -124,12 +124,27 @@ for this dependency
|
|
124
124
|
step(:t1).load + step(:t2).load
|
125
125
|
end
|
126
126
|
|
127
|
+
input :name, :string, "Name", nil, :jobname => true
|
128
|
+
task :call_name => :string do |name|
|
129
|
+
"Hi #{name}"
|
130
|
+
end
|
131
|
+
|
127
132
|
end
|
128
133
|
|
129
134
|
TestWF.workdir = Rbbt.tmp.test.workflow
|
130
135
|
|
131
136
|
class TestWorkflow < Test::Unit::TestCase
|
132
137
|
|
138
|
+
def test_as_jobname
|
139
|
+
job = TestWF.job(:call_name, "Miguel")
|
140
|
+
assert_equal "Hi Miguel", job.run
|
141
|
+
assert_equal "Miguel", job.clean_name
|
142
|
+
|
143
|
+
job = TestWF.job(:call_name, nil, :name => "Miguel")
|
144
|
+
assert_equal "Hi Miguel", job.run
|
145
|
+
assert_equal "Miguel", job.clean_name
|
146
|
+
end
|
147
|
+
|
133
148
|
def test_update_on_input_dependency_update
|
134
149
|
send_input_dep_to_reverse_job = TestWF.job(:send_input_dep_to_reverse, nil, :name => "Miguel")
|
135
150
|
send_input_dep_to_reverse_job.clean
|
@@ -68,7 +68,23 @@ class TestProgress < Test::Unit::TestCase
|
|
68
68
|
sleep 0.2
|
69
69
|
end
|
70
70
|
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_pos
|
74
|
+
size = 10000
|
71
75
|
|
76
|
+
Log::ProgressBar.with_bar(size, :desc => "Bar 1") do |bar|
|
77
|
+
bar.init
|
78
|
+
nums = []
|
79
|
+
100.times do
|
80
|
+
nums << rand(size)
|
81
|
+
end
|
82
|
+
nums.sort.each do |num|
|
83
|
+
bar.pos num
|
84
|
+
sleep 0.1
|
85
|
+
end
|
86
|
+
bar.tick
|
87
|
+
end
|
72
88
|
end
|
73
89
|
|
74
90
|
end
|
@@ -131,13 +131,17 @@ row2 AA BB CC
|
|
131
131
|
row3 AAA BBB CCC
|
132
132
|
row1 A B C
|
133
133
|
EOF
|
134
|
+
Log.severity = 0
|
134
135
|
|
135
136
|
text = text * 10000
|
136
137
|
TmpFile.with_file(text) do |tmp|
|
137
138
|
io = Open.open(tmp)
|
138
139
|
dup = Misc.dup_stream(io)
|
139
|
-
|
140
|
-
|
140
|
+
new_text = StringIO.new ""
|
141
|
+
Misc.consume_stream dup, true, new_text
|
142
|
+
Misc.consume_stream io, false
|
143
|
+
new_text.rewind
|
144
|
+
assert_equal text, new_text.read
|
141
145
|
end
|
142
146
|
|
143
147
|
|
@@ -244,7 +248,25 @@ line4
|
|
244
248
|
out.rewind
|
245
249
|
assert_equal text, out.read
|
246
250
|
end
|
251
|
+
end
|
247
252
|
|
253
|
+
def test_monitor
|
254
|
+
text =<<-EOF
|
255
|
+
line1
|
256
|
+
line2
|
257
|
+
line3
|
258
|
+
line4
|
259
|
+
EOF
|
248
260
|
|
261
|
+
Log.severity = 0
|
262
|
+
TmpFile.with_file(text) do |file|
|
263
|
+
io = Open.open(file)
|
264
|
+
lines = Set.new
|
265
|
+
io2 = Misc.line_monitor_stream io do |line|
|
266
|
+
lines << line
|
267
|
+
end
|
268
|
+
Misc.consume_stream(io2, false)
|
269
|
+
assert_equal text, lines.to_a * ""
|
270
|
+
end
|
249
271
|
end
|
250
272
|
end
|
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.
|
4
|
+
version: 5.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Miguel Vazquez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|