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,279 @@
|
|
1
|
+
# Copyright 2018 John Harwell, All rights reserved.
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
"""Collation functionality for stage3 outputs according to configuration."""
|
5
|
+
|
6
|
+
# Core packages
|
7
|
+
import multiprocessing as mp
|
8
|
+
import queue
|
9
|
+
import typing as tp
|
10
|
+
import logging
|
11
|
+
import pathlib
|
12
|
+
import json
|
13
|
+
import re
|
14
|
+
|
15
|
+
# 3rd party packages
|
16
|
+
import pandas as pd
|
17
|
+
|
18
|
+
# Project packages
|
19
|
+
from sierra.core import utils, config, types, storage, batchroot
|
20
|
+
import sierra.core.variables.batch_criteria as bc
|
21
|
+
from sierra.plugins.prod.graphs import targets
|
22
|
+
from sierra.core import plugin as pm
|
23
|
+
|
24
|
+
_logger = logging.getLogger(__name__)
|
25
|
+
|
26
|
+
|
27
|
+
class GraphCollationInfo:
|
28
|
+
"""Container for :term:`Collated Output Data` files for a particular graph.
|
29
|
+
|
30
|
+
This is one of the focal points for the magic of SIERRA: here is where time
|
31
|
+
series data is transformed into different dataframe formats so as to make
|
32
|
+
generation of different types of graphs seamless when you want to look at
|
33
|
+
some data *across* the batch. The for dataframes by graph type is as
|
34
|
+
follows:
|
35
|
+
|
36
|
+
- :func:`~sierra.core.graphs.stacked_line` : Columns are the raw time
|
37
|
+
series data. Column names are the names of the experiments.
|
38
|
+
|
39
|
+
- :func:`~sierra.core.graphs.summary_line`: Columns are a single time
|
40
|
+
slice of time series data. Column names are the names of the
|
41
|
+
experiments. Indexed by (exp name, summary column).
|
42
|
+
|
43
|
+
- :func:`~sierra.core.graphs.heatmap`: X,Y columns are the indices in
|
44
|
+
the multidimensional array defining the experiment space, parsed out
|
45
|
+
from the exp dirnames for the batch. Z values are a single time slice
|
46
|
+
of time series data for the specified column in each experiment in the
|
47
|
+
batch.
|
48
|
+
"""
|
49
|
+
|
50
|
+
def __init__(
|
51
|
+
self, df_ext: str, exp_names: tp.List[str], graph_type: str, summary_col: str
|
52
|
+
) -> None:
|
53
|
+
self.df_ext = df_ext
|
54
|
+
|
55
|
+
if graph_type == "summary_line":
|
56
|
+
self.df = pd.DataFrame(index=exp_names, columns=[summary_col])
|
57
|
+
self.df.index.name = "Experiment ID"
|
58
|
+
elif graph_type == "stacked_line":
|
59
|
+
self.df = pd.DataFrame(columns=exp_names)
|
60
|
+
elif graph_type == "heatmap":
|
61
|
+
self.df = pd.DataFrame(columns=["x", "y", "z"])
|
62
|
+
|
63
|
+
self.graph_type = graph_type
|
64
|
+
self.summary_col = summary_col
|
65
|
+
self.all_srcs_exist = True
|
66
|
+
self.some_srcs_exist = False
|
67
|
+
|
68
|
+
|
69
|
+
class GraphCollator:
|
70
|
+
"""For a single graph gather needed data from experiments in a batch.
|
71
|
+
|
72
|
+
Results are put into a single :term:`Collated Output Data` file.
|
73
|
+
"""
|
74
|
+
|
75
|
+
def __init__(
|
76
|
+
self,
|
77
|
+
main_config: types.YAMLDict,
|
78
|
+
cmdopts: types.Cmdopts,
|
79
|
+
pathset: batchroot.PathSet,
|
80
|
+
) -> None:
|
81
|
+
self.main_config = main_config
|
82
|
+
self.cmdopts = cmdopts
|
83
|
+
self.pathset = pathset
|
84
|
+
self.logger = logging.getLogger(__name__)
|
85
|
+
|
86
|
+
def __call__(self, criteria, target: types.YAMLDict) -> None:
|
87
|
+
self.logger.info(
|
88
|
+
"Files from univariate experiment in <batch_root>/%s for graph '%s'",
|
89
|
+
self.pathset.output_root.relative_to(self.pathset.root),
|
90
|
+
target["src_stem"],
|
91
|
+
)
|
92
|
+
self.logger.trace(json.dumps(target, indent=4)) # type: ignore
|
93
|
+
|
94
|
+
exp_dirs = utils.exp_range_calc(
|
95
|
+
self.cmdopts["exp_range"],
|
96
|
+
self.pathset.output_root,
|
97
|
+
criteria.gen_exp_names(),
|
98
|
+
)
|
99
|
+
|
100
|
+
# Always do the mean, even if stats are disabled
|
101
|
+
stat_config = config.kStats["mean"].exts
|
102
|
+
|
103
|
+
if self.cmdopts["dist_stats"] in ["conf95", "all"]:
|
104
|
+
stat_config.update(config.kStats["conf95"].exts)
|
105
|
+
|
106
|
+
if self.cmdopts["dist_stats"] in ["bw", "all"]:
|
107
|
+
stat_config.update(config.kStats["bw"].exts)
|
108
|
+
|
109
|
+
stats = [
|
110
|
+
GraphCollationInfo(
|
111
|
+
df_ext=suffix,
|
112
|
+
exp_names=[e.name for e in exp_dirs],
|
113
|
+
summary_col="{0}+{1}".format(
|
114
|
+
self.cmdopts["controller"], self.cmdopts["scenario"]
|
115
|
+
),
|
116
|
+
graph_type=target["type"],
|
117
|
+
)
|
118
|
+
for suffix in stat_config.values()
|
119
|
+
]
|
120
|
+
|
121
|
+
for diri in exp_dirs:
|
122
|
+
self._collate_exp(target, diri.name, stats)
|
123
|
+
|
124
|
+
for stat in stats:
|
125
|
+
if stat.all_srcs_exist:
|
126
|
+
storage.df_write(
|
127
|
+
stat.df,
|
128
|
+
self.pathset.stat_interexp_root
|
129
|
+
/ (target["dest_stem"] + stat.df_ext),
|
130
|
+
"storage.csv",
|
131
|
+
index=stat.graph_type == "summary_line",
|
132
|
+
)
|
133
|
+
|
134
|
+
elif not stat.all_srcs_exist and stat.some_srcs_exist:
|
135
|
+
self.logger.warning(
|
136
|
+
"Not all experiments in '%s' produced '%s%s'",
|
137
|
+
self.pathset.output_root,
|
138
|
+
target["src_stem"],
|
139
|
+
stat.df_ext,
|
140
|
+
)
|
141
|
+
else:
|
142
|
+
self.logger.warning(
|
143
|
+
"No experiments in <batchroot>/%s produced %s%s",
|
144
|
+
self.pathset.output_root.relative_to(self.pathset.root),
|
145
|
+
target["src_stem"],
|
146
|
+
stat.df_ext,
|
147
|
+
)
|
148
|
+
|
149
|
+
def _collate_exp(
|
150
|
+
self, target: dict, exp_dir: str, stats: tp.List[GraphCollationInfo]
|
151
|
+
) -> None:
|
152
|
+
exp_stat_root = self.pathset.stat_root / exp_dir
|
153
|
+
|
154
|
+
for stat in stats:
|
155
|
+
csv_ipath = pathlib.Path(exp_stat_root, target["src_stem"] + stat.df_ext)
|
156
|
+
if not utils.path_exists(csv_ipath):
|
157
|
+
stat.all_srcs_exist = False
|
158
|
+
continue
|
159
|
+
|
160
|
+
stat.some_srcs_exist = True
|
161
|
+
|
162
|
+
data_df = storage.df_read(csv_ipath, "storage.csv")
|
163
|
+
|
164
|
+
# 2025-07-08 [JRH]: This is the ONE place in all the graph
|
165
|
+
# generation code which is a procedural switch on graph type.
|
166
|
+
if target["type"] == "summary_line":
|
167
|
+
idx = target.get("index", -1)
|
168
|
+
assert "col" in target, "'col' key is required"
|
169
|
+
assert (
|
170
|
+
target["col"] in data_df.columns.values
|
171
|
+
), "{0} not in columns of {1}".format(
|
172
|
+
target["col"], target["src_stem"] + stat.df_ext
|
173
|
+
)
|
174
|
+
datapoint = data_df.loc[data_df.index[idx], target["col"]]
|
175
|
+
stat.df.loc[exp_dir, stat.summary_col] = datapoint
|
176
|
+
elif target["type"] == "stacked_line":
|
177
|
+
assert "cols" in target, "'cols' key is required"
|
178
|
+
|
179
|
+
assert (
|
180
|
+
target["cols"] in data_df.columns.values
|
181
|
+
), "{0} not in columns of {1}".format(
|
182
|
+
target["cols"], target["src_stem"] + stat.df_ext
|
183
|
+
)
|
184
|
+
stat.df[exp_dir] = data_df[target["cols"]]
|
185
|
+
elif target["type"] == "heatmap":
|
186
|
+
idx = target.get("index", -1)
|
187
|
+
|
188
|
+
regex = r"c1-exp(\d+)\+c2-exp(\d+)"
|
189
|
+
res = re.match(regex, exp_dir)
|
190
|
+
|
191
|
+
assert (
|
192
|
+
res and len(res.groups()) == 2
|
193
|
+
), f"Unexpected directory name '{exp_dir}': does not match regex {regex}"
|
194
|
+
|
195
|
+
row = pd.DataFrame(
|
196
|
+
[
|
197
|
+
{
|
198
|
+
# group 0 is always the whole matched string
|
199
|
+
"x": int(res.group(1)),
|
200
|
+
"y": int(res.group(2)),
|
201
|
+
"z": data_df.loc[data_df.index[idx], target["col"]],
|
202
|
+
}
|
203
|
+
]
|
204
|
+
)
|
205
|
+
|
206
|
+
stat.df = pd.concat([stat.df, row])
|
207
|
+
|
208
|
+
|
209
|
+
def proc_batch_exp(
|
210
|
+
main_config: types.YAMLDict,
|
211
|
+
cmdopts: types.Cmdopts,
|
212
|
+
pathset: batchroot.PathSet,
|
213
|
+
criteria: bc.XVarBatchCriteria,
|
214
|
+
) -> None:
|
215
|
+
"""
|
216
|
+
Generate :term:`Collated Output Data` files from :term:`Batch Summary Data` files.
|
217
|
+
|
218
|
+
"""
|
219
|
+
utils.dir_create_checked(pathset.stat_interexp_root, exist_ok=True)
|
220
|
+
|
221
|
+
q = mp.JoinableQueue() # type: mp.JoinableQueue
|
222
|
+
|
223
|
+
loader = pm.module_load_tiered(project=cmdopts["project"], path="pipeline.yaml")
|
224
|
+
|
225
|
+
graphs_config = loader.load_config(cmdopts, config.kYAML.graphs)
|
226
|
+
|
227
|
+
if "inter-exp" not in graphs_config:
|
228
|
+
_logger.warning(
|
229
|
+
"Cannot collate data: 'inter-exp' key not found in graphs YAML config"
|
230
|
+
)
|
231
|
+
return
|
232
|
+
|
233
|
+
controller_config = loader.load_config(cmdopts, config.kYAML.controllers)
|
234
|
+
|
235
|
+
# For each category of graphs we are generating
|
236
|
+
for category in targets.inter_exp_calc(
|
237
|
+
graphs_config["inter-exp"], controller_config, cmdopts
|
238
|
+
):
|
239
|
+
# For each graph in each category
|
240
|
+
for graph in category:
|
241
|
+
q.put(graph)
|
242
|
+
|
243
|
+
parallelism = cmdopts["processing_parallelism"]
|
244
|
+
|
245
|
+
for _ in range(0, parallelism):
|
246
|
+
p = mp.Process(
|
247
|
+
target=_thread_worker,
|
248
|
+
args=(q, main_config, cmdopts, pathset, criteria),
|
249
|
+
)
|
250
|
+
p.start()
|
251
|
+
|
252
|
+
q.join()
|
253
|
+
|
254
|
+
|
255
|
+
def _thread_worker(
|
256
|
+
q: mp.Queue,
|
257
|
+
main_config: types.YAMLDict,
|
258
|
+
cmdopts: types.Cmdopts,
|
259
|
+
pathset: batchroot.PathSet,
|
260
|
+
criteria,
|
261
|
+
) -> None:
|
262
|
+
|
263
|
+
collator = GraphCollator(main_config, cmdopts, pathset)
|
264
|
+
|
265
|
+
while True:
|
266
|
+
# Wait for 3 seconds after the queue is empty before bailing
|
267
|
+
try:
|
268
|
+
graph = q.get(True, 3)
|
269
|
+
collator(criteria, graph)
|
270
|
+
q.task_done()
|
271
|
+
except queue.Empty:
|
272
|
+
break
|
273
|
+
|
274
|
+
|
275
|
+
__all__ = [
|
276
|
+
"GraphCollator",
|
277
|
+
"GraphCollationInfo",
|
278
|
+
"proc_batch_exp",
|
279
|
+
]
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2024 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"""Container module for inter-experiment graph generation in stage 4."""
|
7
|
+
|
8
|
+
# Core packages
|
9
|
+
|
10
|
+
# 3rd party packages
|
11
|
+
|
12
|
+
# Project packages
|
13
|
+
from . import generate as generate
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# Copyright 2018 John Harwell, All rights reserved.
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
#
|
5
|
+
|
6
|
+
"""
|
7
|
+
Generate graphs across experiments in a batch.
|
8
|
+
"""
|
9
|
+
|
10
|
+
# Core packages
|
11
|
+
import logging
|
12
|
+
|
13
|
+
# 3rd party packages
|
14
|
+
|
15
|
+
# Project packages
|
16
|
+
from sierra.core import types, utils, batchroot, config
|
17
|
+
from sierra.plugins.prod.graphs import targets
|
18
|
+
from sierra.core import plugin as pm
|
19
|
+
from sierra.core.variables import batch_criteria as bc
|
20
|
+
from . import line, heatmap
|
21
|
+
|
22
|
+
_logger = logging.getLogger(__name__)
|
23
|
+
|
24
|
+
|
25
|
+
def proc_batch_exp(
|
26
|
+
main_config: types.YAMLDict,
|
27
|
+
cmdopts: types.Cmdopts,
|
28
|
+
pathset: batchroot.PathSet,
|
29
|
+
criteria: bc.XVarBatchCriteria,
|
30
|
+
) -> None:
|
31
|
+
"""Generate graphs from :term:`Collated Output Data` files.
|
32
|
+
|
33
|
+
Performs the following steps:
|
34
|
+
|
35
|
+
#. :func:`~sierra.plugins.prod.graphs.inter.line.generate()` to
|
36
|
+
generate linegraphs (univariate batch criteria only).
|
37
|
+
|
38
|
+
#. :func:`~sierra.plugins.prod.graphs.inter.heatmap.generate()`
|
39
|
+
to generate heatmaps (bivariate batch criteria only).
|
40
|
+
|
41
|
+
Which graphs are generated can be controlled by YAML configuration files
|
42
|
+
parsed in stage 4.
|
43
|
+
|
44
|
+
Arguments:
|
45
|
+
main_config: Parsed dictionary of main YAML configuration
|
46
|
+
|
47
|
+
cmdopts: Dictionary of parsed cmdline attributes.
|
48
|
+
|
49
|
+
targets: A list of dictionaries, where each dictionary defines an
|
50
|
+
inter-experiment graph to generate.
|
51
|
+
"""
|
52
|
+
utils.dir_create_checked(pathset.graph_interexp_root, exist_ok=True)
|
53
|
+
|
54
|
+
loader = pm.module_load_tiered(project=cmdopts["project"], path="pipeline.yaml")
|
55
|
+
|
56
|
+
graphs_config = loader.load_config(cmdopts, config.kYAML.graphs)
|
57
|
+
|
58
|
+
if "inter-exp" not in graphs_config:
|
59
|
+
_logger.warning(
|
60
|
+
"Cannot generate graphs: 'inter-exp' key not found in YAML config"
|
61
|
+
)
|
62
|
+
return
|
63
|
+
|
64
|
+
controller_config = loader.load_config(cmdopts, config.kYAML.controllers)
|
65
|
+
|
66
|
+
info = criteria.graph_info(cmdopts, batch_output_root=pathset.output_root)
|
67
|
+
|
68
|
+
if criteria.cardinality() == 1:
|
69
|
+
if not cmdopts["project_no_LN"]:
|
70
|
+
graph_targets = targets.inter_exp_calc(
|
71
|
+
graphs_config["inter-exp"], controller_config, cmdopts
|
72
|
+
)
|
73
|
+
line.generate(cmdopts, pathset, graph_targets, info)
|
74
|
+
else:
|
75
|
+
graph_targets = targets.inter_exp_calc(
|
76
|
+
graphs_config["inter-exp"], controller_config, cmdopts
|
77
|
+
)
|
78
|
+
heatmap.generate(cmdopts, pathset, graph_targets, info)
|
79
|
+
|
80
|
+
|
81
|
+
__all__ = [
|
82
|
+
"proc_batch_exp",
|
83
|
+
]
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2024 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"""Generate heatmaps *across* multiple :term:`Experiments <Experiment>`."""
|
7
|
+
|
8
|
+
# Core packages
|
9
|
+
import typing as tp
|
10
|
+
import logging
|
11
|
+
|
12
|
+
# 3rd party packages
|
13
|
+
import json
|
14
|
+
import yaml
|
15
|
+
import strictyaml
|
16
|
+
|
17
|
+
# Project packages
|
18
|
+
from sierra.core import types, batchroot, graphs
|
19
|
+
from sierra.core.graphs import bcbridge, schema
|
20
|
+
|
21
|
+
_logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
|
24
|
+
def generate(
|
25
|
+
cmdopts: types.Cmdopts,
|
26
|
+
pathset: batchroot.PathSet,
|
27
|
+
targets: tp.List[types.YAMLDict],
|
28
|
+
info: bcbridge.GraphInfo,
|
29
|
+
) -> None:
|
30
|
+
"""
|
31
|
+
Generate heatmaps from: term:`Processed Output Data` files.
|
32
|
+
"""
|
33
|
+
large_text = cmdopts["plot_large_text"]
|
34
|
+
|
35
|
+
_logger.info(
|
36
|
+
"Heatmaps from <batch_root>/%s",
|
37
|
+
pathset.stat_interexp_root.relative_to(pathset.root),
|
38
|
+
)
|
39
|
+
|
40
|
+
# For each category of heatmaps we are generating
|
41
|
+
for category in targets:
|
42
|
+
|
43
|
+
# For each graph in each category
|
44
|
+
for graph in category:
|
45
|
+
# Only try to create heatmaps (duh)
|
46
|
+
if graph["type"] != "heatmap":
|
47
|
+
continue
|
48
|
+
|
49
|
+
_logger.trace("\n" + json.dumps(graph, indent=4)) # type: ignore
|
50
|
+
|
51
|
+
try:
|
52
|
+
graph = strictyaml.load(yaml.dump(graph), schema.heatmap).data
|
53
|
+
|
54
|
+
except strictyaml.YAMLError as e:
|
55
|
+
_logger.critical("Non-conformant heatmap YAML: %s", e)
|
56
|
+
raise
|
57
|
+
|
58
|
+
graph_pathset = graphs.PathSet(
|
59
|
+
input_root=pathset.stat_interexp_root,
|
60
|
+
output_root=pathset.graph_interexp_root,
|
61
|
+
batchroot=pathset.root,
|
62
|
+
model_root=None,
|
63
|
+
)
|
64
|
+
# 2025-06-05 [JRH]: We always write stage {3,4} output data files as
|
65
|
+
# .csv because that is currently SIERRA's 'native' format; this may
|
66
|
+
# change in the future.
|
67
|
+
graphs.heatmap(
|
68
|
+
pathset=graph_pathset,
|
69
|
+
input_stem=graph["dest_stem"],
|
70
|
+
output_stem=graph["dest_stem"],
|
71
|
+
medium="storage.csv",
|
72
|
+
title=graph.get("title", None),
|
73
|
+
xlabel=graph.get("xlabel", ""),
|
74
|
+
ylabel=graph.get("ylabel", ""),
|
75
|
+
zlabel=graph.get("zlabel", ""),
|
76
|
+
backend=graph.get("backend", cmdopts["graphs_backend"]),
|
77
|
+
colnames=(
|
78
|
+
graph.get("x", "x"),
|
79
|
+
graph.get("y", "y"),
|
80
|
+
graph.get("z", "z"),
|
81
|
+
),
|
82
|
+
large_text=large_text,
|
83
|
+
)
|
84
|
+
|
85
|
+
|
86
|
+
__all__ = ["generate"]
|
@@ -0,0 +1,134 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2024 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"""Inter-experiment linegraph generation in stage 4."""
|
7
|
+
|
8
|
+
# Core packages
|
9
|
+
import typing as tp
|
10
|
+
import logging
|
11
|
+
|
12
|
+
# 3rd party packages
|
13
|
+
import json
|
14
|
+
import yaml
|
15
|
+
import strictyaml
|
16
|
+
|
17
|
+
# Project packages
|
18
|
+
from sierra.core import types, batchroot, graphs
|
19
|
+
from sierra.core.graphs import bcbridge, schema
|
20
|
+
|
21
|
+
_logger = logging.getLogger(__name__)
|
22
|
+
|
23
|
+
|
24
|
+
def generate(
|
25
|
+
cmdopts: types.Cmdopts,
|
26
|
+
pathset: batchroot.PathSet,
|
27
|
+
targets: tp.List[types.YAMLDict],
|
28
|
+
info: bcbridge.GraphInfo,
|
29
|
+
) -> None:
|
30
|
+
"""Generate linegraphs from :term:`Collated Output Data` files.
|
31
|
+
|
32
|
+
The graphs generated by this module respect the ``--exp-range`` cmdline
|
33
|
+
option.
|
34
|
+
"""
|
35
|
+
|
36
|
+
_logger.info(
|
37
|
+
"Linegraphs from <batchroot>/%s",
|
38
|
+
pathset.stat_interexp_root.relative_to(pathset.root),
|
39
|
+
)
|
40
|
+
|
41
|
+
# For each category of linegraphs we are generating
|
42
|
+
for category in targets:
|
43
|
+
|
44
|
+
# For each graph in each category
|
45
|
+
for graph in category:
|
46
|
+
if graph["type"] not in ["summary_line", "stacked_line"]:
|
47
|
+
continue
|
48
|
+
|
49
|
+
_logger.trace("\n" + json.dumps(graph, indent=4)) # type: ignore
|
50
|
+
|
51
|
+
if graph["type"] == "summary_line":
|
52
|
+
try:
|
53
|
+
graph = strictyaml.load(yaml.dump(graph), schema.summary_line).data
|
54
|
+
except strictyaml.YAMLError as e:
|
55
|
+
_logger.critical("Non-conformant summary_line YAML: %s", e)
|
56
|
+
raise
|
57
|
+
_gen_summary_linegraph(graph, pathset, cmdopts, info)
|
58
|
+
elif graph["type"] == "stacked_line":
|
59
|
+
try:
|
60
|
+
graph = strictyaml.load(yaml.dump(graph), schema.stacked_line).data
|
61
|
+
except strictyaml.YAMLError as e:
|
62
|
+
_logger.critical("Non-conformant stacked_line YAML: %s", e)
|
63
|
+
raise
|
64
|
+
_gen_stacked_linegraph(graph, pathset, cmdopts, info)
|
65
|
+
|
66
|
+
|
67
|
+
def _gen_summary_linegraph(
|
68
|
+
graph: types.YAMLDict,
|
69
|
+
pathset: batchroot.PathSet,
|
70
|
+
cmdopts: types.Cmdopts,
|
71
|
+
info: bcbridge.GraphInfo,
|
72
|
+
) -> None:
|
73
|
+
legend = "{0}+{1}".format(cmdopts["controller"], cmdopts["scenario"])
|
74
|
+
|
75
|
+
paths = graphs.PathSet(
|
76
|
+
input_root=pathset.stat_interexp_root,
|
77
|
+
output_root=pathset.graph_interexp_root,
|
78
|
+
batchroot=pathset.root,
|
79
|
+
model_root=pathset.model_interexp_root,
|
80
|
+
)
|
81
|
+
|
82
|
+
# 2025-06-05 [JRH]: We always write stage {3,4} output data files as .csv
|
83
|
+
# because that is currently SIERRA's 'native' format; this may change in the
|
84
|
+
# future.
|
85
|
+
graphs.summary_line(
|
86
|
+
paths=paths,
|
87
|
+
input_stem=graph["dest_stem"],
|
88
|
+
output_stem=graph["dest_stem"],
|
89
|
+
medium="storage.csv",
|
90
|
+
legend=[legend],
|
91
|
+
stats=cmdopts["dist_stats"],
|
92
|
+
title=graph["title"],
|
93
|
+
xlabel=info.xlabel,
|
94
|
+
ylabel=graph.get("ylabel", None),
|
95
|
+
backend=graph.get("backend", cmdopts["graphs_backend"]),
|
96
|
+
xticks=info.xticks,
|
97
|
+
xticklabels=info.xticklabels,
|
98
|
+
logyscale=graph.get("logy", cmdopts["plot_log_yscale"]),
|
99
|
+
large_text=cmdopts["plot_large_text"],
|
100
|
+
)
|
101
|
+
|
102
|
+
|
103
|
+
def _gen_stacked_linegraph(
|
104
|
+
graph: types.YAMLDict,
|
105
|
+
pathset: batchroot.PathSet,
|
106
|
+
cmdopts: types.Cmdopts,
|
107
|
+
info: bcbridge.GraphInfo,
|
108
|
+
) -> None:
|
109
|
+
|
110
|
+
paths = graphs.PathSet(
|
111
|
+
input_root=pathset.stat_interexp_root,
|
112
|
+
output_root=pathset.graph_interexp_root,
|
113
|
+
model_root=None,
|
114
|
+
batchroot=pathset.root,
|
115
|
+
)
|
116
|
+
|
117
|
+
graphs.stacked_line(
|
118
|
+
paths=paths,
|
119
|
+
input_stem=graph["dest_stem"],
|
120
|
+
output_stem=graph["dest_stem"],
|
121
|
+
stats=cmdopts["dist_stats"],
|
122
|
+
medium="storage.csv",
|
123
|
+
title=graph["title"],
|
124
|
+
backend=graph.get("backend", cmdopts["graphs_backend"]),
|
125
|
+
xticks=None,
|
126
|
+
xlabel=graph.get("xlabel", "Time"),
|
127
|
+
ylabel=graph.get("ylabel", None),
|
128
|
+
logyscale=graph.get("logy", cmdopts["plot_log_yscale"]),
|
129
|
+
large_text=cmdopts["plot_large_text"],
|
130
|
+
legend=graph.get("legend", [f"exp{i}" for i in range(0, len(info.exp_names))]),
|
131
|
+
)
|
132
|
+
|
133
|
+
|
134
|
+
__all__ = ["generate"]
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2024 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"""Container module for intra-experiment graph generation in stage 4."""
|
7
|
+
|
8
|
+
# Core packages
|
9
|
+
|
10
|
+
# 3rd party packages
|
11
|
+
|
12
|
+
# Project packages
|
13
|
+
from . import generate as generate
|
14
|
+
from . import line as line
|
15
|
+
from . import heatmap as heatmap
|