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.
- sierra/__init__.py +3 -3
- sierra/core/__init__.py +3 -3
- sierra/core/batchroot.py +223 -0
- sierra/core/cmdline.py +681 -1057
- sierra/core/compare.py +11 -0
- sierra/core/config.py +96 -88
- sierra/core/engine.py +306 -0
- sierra/core/execenv.py +380 -0
- sierra/core/expdef.py +11 -0
- sierra/core/experiment/__init__.py +1 -0
- sierra/core/experiment/bindings.py +150 -101
- sierra/core/experiment/definition.py +414 -245
- sierra/core/experiment/spec.py +83 -85
- sierra/core/exproot.py +44 -0
- sierra/core/generators/__init__.py +10 -0
- sierra/core/generators/experiment.py +528 -0
- sierra/core/generators/generator_factory.py +138 -137
- sierra/core/graphs/__init__.py +23 -0
- sierra/core/graphs/bcbridge.py +94 -0
- sierra/core/graphs/heatmap.py +245 -324
- sierra/core/graphs/pathset.py +27 -0
- sierra/core/graphs/schema.py +77 -0
- sierra/core/graphs/stacked_line.py +341 -0
- sierra/core/graphs/summary_line.py +506 -0
- sierra/core/logging.py +3 -2
- sierra/core/models/__init__.py +3 -1
- sierra/core/models/info.py +19 -0
- sierra/core/models/interface.py +52 -122
- sierra/core/pipeline/__init__.py +2 -5
- sierra/core/pipeline/pipeline.py +228 -126
- sierra/core/pipeline/stage1/__init__.py +10 -0
- sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
- sierra/core/pipeline/stage2/__init__.py +10 -0
- sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
- sierra/core/pipeline/stage2/runner.py +401 -0
- sierra/core/pipeline/stage3/__init__.py +12 -0
- sierra/core/pipeline/stage3/gather.py +321 -0
- sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
- sierra/core/pipeline/stage4/__init__.py +12 -2
- sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
- sierra/core/pipeline/stage5/__init__.py +12 -0
- sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
- sierra/core/pipeline/yaml.py +48 -0
- sierra/core/plugin.py +529 -62
- sierra/core/proc.py +11 -0
- sierra/core/prod.py +11 -0
- sierra/core/ros1/__init__.py +5 -1
- sierra/core/ros1/callbacks.py +22 -21
- sierra/core/ros1/cmdline.py +59 -88
- sierra/core/ros1/generators.py +159 -175
- sierra/core/ros1/variables/__init__.py +3 -0
- sierra/core/ros1/variables/exp_setup.py +122 -116
- sierra/core/startup.py +106 -76
- sierra/core/stat_kernels.py +4 -5
- sierra/core/storage.py +13 -32
- sierra/core/trampoline.py +30 -0
- sierra/core/types.py +116 -71
- sierra/core/utils.py +103 -106
- sierra/core/variables/__init__.py +1 -1
- sierra/core/variables/base_variable.py +12 -17
- sierra/core/variables/batch_criteria.py +387 -481
- sierra/core/variables/builtin.py +135 -0
- sierra/core/variables/exp_setup.py +19 -39
- sierra/core/variables/population_size.py +72 -76
- sierra/core/variables/variable_density.py +44 -68
- sierra/core/vector.py +1 -1
- sierra/main.py +256 -88
- sierra/plugins/__init__.py +119 -0
- sierra/plugins/compare/__init__.py +14 -0
- sierra/plugins/compare/graphs/__init__.py +19 -0
- sierra/plugins/compare/graphs/cmdline.py +120 -0
- sierra/plugins/compare/graphs/comparator.py +291 -0
- sierra/plugins/compare/graphs/inter_controller.py +531 -0
- sierra/plugins/compare/graphs/inter_scenario.py +297 -0
- sierra/plugins/compare/graphs/namecalc.py +53 -0
- sierra/plugins/compare/graphs/outputroot.py +73 -0
- sierra/plugins/compare/graphs/plugin.py +147 -0
- sierra/plugins/compare/graphs/preprocess.py +172 -0
- sierra/plugins/compare/graphs/schema.py +37 -0
- sierra/plugins/engine/__init__.py +14 -0
- sierra/plugins/engine/argos/__init__.py +18 -0
- sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
- sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
- sierra/plugins/engine/argos/generators/engine.py +394 -0
- sierra/plugins/engine/argos/plugin.py +393 -0
- sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
- sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
- sierra/plugins/engine/argos/variables/cameras.py +240 -0
- sierra/plugins/engine/argos/variables/constant_density.py +112 -0
- sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
- sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
- sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
- sierra/plugins/engine/argos/variables/population_size.py +115 -0
- sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
- sierra/plugins/engine/argos/variables/rendering.py +108 -0
- sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
- sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
- sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
- sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
- sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
- sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
- sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
- sierra/plugins/engine/ros1robot/__init__.py +18 -0
- sierra/plugins/engine/ros1robot/cmdline.py +159 -0
- sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
- sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
- sierra/plugins/engine/ros1robot/plugin.py +410 -0
- sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
- sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
- sierra/plugins/execenv/__init__.py +11 -0
- sierra/plugins/execenv/hpc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
- sierra/plugins/execenv/hpc/cmdline.py +137 -0
- sierra/plugins/execenv/hpc/local/__init__.py +18 -0
- sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
- sierra/plugins/execenv/hpc/local/plugin.py +145 -0
- sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
- sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
- sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
- sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
- sierra/plugins/execenv/prefectserver/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
- sierra/plugins/execenv/prefectserver/flow.py +66 -0
- sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
- sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
- sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
- sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
- sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
- sierra/plugins/expdef/__init__.py +14 -0
- sierra/plugins/expdef/json/__init__.py +14 -0
- sierra/plugins/expdef/json/plugin.py +504 -0
- sierra/plugins/expdef/xml/__init__.py +14 -0
- sierra/plugins/expdef/xml/plugin.py +386 -0
- sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
- sierra/plugins/proc/collate/__init__.py +15 -0
- sierra/plugins/proc/collate/cmdline.py +47 -0
- sierra/plugins/proc/collate/plugin.py +271 -0
- sierra/plugins/proc/compress/__init__.py +18 -0
- sierra/plugins/proc/compress/cmdline.py +47 -0
- sierra/plugins/proc/compress/plugin.py +123 -0
- sierra/plugins/proc/decompress/__init__.py +18 -0
- sierra/plugins/proc/decompress/plugin.py +96 -0
- sierra/plugins/proc/imagize/__init__.py +15 -0
- sierra/plugins/proc/imagize/cmdline.py +49 -0
- sierra/plugins/proc/imagize/plugin.py +270 -0
- sierra/plugins/proc/modelrunner/__init__.py +16 -0
- sierra/plugins/proc/modelrunner/plugin.py +250 -0
- sierra/plugins/proc/statistics/__init__.py +15 -0
- sierra/plugins/proc/statistics/cmdline.py +64 -0
- sierra/plugins/proc/statistics/plugin.py +390 -0
- sierra/plugins/{hpc → prod}/__init__.py +1 -0
- sierra/plugins/prod/graphs/__init__.py +18 -0
- sierra/plugins/prod/graphs/cmdline.py +269 -0
- sierra/plugins/prod/graphs/collate.py +279 -0
- sierra/plugins/prod/graphs/inter/__init__.py +13 -0
- sierra/plugins/prod/graphs/inter/generate.py +83 -0
- sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
- sierra/plugins/prod/graphs/inter/line.py +134 -0
- sierra/plugins/prod/graphs/intra/__init__.py +15 -0
- sierra/plugins/prod/graphs/intra/generate.py +202 -0
- sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
- sierra/plugins/prod/graphs/intra/line.py +114 -0
- sierra/plugins/prod/graphs/plugin.py +103 -0
- sierra/plugins/prod/graphs/targets.py +63 -0
- sierra/plugins/prod/render/__init__.py +18 -0
- sierra/plugins/prod/render/cmdline.py +72 -0
- sierra/plugins/prod/render/plugin.py +282 -0
- sierra/plugins/storage/__init__.py +5 -0
- sierra/plugins/storage/arrow/__init__.py +18 -0
- sierra/plugins/storage/arrow/plugin.py +38 -0
- sierra/plugins/storage/csv/__init__.py +9 -0
- sierra/plugins/storage/csv/plugin.py +12 -5
- sierra/version.py +3 -2
- sierra_research-1.5.0.dist-info/METADATA +238 -0
- sierra_research-1.5.0.dist-info/RECORD +186 -0
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
- sierra/core/experiment/xml.py +0 -454
- sierra/core/generators/controller_generator_parser.py +0 -34
- sierra/core/generators/exp_creator.py +0 -351
- sierra/core/generators/exp_generators.py +0 -142
- sierra/core/graphs/scatterplot2D.py +0 -109
- sierra/core/graphs/stacked_line_graph.py +0 -251
- sierra/core/graphs/stacked_surface_graph.py +0 -220
- sierra/core/graphs/summary_line_graph.py +0 -371
- sierra/core/hpc/cmdline.py +0 -142
- sierra/core/models/graphs.py +0 -87
- sierra/core/pipeline/stage2/exp_runner.py +0 -286
- sierra/core/pipeline/stage3/imagizer.py +0 -149
- sierra/core/pipeline/stage3/run_collator.py +0 -317
- sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
- sierra/core/pipeline/stage4/graph_collator.py +0 -320
- sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
- sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
- sierra/core/pipeline/stage4/model_runner.py +0 -168
- sierra/core/pipeline/stage4/rendering.py +0 -283
- sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
- sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
- sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
- sierra/core/platform.py +0 -493
- sierra/core/plugin_manager.py +0 -369
- sierra/core/root_dirpath_generator.py +0 -241
- sierra/plugins/hpc/adhoc/plugin.py +0 -125
- sierra/plugins/hpc/local/plugin.py +0 -81
- sierra/plugins/hpc/pbs/__init__.py +0 -9
- sierra/plugins/hpc/pbs/plugin.py +0 -126
- sierra/plugins/hpc/slurm/__init__.py +0 -9
- sierra/plugins/hpc/slurm/plugin.py +0 -130
- sierra/plugins/platform/__init__.py +0 -9
- sierra/plugins/platform/argos/__init__.py +0 -9
- sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
- sierra/plugins/platform/argos/plugin.py +0 -337
- sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
- sierra/plugins/platform/argos/variables/cameras.py +0 -243
- sierra/plugins/platform/argos/variables/constant_density.py +0 -136
- sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
- sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
- sierra/plugins/platform/argos/variables/population_size.py +0 -102
- sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
- sierra/plugins/platform/argos/variables/rendering.py +0 -104
- sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
- sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
- sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
- sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
- sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
- sierra/plugins/platform/ros1robot/__init__.py +0 -9
- sierra/plugins/platform/ros1robot/cmdline.py +0 -175
- sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
- sierra/plugins/platform/ros1robot/plugin.py +0 -373
- sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
- sierra/plugins/robot/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/plugin.py +0 -194
- sierra_research-1.3.11.data/data/share/man/man1/sierra-cli.1 +0 -2349
- sierra_research-1.3.11.data/data/share/man/man7/sierra-examples.7 +0 -508
- sierra_research-1.3.11.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
- sierra_research-1.3.11.data/data/share/man/man7/sierra-glossary.7 +0 -285
- sierra_research-1.3.11.data/data/share/man/man7/sierra-platforms.7 +0 -358
- sierra_research-1.3.11.data/data/share/man/man7/sierra-usage.7 +0 -729
- sierra_research-1.3.11.data/data/share/man/man7/sierra.7 +0 -78
- sierra_research-1.3.11.dist-info/METADATA +0 -492
- sierra_research-1.3.11.dist-info/RECORD +0 -133
- sierra_research-1.3.11.dist-info/top_level.txt +0 -1
- {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
- {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"]
|
@@ -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
|
-
"""
|
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(
|
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=
|
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=
|
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
|
-
"""
|
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__ =
|
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.
|