sierra-research 1.3.11__py3-none-any.whl → 1.5.0__py3-none-any.whl

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 (254) hide show
  1. sierra/__init__.py +3 -3
  2. sierra/core/__init__.py +3 -3
  3. sierra/core/batchroot.py +223 -0
  4. sierra/core/cmdline.py +681 -1057
  5. sierra/core/compare.py +11 -0
  6. sierra/core/config.py +96 -88
  7. sierra/core/engine.py +306 -0
  8. sierra/core/execenv.py +380 -0
  9. sierra/core/expdef.py +11 -0
  10. sierra/core/experiment/__init__.py +1 -0
  11. sierra/core/experiment/bindings.py +150 -101
  12. sierra/core/experiment/definition.py +414 -245
  13. sierra/core/experiment/spec.py +83 -85
  14. sierra/core/exproot.py +44 -0
  15. sierra/core/generators/__init__.py +10 -0
  16. sierra/core/generators/experiment.py +528 -0
  17. sierra/core/generators/generator_factory.py +138 -137
  18. sierra/core/graphs/__init__.py +23 -0
  19. sierra/core/graphs/bcbridge.py +94 -0
  20. sierra/core/graphs/heatmap.py +245 -324
  21. sierra/core/graphs/pathset.py +27 -0
  22. sierra/core/graphs/schema.py +77 -0
  23. sierra/core/graphs/stacked_line.py +341 -0
  24. sierra/core/graphs/summary_line.py +506 -0
  25. sierra/core/logging.py +3 -2
  26. sierra/core/models/__init__.py +3 -1
  27. sierra/core/models/info.py +19 -0
  28. sierra/core/models/interface.py +52 -122
  29. sierra/core/pipeline/__init__.py +2 -5
  30. sierra/core/pipeline/pipeline.py +228 -126
  31. sierra/core/pipeline/stage1/__init__.py +10 -0
  32. sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
  33. sierra/core/pipeline/stage2/__init__.py +10 -0
  34. sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
  35. sierra/core/pipeline/stage2/runner.py +401 -0
  36. sierra/core/pipeline/stage3/__init__.py +12 -0
  37. sierra/core/pipeline/stage3/gather.py +321 -0
  38. sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
  39. sierra/core/pipeline/stage4/__init__.py +12 -2
  40. sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
  41. sierra/core/pipeline/stage5/__init__.py +12 -0
  42. sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
  43. sierra/core/pipeline/yaml.py +48 -0
  44. sierra/core/plugin.py +529 -62
  45. sierra/core/proc.py +11 -0
  46. sierra/core/prod.py +11 -0
  47. sierra/core/ros1/__init__.py +5 -1
  48. sierra/core/ros1/callbacks.py +22 -21
  49. sierra/core/ros1/cmdline.py +59 -88
  50. sierra/core/ros1/generators.py +159 -175
  51. sierra/core/ros1/variables/__init__.py +3 -0
  52. sierra/core/ros1/variables/exp_setup.py +122 -116
  53. sierra/core/startup.py +106 -76
  54. sierra/core/stat_kernels.py +4 -5
  55. sierra/core/storage.py +13 -32
  56. sierra/core/trampoline.py +30 -0
  57. sierra/core/types.py +116 -71
  58. sierra/core/utils.py +103 -106
  59. sierra/core/variables/__init__.py +1 -1
  60. sierra/core/variables/base_variable.py +12 -17
  61. sierra/core/variables/batch_criteria.py +387 -481
  62. sierra/core/variables/builtin.py +135 -0
  63. sierra/core/variables/exp_setup.py +19 -39
  64. sierra/core/variables/population_size.py +72 -76
  65. sierra/core/variables/variable_density.py +44 -68
  66. sierra/core/vector.py +1 -1
  67. sierra/main.py +256 -88
  68. sierra/plugins/__init__.py +119 -0
  69. sierra/plugins/compare/__init__.py +14 -0
  70. sierra/plugins/compare/graphs/__init__.py +19 -0
  71. sierra/plugins/compare/graphs/cmdline.py +120 -0
  72. sierra/plugins/compare/graphs/comparator.py +291 -0
  73. sierra/plugins/compare/graphs/inter_controller.py +531 -0
  74. sierra/plugins/compare/graphs/inter_scenario.py +297 -0
  75. sierra/plugins/compare/graphs/namecalc.py +53 -0
  76. sierra/plugins/compare/graphs/outputroot.py +73 -0
  77. sierra/plugins/compare/graphs/plugin.py +147 -0
  78. sierra/plugins/compare/graphs/preprocess.py +172 -0
  79. sierra/plugins/compare/graphs/schema.py +37 -0
  80. sierra/plugins/engine/__init__.py +14 -0
  81. sierra/plugins/engine/argos/__init__.py +18 -0
  82. sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
  83. sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
  84. sierra/plugins/engine/argos/generators/engine.py +394 -0
  85. sierra/plugins/engine/argos/plugin.py +393 -0
  86. sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
  87. sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
  88. sierra/plugins/engine/argos/variables/cameras.py +240 -0
  89. sierra/plugins/engine/argos/variables/constant_density.py +112 -0
  90. sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
  91. sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
  92. sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
  93. sierra/plugins/engine/argos/variables/population_size.py +115 -0
  94. sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
  95. sierra/plugins/engine/argos/variables/rendering.py +108 -0
  96. sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
  97. sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
  98. sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
  99. sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
  100. sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
  101. sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
  102. sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
  103. sierra/plugins/engine/ros1robot/__init__.py +18 -0
  104. sierra/plugins/engine/ros1robot/cmdline.py +159 -0
  105. sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
  106. sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
  107. sierra/plugins/engine/ros1robot/plugin.py +410 -0
  108. sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
  109. sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
  110. sierra/plugins/execenv/__init__.py +11 -0
  111. sierra/plugins/execenv/hpc/__init__.py +18 -0
  112. sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
  113. sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
  114. sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
  115. sierra/plugins/execenv/hpc/cmdline.py +137 -0
  116. sierra/plugins/execenv/hpc/local/__init__.py +18 -0
  117. sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
  118. sierra/plugins/execenv/hpc/local/plugin.py +145 -0
  119. sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
  120. sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
  121. sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
  122. sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
  123. sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
  124. sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
  125. sierra/plugins/execenv/prefectserver/__init__.py +18 -0
  126. sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
  127. sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
  128. sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
  129. sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
  130. sierra/plugins/execenv/prefectserver/flow.py +66 -0
  131. sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
  132. sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
  133. sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
  134. sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
  135. sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
  136. sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
  137. sierra/plugins/expdef/__init__.py +14 -0
  138. sierra/plugins/expdef/json/__init__.py +14 -0
  139. sierra/plugins/expdef/json/plugin.py +504 -0
  140. sierra/plugins/expdef/xml/__init__.py +14 -0
  141. sierra/plugins/expdef/xml/plugin.py +386 -0
  142. sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
  143. sierra/plugins/proc/collate/__init__.py +15 -0
  144. sierra/plugins/proc/collate/cmdline.py +47 -0
  145. sierra/plugins/proc/collate/plugin.py +271 -0
  146. sierra/plugins/proc/compress/__init__.py +18 -0
  147. sierra/plugins/proc/compress/cmdline.py +47 -0
  148. sierra/plugins/proc/compress/plugin.py +123 -0
  149. sierra/plugins/proc/decompress/__init__.py +18 -0
  150. sierra/plugins/proc/decompress/plugin.py +96 -0
  151. sierra/plugins/proc/imagize/__init__.py +15 -0
  152. sierra/plugins/proc/imagize/cmdline.py +49 -0
  153. sierra/plugins/proc/imagize/plugin.py +270 -0
  154. sierra/plugins/proc/modelrunner/__init__.py +16 -0
  155. sierra/plugins/proc/modelrunner/plugin.py +250 -0
  156. sierra/plugins/proc/statistics/__init__.py +15 -0
  157. sierra/plugins/proc/statistics/cmdline.py +64 -0
  158. sierra/plugins/proc/statistics/plugin.py +390 -0
  159. sierra/plugins/{hpc → prod}/__init__.py +1 -0
  160. sierra/plugins/prod/graphs/__init__.py +18 -0
  161. sierra/plugins/prod/graphs/cmdline.py +269 -0
  162. sierra/plugins/prod/graphs/collate.py +279 -0
  163. sierra/plugins/prod/graphs/inter/__init__.py +13 -0
  164. sierra/plugins/prod/graphs/inter/generate.py +83 -0
  165. sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
  166. sierra/plugins/prod/graphs/inter/line.py +134 -0
  167. sierra/plugins/prod/graphs/intra/__init__.py +15 -0
  168. sierra/plugins/prod/graphs/intra/generate.py +202 -0
  169. sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
  170. sierra/plugins/prod/graphs/intra/line.py +114 -0
  171. sierra/plugins/prod/graphs/plugin.py +103 -0
  172. sierra/plugins/prod/graphs/targets.py +63 -0
  173. sierra/plugins/prod/render/__init__.py +18 -0
  174. sierra/plugins/prod/render/cmdline.py +72 -0
  175. sierra/plugins/prod/render/plugin.py +282 -0
  176. sierra/plugins/storage/__init__.py +5 -0
  177. sierra/plugins/storage/arrow/__init__.py +18 -0
  178. sierra/plugins/storage/arrow/plugin.py +38 -0
  179. sierra/plugins/storage/csv/__init__.py +9 -0
  180. sierra/plugins/storage/csv/plugin.py +12 -5
  181. sierra/version.py +3 -2
  182. sierra_research-1.5.0.dist-info/METADATA +238 -0
  183. sierra_research-1.5.0.dist-info/RECORD +186 -0
  184. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
  185. sierra/core/experiment/xml.py +0 -454
  186. sierra/core/generators/controller_generator_parser.py +0 -34
  187. sierra/core/generators/exp_creator.py +0 -351
  188. sierra/core/generators/exp_generators.py +0 -142
  189. sierra/core/graphs/scatterplot2D.py +0 -109
  190. sierra/core/graphs/stacked_line_graph.py +0 -251
  191. sierra/core/graphs/stacked_surface_graph.py +0 -220
  192. sierra/core/graphs/summary_line_graph.py +0 -371
  193. sierra/core/hpc/cmdline.py +0 -142
  194. sierra/core/models/graphs.py +0 -87
  195. sierra/core/pipeline/stage2/exp_runner.py +0 -286
  196. sierra/core/pipeline/stage3/imagizer.py +0 -149
  197. sierra/core/pipeline/stage3/run_collator.py +0 -317
  198. sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
  199. sierra/core/pipeline/stage4/graph_collator.py +0 -320
  200. sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
  201. sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
  202. sierra/core/pipeline/stage4/model_runner.py +0 -168
  203. sierra/core/pipeline/stage4/rendering.py +0 -283
  204. sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
  205. sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
  206. sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
  207. sierra/core/platform.py +0 -493
  208. sierra/core/plugin_manager.py +0 -369
  209. sierra/core/root_dirpath_generator.py +0 -241
  210. sierra/plugins/hpc/adhoc/plugin.py +0 -125
  211. sierra/plugins/hpc/local/plugin.py +0 -81
  212. sierra/plugins/hpc/pbs/__init__.py +0 -9
  213. sierra/plugins/hpc/pbs/plugin.py +0 -126
  214. sierra/plugins/hpc/slurm/__init__.py +0 -9
  215. sierra/plugins/hpc/slurm/plugin.py +0 -130
  216. sierra/plugins/platform/__init__.py +0 -9
  217. sierra/plugins/platform/argos/__init__.py +0 -9
  218. sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
  219. sierra/plugins/platform/argos/plugin.py +0 -337
  220. sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
  221. sierra/plugins/platform/argos/variables/cameras.py +0 -243
  222. sierra/plugins/platform/argos/variables/constant_density.py +0 -136
  223. sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
  224. sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
  225. sierra/plugins/platform/argos/variables/population_size.py +0 -102
  226. sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
  227. sierra/plugins/platform/argos/variables/rendering.py +0 -104
  228. sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
  229. sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
  230. sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
  231. sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
  232. sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
  233. sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
  234. sierra/plugins/platform/ros1robot/__init__.py +0 -9
  235. sierra/plugins/platform/ros1robot/cmdline.py +0 -175
  236. sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
  237. sierra/plugins/platform/ros1robot/plugin.py +0 -373
  238. sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
  239. sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
  240. sierra/plugins/robot/__init__.py +0 -9
  241. sierra/plugins/robot/turtlebot3/__init__.py +0 -9
  242. sierra/plugins/robot/turtlebot3/plugin.py +0 -194
  243. sierra_research-1.3.11.data/data/share/man/man1/sierra-cli.1 +0 -2349
  244. sierra_research-1.3.11.data/data/share/man/man7/sierra-examples.7 +0 -508
  245. sierra_research-1.3.11.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
  246. sierra_research-1.3.11.data/data/share/man/man7/sierra-glossary.7 +0 -285
  247. sierra_research-1.3.11.data/data/share/man/man7/sierra-platforms.7 +0 -358
  248. sierra_research-1.3.11.data/data/share/man/man7/sierra-usage.7 +0 -729
  249. sierra_research-1.3.11.data/data/share/man/man7/sierra.7 +0 -78
  250. sierra_research-1.3.11.dist-info/METADATA +0 -492
  251. sierra_research-1.3.11.dist-info/RECORD +0 -133
  252. sierra_research-1.3.11.dist-info/top_level.txt +0 -1
  253. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
  254. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,282 @@
1
+ # Copyright 2019 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Classes for rendering frames (images) into videos.
6
+
7
+ Frames can be:
8
+
9
+ - Captured by by the ``--engine`` during stage 2.
10
+
11
+ - Generated during stage 3 of SIERRA via imagizing.
12
+
13
+ - Generated inter-experiment heatmaps from bivariate experiments.
14
+
15
+ """
16
+
17
+ # Core packages
18
+ import subprocess
19
+ import typing as tp
20
+ import multiprocessing as mp
21
+ import queue
22
+ import copy
23
+ import shutil
24
+ import logging
25
+ import pathlib
26
+ import time
27
+ import datetime
28
+
29
+ # 3rd party packages
30
+
31
+ # Project packages
32
+ import sierra.core.variables.batch_criteria as bc
33
+ from sierra.core import types, config, utils, batchroot
34
+ from sierra.core import plugin as pm
35
+
36
+ _logger = logging.getLogger(__name__)
37
+
38
+
39
+ def proc_batch_exp(
40
+ main_config: types.YAMLDict,
41
+ cmdopts: types.Cmdopts,
42
+ pathset: batchroot.PathSet,
43
+ criteria: bc.XVarBatchCriteria,
44
+ ) -> None:
45
+ """
46
+ Render videos.
47
+
48
+ #. From :term:`Engine` if ``--engine-vc`` was passed.
49
+
50
+ #. From imagized images if ``proc.imagize`` was run previously to
51
+ generate frames, and ``--project-rendering`` is passed.
52
+ """
53
+ if (not cmdopts["engine_vc"]) and (not cmdopts["project_rendering"]):
54
+ return
55
+
56
+ _logger.info("Rendering videos...")
57
+ start = time.time()
58
+
59
+ graphs_path = pathlib.Path(cmdopts["project_config_root"]) / pathlib.Path(
60
+ config.kYAML.graphs
61
+ )
62
+ if utils.path_exists(graphs_path):
63
+ _logger.info("Loading render config for project=%s", cmdopts["project"])
64
+ loader = pm.module_load_tiered(project=cmdopts["project"], path="pipeline.yaml")
65
+ render_config = loader.load_config(cmdopts, config.kYAML.graphs)
66
+
67
+ else:
68
+ _logger.warning("%s does not exist--cannot generate render", graphs_path)
69
+ return
70
+
71
+ if cmdopts["engine_vc"]:
72
+ _from_engine(render_config["intra-exp"], cmdopts, pathset, criteria)
73
+ else:
74
+ _logger.debug(
75
+ (
76
+ "--engine-vc not passed--(possibly) skipping "
77
+ "rendering frames captured by the engine"
78
+ )
79
+ )
80
+
81
+ if cmdopts["project_rendering"] and "imagize" in render_config:
82
+ _from_project_imagized(render_config["imagize"], cmdopts, pathset, criteria)
83
+ else:
84
+ _logger.debug(
85
+ (
86
+ "--project-rendering not passed--(possibly) "
87
+ "skipping rendering frames captured by the "
88
+ "project"
89
+ )
90
+ )
91
+
92
+ elapsed = int(time.time() - start)
93
+ sec = datetime.timedelta(seconds=elapsed)
94
+ _logger.info("Rendering complete in %s", str(sec))
95
+
96
+
97
+ def _from_engine(
98
+ render_config: types.YAMLDict,
99
+ cmdopts: types.Cmdopts,
100
+ pathset: batchroot.PathSet,
101
+ criteria: bc.XVarBatchCriteria,
102
+ ) -> None:
103
+ """Render frames (images) captured in by a engine into videos.
104
+
105
+ Frames are stitched together to make a video using :program:`ffmpeg`. Output
106
+ format controlled via configuration.
107
+
108
+ Targets to render are found in::
109
+
110
+ <batch_root>/<exp_name>/<run_name>/<frames_leaf>
111
+
112
+ Videos are output in::
113
+
114
+ <batch_root>/videos/<exp_name>
115
+
116
+ ``<frames_leaf>`` is controlled via configuration. For more
117
+ details, see :ref:`plugins/prod/render`.
118
+
119
+ .. note:: This currently only works with PNG images.
120
+ """
121
+ exp_to_render = utils.exp_range_calc(
122
+ cmdopts["exp_range"], pathset.output_root, criteria.gen_exp_names()
123
+ )
124
+
125
+ inputs = []
126
+ for exp in exp_to_render:
127
+ output_dir = pathset.video_root / exp.name
128
+
129
+ for run in exp.iterdir():
130
+ engine = cmdopts["engine"].split(".")[1]
131
+ frames_leaf = config.kRendering[engine]["frames_leaf"]
132
+ output_path = output_dir / (run.name + config.kRenderFormat)
133
+ opts = {
134
+ "exp_root": pathset.imagize_root / exp.name,
135
+ "output_path": output_path,
136
+ "input_dir": str(exp / run / frames_leaf),
137
+ "ffmpeg_opts": cmdopts["render_cmd_opts"],
138
+ }
139
+ inputs.append(copy.deepcopy(opts))
140
+
141
+ _parallel(render_config, cmdopts, inputs)
142
+
143
+
144
+ def _from_project_imagized(
145
+ render_config: types.YAMLDict,
146
+ cmdopts: types.Cmdopts,
147
+ pathset: batchroot.PathSet,
148
+ criteria: bc.XVarBatchCriteria,
149
+ ) -> None:
150
+ """Render THINGS previously imagized in a project in stage 3 into videos.
151
+
152
+ Frames (images) in the imagize root (see :ref:`usage/run-time-tree`) are
153
+ stitched together to make a video using :program:`ffmpeg`. Output format
154
+ controlled via configuration.
155
+
156
+ Targets to render are found in::
157
+
158
+ <batch_root>/imagize/<subdir_path>
159
+
160
+ Videos are output in::
161
+
162
+ <batch_root>/videos/<exp>/<subdir_path>
163
+
164
+ For more details, see :ref:`plugins/prod/render`.
165
+
166
+ .. note:: This currently only works with PNG images.
167
+ """
168
+ exp_to_render = utils.exp_range_calc(
169
+ cmdopts["exp_range"], pathset.output_root, criteria.gen_exp_names()
170
+ )
171
+
172
+ inputs = []
173
+ # For each category of imagized/rendered graphs
174
+ # For each graph in each category
175
+ for graph in render_config:
176
+ # Across all experiments
177
+ for exp in exp_to_render:
178
+ exp_imagize_root = pathset.imagize_root / exp.name
179
+ if not exp_imagize_root.exists():
180
+ continue
181
+
182
+ # Check all directories recursively
183
+ for candidate in exp_imagize_root.rglob("*"):
184
+ path = pathlib.Path(dict(graph)["src_stem"])
185
+ fragment = path.parent / path.name
186
+ if candidate.is_file():
187
+ continue
188
+
189
+ if str(fragment) not in str(candidate):
190
+ continue
191
+
192
+ output_path = (
193
+ pathset.video_root
194
+ / exp.name
195
+ / candidate.relative_to(exp_imagize_root)
196
+ ) / (candidate.name + config.kRenderFormat)
197
+ inputs.append(
198
+ {
199
+ "input_dir": candidate,
200
+ "exp_root": pathset.imagize_root / exp.name,
201
+ "output_path": output_path,
202
+ "ffmpeg_opts": cmdopts["render_cmd_opts"],
203
+ }
204
+ )
205
+
206
+ _parallel(render_config, cmdopts, inputs)
207
+
208
+
209
+ def _parallel(
210
+ render_config: types.YAMLDict,
211
+ cmdopts: types.Cmdopts,
212
+ inputs: tp.List[types.SimpleDict],
213
+ ) -> None:
214
+ """Perform the requested rendering in parallel.
215
+
216
+ Unless disabled with ``--proccessing-serial``, then it is done serially.
217
+ """
218
+ q = mp.JoinableQueue() # type: mp.JoinableQueue
219
+
220
+ for spec in inputs:
221
+ q.put(spec)
222
+
223
+ # Render videos in parallel--waaayyyy faster
224
+ parallelism = cmdopts["processing_parallelism"]
225
+
226
+ for _ in range(0, parallelism):
227
+ p = mp.Process(target=_worker, args=(q, render_config))
228
+ p.start()
229
+
230
+ q.join()
231
+
232
+
233
+ def _worker(q: mp.Queue, render_config: types.YAMLDict) -> None:
234
+ assert shutil.which("ffmpeg") is not None, "ffmpeg not found"
235
+
236
+ while True:
237
+ # Wait for 3 seconds after the queue is empty before bailing
238
+ try:
239
+ render_opts = q.get(True, 3)
240
+
241
+ _logger.info("Rendering images in %s...", render_opts["exp_root"].name)
242
+
243
+ opts = render_opts["ffmpeg_opts"].split(" ")
244
+
245
+ ipaths = "'{0}/*.{1}'".format(
246
+ render_opts["input_dir"], config.kStaticImageType
247
+ )
248
+ cmd = ["ffmpeg", "-y", "-pattern_type", "glob", "-i", ipaths]
249
+ cmd.extend(opts)
250
+ cmd.extend([str(render_opts["output_path"])])
251
+
252
+ to_run = " ".join(cmd)
253
+ _logger.trace("Run cmd: %s", to_run) # type: ignore
254
+
255
+ utils.dir_create_checked(render_opts["output_path"].parent, exist_ok=True)
256
+
257
+ with subprocess.Popen(
258
+ to_run, shell=True, stderr=subprocess.PIPE, stdout=subprocess.PIPE
259
+ ) as proc:
260
+ proc.wait()
261
+
262
+ # We use communicate(), not wait() to avoid issues with IO buffers
263
+ # becoming full (e.g., you get deadlocks with wait() regularly).
264
+ stdout_raw, stderr_raw = proc.communicate()
265
+
266
+ # Only show output if the process failed (i.e., did not return 0)
267
+ if proc.returncode != 0:
268
+ _logger.error("Cmd '%s' failed!", to_run)
269
+ stdout_str = stdout_raw.decode("ascii")
270
+ stderr_str = stderr_raw.decode("ascii")
271
+
272
+ _logger.error("Return code=%d", proc.returncode)
273
+ _logger.error("stdout: %s", stdout_str)
274
+ _logger.error("stderr: %s", stderr_str)
275
+
276
+ q.task_done()
277
+
278
+ except queue.Empty:
279
+ break
280
+
281
+
282
+ __all__ = ["proc_batch_exp"]
@@ -1,6 +1,11 @@
1
1
  # Copyright 2021 John Harwell, All rights reserved.
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
+ """
5
+ Container module for plugins related to storage media.
6
+
7
+ Driven by ``--storage``.
8
+ """
4
9
 
5
10
  # Core packages
6
11
 
@@ -0,0 +1,18 @@
1
+ # Copyright 2021 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ Container module for the arrow storage plugin.
6
+
7
+ See :ref:`plugins/storage/arrow`.
8
+ """
9
+
10
+ # Core packages
11
+
12
+ # 3rd party packages
13
+
14
+ # Project packages
15
+
16
+
17
+ def sierra_plugin_type() -> str:
18
+ return "pipeline"
@@ -0,0 +1,38 @@
1
+ # Copyright 2025 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+ """
5
+ Plugin for reading/writing apache .arrow files.
6
+ """
7
+
8
+ # Core packages
9
+ import pathlib
10
+ import typing as tp
11
+
12
+ # 3rd party packages
13
+ from retry import retry
14
+ import pandas as pd
15
+
16
+ # Project packages
17
+
18
+
19
+ def suffixes() -> tp.Set[str]:
20
+ return {".arrow"}
21
+
22
+
23
+ @retry(pd.errors.ParserError, tries=10, delay=0.100, backoff=1.1) # type:ignore
24
+ def df_read(
25
+ path: pathlib.Path, run_output_root: tp.Optional[pathlib.Path] = None, **kwargs
26
+ ) -> pd.DataFrame:
27
+ """
28
+ Read a pandas dataframe from an apache .arrow file.
29
+ """
30
+ return pd.read_feather(path)
31
+
32
+
33
+ @retry(pd.errors.ParserError, tries=10, delay=0.100, backoff=1.1) # type:ignore
34
+ def df_write(df: pd.DataFrame, path: pathlib.Path, **kwargs) -> None:
35
+ """
36
+ Write a pandas dataframe to a apache .arrow file.
37
+ """
38
+ df.to_feather(path, **kwargs)
@@ -1,9 +1,18 @@
1
1
  # Copyright 2021 John Harwell, All rights reserved.
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
+ """
5
+ Container module for the CSV storage plugin.
6
+
7
+ See :ref:`plugins/storage/csv`.
8
+ """
4
9
 
5
10
  # Core packages
6
11
 
7
12
  # 3rd party packages
8
13
 
9
14
  # Project packages
15
+
16
+
17
+ def sierra_plugin_type() -> str:
18
+ return "pipeline"
@@ -1,12 +1,13 @@
1
1
  # Copyright 2021 John Harwell, All rights reserved.
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- """Plugin for reading from CSV files when processing experimental run results.
5
-
4
+ """
5
+ Plugin for reading/writing CSV files.
6
6
  """
7
7
 
8
8
  # Core packages
9
9
  import pathlib
10
+ import typing as tp
10
11
 
11
12
  # 3rd party packages
12
13
  from retry import retry
@@ -15,14 +16,20 @@ import pandas as pd
15
16
  # Project packages
16
17
 
17
18
 
19
+ def suffixes() -> tp.Set[str]:
20
+ return {".csv"}
21
+
22
+
18
23
  @retry(pd.errors.ParserError, tries=10, delay=0.100, backoff=1.1) # type:ignore
19
- def df_read(path: pathlib.Path, **kwargs) -> pd.DataFrame:
24
+ def df_read(
25
+ path: pathlib.Path, run_output_root: tp.Optional[pathlib.Path] = None, **kwargs
26
+ ) -> pd.DataFrame:
20
27
  """
21
28
  Read a dataframe from a CSV file using pandas.
22
29
  """
23
30
  # Always specify the datatype so pandas does not have to infer it--much
24
31
  # faster.
25
- return pd.read_csv(path, sep=';', float_precision='high', **kwargs)
32
+ return pd.read_csv(path, sep=",", **kwargs)
26
33
 
27
34
 
28
35
  @retry(pd.errors.ParserError, tries=10, delay=0.100, backoff=1.1) # type:ignore
@@ -30,4 +37,4 @@ def df_write(df: pd.DataFrame, path: pathlib.Path, **kwargs) -> None:
30
37
  """
31
38
  Write a dataframe to a CSV file using pandas.
32
39
  """
33
- df.to_csv(path, sep=';', float_format='%.8f', **kwargs)
40
+ df.to_csv(path, sep=",", float_format="%.8f", **kwargs)
sierra/version.py CHANGED
@@ -1,12 +1,13 @@
1
1
  # Copyright 2021 John Harwell, All rights reserved.
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- """The one and only place where the current SIERRA version is recorded."""
4
+ """Provide access to the SIERRA version from the pyproject.toml in source code."""
5
5
 
6
6
  # Core packages
7
+ import importlib.metadata
7
8
 
8
9
  # 3rd party packages
9
10
 
10
11
  # Project packages
11
12
 
12
- __version__ = "1.3.11"
13
+ __version__ = importlib.metadata.version("sierra_research")
@@ -0,0 +1,238 @@
1
+ Metadata-Version: 2.4
2
+ Name: sierra-research
3
+ Version: 1.5.0
4
+ Summary: Automation framework for the scientific method in R&D
5
+ Project-URL: Homepage, https://github.com/jharwell/sierra
6
+ Author-email: John Harwell <john.r.harwell@gmail.com>
7
+ License: Copyright 2022 John Harwell
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
10
+ this software and associated documentation files (the "Software"), to deal in
11
+ the Software without restriction, including without limitation the rights to
12
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
13
+ the Software, and to permit persons to whom the Software is furnished to do so,
14
+ subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
21
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
22
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
23
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ License-File: LICENSE
26
+ Keywords: agent-based modeling,automation,parameter sweeps,reproducibility,research,reusability,robotics
27
+ Classifier: Development Status :: 5 - Production/Stable
28
+ Classifier: Environment :: Console
29
+ Classifier: Intended Audience :: Developers
30
+ Classifier: Intended Audience :: Science/Research
31
+ Classifier: Operating System :: MacOS :: MacOS X
32
+ Classifier: Operating System :: POSIX :: Linux
33
+ Classifier: Programming Language :: Python :: 3.9
34
+ Classifier: Programming Language :: Python :: 3.10
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
38
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
39
+ Classifier: Topic :: Scientific/Engineering :: Visualization
40
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
41
+ Requires-Python: >=3.9
42
+ Requires-Dist: coloredlogs
43
+ Requires-Dist: distro
44
+ Requires-Dist: haggis
45
+ Requires-Dist: hatchling
46
+ Requires-Dist: holoviews
47
+ Requires-Dist: hvplot
48
+ Requires-Dist: implements
49
+ Requires-Dist: jsonpath-ng
50
+ Requires-Dist: matplotlib
51
+ Requires-Dist: netifaces
52
+ Requires-Dist: numpy
53
+ Requires-Dist: pandas
54
+ Requires-Dist: prefect
55
+ Requires-Dist: prefect[docker]
56
+ Requires-Dist: psutil
57
+ Requires-Dist: pyarrow
58
+ Requires-Dist: pyyaml
59
+ Requires-Dist: retry
60
+ Requires-Dist: strictyaml
61
+ Requires-Dist: sympy
62
+ Description-Content-Type: text/x-rst
63
+
64
+ ===========================================================================
65
+ SIERRA (reSearch pIpEline for Reproducibility, Reusability, and Automation)
66
+ ===========================================================================
67
+
68
+ .. |pepy-downloads| image:: https://pepy.tech/badge/sierra-research
69
+ :target: https://pepy.tech/project/sierra-research
70
+
71
+ .. |pypi-version| image:: https://img.shields.io/pypi/v/sierra-research.svg
72
+ :target: https://pypi.python.org/pypi/sierra-research/
73
+
74
+ .. |supported-pythons| image:: https://img.shields.io/pypi/pyversions/sierra-research.svg
75
+
76
+ .. |os-supported| image:: https://img.shields.io/badge/os-linux%20%7C%20macOS-blue
77
+
78
+ .. |ci-analysis-master| image:: https://github.com/jharwell/sierra/actions/workflows/analysis-top.yml/badge.svg?branch=master
79
+ .. |ci-coverage-master| image:: https://coveralls.io/repos/github/jharwell/sierra/badge.svg?branch=master
80
+
81
+ .. |ci-analysis-devel| image:: https://github.com/jharwell/sierra/actions/workflows/analysis-top.yml/badge.svg?branch=devel
82
+ .. |ci-coverage-devel| image:: https://coveralls.io/repos/github/jharwell/sierra/badge.svg?branch=devel
83
+
84
+ .. |license| image:: https://img.shields.io/badge/License-MIT-blue.svg
85
+
86
+ .. |doi| image:: https://zenodo.org/badge/125774567.svg
87
+ :target: https://zenodo.org/badge/latestdoi/125774567
88
+
89
+ .. |docs| image:: https://readthedocs.org/projects/sierra/badge/?version=master
90
+ :target: https://sierra.readthedocs.io/en/master/
91
+
92
+ .. |maintenance| image:: https://img.shields.io/badge/Maintained%3F-yes-green.svg
93
+
94
+
95
+ +---------------+--------------------------------------------------------------------+
96
+ | Usage | |pepy-downloads| |pypi-version| |supported-pythons| |os-supported| |
97
+ +---------------+--------------------------------------------------------------------+
98
+ | Release | |ci-analysis-master| |ci-coverage-master| |
99
+ +---------------+--------------------------------------------------------------------+
100
+ | Development | |ci-analysis-devel| |ci-coverage-devel| |
101
+ +---------------+--------------------------------------------------------------------+
102
+ | Miscellaneous | |license| |doi| |docs| |maintenance| |
103
+ +---------------+--------------------------------------------------------------------+
104
+
105
+
106
+ TL;DR
107
+ =====
108
+
109
+ What is SIERRA? See `What is SIERRA?`_
110
+
111
+ Why should you use SIERRA? See `Why SIERRA?`_
112
+
113
+ To install SIERRA (requires python 3.9+):
114
+
115
+ ::
116
+
117
+ pip3 install sierra-research
118
+
119
+
120
+ SIERRA requires a recent OSX (tested with 13+) or Linux (tested with ubuntu
121
+ 20.04+) and python >= 3.9. For more details, including the requirements for
122
+ project code, see the `SIERRA requirements
123
+ <https://sierra.readthedocs.io/en/master/src/requirements.html>`_.
124
+
125
+ To get started using SIERRA, see `getting started
126
+ <https://sierra.readthedocs.io/en/master/src/getting_started.html>`_.
127
+
128
+ Want to cite SIERRA? See `Citing`_.
129
+
130
+ Have an issue using SIERRA? See `Troubleshooting`_.
131
+
132
+ What is SIERRA?
133
+ ===============
134
+
135
+ .. figure:: https://raw.githubusercontent.com/jharwell/sierra/master/docs/figures/architecture.png
136
+
137
+ SIERRA architecture, organized by pipeline stage, left to right. High-level
138
+ inputs/outputs and active plugins and shown for each stage. “...” indicates
139
+ areas of further extensibility and customization via new plugins. “Host
140
+ machine” indicates the machine SIERRA was invoked on. The active plugins in
141
+ each stage and what they cumulatively enable are highlighted in red.
142
+
143
+ SIERRA is a command line tool and plugin framework for:
144
+
145
+ - Automating R&D, providing faculties for seamless experiment
146
+ generation, execution, and results processing.
147
+
148
+ - Accelerating R&D cycles by allowing researchers/developers to focus on the
149
+ “science” aspects: developing new things and designing experiments to test
150
+ them, rather than the engineering aspects (writing scripts, configuring
151
+ environments, etc.).
152
+
153
+ - Improving the reproducibility of scientific research, particularly in AI.
154
+
155
+ Why SIERRA?
156
+ ===========
157
+
158
+ - It changes the paradigm of the engineering tasks researchers must perform
159
+ from manual and procedural to declarative and automated. That is, from::
160
+
161
+ "I need to perform these steps to run the experiment, process the data and
162
+ generate the graphs I want."
163
+
164
+ to::
165
+
166
+ "Here is the environment and simulator/platforms(s) I want to use, the
167
+ deliverables I want to generate, and the data I want to appear on them for
168
+ my research query--GO!"
169
+
170
+ Essentially, SIERRA handles the “engineering” parts of research on the
171
+ backend, acting as a compiler of sorts, turning research queries into
172
+ executable objects, running the "compiled" experiments, and processing results
173
+ into visualizations or other deliverables.
174
+
175
+ - It has deep support for arbitrary parameter sweeps: numeric, categorical, or
176
+ any combination thereof.
177
+
178
+ - It supports a wide range of execution engines/environments, and experiment
179
+ input/output formats via plugins. SIERRA supports mix-and-match between all
180
+ plugin types, subject to restrictions within the plugins themselves. This is
181
+ and makes it very easy to run experiments on different hardware, targeting
182
+ different simulators, generating different outputs, etc., all with little to
183
+ no configuration changes by the user.
184
+
185
+ - SIERRA maximizes reusability of code and configuration; it is designed so that
186
+ *no* copy-pasting is ever needed, improving code quality with no additional
187
+ effort from users.
188
+
189
+ - SIERRA has a rich model framework allowing you to run arbitrary models,
190
+ generate data, and plot it on the same figure as empirical
191
+ results--automatically.
192
+
193
+ - Why use SIERRA over something like `prefect <https://www.prefect.io>`_,
194
+ `dagster <https://www.dagster.io>`_, or `airflow
195
+ <https://airflow.apache.org>`_ ? Briefly, because SIERRA provides a common
196
+ pipeline which is tested and can accommodate most use cases; SIERRA is not as
197
+ feature complete as these other frameworks, though. For most use cases (but
198
+ not all), that delta doesn't matter. In addition, with the other frameworks,
199
+ you have to create your own pipelines from scratch.
200
+
201
+ Not sure if SIERRA makes sense for you? Check out some of the `use cases
202
+ <https://sierra.readthedocs.io/en/master/src/use-cases.html>`_ for which SIERRA
203
+ was designed. If aspects of any sound familiar, then there is a strong chance
204
+ SIERRA could help you! See the `SIERRA docs
205
+ <https://sierra.readthedocs.io/en/master/>`_ to get started.
206
+
207
+ Citing
208
+ ======
209
+
210
+ If you use SIERRA and have found it helpful, please cite the following paper::
211
+
212
+ @inproceedings{Harwell2022a-SIERRA,
213
+ author = {Harwell, John and Lowmanstone, London and Gini, Maria},
214
+ title = {SIERRA: A Modular Framework for Research Automation},
215
+ year = {2022},
216
+ isbn = {9781450392136},
217
+ publisher = {International Foundation for Autonomous Agents and Multiagent Systems},
218
+ booktitle = {Proceedings of the 21st International Conference on Autonomous Agents and Multiagent Systems},
219
+ pages = {1905–1907}
220
+ }
221
+
222
+ You can also cite the specific version of SIERRA used with the DOI at the top of
223
+ this page, to help facilitate reproducibility.
224
+
225
+ Troubleshooting
226
+ ===============
227
+
228
+ If you have problems using SIERRA, please open an issue or post in the Github
229
+ forum and I'll be happy to help you work through it.
230
+
231
+ Contributing
232
+ ============
233
+
234
+ I welcome all types of contributions, no matter how large or how small, and if
235
+ you have an idea, I'm happy to talk about it at any point :-). See the
236
+ `contributing guide
237
+ <https://sierra.readthedocs.io/en/master/src/contributing.html>`_ for the
238
+ general procedure.