sierra-research 1.3.6__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.6.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 -249
- sierra/core/graphs/stacked_surface_graph.py +0 -220
- sierra/core/graphs/summary_line_graph.py +0 -369
- 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 -319
- 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.6.data/data/share/man/man1/sierra-cli.1 +0 -2349
- sierra_research-1.3.6.data/data/share/man/man7/sierra-examples.7 +0 -488
- sierra_research-1.3.6.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
- sierra_research-1.3.6.data/data/share/man/man7/sierra-glossary.7 +0 -285
- sierra_research-1.3.6.data/data/share/man/man7/sierra-platforms.7 +0 -358
- sierra_research-1.3.6.data/data/share/man/man7/sierra-usage.7 +0 -725
- sierra_research-1.3.6.data/data/share/man/man7/sierra.7 +0 -78
- sierra_research-1.3.6.dist-info/METADATA +0 -500
- sierra_research-1.3.6.dist-info/RECORD +0 -133
- sierra_research-1.3.6.dist-info/top_level.txt +0 -1
- {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
- {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,270 @@
|
|
1
|
+
# Copyright 2019 John Harwell, All rights reserved.
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
|
5
|
+
"""Classes for creating image files from ``.mean`` files for experiments.
|
6
|
+
|
7
|
+
See :ref:`plugins/proc/imagize` for usage documentation.
|
8
|
+
|
9
|
+
"""
|
10
|
+
|
11
|
+
# Core packages
|
12
|
+
import multiprocessing as mp
|
13
|
+
import logging
|
14
|
+
import pathlib
|
15
|
+
import typing as tp
|
16
|
+
|
17
|
+
# 3rd party packages
|
18
|
+
import yaml
|
19
|
+
|
20
|
+
# Project packages
|
21
|
+
import sierra.core.variables.batch_criteria as bc
|
22
|
+
from sierra.core import types, utils, batchroot, graphs, config
|
23
|
+
from sierra.core.pipeline.stage3 import gather
|
24
|
+
from sierra.plugins.proc.statistics import plugin as statistics
|
25
|
+
import sierra.core.plugin as pm
|
26
|
+
|
27
|
+
_logger = logging.getLogger(__name__)
|
28
|
+
|
29
|
+
|
30
|
+
def proc_batch_exp(
|
31
|
+
main_config: types.YAMLDict,
|
32
|
+
cmdopts: types.Cmdopts,
|
33
|
+
pathset: batchroot.PathSet,
|
34
|
+
criteria: bc.XVarBatchCriteria,
|
35
|
+
) -> None:
|
36
|
+
"""
|
37
|
+
Generate images for each :term:`Experiment` in the :term:`Batch Experiment`.
|
38
|
+
|
39
|
+
Ideally this is done in parallel across experiments, but this can be changed
|
40
|
+
to serial if memory on the SIERRA host machine is limited via
|
41
|
+
``--processing-parallelism``.
|
42
|
+
"""
|
43
|
+
config_path = pathlib.Path(cmdopts["project_config_root"]) / pathlib.Path(
|
44
|
+
config.kYAML.graphs
|
45
|
+
)
|
46
|
+
if utils.path_exists(config_path):
|
47
|
+
_logger.info("Loading imagizing config for project=%s", cmdopts["project"])
|
48
|
+
imagize_config = yaml.load(utils.utf8open(config_path), yaml.FullLoader)[
|
49
|
+
"imagize"
|
50
|
+
]
|
51
|
+
else:
|
52
|
+
_logger.warning("%s does not exist--cannot imagize", config_path)
|
53
|
+
return
|
54
|
+
|
55
|
+
if not cmdopts["imagize_no_stats"]:
|
56
|
+
statistics.proc_batch_exp(
|
57
|
+
main_config, cmdopts, pathset, criteria, ImagizeInputGatherer
|
58
|
+
)
|
59
|
+
|
60
|
+
exp_to_imagize = utils.exp_range_calc(
|
61
|
+
cmdopts["exp_range"], pathset.output_root, criteria.gen_exp_names()
|
62
|
+
)
|
63
|
+
|
64
|
+
parallelism = cmdopts["processing_parallelism"]
|
65
|
+
|
66
|
+
tasks = []
|
67
|
+
for exp in exp_to_imagize:
|
68
|
+
exp_stat_root = pathset.stat_root / exp.name
|
69
|
+
exp_imagize_root = pathset.imagize_root / exp.name
|
70
|
+
|
71
|
+
tasks.extend(
|
72
|
+
_build_tasklist_for_exp(
|
73
|
+
exp_stat_root, exp_imagize_root, imagize_config, cmdopts["storage"]
|
74
|
+
)
|
75
|
+
)
|
76
|
+
|
77
|
+
# 2025-06-06 [JRH]: This works around what is apparently a nasty memory leak
|
78
|
+
# in hv caused by the hv.save() function for which the usual methods of
|
79
|
+
# clearing memory/figures do not work. The maxtasksperchild argument +
|
80
|
+
# chunksize kills all the child threads periodically, which fixes the leak
|
81
|
+
# problem, for now.
|
82
|
+
_logger.debug("Starting %s workers, method=%s", parallelism, mp.get_start_method())
|
83
|
+
with mp.Pool(processes=parallelism, maxtasksperchild=1) as pool:
|
84
|
+
processed = pool.starmap_async(_worker, tasks, chunksize=10)
|
85
|
+
|
86
|
+
_logger.debug("Waiting for workers to finish")
|
87
|
+
processed.get()
|
88
|
+
|
89
|
+
_logger.debug("All workers finished")
|
90
|
+
|
91
|
+
|
92
|
+
def _build_tasklist_for_exp(
|
93
|
+
exp_stat_root: pathlib.Path,
|
94
|
+
exp_imagize_root: pathlib.Path,
|
95
|
+
imagize_config: types.YAMLDict,
|
96
|
+
storage: str,
|
97
|
+
) -> tp.List[tp.Tuple[dict, types.YAMLDict]]:
|
98
|
+
"""Add all files from experiment to multiprocessing queue for processing.
|
99
|
+
|
100
|
+
Enqueueing for processing is done at the file-level rather than
|
101
|
+
per-experiment, so that for systems with more CPUs than experiments you
|
102
|
+
still get maximum throughput.
|
103
|
+
"""
|
104
|
+
res = []
|
105
|
+
# For each graph in each category
|
106
|
+
for graph in imagize_config:
|
107
|
+
candidate = exp_stat_root / dict(graph)["src_stem"]
|
108
|
+
|
109
|
+
if not candidate.is_dir():
|
110
|
+
_logger.debug(
|
111
|
+
"Configured imagize source <batch stat root>/%s does not exist",
|
112
|
+
(candidate.relative_to(exp_stat_root)),
|
113
|
+
)
|
114
|
+
continue
|
115
|
+
|
116
|
+
imagize_output_root = exp_imagize_root / candidate.relative_to(exp_stat_root)
|
117
|
+
utils.dir_create_checked(imagize_output_root, exist_ok=True)
|
118
|
+
|
119
|
+
for fpath in candidate.iterdir():
|
120
|
+
assert (
|
121
|
+
fpath.is_file()
|
122
|
+
), f"Imagize directory {candidate} must only contain files!"
|
123
|
+
|
124
|
+
res.append(
|
125
|
+
(
|
126
|
+
{
|
127
|
+
"input_path": fpath,
|
128
|
+
"graph_stem": candidate.relative_to(exp_stat_root),
|
129
|
+
"imagize_output_root": imagize_output_root,
|
130
|
+
"batch_root": exp_stat_root.parent.parent,
|
131
|
+
"storage": storage,
|
132
|
+
},
|
133
|
+
imagize_config,
|
134
|
+
)
|
135
|
+
)
|
136
|
+
|
137
|
+
return res
|
138
|
+
|
139
|
+
|
140
|
+
def _worker(imagize_opts: dict, imagize_config: types.YAMLDict) -> None:
|
141
|
+
_proc_single_exp(imagize_config, imagize_opts)
|
142
|
+
|
143
|
+
|
144
|
+
def _proc_single_exp(imagize_config: types.YAMLDict, imagize_opts: dict) -> None:
|
145
|
+
"""Create images from the averaged ``.mean`` files from a single experiment.
|
146
|
+
|
147
|
+
If no ``.mean`` files suitable for averaging are found, nothing is done. See
|
148
|
+
:ref:`plugins/proc/imagize` for per-engine descriptions of what
|
149
|
+
"suitable" means.
|
150
|
+
|
151
|
+
Arguments:
|
152
|
+
|
153
|
+
imagize_config: Parsed YAML configuration for heatmaps.
|
154
|
+
|
155
|
+
imagize_opts: Dictionary of imagizing options.
|
156
|
+
"""
|
157
|
+
|
158
|
+
match = None
|
159
|
+
for graph in imagize_config:
|
160
|
+
if dict(graph)["src_stem"] == str(imagize_opts["graph_stem"]):
|
161
|
+
match = graph
|
162
|
+
|
163
|
+
if match is not None:
|
164
|
+
graph_pathset = graphs.PathSet(
|
165
|
+
input_root=imagize_opts["input_path"].parent,
|
166
|
+
output_root=imagize_opts["imagize_output_root"],
|
167
|
+
model_root=None,
|
168
|
+
batchroot=imagize_opts["batch_root"],
|
169
|
+
)
|
170
|
+
|
171
|
+
# 2025-06-05 [JRH]: We always write stage {3,4} output data files as
|
172
|
+
# .csv because that is currently SIERRA's 'native' format; this may
|
173
|
+
# change in the future.
|
174
|
+
#
|
175
|
+
# Input paths are of the form <dir>/<dir>_<NUMBER>.{extension}
|
176
|
+
graphs.heatmap(
|
177
|
+
pathset=graph_pathset,
|
178
|
+
input_stem=imagize_opts["input_path"].stem,
|
179
|
+
output_stem=imagize_opts["input_path"].stem,
|
180
|
+
title=dict(match)["title"],
|
181
|
+
medium="storage.csv",
|
182
|
+
xlabel="X",
|
183
|
+
ylabel="Y",
|
184
|
+
colnames=(
|
185
|
+
match.get("x", "x"),
|
186
|
+
match.get("y", "y"),
|
187
|
+
match.get("z", "z"),
|
188
|
+
),
|
189
|
+
backend="matplotlib",
|
190
|
+
)
|
191
|
+
|
192
|
+
else:
|
193
|
+
_logger.warning(
|
194
|
+
"No match for graph with src_stem='%s' found in configuration",
|
195
|
+
imagize_opts["graph_stem"],
|
196
|
+
)
|
197
|
+
|
198
|
+
|
199
|
+
class ImagizeInputGatherer(gather.BaseGatherer):
|
200
|
+
"""Gather :term:`Raw Output Data` files from all runs for imagizing.
|
201
|
+
|
202
|
+
The configured output directory for each run is searched recursively for
|
203
|
+
directories containing files to gather. To be eligible for gathering and
|
204
|
+
later processing, files must:
|
205
|
+
|
206
|
+
- Be in a directory with the same name as the file, sans extension.
|
207
|
+
|
208
|
+
- Be non-empty
|
209
|
+
|
210
|
+
- Have a suffix which supported by the selected ``--storage`` plugin.
|
211
|
+
|
212
|
+
Recursive nesting of files *within* a directory containing files to imagize
|
213
|
+
is not supported--why would you do this anyway?
|
214
|
+
"""
|
215
|
+
|
216
|
+
def __init__(
|
217
|
+
self,
|
218
|
+
main_config: types.YAMLDict,
|
219
|
+
gather_opts: types.SimpleDict,
|
220
|
+
processq: mp.Queue,
|
221
|
+
) -> None:
|
222
|
+
super().__init__(main_config, gather_opts, processq)
|
223
|
+
self.logger = logging.getLogger(__name__)
|
224
|
+
|
225
|
+
self.config_path = (
|
226
|
+
pathlib.Path(gather_opts["project_config_root"]) / config.kYAML.graphs
|
227
|
+
)
|
228
|
+
|
229
|
+
self.imagize_config = yaml.load(
|
230
|
+
utils.utf8open(self.config_path), yaml.FullLoader
|
231
|
+
)["imagize"]
|
232
|
+
|
233
|
+
def calc_gather_items(
|
234
|
+
self, run_output_root: pathlib.Path, exp_name: str
|
235
|
+
) -> tp.List[gather.GatherSpec]:
|
236
|
+
to_gather = []
|
237
|
+
proj_output_root = run_output_root / str(self.run_metrics_leaf)
|
238
|
+
plugin = pm.pipeline.get_plugin_module(self.gather_opts["storage"])
|
239
|
+
|
240
|
+
for item in proj_output_root.rglob("*"):
|
241
|
+
if not item.is_dir():
|
242
|
+
continue
|
243
|
+
|
244
|
+
for imagizable in item.iterdir():
|
245
|
+
if (
|
246
|
+
not any(s in plugin.suffixes() for s in imagizable.suffixes)
|
247
|
+
and imagizable.stat().st_size > 0
|
248
|
+
):
|
249
|
+
continue
|
250
|
+
|
251
|
+
if not any(
|
252
|
+
g["src_stem"] in str(imagizable) for g in self.imagize_config
|
253
|
+
):
|
254
|
+
continue
|
255
|
+
|
256
|
+
if item.name in imagizable.name:
|
257
|
+
to_gather.append(
|
258
|
+
gather.GatherSpec(
|
259
|
+
exp_name=exp_name,
|
260
|
+
item_stem_path=imagizable.relative_to(proj_output_root),
|
261
|
+
collate_col=None,
|
262
|
+
)
|
263
|
+
)
|
264
|
+
|
265
|
+
return to_gather
|
266
|
+
|
267
|
+
|
268
|
+
__all__ = [
|
269
|
+
"proc_batch_exp",
|
270
|
+
]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2025 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"Plugin for running models during stage 3."
|
7
|
+
|
8
|
+
# Core packages
|
9
|
+
|
10
|
+
# 3rd party packages
|
11
|
+
|
12
|
+
# Project packages
|
13
|
+
|
14
|
+
|
15
|
+
def sierra_plugin_type() -> str:
|
16
|
+
return "pipeline"
|
@@ -0,0 +1,250 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2025 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"""Functionality for runner different types of models.
|
7
|
+
|
8
|
+
See :ref:`plugins/proc/modelrunner` for usage documentation.
|
9
|
+
|
10
|
+
"""
|
11
|
+
# Core packages
|
12
|
+
import pathlib
|
13
|
+
import time
|
14
|
+
import datetime
|
15
|
+
import typing as tp
|
16
|
+
import logging
|
17
|
+
|
18
|
+
# 3rd party packages
|
19
|
+
import yaml
|
20
|
+
|
21
|
+
# Project packages
|
22
|
+
from sierra.core import config, utils, types, batchroot, storage, exproot
|
23
|
+
from sierra.core.variables import batch_criteria as bc
|
24
|
+
from sierra.core import plugin as pm
|
25
|
+
from sierra.core.models import interface
|
26
|
+
|
27
|
+
_logger = logging.getLogger(__name__)
|
28
|
+
|
29
|
+
|
30
|
+
def proc_batch_exp(
|
31
|
+
main_config: types.YAMLDict,
|
32
|
+
cmdopts: types.Cmdopts,
|
33
|
+
pathset: batchroot.PathSet,
|
34
|
+
criteria: bc.XVarBatchCriteria,
|
35
|
+
) -> None:
|
36
|
+
"""
|
37
|
+
Run all intra- and inter-exp models.
|
38
|
+
"""
|
39
|
+
models = _load_models(main_config, cmdopts, "intra")
|
40
|
+
|
41
|
+
_logger.info("Running %d intra-experiment models...", len(models))
|
42
|
+
start = time.time()
|
43
|
+
_run_intra_exp(cmdopts, pathset, models, criteria)
|
44
|
+
elapsed = int(time.time() - start)
|
45
|
+
sec = datetime.timedelta(seconds=elapsed)
|
46
|
+
_logger.info("Intra-experiment models finished in %s", str(sec))
|
47
|
+
|
48
|
+
models = _load_models(main_config, cmdopts, "inter")
|
49
|
+
|
50
|
+
_logger.info("Running %d inter-experiment models...", len(models))
|
51
|
+
start = time.time()
|
52
|
+
|
53
|
+
_run_inter_exp(cmdopts, pathset, models, criteria)
|
54
|
+
|
55
|
+
elapsed = int(time.time() - start)
|
56
|
+
sec = datetime.timedelta(seconds=elapsed)
|
57
|
+
_logger.info("Inter-experiment models finished in %s", str(sec))
|
58
|
+
|
59
|
+
|
60
|
+
def _load_models(
|
61
|
+
main_config: types.YAMLDict, cmdopts: types.Cmdopts, model_type: str
|
62
|
+
) -> tp.Dict[str, tp.Union[tp.Dict[str, tp.Any]]]:
|
63
|
+
project_models = pathlib.Path(cmdopts["project_config_root"]) / config.kYAML.models
|
64
|
+
loaded = {}
|
65
|
+
|
66
|
+
_logger.info("Loading %s-exp models for project %s", model_type, cmdopts["project"])
|
67
|
+
|
68
|
+
models_config = yaml.load(utils.utf8open(project_models), yaml.FullLoader)
|
69
|
+
|
70
|
+
# This is ALL model plugins found by SIERRA.
|
71
|
+
loaded_model_plugins = [
|
72
|
+
p
|
73
|
+
for p in pm.pipeline.loaded_plugins()
|
74
|
+
if pm.pipeline.loaded_plugins()[p]["type"] == "model"
|
75
|
+
]
|
76
|
+
_logger.debug(
|
77
|
+
"%d loaded model plugins on SIERRA_PLUGIN_PATH", len(loaded_model_plugins)
|
78
|
+
)
|
79
|
+
|
80
|
+
for plugin_name in loaded_model_plugins:
|
81
|
+
# This is all available models for a specific plugin
|
82
|
+
module = pm.module_load(plugin_name)
|
83
|
+
available_models = getattr(module, "sierra_models")(model_type)
|
84
|
+
_logger.debug(
|
85
|
+
"Loaded model plugin %s has %d %s-exp models: %s",
|
86
|
+
plugin_name,
|
87
|
+
len(available_models) if available_models else 0,
|
88
|
+
model_type,
|
89
|
+
available_models,
|
90
|
+
)
|
91
|
+
if models_config.get(f"{model_type}-exp"):
|
92
|
+
for conf in models_config[f"{model_type}-exp"]:
|
93
|
+
|
94
|
+
# Class name of the model is the last part of the dot-separated
|
95
|
+
# path, and plays no part in module lookup in the python
|
96
|
+
# interpreter.
|
97
|
+
model_name = conf["name"].split(".")[-1]
|
98
|
+
|
99
|
+
# The part of the model name which is relative to the plugin
|
100
|
+
# directory in which it should be found.
|
101
|
+
model_module_relpath = ".".join(conf["name"].split(".")[:-1])
|
102
|
+
model_path = "{0}.{1}".format(plugin_name, model_module_relpath)
|
103
|
+
model_fullpath = f"{model_module_relpath}.{model_name}"
|
104
|
+
if pm.module_exists(model_path):
|
105
|
+
_logger.debug(
|
106
|
+
"Loading %s-exp model %s using path %s: YAML configuration match",
|
107
|
+
model_type,
|
108
|
+
model_name,
|
109
|
+
model_module_relpath,
|
110
|
+
)
|
111
|
+
model_params = {
|
112
|
+
k: v for k, v in conf.items() if k not in ["name", "targets"]
|
113
|
+
}
|
114
|
+
loaded[model_fullpath] = {
|
115
|
+
"targets": conf["targets"],
|
116
|
+
"legend": (
|
117
|
+
conf["legend"]
|
118
|
+
if "legend" in conf
|
119
|
+
else ["Model Prediction" for t in conf["targets"]]
|
120
|
+
),
|
121
|
+
"model": getattr(pm.module_load(model_path), model_name)(
|
122
|
+
model_params
|
123
|
+
),
|
124
|
+
}
|
125
|
+
|
126
|
+
else:
|
127
|
+
_logger.debug("All %s-exp models disabled: no configuration", model_type)
|
128
|
+
|
129
|
+
if len(loaded) > 0:
|
130
|
+
_logger.info(
|
131
|
+
"Loaded %s-exp %s models for project %s",
|
132
|
+
len(loaded),
|
133
|
+
model_type,
|
134
|
+
cmdopts["project"],
|
135
|
+
)
|
136
|
+
|
137
|
+
return loaded
|
138
|
+
|
139
|
+
|
140
|
+
def _run_intra_exp(
|
141
|
+
cmdopts: types.Cmdopts,
|
142
|
+
pathset: batchroot.PathSet,
|
143
|
+
to_run: tp.Dict[str, tp.Dict[str, tp.Any]],
|
144
|
+
criteria: bc.XVarBatchCriteria,
|
145
|
+
) -> None:
|
146
|
+
"""
|
147
|
+
Run all enabled intra-experiment models for all experiments in a batch.
|
148
|
+
"""
|
149
|
+
exp_dirnames = criteria.gen_exp_names()
|
150
|
+
exp_to_run = utils.exp_range_calc(
|
151
|
+
cmdopts["exp_range"], pathset.output_root, exp_dirnames
|
152
|
+
)
|
153
|
+
|
154
|
+
for exp in exp_to_run:
|
155
|
+
exp_index = exp_dirnames.index(exp.name)
|
156
|
+
exproots = exproot.PathSet(pathset, exp.name, exp_dirnames[0])
|
157
|
+
|
158
|
+
utils.dir_create_checked(exproots.model_root, exist_ok=True)
|
159
|
+
|
160
|
+
for blob in to_run.values():
|
161
|
+
_run_intra_single_in_exp(criteria, cmdopts, exproots, exp_index, blob)
|
162
|
+
|
163
|
+
|
164
|
+
def _run_intra_single_in_exp(
|
165
|
+
criteria: bc.XVarBatchCriteria,
|
166
|
+
cmdopts: types.Cmdopts,
|
167
|
+
pathset: exproot.PathSet,
|
168
|
+
exp_index: int,
|
169
|
+
blob: tp.Dict[str, tp.Union[interface.IIntraExpModel1D, tp.List[str]]],
|
170
|
+
) -> None:
|
171
|
+
model = blob["model"]
|
172
|
+
targets = blob["targets"]
|
173
|
+
if not model.should_run(criteria, cmdopts, exp_index):
|
174
|
+
_logger.debug(
|
175
|
+
"Skip running intra-experiment model from '%s' for exp%s",
|
176
|
+
str(model),
|
177
|
+
exp_index,
|
178
|
+
)
|
179
|
+
return
|
180
|
+
|
181
|
+
# Run the model
|
182
|
+
_logger.debug(
|
183
|
+
"Run intra-experiment model %s for %s",
|
184
|
+
str(model),
|
185
|
+
pathset.input_root.name,
|
186
|
+
)
|
187
|
+
dfs = model.run(criteria, exp_index, cmdopts, pathset)
|
188
|
+
legend = blob["legend"]
|
189
|
+
|
190
|
+
for df, target in zip(dfs, targets):
|
191
|
+
path_stem = pathset.model_root / target
|
192
|
+
|
193
|
+
# Write model legend file so the generated graph can find it
|
194
|
+
idx = dfs.index(df)
|
195
|
+
with utils.utf8open(
|
196
|
+
path_stem.with_suffix(config.kModelsExt["legend"]), "w"
|
197
|
+
) as f:
|
198
|
+
f.write(legend[idx])
|
199
|
+
|
200
|
+
# Write model .csv file
|
201
|
+
storage.df_write(
|
202
|
+
df,
|
203
|
+
path_stem.with_suffix(config.kModelsExt["model"]),
|
204
|
+
"storage.csv",
|
205
|
+
index=False,
|
206
|
+
)
|
207
|
+
|
208
|
+
|
209
|
+
def _run_inter_exp(
|
210
|
+
cmdopts: types.Cmdopts,
|
211
|
+
pathset: batchroot.PathSet,
|
212
|
+
to_run: tp.Dict[str, tp.Any],
|
213
|
+
criteria: bc.XVarBatchCriteria,
|
214
|
+
) -> None:
|
215
|
+
utils.dir_create_checked(pathset.model_interexp_root, exist_ok=True)
|
216
|
+
|
217
|
+
for blob in to_run.values():
|
218
|
+
model = blob["model"]
|
219
|
+
legend = blob["legend"]
|
220
|
+
targets = blob["targets"]
|
221
|
+
|
222
|
+
if not model.should_run(criteria, cmdopts):
|
223
|
+
_logger.debug("Skip running inter-experiment model '%s'", str(model))
|
224
|
+
continue
|
225
|
+
|
226
|
+
# Run the model
|
227
|
+
_logger.debug("Run inter-experiment model '%s'", str(model))
|
228
|
+
|
229
|
+
dfs = model.run(criteria, cmdopts, pathset)
|
230
|
+
|
231
|
+
for df, csv_stem in zip(dfs, targets):
|
232
|
+
path_stem = pathset.model_interexp_root / csv_stem
|
233
|
+
utils.dir_create_checked(path_stem.parent, exist_ok=True)
|
234
|
+
|
235
|
+
# Write model .csv file
|
236
|
+
storage.df_write(
|
237
|
+
df,
|
238
|
+
path_stem.with_suffix(config.kModelsExt["model"]),
|
239
|
+
"storage.csv",
|
240
|
+
index=True,
|
241
|
+
)
|
242
|
+
|
243
|
+
idx = dfs.index(df)
|
244
|
+
with utils.utf8open(
|
245
|
+
path_stem.with_suffix(config.kModelsExt["legend"]), "w"
|
246
|
+
) as f:
|
247
|
+
f.write(legend[idx])
|
248
|
+
|
249
|
+
|
250
|
+
__all__ = ["proc_batch_exp"]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2025 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"""Container module for the statistics generation data processing plugin."""
|
7
|
+
# Core packages
|
8
|
+
|
9
|
+
# 3rd party packages
|
10
|
+
|
11
|
+
# Project packages
|
12
|
+
|
13
|
+
|
14
|
+
def sierra_plugin_type() -> str:
|
15
|
+
return "pipeline"
|
@@ -0,0 +1,64 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2025 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
|
7
|
+
# Core packages
|
8
|
+
import typing as tp
|
9
|
+
import argparse
|
10
|
+
|
11
|
+
# 3rd party packages
|
12
|
+
|
13
|
+
# Project packages
|
14
|
+
from sierra.core import types
|
15
|
+
from sierra.plugins import PluginCmdline
|
16
|
+
|
17
|
+
|
18
|
+
def build(
|
19
|
+
parents: tp.List[argparse.ArgumentParser], stages: tp.List[int]
|
20
|
+
) -> PluginCmdline:
|
21
|
+
"""
|
22
|
+
Get a cmdline supporting the ``proc.statistics`` plugin.
|
23
|
+
"""
|
24
|
+
cmdline = PluginCmdline(parents, stages)
|
25
|
+
cmdline.multistage.add_argument(
|
26
|
+
"--dist-stats",
|
27
|
+
choices=["none", "all", "conf95", "bw"],
|
28
|
+
help="""
|
29
|
+
Specify what kinds of statistics, if any, should be calculated on
|
30
|
+
the distribution of experimental data during stage 3 for inclusion
|
31
|
+
on graphs during stage 4:
|
32
|
+
|
33
|
+
- ``none`` - Only calculate and show raw mean on graphs.
|
34
|
+
|
35
|
+
- ``conf95`` - Calculate standard deviation of experimental
|
36
|
+
distribution and show 95%% confidence interval on relevant
|
37
|
+
graphs.
|
38
|
+
|
39
|
+
- ``bw`` - Calculate statistics necessary to show box and
|
40
|
+
whisker plots around each point in the graph (Summary Line
|
41
|
+
graphs only).
|
42
|
+
|
43
|
+
- ``all`` - Generate all possible statistics, and plot all
|
44
|
+
possible statistics on graphs.
|
45
|
+
"""
|
46
|
+
+ cmdline.graphs_applicable_doc(
|
47
|
+
[
|
48
|
+
":py:func:`Summary Line <sierra.core.graphs.summary_line.generate>`",
|
49
|
+
":py:func:`Stacked Line <sierra.core.graphs.stacked_line.generate>`",
|
50
|
+
]
|
51
|
+
)
|
52
|
+
+ cmdline.stage_usage_doc([3, 4, 5]),
|
53
|
+
default="none",
|
54
|
+
)
|
55
|
+
|
56
|
+
return cmdline
|
57
|
+
|
58
|
+
|
59
|
+
def to_cmdopts(args: argparse.Namespace) -> types.Cmdopts:
|
60
|
+
return {"dist_stats": args.dist_stats}
|
61
|
+
|
62
|
+
|
63
|
+
def sphinx_cmdline_multistage():
|
64
|
+
return build([], [3, 4, 5]).parser
|