rbbt-util 5.34.1 → 5.34.4

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: dce81f37830228a43c702909b856ebf661002d17b49614d67b6c04e16d339d4b
4
- data.tar.gz: d7cb5ef82e50da2287c4bf9cf3912d66e36c27bb72a1c1c702d86cf7d1e8df78
3
+ metadata.gz: eda1db070a45b3361a0c5c6b02fd59e39b031ae4264771f015e4068a888d1f09
4
+ data.tar.gz: 0f9a4bfafce4180f1db402510f83a880e22f5a75d92bf7506781801ce61575a2
5
5
  SHA512:
6
- metadata.gz: fd9ad6b40180ef8cdc5a8e8335f291e557543f14cdd0cbc6760e7dd6f1327a5a73b5be92b1c037ccd46bca8596c86e7bf6eb7221989e9edac52ad34e81ad4e45
7
- data.tar.gz: 72798bb53863c93aa768edc6c523d34e682dc374ebf4fe0307590faddb9022237a49f0556de364e7139345b35504b6d19b9c134abf8d0ae751a38c1d2c0331f7
6
+ metadata.gz: 7738b49efed37124e80b5aa72b367e9d92d32dc13d64fceef5c452e5b50687882d5bc03106aa906c7f425937ceac72694f8eb8959e2c9d3402164b8618c4c639
7
+ data.tar.gz: de617b931b585915e029f8f23124b6ce5cccc9091dec25e2fc3fdd8c4d2eaf4e23bfce798c73b753cb08f590933c316ceb7deffafd8e8aca854ea175d5744014
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2013 Miguel Vázquez García
1
+ Copyright (c) 2010-2022 Miguel Vázquez García
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -86,6 +86,8 @@ module Association
86
86
  info_fields = field_pos.collect{|f| f == :key ? :key : all_fields[f]}
87
87
  options = options.merge({:key_field => source_field, :fields => info_fields})
88
88
 
89
+ fields = field_headers if fields.nil?
90
+
89
91
  data = options[:data] || {}
90
92
  TmpFile.with_file do |tmpfile|
91
93
  tmp_data = Persist.open_database(tmpfile, true, :double, "HDB")
@@ -24,7 +24,7 @@ module Association
24
24
  options = options.dup
25
25
  data.serializer = :double if data.respond_to? :serializer
26
26
 
27
- tsv = Association.database(file, options.merge(:persist => true, :unnamed => true, :data => data, :type => :double))
27
+ tsv = Association.database(file, options.merge(:unnamed => true, :data => data, :type => :double))
28
28
 
29
29
  data
30
30
  end
data/lib/rbbt/resource.rb CHANGED
@@ -346,9 +346,12 @@ url='#{url}'
346
346
  locations = (Path::STANDARD_SEARCH + resource.search_order + resource.search_paths.keys)
347
347
  locations -= [:current, "current"]
348
348
  locations << :current
349
+ search_paths = IndiferentHash.setup(resource.search_paths)
349
350
  locations.uniq.each do |name|
350
- pattern = resource.search_paths[name]
351
+ pattern = search_paths[name]
352
+ pattern = resource.search_paths[pattern] while Symbol === pattern
351
353
  next if pattern.nil?
354
+
352
355
  pattern = pattern.sub('{PWD}', Dir.pwd)
353
356
  if String === pattern and pattern.include?('{')
354
357
  regexp = "^" + pattern.gsub(/{([^}]+)}/,'(?<\1>[^/]+)') + "(?:/(?<REST>.*))?/?$"
@@ -696,7 +696,7 @@ module TSV
696
696
 
697
697
  options[:join] = Proc.new do |error|
698
698
  error = false if error.nil?
699
- Log::ProgressBar.remove_bar(bar, error)
699
+ Log::ProgressBar.remove_bar(bar, error) if bar
700
700
  end if bar
701
701
 
702
702
  options[:callback] = Proc.new do |e|
@@ -650,7 +650,7 @@ module TSV
650
650
  end
651
651
  end
652
652
  ensure
653
- Log::ProgressBar.remove_bar(progress_monitor)
653
+ Log::ProgressBar.remove_bar(progress_monitor) if progress_monitor
654
654
  stream.close unless stream.closed?
655
655
  stream.join if stream.respond_to? :join and not stream.joined?
656
656
  end
@@ -65,11 +65,17 @@ module Log
65
65
 
66
66
  thr = 0.0000001 if thr == 0
67
67
 
68
- if mean.nil? or mean.to_i > 1
68
+ if mean.nil? or mean.to_i > 2
69
69
  str = "#{ Log.color :blue, thr.to_i.to_s } per sec."
70
70
  #str << " #{ Log.color :yellow, mean.to_i.to_s } avg. #{Log.color :yellow, @mean_max.to_i.to_s} max." if @mean_max > 0
71
71
  else
72
- str = "#{ Log.color :blue, (1/thr).ceil.to_s } secs each"
72
+ if 1.0/thr < 1
73
+ str = "#{ Log.color :blue, (1.0/thr).round(2).to_s } secs each"
74
+ elsif 1.0/thr < 2
75
+ str = "#{ Log.color :blue, (1.0/thr).round(1).to_s } secs each"
76
+ else
77
+ str = "#{ Log.color :blue, (1/thr).ceil.to_s } secs each"
78
+ end
73
79
  #str << " #{ Log.color :yellow, (1/mean).ceil.to_s } avg. #{Log.color :yellow, (1/@mean_max).ceil.to_s} min." if @mean_max > 0
74
80
  end
75
81
 
@@ -184,6 +190,7 @@ module Log
184
190
  @last_time = Time.now
185
191
  @last_count = ticks
186
192
  @last_percent = percent if max and max > 0
193
+ Log::LAST.replace "progress"
187
194
  save if file
188
195
  end
189
196
 
@@ -1,7 +1,8 @@
1
1
  class RbbtException < StandardError; end
2
2
  class ParameterException < RbbtException; end
3
- class FieldNotFoundError < RbbtException;end
4
- class ClosedStream < RbbtException; end
3
+
4
+ class FieldNotFoundError < StandardError;end
5
+ class ClosedStream < StandardError; end
5
6
 
6
7
  class ProcessFailed < StandardError;
7
8
  def initialize(pid = Process.pid)
@@ -26,7 +27,7 @@ end
26
27
  class SemaphoreInterrupted < TryAgain; end
27
28
  class LockInterrupted < TryAgain; end
28
29
 
29
- class RemoteServerError < RbbtException; end
30
+ class RemoteServerError < StandardError; end
30
31
 
31
32
  class DependencyError < Aborted
32
33
  def initialize(msg)
@@ -298,6 +298,8 @@ module Misc
298
298
  str = case obj
299
299
  when nil
300
300
  'nil'
301
+ when Numeric
302
+ obj.to_f
301
303
  when Symbol
302
304
  obj.to_s
303
305
  when TrueClass
@@ -420,7 +420,7 @@ module Misc
420
420
  end
421
421
 
422
422
  Open.touch path if Open.exists? path
423
- content.join if content.respond_to? :join and not (content.respond_to?(:joined?) and content.joined?)
423
+ content.join if content.respond_to?(:join) and not Path === content and not (content.respond_to?(:joined?) && content.joined?)
424
424
 
425
425
  Open.notify_write(path)
426
426
  rescue Aborted
@@ -22,7 +22,7 @@ module NamedArray
22
22
  def self.setup(array, fields, key = nil, entity_options = nil, entity_templates = nil)
23
23
  return array if array.nil?
24
24
  array.extend NamedArray unless NamedArray === array
25
- array.fields = Annotated.purge fields
25
+ array.fields = Annotated === fields ? Annotated.purge(fields) : fields
26
26
  array.key = key
27
27
  array.entity_options = entity_options unless entity_options.nil?
28
28
  array.entity_templates = entity_templates unless entity_templates.nil?
@@ -4,6 +4,35 @@ require 'pycall/import'
4
4
  module RbbtPython
5
5
  extend PyCall::Import
6
6
 
7
+ def self.script(text, options = {})
8
+ Log.debug "Running python script:\n#{text.dup}"
9
+ text = StringIO.new text unless IO === text
10
+ CMD.cmd_log(:python, options.merge(:in => text))
11
+ end
12
+
13
+ def self.add_path(path)
14
+ self.run 'sys' do
15
+ sys.path.append path
16
+ end
17
+ end
18
+
19
+ def self.add_paths(paths)
20
+ self.run 'sys' do
21
+ paths.each do |path|
22
+ sys.path.append path
23
+ end
24
+ end
25
+ end
26
+
27
+ def self.init_rbbt
28
+ if ! defined?(@@__init_rbbt) || ! @@__init_rbbt
29
+ Log.debug "Loading python 'rbbt' module into pycall RbbtPython module"
30
+ RbbtPython.add_paths(Rbbt.python.find_all)
31
+ RbbtPython.pyimport("rbbt")
32
+ @@__init_rbbt = true
33
+ end
34
+ end
35
+
7
36
  def self.exec(script)
8
37
  PyCall.exec(script)
9
38
  end
@@ -63,7 +92,9 @@ module RbbtPython
63
92
 
64
93
  def self.run_log(mod = nil, imports = nil, severity = 0, severity_err = nil, &block)
65
94
  if mod
66
- if Array === imports
95
+ if imports == "*" || imports == ["*"]
96
+ pyfrom mod
97
+ elsif Array === imports
67
98
  pyfrom mod, :import => imports
68
99
  elsif Hash === imports
69
100
  pyimport mod, imports
@@ -92,21 +123,4 @@ module RbbtPython
92
123
  module_eval(&block)
93
124
  end
94
125
  end
95
-
96
- def self.add_path(path)
97
- self.run 'sys' do
98
- sys.path.append path
99
- end
100
- end
101
-
102
- def self.add_paths(paths)
103
- self.run 'sys' do
104
- paths.each do |path|
105
- sys.path.append path
106
- end
107
- end
108
- end
109
-
110
- RbbtPython.add_paths Rbbt.python.find_all
111
- RbbtPython.pyimport "rbbt"
112
126
  end
@@ -22,8 +22,13 @@ module Workflow
22
22
  :extension => nil)
23
23
 
24
24
 
25
- def helper(name, &block)
26
- helpers[name] = block
25
+ def helper(name, *args, &block)
26
+ if block_given?
27
+ helpers[name] = block
28
+ else
29
+ raise RbbtException, "helper #{name} unkown in #{self} workflow" unless helpers[name]
30
+ helpers[name].call(*args)
31
+ end
27
32
  end
28
33
 
29
34
  def desc(description)
@@ -71,6 +71,7 @@ module Workflow
71
71
 
72
72
  def setup_override_dependency(dep, workflow, task_name)
73
73
  return [] if dep == :skip || dep == 'skip'
74
+
74
75
  dep = Step === dep ? dep.dup : Workflow.load_step(dep)
75
76
 
76
77
  dep.original_workflow ||= dep.workflow if dep.workflow
@@ -230,7 +230,14 @@ class Step
230
230
  if dep_step[step.path] and dep_step[step.path].length > 1
231
231
  stream = step.result
232
232
  other_steps = dep_step[step.path].uniq.reject{|d| d.overriden }
233
+
234
+ other_steps = other_steps.collect{|d|
235
+ deps_using_step_input = d.rec_dependencies.select{|d| d.inputs.include? step }
236
+ deps_using_step_input.any? ? deps_using_step_input : d
237
+ }.flatten.uniq
238
+
233
239
  return unless other_steps.length > 1
240
+
234
241
  log_dependency_exec(step, "duplicating #{other_steps.length}")
235
242
  copies = Misc.tee_stream_thread_multiple(stream, other_steps.length)
236
243
  copies.extend StreamArray
@@ -370,7 +377,6 @@ class Step
370
377
  end
371
378
 
372
379
  def run_dependencies
373
- dep_step = {}
374
380
 
375
381
  rec_dependencies = self.rec_dependencies(true) + input_dependencies
376
382
 
@@ -385,23 +391,30 @@ class Step
385
391
 
386
392
  canfail_paths = self.canfail_paths
387
393
 
394
+ dep_step = {}
388
395
  seen_paths = Set.new
389
396
  all_deps.uniq.each do |step|
390
397
  next if seen_paths.include? step.path
391
398
  seen_paths << step.path
399
+
392
400
  begin
393
401
  Step.prepare_for_execution(step) unless step == self
394
402
  rescue DependencyError, DependencyRbbtException
395
403
  raise $! unless canfail_paths.include? step.path
396
404
  end
405
+
397
406
  next unless step.dependencies and step.dependencies.any?
398
- (step.dependencies + step.input_dependencies).each do |step_dep|
407
+
408
+ # ToDo is this really necessary
409
+ #(step.dependencies + step.input_dependencies).each do |step_dep|
410
+ step.dependencies.each do |step_dep|
399
411
  next unless step.dependencies.include?(step_dep)
400
412
  next if step_dep.done? or step_dep.running? or
401
413
  (ComputeDependency === step_dep and (step_dep.compute == :nodup or step_dep.compute == :ignore))
402
414
  dep_step[step_dep.path] ||= []
403
415
  dep_step[step_dep.path] << step
404
416
  end
417
+
405
418
  end
406
419
 
407
420
  produced = []
@@ -125,86 +125,6 @@ module Workflow
125
125
  inputs = task_inputs_from_directory(task_name, directory)
126
126
  job(task_name, jobname, inputs)
127
127
  end
128
-
129
- #def self.load_inputs_old(dir, input_names, input_types)
130
- # inputs = {}
131
- # if File.exists?(dir) && ! File.directory?(dir)
132
- # Log.debug "Loading inputs from #{dir}, not a directory trying as tar.gz"
133
- # tarfile = dir
134
- # digest = CMD.cmd("md5sum '#{tarfile}'").read.split(" ").first
135
- # tmpdir = Rbbt.tmp.input_bundle[digest].find
136
- # Misc.untar(tarfile, tmpdir) unless File.exists? tmpdir
137
- # files = tmpdir.glob("*")
138
- # if files.length == 1 && File.directory?(files.first)
139
- # tmpdir = files.first
140
- # end
141
- # load_inputs(tmpdir, input_names, input_types)
142
- # else
143
- # dir = Path.setup(dir.dup)
144
- # input_names.each do |input|
145
- # file = dir[input].find
146
- # file = dir.glob(input.to_s + ".*").reject{|f| f =~ /\.md5$/}.first if file.nil? or not (File.symlink?(file) || file.exists?)
147
- # Log.debug "Trying #{ input }: #{file}"
148
- # next unless file and (File.symlink?(file) || file.exists?)
149
-
150
- # type = input_types[input]
151
-
152
- # type = :io if file.split(".").last == 'as_io'
153
-
154
- # type = :path if file.split(".").last == 'as_path'
155
-
156
- # type = :filename if file.split(".").last == 'as_filename'
157
-
158
- # type = :nofile if file.split(".").last == 'nofile'
159
-
160
- # case type
161
- # when :nofile
162
- # inputs[input.to_sym] = Open.realpath(file)
163
- # when :path
164
- # inputs[input.to_sym] = Open.realpath(Open.read(file).strip)
165
- # when :io
166
- # inputs[input.to_sym] = Open.open(Open.realpath(file))
167
- # when :file, :binary
168
- # Log.debug "Pointing #{ input } to #{file}"
169
- # if file =~ /\.yaml/
170
- # inputs[input.to_sym] = YAML.load(Open.read(file))
171
- # else
172
- # if File.symlink?(file)
173
- # link_target = File.expand_path(File.readlink(file), File.dirname(file))
174
- # inputs[input.to_sym] = link_target
175
- # else
176
- # inputs[input.to_sym] = Open.realpath(file)
177
- # end
178
- # end
179
- # when :text
180
- # Log.debug "Reading #{ input } from #{file}"
181
- # inputs[input.to_sym] = Open.read(file)
182
- # when :array
183
- # Log.debug "Reading array #{ input } from #{file}"
184
- # inputs[input.to_sym] = Open.read(file).split("\n")
185
- # when :tsv
186
- # Log.debug "Opening tsv #{ input } from #{file}"
187
- # inputs[input.to_sym] = TSV.open(file)
188
- # when :boolean
189
- # inputs[input.to_sym] = (file.read.strip == 'true')
190
- # else
191
- # Log.debug "Loading #{ input } from #{file}"
192
- # inputs[input.to_sym] = file.read.strip
193
- # end
194
-
195
- # end
196
- # inputs = IndiferentHash.setup(inputs)
197
-
198
- # dir.glob("*#*").each do |od|
199
- # name = File.basename(od)
200
- # value = Open.read(od)
201
- # Log.debug "Loading override dependency #{ name } as #{value}"
202
- # inputs[name] = value.chomp
203
- # end
204
-
205
- # inputs
206
- # end
207
- #end
208
128
  end
209
129
 
210
130
  class Step
data/share/Rlib/svg.R CHANGED
@@ -20,9 +20,11 @@ rbbt.SVG.extract <- function(plot, size=NULL, prefix=NULL, ...){
20
20
  resolution = 72 * (size/7)
21
21
 
22
22
  if (length(plot$theme) == 0) plot <- plot + theme_light();
23
+
23
24
  if (length(plot$theme$text) == 0) plot <- plot + theme(text = element_text(size=base.size));
24
25
 
25
- plot$theme$text$size = base.size
26
+ if (is.null(plot$theme$text$size))
27
+ plot$theme$text$size = base.size
26
28
 
27
29
  print(plot, type='cairo')
28
30
  mysvg <- grid.export(res=resolution, prefix=prefix, ...)
@@ -114,7 +114,7 @@ TmpFile.with_file do |app_dir|
114
114
  name, _sep, value = pair.partition("=")
115
115
  name = name[1..-1].to_sym if name[0] == ':'
116
116
  value = value.to_i if value =~ /^\d+$/
117
- value = true if value == "true"
117
+ value = true if value.nil? || value == "true"
118
118
  value = false if value == "false"
119
119
  options[name] = value
120
120
  end
@@ -598,14 +598,14 @@ when Step
598
598
  elsif detach
599
599
  exit! 0
600
600
  else
601
- res.join
601
+ res.join if res.running?
602
602
  if %w(float integer string boolean).include?(res.result_type.to_s)
603
603
  out.puts res.load
604
604
  else
605
605
  Open.open(res.path, :mode => 'rb') do |io|
606
606
  Misc.consume_stream(io, false, out)
607
607
  end if Open.exist?(res.path) || Open.remote?(res.path) || Open.ssh?(res.path)
608
- end
608
+ end if res.done?
609
609
  end
610
610
  else
611
611
  if Array === res
@@ -88,8 +88,28 @@ class TestMiscOmics < Test::Unit::TestCase
88
88
  index = Misc.index_BED(io, dir)
89
89
  assert_equal ["2:2"], index["2:220:230"]
90
90
  end
91
+ end
91
92
 
93
+ def test_sort_genomic_locations
94
+ mutations =<<-EOF.split("\n").shuffle
95
+ 1:100:A
96
+ 1:20:A
97
+ 1:300:A
98
+ 2:100:A
99
+ 2:20:A
100
+ 2:300:A
101
+ 10:100:A
102
+ 10:20:A
103
+ 10:300:A
104
+ EOF
105
+ sorted = Misc.sort_mutation_stream(StringIO.new(mutations * "\n")).read.split("\n")
106
+ strict_sorted = Misc.sort_mutation_stream_strict(StringIO.new(mutations * "\n")).read.split("\n")
92
107
 
93
-
108
+ assert sorted.index("1:20:A") < sorted.index("1:100:A")
109
+ assert sorted.index("1:300:A") < sorted.index("10:300:A")
110
+ assert sorted.index("10:300:A") < sorted.index("2:300:A")
111
+ assert strict_sorted.index("1:20:A") < strict_sorted.index("1:100:A")
112
+ assert strict_sorted.index("1:300:A") < strict_sorted.index("10:300:A")
113
+ assert strict_sorted.index("2:300:A") < strict_sorted.index("10:300:A")
94
114
  end
95
115
  end
@@ -107,6 +107,23 @@ row1 A B C
107
107
  assert_equal %w(## ## ## #Row row1 row2 row3), sorted.read.split("\n").collect{|l| l.split(" ").first}
108
108
  end
109
109
 
110
+ def test_sort_long_stream
111
+ text =<<-EOF
112
+ ##
113
+ ##
114
+ ##
115
+ #Row LabelA LabelB LabelC
116
+ row2 AA BB CC
117
+ row3 AAA BBB CCC
118
+ row1 A B C
119
+ EOF
120
+
121
+ s = StringIO.new text + (text.split("\n")[-3..-1] * "\n" + "\n") * 10000
122
+ sorted = Misc.sort_stream(s)
123
+ assert_equal %w(## ## ## #Row row2 row3 row1), text.split("\n").collect{|l| l.split(" ").first}
124
+ assert_equal %w(## ## ## #Row row1 row2 row3), sorted.read.split("\n").collect{|l| l.split(" ").first}
125
+ end
126
+
110
127
  def test_sort_stream2
111
128
  text =<<-EOF
112
129
  ##
@@ -318,7 +335,9 @@ line4
318
335
 
319
336
  TmpFile.with_file do |tmp|
320
337
  #Misc.consume_stream(sout, false, tmp)
321
- Open.write(tmp, sout)
338
+ assert_raise do
339
+ Open.write(tmp, sout)
340
+ end
322
341
  end
323
342
  end
324
343
  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.34.1
4
+ version: 5.34.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miguel Vazquez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-07 00:00:00.000000000 Z
11
+ date: 2022-07-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - ">="
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: method_source
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: '0'
167
181
  description: Utilities for handling tsv files, caches, etc
168
182
  email: miguel.vazquez.g@bsc.es
169
183
  executables: