rbbt-util 5.44.1 → 6.0.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.
Files changed (175) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/bin/rbbt +67 -90
  4. data/bin/rbbt_exec.rb +2 -2
  5. data/etc/app.d/base.rb +2 -2
  6. data/etc/app.d/semaphores.rb +3 -3
  7. data/lib/rbbt/annotations/annotated_array.rb +207 -207
  8. data/lib/rbbt/annotations/refactor.rb +27 -0
  9. data/lib/rbbt/annotations/util.rb +282 -282
  10. data/lib/rbbt/annotations.rb +343 -320
  11. data/lib/rbbt/association/database.rb +200 -225
  12. data/lib/rbbt/association/index.rb +294 -291
  13. data/lib/rbbt/association/item.rb +227 -227
  14. data/lib/rbbt/association/open.rb +35 -34
  15. data/lib/rbbt/association/util.rb +0 -169
  16. data/lib/rbbt/association.rb +2 -4
  17. data/lib/rbbt/entity/identifiers.rb +119 -118
  18. data/lib/rbbt/entity/refactor.rb +12 -0
  19. data/lib/rbbt/entity.rb +319 -315
  20. data/lib/rbbt/hpc/batch.rb +72 -53
  21. data/lib/rbbt/hpc/lsf.rb +2 -2
  22. data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
  23. data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
  24. data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
  25. data/lib/rbbt/hpc/orchestrate.rb +19 -13
  26. data/lib/rbbt/hpc/slurm.rb +18 -18
  27. data/lib/rbbt/knowledge_base/entity.rb +13 -5
  28. data/lib/rbbt/knowledge_base/query.rb +2 -2
  29. data/lib/rbbt/knowledge_base/registry.rb +32 -31
  30. data/lib/rbbt/knowledge_base/traverse.rb +1 -1
  31. data/lib/rbbt/knowledge_base.rb +1 -1
  32. data/lib/rbbt/monitor.rb +36 -25
  33. data/lib/rbbt/persist/refactor.rb +166 -0
  34. data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
  35. data/lib/rbbt/persist/tsv.rb +187 -185
  36. data/lib/rbbt/persist.rb +556 -551
  37. data/lib/rbbt/refactor.rb +20 -0
  38. data/lib/rbbt/resource/path/refactor.rb +178 -0
  39. data/lib/rbbt/resource/path.rb +317 -497
  40. data/lib/rbbt/resource/util.rb +0 -48
  41. data/lib/rbbt/resource.rb +3 -390
  42. data/lib/rbbt/tsv/accessor.rb +2 -838
  43. data/lib/rbbt/tsv/attach.rb +303 -299
  44. data/lib/rbbt/tsv/change_id.rb +244 -245
  45. data/lib/rbbt/tsv/csv.rb +87 -85
  46. data/lib/rbbt/tsv/dumper.rb +2 -100
  47. data/lib/rbbt/tsv/excel.rb +26 -24
  48. data/lib/rbbt/tsv/field_index.rb +4 -1
  49. data/lib/rbbt/tsv/filter.rb +3 -2
  50. data/lib/rbbt/tsv/index.rb +2 -284
  51. data/lib/rbbt/tsv/manipulate.rb +750 -747
  52. data/lib/rbbt/tsv/marshal.rb +3 -3
  53. data/lib/rbbt/tsv/matrix.rb +2 -2
  54. data/lib/rbbt/tsv/parallel/through.rb +2 -1
  55. data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
  56. data/lib/rbbt/tsv/parser.rb +678 -678
  57. data/lib/rbbt/tsv/refactor.rb +195 -0
  58. data/lib/rbbt/tsv/stream.rb +253 -251
  59. data/lib/rbbt/tsv/util.rb +420 -420
  60. data/lib/rbbt/tsv.rb +210 -208
  61. data/lib/rbbt/util/R/eval.rb +4 -4
  62. data/lib/rbbt/util/R/plot.rb +62 -166
  63. data/lib/rbbt/util/R.rb +21 -18
  64. data/lib/rbbt/util/cmd.rb +2 -318
  65. data/lib/rbbt/util/color.rb +269 -269
  66. data/lib/rbbt/util/colorize.rb +89 -89
  67. data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
  68. data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
  69. data/lib/rbbt/util/concurrency/processes.rb +389 -386
  70. data/lib/rbbt/util/config.rb +169 -167
  71. data/lib/rbbt/util/filecache.rb +1 -1
  72. data/lib/rbbt/util/iruby.rb +20 -0
  73. data/lib/rbbt/util/log/progress/report.rb +241 -241
  74. data/lib/rbbt/util/log/progress/util.rb +99 -99
  75. data/lib/rbbt/util/log/progress.rb +102 -102
  76. data/lib/rbbt/util/log/refactor.rb +49 -0
  77. data/lib/rbbt/util/log.rb +486 -532
  78. data/lib/rbbt/util/migrate.rb +2 -2
  79. data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
  80. data/lib/rbbt/util/misc/development.rb +12 -11
  81. data/lib/rbbt/util/misc/exceptions.rb +117 -112
  82. data/lib/rbbt/util/misc/format.rb +2 -230
  83. data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
  84. data/lib/rbbt/util/misc/inspect.rb +2 -476
  85. data/lib/rbbt/util/misc/lock.rb +109 -106
  86. data/lib/rbbt/util/misc/omics.rb +9 -1
  87. data/lib/rbbt/util/misc/pipes.rb +765 -793
  88. data/lib/rbbt/util/misc/refactor.rb +20 -0
  89. data/lib/rbbt/util/misc/ssw.rb +27 -17
  90. data/lib/rbbt/util/misc/system.rb +92 -105
  91. data/lib/rbbt/util/misc.rb +39 -20
  92. data/lib/rbbt/util/named_array/refactor.rb +4 -0
  93. data/lib/rbbt/util/named_array.rb +3 -220
  94. data/lib/rbbt/util/open/refactor.rb +7 -0
  95. data/lib/rbbt/util/open.rb +3 -857
  96. data/lib/rbbt/util/procpath.rb +6 -6
  97. data/lib/rbbt/util/python/paths.rb +27 -0
  98. data/lib/rbbt/util/python/run.rb +115 -0
  99. data/lib/rbbt/util/python/script.rb +110 -0
  100. data/lib/rbbt/util/python/util.rb +3 -3
  101. data/lib/rbbt/util/python.rb +22 -81
  102. data/lib/rbbt/util/semaphore.rb +152 -148
  103. data/lib/rbbt/util/simpleopt.rb +9 -8
  104. data/lib/rbbt/util/ssh/refactor.rb +19 -0
  105. data/lib/rbbt/util/ssh.rb +122 -118
  106. data/lib/rbbt/util/tar.rb +117 -115
  107. data/lib/rbbt/util/tmpfile.rb +69 -67
  108. data/lib/rbbt/util/version.rb +2 -0
  109. data/lib/rbbt/workflow/refactor/entity.rb +11 -0
  110. data/lib/rbbt/workflow/refactor/export.rb +66 -0
  111. data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
  112. data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
  113. data/lib/rbbt/workflow/refactor/task_info.rb +66 -0
  114. data/lib/rbbt/workflow/refactor.rb +150 -0
  115. data/lib/rbbt/workflow/remote_workflow/driver/rest.rb +1 -2
  116. data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
  117. data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
  118. data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
  119. data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
  120. data/lib/rbbt/workflow/remote_workflow.rb +6 -1
  121. data/lib/rbbt/workflow/step/run.rb +766 -766
  122. data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
  123. data/lib/rbbt/workflow/step.rb +2 -362
  124. data/lib/rbbt/workflow/task.rb +118 -118
  125. data/lib/rbbt/workflow/usage.rb +289 -287
  126. data/lib/rbbt/workflow/util/archive.rb +6 -5
  127. data/lib/rbbt/workflow/util/data.rb +1 -1
  128. data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
  129. data/lib/rbbt/workflow/util/trace.rb +79 -44
  130. data/lib/rbbt/workflow.rb +4 -882
  131. data/lib/rbbt-util.rb +21 -13
  132. data/lib/rbbt.rb +16 -3
  133. data/python/rbbt/__init__.py +96 -4
  134. data/python/rbbt/workflow/remote.py +104 -0
  135. data/python/rbbt/workflow.py +64 -0
  136. data/python/test.py +10 -0
  137. data/share/Rlib/plot.R +37 -37
  138. data/share/Rlib/svg.R +22 -5
  139. data/share/install/software/lib/install_helpers +1 -1
  140. data/share/rbbt_commands/hpc/list +2 -3
  141. data/share/rbbt_commands/hpc/orchestrate +4 -4
  142. data/share/rbbt_commands/hpc/tail +2 -0
  143. data/share/rbbt_commands/hpc/task +10 -7
  144. data/share/rbbt_commands/lsf/list +2 -3
  145. data/share/rbbt_commands/lsf/orchestrate +4 -4
  146. data/share/rbbt_commands/lsf/tail +2 -0
  147. data/share/rbbt_commands/lsf/task +10 -7
  148. data/share/rbbt_commands/migrate +1 -1
  149. data/share/rbbt_commands/pbs/list +2 -3
  150. data/share/rbbt_commands/pbs/orchestrate +4 -4
  151. data/share/rbbt_commands/pbs/tail +2 -0
  152. data/share/rbbt_commands/pbs/task +10 -7
  153. data/share/rbbt_commands/resource/produce +8 -1
  154. data/share/rbbt_commands/slurm/list +2 -3
  155. data/share/rbbt_commands/slurm/orchestrate +4 -4
  156. data/share/rbbt_commands/slurm/tail +2 -0
  157. data/share/rbbt_commands/slurm/task +10 -7
  158. data/share/rbbt_commands/system/clean +5 -5
  159. data/share/rbbt_commands/system/status +5 -5
  160. data/share/rbbt_commands/tsv/get +2 -3
  161. data/share/rbbt_commands/tsv/info +10 -13
  162. data/share/rbbt_commands/tsv/keys +18 -14
  163. data/share/rbbt_commands/tsv/slice +2 -2
  164. data/share/rbbt_commands/tsv/transpose +6 -2
  165. data/share/rbbt_commands/workflow/info +20 -24
  166. data/share/rbbt_commands/workflow/list +1 -1
  167. data/share/rbbt_commands/workflow/prov +20 -13
  168. data/share/rbbt_commands/workflow/retry +43 -0
  169. data/share/rbbt_commands/workflow/server +12 -2
  170. data/share/rbbt_commands/workflow/task +80 -73
  171. data/share/rbbt_commands/workflow/write_info +26 -9
  172. data/share/software/opt/ssw/ssw.c +861 -0
  173. data/share/software/opt/ssw/ssw.h +130 -0
  174. data/share/workflow_config.ru +3 -3
  175. metadata +45 -6
data/lib/rbbt-util.rb CHANGED
@@ -1,18 +1,26 @@
1
- require 'rbbt'
2
- require 'rbbt/util/misc'
3
- require 'rbbt/util/open'
4
- Open.cachedir = Rbbt.var.cache["open-remote"].find :user
1
+ require_relative 'rbbt'
2
+ require_relative 'rbbt/util/misc'
3
+ require 'scout/open'
4
+ Open.remote_cache_dir = Rbbt.var.cache["open-remote"].find :user
5
5
 
6
- require 'rbbt/persist'
7
- Persist.cachedir = Rbbt.var.cache.persistence
6
+ require 'scout/path'
8
7
 
9
- require 'rbbt/util/filecache'
10
- FileCache.cachedir = Rbbt.var.cache.filecache.find :user
8
+ require 'set'
9
+ require 'scout/persist'
11
10
 
12
- require 'rbbt/util/tmpfile'
13
- TmpFile.tmpdir = Rbbt.tmp.find :user
11
+ require 'scout/resource'
14
12
 
15
- require 'rbbt/util/cmd'
16
- require 'rbbt/tsv'
13
+ require_relative 'rbbt/util/filecache'
14
+
15
+ require_relative 'rbbt/util/tmpfile'
16
+
17
+ require_relative 'rbbt/util/cmd'
18
+ require_relative 'rbbt/tsv'
19
+
20
+ require_relative 'rbbt/workflow'
21
+
22
+ Persist.cache_dir = Rbbt.var.cache.persistence
23
+ FileCache.cachedir = Rbbt.var.cache.filecache.find
24
+ TmpFile.tmpdir = Rbbt.tmp.find
25
+ Resource.default_resource = Rbbt
17
26
 
18
- require 'rbbt/util/config'
data/lib/rbbt.rb CHANGED
@@ -1,7 +1,20 @@
1
- require 'rbbt/resource'
1
+ $LOAD_PATH.unshift File.join(__dir__)
2
+ $LOAD_PATH.unshift File.join(__dir__, '../../lib')
3
+
4
+ require 'scout/path'
5
+ require 'scout/resource'
6
+ Path.add_path :rbbt_util, File.join(Path.caller_lib_dir(__FILE__), "{TOPLEVEL}/{SUBPATH}")
2
7
  module Rbbt
3
8
  extend Resource
4
- pkgdir = 'rbbt'
9
+
10
+ self.pkgdir = 'rbbt'
5
11
  end
12
+ Path.default_pkgdir = Rbbt
13
+ Resource.set_software_env Rbbt.software
14
+
15
+ require_relative 'rbbt/util/version'
16
+ require 'scout/log'
17
+ require_relative 'rbbt/refactor'
6
18
 
7
- require 'rbbt/util/version'
19
+ require 'scout/config'
20
+ Rbbt::Config = Scout::Config
@@ -1,22 +1,29 @@
1
- import warnings
2
1
  import sys
3
2
  import os
4
3
  import subprocess
4
+ import tempfile
5
+ import shutil
6
+ import pandas
7
+ import numpy
5
8
 
6
- def rbbt(cmd = None):
9
+
10
+ def cmd(cmd=None):
7
11
  if cmd is None:
8
12
  print("Rbbt")
9
13
  else:
10
14
  return subprocess.run('rbbt_exec.rb', input=cmd.encode('utf-8'), capture_output=True).stdout.decode()
11
15
 
16
+
12
17
  def libdir():
13
- return rbbt('puts Rbbt.find(:lib)').rstrip()
18
+ return cmd('puts Rbbt.find(:lib)').rstrip()
19
+
14
20
 
15
21
  def add_libdir():
16
22
  pythondir = os.path.join(libdir(), 'python')
17
23
  sys.path.insert(0, pythondir)
18
24
 
19
- def path(subdir = None, base_dir = None):
25
+
26
+ def path(subdir=None, base_dir=None):
20
27
  from pathlib import Path
21
28
  import os
22
29
 
@@ -52,6 +59,15 @@ def log_tsv(tsv):
52
59
  print(tsv)
53
60
  print(tsv.keys())
54
61
 
62
+ def benchmark():
63
+ import time
64
+ tic: float = time.perf_counter()
65
+ try:
66
+ yield
67
+ finally:
68
+ toc: float = time.perf_counter()
69
+ print(f"Computation time = {1000*(toc - tic):.3f}ms")
70
+
55
71
  def tsv_preamble(line, comment_char="#"):
56
72
  import re
57
73
  header = dict()
@@ -127,3 +143,79 @@ def tsv_pandas(filename, sep="\t", comment_char="#", index_col=0, **kwargs):
127
143
  def tsv(*args, **kwargs):
128
144
  return tsv_pandas(*args, **kwargs)
129
145
 
146
+ def save_tsv(filename, df, key=None):
147
+ if (key == None):
148
+ key = df.index.name
149
+ if (key == None):
150
+ key = "Key"
151
+ key = "#" + key
152
+ df.to_csv(filename, sep="\t", index_label=key)
153
+
154
+ def save_job_inputs(data):
155
+ temp_dir = tempfile.mkdtemp() # Create a temporary directory
156
+
157
+ for name, value in data.items():
158
+ file_path = os.path.join(temp_dir, name)
159
+
160
+ if isinstance(value, str):
161
+ file_path += ".txt"
162
+ with open(file_path, "w") as f:
163
+ f.write(value)
164
+
165
+ elif isinstance(value, (bool)):
166
+ with open(file_path, "w") as f:
167
+ if value:
168
+ f.write('true')
169
+ else:
170
+ f.write('false')
171
+
172
+ elif isinstance(value, (int, float)):
173
+ with open(file_path, "w") as f:
174
+ f.write(str(value))
175
+
176
+ elif isinstance(value, pandas.DataFrame):
177
+ file_path += ".tsv"
178
+ save_tsv(file_path, value)
179
+
180
+ elif isinstance(value, numpy.ndarray) or isinstance(value, list):
181
+ file_path += ".list"
182
+ with open(file_path, "w") as f:
183
+ f.write("\n".join(value))
184
+
185
+ else:
186
+ raise TypeError(f"Unsupported data type for argument '{name}': {type(value)}")
187
+
188
+ return temp_dir
189
+
190
+
191
+ def run_job(workflow, task, name='Default', fork=False, clean=False, **kwargs):
192
+ inputs_dir = save_job_inputs(kwargs)
193
+ cmd = ['rbbt', 'workflow', 'task', workflow, task, '--jobname', name, '--load_inputs', inputs_dir, '--nocolor']
194
+
195
+ if fork:
196
+ cmd.append('--fork')
197
+ cmd.append('--detach')
198
+
199
+ if clean:
200
+ if clean == 'recursive':
201
+ cmd.append('--recursive_clean')
202
+ else:
203
+ cmd.append('--clean')
204
+
205
+ proc = subprocess.run(
206
+ cmd,
207
+ capture_output=True, # Capture both stdout and stderr
208
+ text=True # Automatically decode outputs to strings
209
+ )
210
+ shutil.rmtree(inputs_dir)
211
+ if proc.returncode != 0:
212
+ output = proc.stderr.strip()
213
+ if output == '' :
214
+ output = proc.stdout.strip()
215
+ raise RuntimeError(output) # Raise error with cleaned stderr content
216
+ return proc.stdout.strip()
217
+
218
+ if __name__ == "__main__":
219
+ import json
220
+ res = run_job('Baking', 'bake_muffin_tray', 'test', add_blueberries=True, fork=True)
221
+ print(res)
@@ -0,0 +1,104 @@
1
+ import requests
2
+ import logging
3
+ import json
4
+ from urllib.parse import urlencode, urljoin
5
+ from time import sleep
6
+ import itertools
7
+
8
+ def request_post(url, params):
9
+ response = requests.post(url, params)
10
+ return response
11
+
12
+ def request_get(url, params):
13
+ query = urlencode(params)
14
+ full_url = f"{url}?{query}"
15
+ response = requests.get(full_url)
16
+ return response
17
+
18
+ def get_json(url, params={}):
19
+ params['_format'] = 'json'
20
+ response = request_get(url, params)
21
+ if response.status_code == 200:
22
+ return json.loads(response.content) # parse the JSON content from the response
23
+ else:
24
+ logging.error("Failed to initialize remote tasks")
25
+
26
+ def get_raw(url, params={}):
27
+ params['_format'] = 'raw'
28
+ response = request_get(url, params)
29
+ if response.status_code == 200:
30
+ return response.content # parse the JSON content from the response
31
+ else:
32
+ logging.error("Failed to initialize remote tasks")
33
+
34
+ def join(url, *subpaths):
35
+ return url + "/" + "/".join(subpaths)
36
+
37
+ class RemoteStep:
38
+ def __init__(self, url):
39
+ self.url = url
40
+
41
+ def info(self):
42
+ return get_json(join(self.url, 'info'))
43
+ def status(self):
44
+ return self.info()['status']
45
+
46
+ def done(self):
47
+ return self.status() == 'done'
48
+
49
+ def error(self):
50
+ return self.status() == 'error' or self.status() == 'aborted'
51
+
52
+ def running(self):
53
+ return not (self.done() or self.error())
54
+
55
+ def wait(self, time=1):
56
+ while self.running():
57
+ sleep(time)
58
+
59
+
60
+ def raw(self):
61
+ return get_raw(self.url)
62
+
63
+ def json(self):
64
+ return get_json(self.url)
65
+
66
+ class RemoteWorkflow:
67
+ def __init__(self, url):
68
+ self.url = url
69
+ self.task_exports = {}
70
+ self.init_remote_tasks()
71
+
72
+ def init_remote_tasks(self):
73
+ self.task_exports = get_json(self.url)
74
+ self.tasks = []
75
+ self.tasks += self.task_exports['asynchronous']
76
+ self.tasks += self.task_exports['synchronous']
77
+ self.tasks += self.task_exports['exec']
78
+
79
+ def task_info(self, name):
80
+ return get_json(join(self.url, name, '/info'))
81
+
82
+ def job(self, task, **kwargs):
83
+ kwargs['_format'] = 'jobname'
84
+ response = request_post(join(self.url, task), kwargs)
85
+ if response.status_code == 200:
86
+ jobname = response.content.decode('utf-8')
87
+ step_url = join(self.url, task, jobname)
88
+ print(step_url)
89
+ return RemoteStep(step_url)
90
+ else:
91
+ logging.error("Failed to initialize remote tasks")
92
+
93
+
94
+ if __name__ == "__main__":
95
+ wf = RemoteWorkflow('http://localhost:1900/Baking')
96
+ print(wf.tasks)
97
+ print(wf.task_info('bake_muffin_tray'))
98
+
99
+ step = wf.job('bake_muffin_tray', add_blueberries=True)
100
+ step.wait()
101
+ print(step.json())
102
+
103
+
104
+
@@ -0,0 +1,64 @@
1
+ from . import cmd, run_job
2
+ import subprocess
3
+ import json
4
+ import time
5
+
6
+ def save_inputs(directory, inputs, types):
7
+ return
8
+
9
+ class Workflow:
10
+ def __init__(self, name):
11
+ self.name = name
12
+
13
+ def tasks(self):
14
+ ruby=f'Workflow.require_workflow("{self.name}").tasks.keys * "\n"'
15
+ return cmd(ruby).strip().split("\n")
16
+
17
+ def task_info(self, name):
18
+ ruby=f'Workflow.require_workflow("{self.name}").task_info("{name}").to_json'
19
+ return cmd(ruby)
20
+
21
+ def run(self, task, **kwargs):
22
+ return run_job(self.name, task, **kwargs)
23
+
24
+ def fork(self, task, **kwargs):
25
+ path = run_job(self.name, task, fork=True, **kwargs)
26
+ return Step(path)
27
+
28
+ class Step:
29
+ def __init__(self, path):
30
+ self.path = path
31
+ self.info_content = None
32
+
33
+ def info(self):
34
+ if self.info_content:
35
+ return self.info_content
36
+ ruby=f'puts Step.load("{self.path}").info.to_json'
37
+ txt = cmd(ruby)
38
+ info_content = json.loads(txt)
39
+ status = info_content["status"]
40
+ if status == "done" or status == "error" or status == "aborted":
41
+ self.info_content = info_content
42
+ return info_content
43
+
44
+ def status(self):
45
+ return self.info()["status"]
46
+
47
+ def done(self):
48
+ return self.status() == 'done'
49
+
50
+ def error(self):
51
+ return self.status() == 'error'
52
+
53
+ def aborted(self):
54
+ return self.status() == 'aborted'
55
+
56
+ def join(self):
57
+ while not (self.done() or self.error() or self.aborted()):
58
+ time.sleep(1)
59
+
60
+ def load(self):
61
+ ruby=f'puts Step.load("{self.path}").load.to_json'
62
+ txt = cmd(ruby)
63
+ return json.loads(txt)
64
+
data/python/test.py ADDED
@@ -0,0 +1,10 @@
1
+ if __name__ == "__main__":
2
+ import rbbt
3
+ import rbbt.workflow
4
+ wf = rbbt.workflow.Workflow('Baking')
5
+ step = wf.fork('bake_muffin_tray', add_blueberries=True, clean='recursive')
6
+ step.join()
7
+ print(step.load())
8
+
9
+
10
+
data/share/Rlib/plot.R CHANGED
@@ -1,42 +1,42 @@
1
1
  rbbt.require('ggplot2')
2
2
 
3
- geom_entity <- function (real.geom = NULL, mapping = NULL, data = NULL, stat = "identity",
4
- position = "identity", ...) {
5
- rg <- real.geom(mapping = mapping, data = data, stat = stat,
6
- position = position, ...)
7
-
8
- rg$geom <- proto(rg$geom, {
9
- draw <- function(., data, ...) {
10
- grobs <- list()
11
-
12
- for (i in 1:nrow(data)) {
13
- grob <- .super$draw(., data[i,], ...)
14
- if (is.null(data$entity.type))
15
- grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity)
16
- else
17
- grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity, `data-entity-type`=data[i,]$entity.type)
18
- }
19
-
20
- ggplot2:::ggname("geom_entity", gTree(children = do.call("gList", grobs)))
21
- }
22
-
23
- draw_groups <- function(., data, ...) {
24
- grobs <- list()
25
-
26
- for (i in 1:nrow(data)) {
27
- grob <- .super$draw_groups(., data[i,], ...)
28
- if (is.null(data$entity.type))
29
- grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity)
30
- else
31
- grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity, `data-entity-type`=data[i,]$entity.type)
32
- }
33
-
34
- ggplot2:::ggname("geom_entity", gTree(children = do.call("gList", grobs)))
35
- }
36
- })
37
-
38
- rg
39
- }
3
+ #geom_entity <- function (real.geom = NULL, mapping = NULL, data = NULL, stat = "identity",
4
+ # position = "identity", ...) {
5
+ # rg <- real.geom(mapping = mapping, data = data, stat = stat,
6
+ # position = position, ...)
7
+ #
8
+ # rg$geom <- ggproto(rg$geom, {
9
+ # draw <- function(., data, ...) {
10
+ # grobs <- list()
11
+ #
12
+ # for (i in 1:nrow(data)) {
13
+ # grob <- .super$draw(., data[i,], ...)
14
+ # if (is.null(data$entity.type))
15
+ # grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity)
16
+ # else
17
+ # grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity, `data-entity-type`=data[i,]$entity.type)
18
+ # }
19
+ #
20
+ # ggplot2:::ggname("geom_entity", gTree(children = do.call("gList", grobs)))
21
+ # }
22
+ #
23
+ # draw_groups <- function(., data, ...) {
24
+ # grobs <- list()
25
+ #
26
+ # for (i in 1:nrow(data)) {
27
+ # grob <- .super$draw_groups(., data[i,], ...)
28
+ # if (is.null(data$entity.type))
29
+ # grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity)
30
+ # else
31
+ # grobs[[i]] <- garnishGrob(grob, `data-entity`=data[i,]$entity, `data-entity-type`=data[i,]$entity.type)
32
+ # }
33
+ #
34
+ # ggplot2:::ggname("geom_entity", gTree(children = do.call("gList", grobs)))
35
+ # }
36
+ # })
37
+ #
38
+ # rg
39
+ #}
40
40
 
41
41
  rbbt.ggplot2.rotate_x_labels <- function(){ theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) }
42
42
 
data/share/Rlib/svg.R CHANGED
@@ -9,12 +9,17 @@ rbbt.require('Cairo')
9
9
 
10
10
  # Modified from http://aaronecay.com/blog/2014/02/tooltips-in-ggplot/
11
11
 
12
- rbbt.SVG.extract <- function(plot, size=NULL, prefix=NULL, ...){
12
+ rbbt.SVG.extract <- function(plot, size=NULL, prefix=NULL, entity.geom='geom_point', data=NULL, ...){
13
+
14
+ if (is.null(data)) data = plot$data;
13
15
 
14
16
  if (is.null(prefix)) prefix = rbbt.random_string();
17
+
18
+ if (!endsWith(prefix, '.'))
19
+ prefix = paste(prefix, ".", sep="")
20
+
15
21
  if (is.null(size)){
16
22
  print(plot, type='cairo');
17
- mysvg <- grid.export(prefix=prefix, ...)
18
23
  }else{
19
24
  base.size = 10 * (7/size)
20
25
  resolution = 72 * (size/7)
@@ -25,11 +30,23 @@ rbbt.SVG.extract <- function(plot, size=NULL, prefix=NULL, ...){
25
30
 
26
31
  if (is.null(plot$theme$text$size))
27
32
  plot$theme$text$size = base.size
28
-
29
- print(plot, type='cairo')
30
- mysvg <- grid.export(res=resolution, prefix=prefix, ...)
33
+ print(plot, type='cairo');
31
34
  }
32
35
 
36
+ grid.force()
37
+
38
+ if (!is.null(data[["Entity"]]))
39
+ grid.garnish(entity.geom, 'data-entity'= data[["Entity"]], group = FALSE, grep = TRUE, redraw = TRUE)
40
+ else
41
+ grid.garnish(entity.geom, 'data-entity'= rownames(data), group = FALSE, grep = TRUE, redraw = TRUE)
42
+
43
+ if (!is.null(data[["Entity type"]]))
44
+ grid.garnish(entity.geom, 'data-entity_type' = data[["Entity type"]], group = FALSE, grep = TRUE, redraw = TRUE)
45
+ else if (!is.null(attributes(data)$key.field))
46
+ grid.garnish(entity.geom, 'data-entity_type' = rep(attributes(data)$key.field, length(rownames(data))), group = FALSE, grep = TRUE, redraw = TRUE)
47
+
48
+ mysvg <- grid.export(prefix=prefix, strict = FALSE, ...)
49
+
33
50
  xml <- saveXML(mysvg$svg)
34
51
  xml
35
52
  }
@@ -10,7 +10,7 @@ OPT_BUILD_DIR="$SOFTWARE_DIR/.build"; [ -d $OPT_BUILD_DIR ] || mkdir -p $OPT_BUI
10
10
 
11
11
  mkdir -p "$OPT_BUILD_DIR"
12
12
 
13
- if realpath --help | grep realative > /dev/null; then
13
+ if (command -v realpath && realpath --help | grep relative) > /dev/null; then
14
14
  function relative_path(){
15
15
  local basedir=$1
16
16
  local path=$2
@@ -206,7 +206,6 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
206
206
  require 'rbbt/workflow'
207
207
  step_path = step_line.split(": ").last.strip
208
208
  step = Step.new step_path
209
- step.load_dependencies_from_info
210
209
  has_bar = false
211
210
  [step].reverse.each do |j|
212
211
  next if j.done?
@@ -218,6 +217,7 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
218
217
  prog_rep << [rep]
219
218
  end
220
219
  end
220
+ prog_rep = [Log.color(step.status, step.status)] if prog_rep.empty?
221
221
  end
222
222
  end
223
223
  workflow, task, name = step_path.split("/")[-3..-1]
@@ -321,7 +321,7 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
321
321
  if tail && File.exist?(File.join(dir, 'std.err'))
322
322
  if exit_status && exit_status != 0
323
323
  puts Log.color(:magenta, "First error or exception found: ")
324
- puts CMD.cmd("grep -i -w 'error\\|[a-z]*exception' #{File.join(dir, 'std.err')} -A #{tail.to_i} |head -n #{tail.to_i}", :no_fail => true).read
324
+ puts CMD.cmd("grep -i 'error\\|exception' #{File.join(dir, 'std.err')} -A #{tail.to_i} |head -n #{tail.to_i}", :no_fail => true).read
325
325
  elsif exit_status
326
326
  puts Log.color(:magenta, "Completed jobs: ")
327
327
  puts CMD.cmd("grep -i -w 'Completed step' #{File.join(dir, 'std.err')} | grep -v 'Retrying dep.' | tail -n #{tail.to_i}", :no_fail => true).read
@@ -337,7 +337,6 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
337
337
  require 'rbbt/workflow'
338
338
  step_path = step_line.split(": ").last.strip
339
339
  step = Step.new step_path
340
- step.load_dependencies_from_info
341
340
  has_bar = false
342
341
  (step.rec_dependencies + [step]).reverse.each do |j|
343
342
  next if j.done?
@@ -18,9 +18,9 @@ $slurm_options = SOPT.get <<EOF
18
18
  -si--singularity_img* Singularity image to use
19
19
  -sm--singularity_mounts* Singularity image to use
20
20
  -ug--user_group* Use alternative user group for group project directory
21
- -c--contain* Contain in directory (using Singularity)
22
- -s--sync* Contain in directory and sync jobs
23
- -e--exclusive Make exclusive use of the node
21
+ --contain* Contain in directory (using Singularity)
22
+ --sync* Contain in directory and sync jobs
23
+ --exclusive Make exclusive use of the node
24
24
  -hm--highmem Make use of highmem cores
25
25
  -wc--wipe_container* Wipe the jobs from the contain directory
26
26
  -pd--purge_deps Purge job dependencies
@@ -57,7 +57,7 @@ raise ParameterException.new("Could not detect batch_system: #{Misc.fingerprint
57
57
 
58
58
  class Step
59
59
  def join
60
- HPC::BATCH_MODULE.wait_for_job(@batch_job_dir)
60
+ HPC::BATCH_MODULE.wait_for_job(@batch_job_dir) unless done?
61
61
  end
62
62
 
63
63
  def run(no_load = true)
@@ -33,6 +33,8 @@ raise ParameterException.new("Could not detect batch_system: #{Misc.fingerprint
33
33
 
34
34
  directory = ARGV.shift
35
35
 
36
+ directory = HPC::BATCH_MODULE.jobs.first if directory.nil?
37
+
36
38
  raise ParameterException if directory.nil?
37
39
 
38
40
  if directory =~ /^[0-9]*$/
@@ -9,7 +9,7 @@ require 'time'
9
9
 
10
10
  rbbt_options = SOPT::GOT_OPTIONS
11
11
 
12
- $slurm_options = SOPT.get <<EOF
12
+ $batch_options = SOPT.get <<EOF
13
13
  -dr--dry_run Print only the template
14
14
  -cj--clean_job Clean job
15
15
  --drbbt* Use development version of rbbt
@@ -17,9 +17,9 @@ $slurm_options = SOPT.get <<EOF
17
17
  -si--singularity_img* Singularity image to use
18
18
  -sm--singularity_mounts* Singularity image to use
19
19
  -ug--user_group* Use alternative user group for group project directory
20
- -c--contain* Contain in directory (using Singularity)
21
- -s--sync* Contain in directory and sync jobs
22
- -e--exclusive Make exclusive use of the node
20
+ --contain* Contain in directory (using Singularity)
21
+ --sync* Contain in directory and sync jobs
22
+ --exclusive Make exclusive use of the node
23
23
  -hm--highmem Make use of highmem cores
24
24
  -wc--wipe_container* Wipe the jobs from the contain directory
25
25
  -pd--purge_deps Purge job dependencies
@@ -45,11 +45,14 @@ $slurm_options = SOPT.get <<EOF
45
45
  -OR--orchestration_rules* Orchestration rules
46
46
  EOF
47
47
 
48
- batch_system = $slurm_options.delete :batch_system
48
+ batch_system = $batch_options.delete :batch_system
49
49
  batch_system ||= 'auto'
50
+ $batch_options[:log] = rbbt_options[:log]
51
+ $batch_options[:config_keys] = rbbt_options[:config_keys]
50
52
 
51
53
  HPC::BATCH_MODULE = HPC.batch_system batch_system
52
54
 
55
+
53
56
  raise ParameterException.new("Could not detect batch_system: #{Misc.fingerprint batch_system}") if HPC::BATCH_MODULE.nil?
54
57
 
55
58
  class Step
@@ -60,7 +63,7 @@ class Step
60
63
  else
61
64
  begin
62
65
  Log.debug "Issuing BATCH job for #{self.path}"
63
- HPC::BATCH_MODULE.run_job(self, $slurm_options)
66
+ HPC::BATCH_MODULE.run_job(self, $batch_options)
64
67
  rescue HPC::BATCH_DRY_RUN
65
68
  end
66
69
  end
@@ -70,7 +73,7 @@ end
70
73
  module RemoteStep::SSH
71
74
 
72
75
  def _run
73
- RemoteWorkflow::SSH.run_slurm_job(File.join(base_url, task.to_s), @input_id, @base_name, $slurm_options)
76
+ RemoteWorkflow::SSH.run_slurm_job(File.join(base_url, task.to_s), @input_id, @base_name, $batch_options)
74
77
  end
75
78
 
76
79
  end
@@ -206,7 +206,6 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
206
206
  require 'rbbt/workflow'
207
207
  step_path = step_line.split(": ").last.strip
208
208
  step = Step.new step_path
209
- step.load_dependencies_from_info
210
209
  has_bar = false
211
210
  [step].reverse.each do |j|
212
211
  next if j.done?
@@ -218,6 +217,7 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
218
217
  prog_rep << [rep]
219
218
  end
220
219
  end
220
+ prog_rep = [Log.color(step.status, step.status)] if prog_rep.empty?
221
221
  end
222
222
  end
223
223
  workflow, task, name = step_path.split("/")[-3..-1]
@@ -321,7 +321,7 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
321
321
  if tail && File.exist?(File.join(dir, 'std.err'))
322
322
  if exit_status && exit_status != 0
323
323
  puts Log.color(:magenta, "First error or exception found: ")
324
- puts CMD.cmd("grep -i -w 'error\\|[a-z]*exception' #{File.join(dir, 'std.err')} -A #{tail.to_i} |head -n #{tail.to_i}", :no_fail => true).read
324
+ puts CMD.cmd("grep -i 'error\\|exception' #{File.join(dir, 'std.err')} -A #{tail.to_i} |head -n #{tail.to_i}", :no_fail => true).read
325
325
  elsif exit_status
326
326
  puts Log.color(:magenta, "Completed jobs: ")
327
327
  puts CMD.cmd("grep -i -w 'Completed step' #{File.join(dir, 'std.err')} | grep -v 'Retrying dep.' | tail -n #{tail.to_i}", :no_fail => true).read
@@ -337,7 +337,6 @@ workdir.glob("**/command.batch").sort_by{|f| File.mtime(f)}.each do |fcmd|
337
337
  require 'rbbt/workflow'
338
338
  step_path = step_line.split(": ").last.strip
339
339
  step = Step.new step_path
340
- step.load_dependencies_from_info
341
340
  has_bar = false
342
341
  (step.rec_dependencies + [step]).reverse.each do |j|
343
342
  next if j.done?