rbbt-util 5.22.5 → 5.23.0
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 +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
|