rbbt-util 5.41.0 → 5.42.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/hpc/batch.rb +2 -1
- data/lib/rbbt/tsv/change_id.rb +6 -3
- data/lib/rbbt/tsv.rb +1 -0
- data/lib/rbbt/util/R.rb +1 -1
- data/lib/rbbt/util/config.rb +1 -1
- data/lib/rbbt/util/log.rb +4 -0
- data/lib/rbbt/util/named_array.rb +1 -1
- data/lib/rbbt/util/open.rb +6 -2
- data/lib/rbbt/workflow/definition.rb +2 -0
- data/lib/rbbt/workflow/integration/nextflow.rb +98 -20
- data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +14 -15
- data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +9 -9
- data/lib/rbbt/workflow/step/info.rb +11 -2
- data/lib/rbbt/workflow.rb +1 -1
- data/share/Rlib/util.R +22 -4
- data/share/config.ru +1 -1
- data/share/rbbt_commands/resource/find +1 -1
- data/share/rbbt_commands/tsv/get +20 -4
- data/share/rbbt_commands/workflow/task +3 -3
- data/share/workflow_config.ru +0 -1
- data/test/rbbt/resource/test_path.rb +2 -2
- data/test/rbbt/tsv/test_accessor.rb +19 -0
- data/test/rbbt/util/test_open.rb +9 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b23de77e3900d1a81e8ffa349ab9f88a4283f30bb2cec62c04bff4539243170
|
4
|
+
data.tar.gz: 494b18d5e2ba4802225617a03b2f69255ec9deab173e8d18e06654a7b415325c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d57bd3bc7ff84a4e8101dd907f98ef20923dbcab95c3187523e6b84eba6774d900f269ed2457fd6e1a81821edf3e2d1f11fcbdd5863f791282d549bcf83a48a5
|
7
|
+
data.tar.gz: a4857d82292ab4234cf10fbf2fcb242b466e6400f9476cb4de4bc625ff808542a690f27fbd9dede4ff692a82644561ebfc086ccdf953102cb4f7a0020b094849
|
data/lib/rbbt/hpc/batch.rb
CHANGED
@@ -15,6 +15,7 @@ module HPC
|
|
15
15
|
when 'pbs'
|
16
16
|
HPC::PBS
|
17
17
|
when 'auto'
|
18
|
+
$previous_commands = [] if $previous_commands.nil?
|
18
19
|
case $previous_commands.last
|
19
20
|
when 'slurm'
|
20
21
|
HPC::SLURM
|
@@ -735,7 +736,7 @@ env > #{batch_options[:fenv]}
|
|
735
736
|
end
|
736
737
|
|
737
738
|
def job_queued(job)
|
738
|
-
job_status(job).split(
|
739
|
+
job_status(job).split(/[\s\.]+/).include?(job.to_s)
|
739
740
|
end
|
740
741
|
|
741
742
|
def wait_for_job(batch_dir, time = 1)
|
data/lib/rbbt/tsv/change_id.rb
CHANGED
@@ -8,8 +8,8 @@ module TSV
|
|
8
8
|
|
9
9
|
identifiers, persist_input = Misc.process_options options, :identifiers, :persist_input
|
10
10
|
|
11
|
-
identifiers = Organism.identifiers(tsv.namespace) if identifiers.nil?
|
12
|
-
|
11
|
+
identifiers = Organism.identifiers(tsv.namespace) if identifiers.nil? && tsv.namespace &&
|
12
|
+
defined?(Organism) && Organism.identifiers(tsv.namespace).exists?
|
13
13
|
|
14
14
|
if ! tsv.fields.include?(format)
|
15
15
|
new = {}
|
@@ -58,7 +58,10 @@ module TSV
|
|
58
58
|
|
59
59
|
identifiers, persist_input, compact = Misc.process_options options, :identifiers, :persist, :compact
|
60
60
|
identifiers = tsv.identifier_files.first if identifiers.nil?
|
61
|
-
|
61
|
+
|
62
|
+
identifiers = Organism.identifiers(tsv.namespace) if identifiers.nil? && tsv.namespace &&
|
63
|
+
defined?(Organism) && Organism.identifiers(tsv.namespace).exists?
|
64
|
+
|
62
65
|
identifiers.namespace ||= tsv.namespace
|
63
66
|
|
64
67
|
fields = (identifiers and identifiers.all_fields.include?(field))? [field] : nil
|
data/lib/rbbt/tsv.rb
CHANGED
@@ -69,6 +69,7 @@ module TSV
|
|
69
69
|
options = TSV.str2options(options) if String === options and options.include? "~"
|
70
70
|
options ||= {}
|
71
71
|
options[:type] ||= type unless type.nil?
|
72
|
+
options[:zipped] = true if options[:one2one]
|
72
73
|
|
73
74
|
persist_options = Misc.pull_keys options, :persist
|
74
75
|
|
data/lib/rbbt/util/R.rb
CHANGED
data/lib/rbbt/util/config.rb
CHANGED
@@ -18,7 +18,7 @@ module Rbbt::Config
|
|
18
18
|
Log.debug "Loading config file: #{ file }"
|
19
19
|
TSV.traverse file, :type => :array do |line|
|
20
20
|
next if line =~ /^#/
|
21
|
-
key, value, *tokens = line.strip.split(/\s
|
21
|
+
key, value, *tokens = line.strip.split(/\s+/)
|
22
22
|
|
23
23
|
self.add_entry(key, value, tokens) if key
|
24
24
|
end
|
data/lib/rbbt/util/log.rb
CHANGED
data/lib/rbbt/util/open.rb
CHANGED
@@ -101,7 +101,6 @@ module Open
|
|
101
101
|
|
102
102
|
CMD.cmd("wget '#{ url }'", wget_options)
|
103
103
|
rescue
|
104
|
-
STDERR.puts $!.backtrace.inspect
|
105
104
|
raise OpenURLError, "Error reading remote url: #{ url }.\n#{$!.message}"
|
106
105
|
end
|
107
106
|
end
|
@@ -654,7 +653,12 @@ module Open
|
|
654
653
|
end
|
655
654
|
|
656
655
|
def self.download(url, path)
|
657
|
-
|
656
|
+
begin
|
657
|
+
Open.wget(url, "--output-document" => path, :pipe => false)
|
658
|
+
rescue Exception
|
659
|
+
Open.rm(path) if Open.exist?(path)
|
660
|
+
raise $!
|
661
|
+
end
|
658
662
|
end
|
659
663
|
|
660
664
|
def self.can_open?(file)
|
@@ -1,4 +1,47 @@
|
|
1
1
|
module Workflow
|
2
|
+
|
3
|
+
OUTPUT_FIELDS=%w(outdir output)
|
4
|
+
|
5
|
+
def self.parse_nextflow_schema(file)
|
6
|
+
doc = Open.open(file){|f| JSON.parse(f.read) }
|
7
|
+
description = doc["description"]
|
8
|
+
|
9
|
+
properties = {}
|
10
|
+
required = []
|
11
|
+
|
12
|
+
properties[nil] = doc["properties"] if doc["properties"]
|
13
|
+
required.concat doc["required"] if doc["required"]
|
14
|
+
|
15
|
+
doc["definitions"].each do |section,section_info|
|
16
|
+
next unless section_info["properties"]
|
17
|
+
name = section_info["title"] || section
|
18
|
+
properties[name] = section_info["properties"]
|
19
|
+
required.concat section_info["required"] if section_info["required"] if section_info["required"]
|
20
|
+
end if doc["definitions"]
|
21
|
+
|
22
|
+
required = required.compact.flatten
|
23
|
+
|
24
|
+
parameters = {}
|
25
|
+
properties.each do |section,param_info|
|
26
|
+
param_info.each do |name,info|
|
27
|
+
input_options = {}
|
28
|
+
type = info["type"]
|
29
|
+
format = info["format"]
|
30
|
+
input_desc = info["description"]
|
31
|
+
input_section = info["description"]
|
32
|
+
input_required = required.include?(name)
|
33
|
+
input_options[:required] = true if input_required && ! OUTPUT_FIELDS.include?(name)
|
34
|
+
if info.include?("enum")
|
35
|
+
type = 'select'
|
36
|
+
input_options[:select_options] = info["enum"]
|
37
|
+
end
|
38
|
+
parameters[name] = {type: type, format: format, description: input_desc, options: input_options, section: section}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
[description, parameters]
|
43
|
+
end
|
44
|
+
|
2
45
|
def self.nextflow_file_params(file)
|
3
46
|
Open.read(file).scan(/params\.\w+/).collect{|p| p.split(".").last}.uniq
|
4
47
|
end
|
@@ -16,8 +59,11 @@ module Workflow
|
|
16
59
|
included_file += '.nf' unless File.exist?(included_file) || ! File.exist?(included_file + '.nf')
|
17
60
|
name_str.split(";").each do |name|
|
18
61
|
name = name.strip
|
19
|
-
|
20
|
-
|
62
|
+
begin
|
63
|
+
include_params = nextflow_recursive_params(included_file).collect{|p| [p,name] * "-"}
|
64
|
+
params += include_params
|
65
|
+
rescue
|
66
|
+
end
|
21
67
|
end
|
22
68
|
params
|
23
69
|
end
|
@@ -32,22 +78,31 @@ module Workflow
|
|
32
78
|
result = :text
|
33
79
|
end
|
34
80
|
|
81
|
+
dir = Path.setup(File.dirname(file))
|
82
|
+
|
83
|
+
nextflow_schema = dir['nextflow_schema.json']
|
84
|
+
|
85
|
+
description, params = Workflow.parse_nextflow_schema(nextflow_schema) if nextflow_schema.exists?
|
86
|
+
|
35
87
|
file = file + '.nf' unless File.exist?(file) || ! File.exist?(file + '.nf')
|
36
88
|
file = File.expand_path(file)
|
37
89
|
name ||= File.basename(file).sub(/\.nf$/,'').gsub(/\s/,'_')
|
38
|
-
|
39
|
-
|
40
|
-
params.each do |param|
|
90
|
+
Workflow.nextflow_recursive_params(file).each do |param|
|
41
91
|
p,_sep, section = param.partition("-")
|
42
|
-
if
|
43
|
-
|
44
|
-
else
|
45
|
-
input param, :string, "Nextflow param #{p} from import #{section}", nil, :nofile => true
|
92
|
+
if ! params.include?(p)
|
93
|
+
params[p] = {type: :string, description: "Undocumented"}
|
46
94
|
end
|
47
95
|
end
|
96
|
+
|
97
|
+
used_params = []
|
98
|
+
desc description
|
99
|
+
params.each do |name,info|
|
100
|
+
input name.to_sym, info[:type], info[:description], nil, info[:options].merge(:noload => true)
|
101
|
+
end
|
48
102
|
task name => result do
|
49
103
|
work = file('work')
|
50
104
|
profile = config :profile, :nextflow
|
105
|
+
resume = config :resume, :nextflow
|
51
106
|
config_file = config :config, :nextflow
|
52
107
|
|
53
108
|
nextflow_inputs = {}
|
@@ -68,9 +123,17 @@ module Workflow
|
|
68
123
|
name = f
|
69
124
|
end
|
70
125
|
|
71
|
-
|
126
|
+
case name.to_s
|
127
|
+
when 'outdir'
|
128
|
+
output = nextflow_inputs[name] = v || output || file('output')
|
129
|
+
when 'output'
|
130
|
+
output = nextflow_inputs[name] = v || output || self.tmp_path
|
131
|
+
else
|
132
|
+
nextflow_inputs[name] = v
|
133
|
+
end
|
72
134
|
end
|
73
|
-
|
135
|
+
|
136
|
+
current_pwd = FileUtils.pwd
|
74
137
|
Misc.in_dir file('stage') do
|
75
138
|
|
76
139
|
cmd = "nextflow "
|
@@ -83,19 +146,26 @@ module Workflow
|
|
83
146
|
|
84
147
|
cmd += " -profile #{profile}" if profile
|
85
148
|
|
149
|
+
cmd += " -resume" if resume == 'true'
|
150
|
+
|
151
|
+
Dir.glob(current_pwd + "/*").each do |file|
|
152
|
+
target = File.basename(file)
|
153
|
+
Open.ln_s file, target unless File.exist?(target)
|
154
|
+
end
|
86
155
|
|
87
156
|
cmd("#{cmd} #{file}", nextflow_inputs.merge('add_option_dashes' => true))
|
88
157
|
end
|
89
158
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
159
|
+
if output && Open.exists?(output)
|
160
|
+
if File.directory?(output)
|
161
|
+
Dir.glob(output + "/**/*") * "\n"
|
162
|
+
else
|
163
|
+
output_file = output
|
164
|
+
Open.link output, self.tmp_path
|
165
|
+
nil
|
166
|
+
end
|
95
167
|
else
|
96
|
-
|
97
|
-
#Open.rm_rf file('work')
|
98
|
-
nil
|
168
|
+
work[File.join("*", "*", "*")].glob * "\n"
|
99
169
|
end
|
100
170
|
end
|
101
171
|
end
|
@@ -105,11 +175,19 @@ module Workflow
|
|
105
175
|
nextflow_file main, File.basename(path), output
|
106
176
|
end
|
107
177
|
|
178
|
+
def nextflow_project(project, *args)
|
179
|
+
CMD.cmd_log("nextflow pull #{project}")
|
180
|
+
directory = File.join(ENV["HOME"], '.nextflow/assets', project)
|
181
|
+
nextflow_dir directory, *args
|
182
|
+
end
|
183
|
+
|
108
184
|
def nextflow(path, *args)
|
109
185
|
if File.directory?(path)
|
110
186
|
nextflow_dir path, *args
|
111
|
-
|
187
|
+
elsif File.exist?(path)
|
112
188
|
nextflow_file path, *args
|
189
|
+
else
|
190
|
+
nextflow_project path, *args
|
113
191
|
end
|
114
192
|
end
|
115
193
|
end
|
@@ -136,33 +136,33 @@ STDOUT.write job.path
|
|
136
136
|
Misc.ssh_run(server, script)
|
137
137
|
end
|
138
138
|
|
139
|
-
def self.
|
139
|
+
def self.run_batch_job(url, input_id, jobname = nil, batch_options = {})
|
140
140
|
server, path = parse_url(url)
|
141
141
|
|
142
142
|
script = path_script(path)
|
143
143
|
script += job_script(input_id, jobname)
|
144
144
|
script +=<<-EOF
|
145
145
|
require 'rbbt/hpc'
|
146
|
-
HPC::BATCH_MODULE = HPC.batch_system
|
147
|
-
|
146
|
+
HPC::BATCH_MODULE = HPC.batch_system
|
147
|
+
batch_options = JSON.parse(%q(#{batch_options.to_json}))
|
148
148
|
job.clean if job.error? and job.recoverable_error?
|
149
|
-
HPC::BATCH_MODULE.run_job(job,
|
149
|
+
HPC::BATCH_MODULE.run_job(job, batch_options) unless job.done? || job.error?
|
150
150
|
STDOUT.write job.path
|
151
151
|
EOF
|
152
152
|
Misc.ssh_run(server, script)
|
153
153
|
end
|
154
154
|
|
155
|
-
def self.
|
155
|
+
def self.orchestrate_batch_job(url, input_id, jobname = nil, batch_options = {})
|
156
156
|
server, path = parse_url(url)
|
157
157
|
|
158
158
|
script = path_script(path)
|
159
159
|
script += job_script(input_id, jobname)
|
160
160
|
script +=<<-EOF
|
161
161
|
require 'rbbt/hpc'
|
162
|
-
HPC::BATCH_MODULE = HPC.batch_system
|
163
|
-
|
162
|
+
HPC::BATCH_MODULE = HPC.batch_system
|
163
|
+
batch_options = JSON.parse(%q(#{batch_options.to_json}))
|
164
164
|
job.clean if job.error? and job.recoverable_error?
|
165
|
-
HPC::BATCH_MODULE.orchestrate_job(job,
|
165
|
+
HPC::BATCH_MODULE.orchestrate_job(job, batch_options) unless job.done? || job.error?
|
166
166
|
STDOUT.write job.path
|
167
167
|
EOF
|
168
168
|
Misc.ssh_run(server, script)
|
@@ -268,8 +268,8 @@ job.clean
|
|
268
268
|
end
|
269
269
|
|
270
270
|
def self.relay_job(job, server, options = {})
|
271
|
-
migrate, produce, produce_dependencies, search_path, run_type,
|
272
|
-
:migrate, :produce, :produce_dependencies, :search_path, :run_type, :
|
271
|
+
migrate, produce, produce_dependencies, search_path, run_type, batch_options = Misc.process_options options.dup,
|
272
|
+
:migrate, :produce, :produce_dependencies, :search_path, :run_type, :batch_options
|
273
273
|
|
274
274
|
search_path ||= 'user'
|
275
275
|
|
@@ -287,7 +287,7 @@ job.clean
|
|
287
287
|
rjob.override_dependencies = override_dependencies
|
288
288
|
|
289
289
|
rjob.run_type = run_type
|
290
|
-
rjob.
|
290
|
+
rjob.batch_options = batch_options || {}
|
291
291
|
|
292
292
|
if options[:migrate]
|
293
293
|
rjob.produce
|
@@ -298,8 +298,8 @@ job.clean
|
|
298
298
|
end
|
299
299
|
|
300
300
|
def self.relay_job_list(job_list, server, options = {})
|
301
|
-
migrate, produce, produce_dependencies, search_path, run_type,
|
302
|
-
:migrate, :produce, :produce_dependencies, :search_path, :run_type, :
|
301
|
+
migrate, produce, produce_dependencies, search_path, run_type, batch_options = Misc.process_options options.dup,
|
302
|
+
:migrate, :produce, :produce_dependencies, :search_path, :run_type, :batch_options
|
303
303
|
|
304
304
|
search_path ||= 'user'
|
305
305
|
|
@@ -320,7 +320,7 @@ job.clean
|
|
320
320
|
rjob.override_dependencies = override_dependencies
|
321
321
|
|
322
322
|
rjob.run_type = run_type
|
323
|
-
rjob.
|
323
|
+
rjob.batch_options = batch_options || {}
|
324
324
|
|
325
325
|
rjob.run(true)
|
326
326
|
|
@@ -330,7 +330,6 @@ job.clean
|
|
330
330
|
if options[:migrate]
|
331
331
|
rjobs_job.each do |rjob,job|
|
332
332
|
rjob.produce
|
333
|
-
iif [:migrate, job]
|
334
333
|
Step.migrate(Rbbt.identify(job.path), 'user', :source => server)
|
335
334
|
end
|
336
335
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class RemoteStep
|
2
2
|
module SSH
|
3
|
-
attr_accessor :override_dependencies, :run_type, :
|
3
|
+
attr_accessor :override_dependencies, :run_type, :batch_options, :produce_dependencies
|
4
4
|
|
5
5
|
def init_job(cache_type = nil, other_params = {})
|
6
6
|
return self if @url
|
@@ -22,7 +22,7 @@ class RemoteStep
|
|
22
22
|
|
23
23
|
RemoteWorkflow::SSH.upload_inputs(@server, inputs, @input_types, @input_id)
|
24
24
|
|
25
|
-
@remote_path ||= Persist.memory("
|
25
|
+
@remote_path ||= Persist.memory("RemoteStep", :workflow => self.workflow, :task => task, :jobname => @name, :inputs => inputs, :cache_type => cache_type) do
|
26
26
|
Misc.insist do
|
27
27
|
input_types = {}
|
28
28
|
RemoteWorkflow::SSH.post_job(File.join(base_url, task.to_s), @input_id, @base_name)
|
@@ -56,13 +56,13 @@ class RemoteStep
|
|
56
56
|
RemoteWorkflow::SSH.run_job(File.join(base_url, task.to_s), @input_id, @base_name)
|
57
57
|
end
|
58
58
|
|
59
|
-
def
|
59
|
+
def _run_batch
|
60
60
|
RemoteWorkflow::SSH.upload_dependencies(self, @server, 'user', @produce_dependencies)
|
61
|
-
RemoteWorkflow::SSH.
|
61
|
+
RemoteWorkflow::SSH.run_batch_job(File.join(base_url, task.to_s), @input_id, @base_name, @batch_options || {})
|
62
62
|
end
|
63
63
|
|
64
|
-
def
|
65
|
-
RemoteWorkflow::SSH.
|
64
|
+
def _orchestrate_batch
|
65
|
+
RemoteWorkflow::SSH.orchestrate_batch_job(File.join(base_url, task.to_s), @input_id, @base_name, @batch_options || {})
|
66
66
|
end
|
67
67
|
|
68
68
|
def issue
|
@@ -71,10 +71,10 @@ class RemoteStep
|
|
71
71
|
@remote_path = case @run_type
|
72
72
|
when 'run', :run, nil
|
73
73
|
_run
|
74
|
-
when '
|
75
|
-
|
74
|
+
when 'batch', :batch
|
75
|
+
_run_batch
|
76
76
|
when 'orchestrate', :orchestrate
|
77
|
-
|
77
|
+
_orchestrate_batch
|
78
78
|
end
|
79
79
|
@started = true
|
80
80
|
end
|
@@ -219,7 +219,7 @@ class Step
|
|
219
219
|
Step.log_progress(status, options, file(:progress), &block)
|
220
220
|
end
|
221
221
|
|
222
|
-
def progress_bar(msg = "Progress", options = nil)
|
222
|
+
def progress_bar(msg = "Progress", options = nil, &block)
|
223
223
|
if Hash === msg and options.nil?
|
224
224
|
options = msg
|
225
225
|
msg = nil
|
@@ -227,7 +227,16 @@ class Step
|
|
227
227
|
options = {} if options.nil?
|
228
228
|
|
229
229
|
max = options[:max]
|
230
|
-
Log::ProgressBar.new_bar(max, {:desc => msg, :file => (@exec ? nil : file(:progress))}.merge(options))
|
230
|
+
bar = Log::ProgressBar.new_bar(max, {:desc => msg, :file => (@exec ? nil : file(:progress))}.merge(options))
|
231
|
+
|
232
|
+
if block_given?
|
233
|
+
bar.init
|
234
|
+
res = yield bar
|
235
|
+
bar.remove
|
236
|
+
res
|
237
|
+
else
|
238
|
+
bar
|
239
|
+
end
|
231
240
|
end
|
232
241
|
|
233
242
|
def self.log(status, message, path, &block)
|
data/lib/rbbt/workflow.rb
CHANGED
@@ -496,7 +496,7 @@ module Workflow
|
|
496
496
|
end
|
497
497
|
|
498
498
|
#overriden = true if dependencies.select{|d| d.overriden && d.clean_name != d.name }.any?
|
499
|
-
overriden = true if dependencies.select{|d| Symbol === d.overriden }.any?
|
499
|
+
overriden = true if not_overriden && dependencies.select{|d| Symbol === d.overriden }.any?
|
500
500
|
|
501
501
|
input_values = task.take_input_values(inputs)
|
502
502
|
if real_inputs.empty? && Workflow::TAG != :inputs && ! overriden #&& ! dependencies.select{|d| d.overriden && d.clean_name != d.name }.any?
|
data/share/Rlib/util.R
CHANGED
@@ -646,10 +646,8 @@ rbbt.pheatmap <- function(filename, data, width=800, height=800, take_log=FALSE,
|
|
646
646
|
}
|
647
647
|
|
648
648
|
rbbt.heatmap <- function(filename, data, width=800, height=800, take_log=FALSE, stdize=FALSE, ...){
|
649
|
+
rbbt.require('gplots')
|
649
650
|
opar = par()
|
650
|
-
png(filename=filename, width=width, height=height);
|
651
|
-
|
652
|
-
#par(cex.lab=0.5, cex=0.5, ...)
|
653
651
|
|
654
652
|
data = as.matrix(data)
|
655
653
|
data[is.nan(data)] = NA
|
@@ -657,6 +655,22 @@ rbbt.heatmap <- function(filename, data, width=800, height=800, take_log=FALSE,
|
|
657
655
|
#data = data[rowSums(!is.na(data))!=0, colSums(!is.na(data))!=0]
|
658
656
|
data = data[rowSums(is.na(data))==0, ]
|
659
657
|
|
658
|
+
key.size = 150
|
659
|
+
label.size = 200
|
660
|
+
block.size = 12
|
661
|
+
|
662
|
+
if (height == 'auto'){
|
663
|
+
height = max(c(dim(data)[1], 30)) * block.size + key.size + label.size
|
664
|
+
}
|
665
|
+
|
666
|
+
if (width == 'auto'){
|
667
|
+
width = max(c(dim(data)[2], 30)) * block.size + key.size + label.size
|
668
|
+
}
|
669
|
+
|
670
|
+
png(filename=filename, width=width, height=height);
|
671
|
+
|
672
|
+
#par(cex.lab=0.5, cex=0.5, ...)
|
673
|
+
|
660
674
|
if (take_log){
|
661
675
|
for (study in colnames(data)){
|
662
676
|
skip = sum(data[, study] <= 0) != 0
|
@@ -673,7 +687,11 @@ rbbt.heatmap <- function(filename, data, width=800, height=800, take_log=FALSE,
|
|
673
687
|
data = stdize(data)
|
674
688
|
}
|
675
689
|
|
676
|
-
|
690
|
+
lwid = key.size / (width)
|
691
|
+
lhei = key.size / (height)
|
692
|
+
str(dim(data))
|
693
|
+
str(c(height, lhei, width, lwid))
|
694
|
+
heatmap.2(data, scale='column', lwid = c(lwid, 1-lwid), lhei = c(lhei, 1-lhei), ...)
|
677
695
|
|
678
696
|
dev.off();
|
679
697
|
par(opar)
|
data/share/config.ru
CHANGED
@@ -44,7 +44,7 @@ app_eval app, Rbbt.etc['app.d/remote_workflow_tasks.rb'].find_all
|
|
44
44
|
app_eval app, Rbbt.etc['app.d/base.rb'].find
|
45
45
|
|
46
46
|
#{{{ SINATRA
|
47
|
-
|
47
|
+
app_eval app, Rbbt.lib['sinatra.rb'].find_all
|
48
48
|
|
49
49
|
#{{{ RESOURCES
|
50
50
|
load_file Rbbt.etc['app.d/resources.rb'].find
|
data/share/rbbt_commands/tsv/get
CHANGED
@@ -7,9 +7,10 @@ options = SOPT.setup <<EOF
|
|
7
7
|
|
8
8
|
Query a TSV value
|
9
9
|
|
10
|
-
$ rbbt tsv get [options] <filename.tsv|-> <key>
|
10
|
+
$ rbbt tsv get [options] <filename.tsv|-> [<key>]
|
11
11
|
|
12
|
-
Use - to read from STDIN
|
12
|
+
Use - to read from STDIN, 'key' can be the key string or a number representing
|
13
|
+
its position. If not specified 'key' defaults to 0, the first entry.
|
13
14
|
|
14
15
|
-tch--tokyocabinet File is a tokyocabinet hash database
|
15
16
|
-tcb--tokyocabinet_bd File is a tokyocabinet B database
|
@@ -26,7 +27,7 @@ rbbt_usage and exit 0 if options[:help]
|
|
26
27
|
|
27
28
|
file, key = ARGV
|
28
29
|
|
29
|
-
raise ParameterException, "Please specify file
|
30
|
+
raise ParameterException, "Please specify file" if file.nil?
|
30
31
|
|
31
32
|
file = STDIN if file == '-'
|
32
33
|
|
@@ -48,7 +49,15 @@ key_field = options[:key_field]
|
|
48
49
|
fields = fields.split(/[,|]/, -1) unless fields.nil?
|
49
50
|
|
50
51
|
if TSV === tsv
|
52
|
+
case key
|
53
|
+
when nil
|
54
|
+
key = tsv.keys.first if key.nil?
|
55
|
+
when /^\d+$/
|
56
|
+
key = tsv.keys[key.to_i] unless tsv.include?(key)
|
57
|
+
end
|
58
|
+
|
51
59
|
v = tsv[key]
|
60
|
+
|
52
61
|
fields ||= tsv.fields
|
53
62
|
puts Log.color(:blue, "Key: #{ key }")
|
54
63
|
if fields
|
@@ -72,8 +81,15 @@ end
|
|
72
81
|
parser = TSV::Parser.new tsv, :key_field => key_field, :fields => fields, :type => options[:type], :header_hash => options[:header_hash], :sep => options[:sep]
|
73
82
|
fields ||= parser.fields
|
74
83
|
|
84
|
+
i = 0
|
75
85
|
TSV.traverse(parser) do |k,v|
|
76
|
-
|
86
|
+
if key== "#{i}"
|
87
|
+
key = k.first
|
88
|
+
elsif key.nil?
|
89
|
+
key = k.first
|
90
|
+
end
|
91
|
+
i += 1
|
92
|
+
next unless k.include?(key)
|
77
93
|
k = k.first if Array === k
|
78
94
|
puts Log.color(:blue, "Key: #{ k }")
|
79
95
|
if fields
|
@@ -221,7 +221,7 @@ The `recursive_clean` cleans all the job dependency steps recursively.
|
|
221
221
|
-od--override_deps* Override deps using 'Workflow#task=<path>' array_separated
|
222
222
|
-PERF--procpath_performance* Measure performance using procpath
|
223
223
|
--relay* Relay job to SSH server
|
224
|
-
--
|
224
|
+
--batch_relay* Relay job to SSH BATCH server (SLURM, PBS, etc.)
|
225
225
|
-rdep--relay_dependencies* Relay dependencies instead of main job
|
226
226
|
-pdr--produce_dependencies_for_relay Prepare dependencies previous to relay jobs
|
227
227
|
EOF
|
@@ -493,9 +493,9 @@ begin
|
|
493
493
|
replace_relayed_jobs(jobs_to_relay, server, produce_dependencies_for_relay, :run)
|
494
494
|
end
|
495
495
|
|
496
|
-
if server = options.delete(:
|
496
|
+
if server = options.delete(:batch_relay)
|
497
497
|
require 'rbbt/workflow/remote_workflow'
|
498
|
-
relay_dependencies = options.delete(:relay_dependencies).split(",")
|
498
|
+
relay_dependencies = options.include?(:relay_dependencies) ? options.delete(:relay_dependencies).split(",") : nil
|
499
499
|
produce_dependencies_for_relay = options.delete(:produce_dependencies_for_relay)
|
500
500
|
jobs_to_relay = relay_dependencies ? match_dependencies(relay_dependencies, job.rec_dependencies) : [job]
|
501
501
|
jobs_to_relay.reject!{|d| d.done? }
|
data/share/workflow_config.ru
CHANGED
@@ -38,8 +38,8 @@ class TestTSV < Test::Unit::TestCase
|
|
38
38
|
assert_equal Path.setup(File.join('doc', path)).find(:lib), path.find(:lib).doc_file
|
39
39
|
|
40
40
|
assert_equal "lib/rbbt/resource.rb", path.doc_file.source_for_doc_file
|
41
|
-
assert_equal path.find, path.doc_file.find(:lib).source_for_doc_file
|
42
|
-
assert_equal path.find, path.doc_file.source_for_doc_file.find
|
41
|
+
assert_equal File.realpath(path.find), File.realpath(path.doc_file.find(:lib).source_for_doc_file)
|
42
|
+
assert_equal File.realpath(path.find), File.realpath(path.doc_file.source_for_doc_file.find)
|
43
43
|
|
44
44
|
assert_equal "doc/lib/rbbt/resource.rb.doc", path.doc_file.set_extension('doc')
|
45
45
|
#assert_equal "lib/rbbt/resource.rb", path.doc_file.set_extension('doc').source_for_doc_file
|
@@ -74,6 +74,25 @@ row2 A B Id3
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
+
def test_to_s_no_preable
|
78
|
+
content =<<-EOF
|
79
|
+
#Id ValueA ValueB OtherID
|
80
|
+
row1 a|aa|aaa b Id1|Id2
|
81
|
+
row2 A B Id3
|
82
|
+
EOF
|
83
|
+
|
84
|
+
target =<<-EOF
|
85
|
+
Id,ValueA,ValueB,OtherID
|
86
|
+
row1,a|aa|aaa,b,Id1|Id2
|
87
|
+
row2,A,B,Id3
|
88
|
+
EOF
|
89
|
+
|
90
|
+
TmpFile.with_file(content) do |filename|
|
91
|
+
tsv = TSV.open(filename, :sep => /\s+/)
|
92
|
+
assert_equal tsv.to_s(preamble: false, header_hash: '').gsub(/\t/, ','), target
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
77
96
|
def test_entries
|
78
97
|
content =<<-EOF
|
79
98
|
#Id ValueA ValueB OtherID
|
data/test/rbbt/util/test_open.rb
CHANGED
@@ -187,5 +187,14 @@ class TestOpen < Test::Unit::TestCase
|
|
187
187
|
|
188
188
|
end
|
189
189
|
|
190
|
+
def test_download_fails
|
191
|
+
TmpFile.with_file do |tmp|
|
192
|
+
assert_raise do
|
193
|
+
Open.download("http:fake-host/some_path", tmp)
|
194
|
+
end
|
195
|
+
refute Open.exists?(tmp)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
190
199
|
end
|
191
200
|
|
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.42.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:
|
11
|
+
date: 2024-02-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|