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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. sierra/__init__.py +3 -3
  2. sierra/core/__init__.py +3 -3
  3. sierra/core/batchroot.py +223 -0
  4. sierra/core/cmdline.py +681 -1057
  5. sierra/core/compare.py +11 -0
  6. sierra/core/config.py +96 -88
  7. sierra/core/engine.py +306 -0
  8. sierra/core/execenv.py +380 -0
  9. sierra/core/expdef.py +11 -0
  10. sierra/core/experiment/__init__.py +1 -0
  11. sierra/core/experiment/bindings.py +150 -101
  12. sierra/core/experiment/definition.py +414 -245
  13. sierra/core/experiment/spec.py +83 -85
  14. sierra/core/exproot.py +44 -0
  15. sierra/core/generators/__init__.py +10 -0
  16. sierra/core/generators/experiment.py +528 -0
  17. sierra/core/generators/generator_factory.py +138 -137
  18. sierra/core/graphs/__init__.py +23 -0
  19. sierra/core/graphs/bcbridge.py +94 -0
  20. sierra/core/graphs/heatmap.py +245 -324
  21. sierra/core/graphs/pathset.py +27 -0
  22. sierra/core/graphs/schema.py +77 -0
  23. sierra/core/graphs/stacked_line.py +341 -0
  24. sierra/core/graphs/summary_line.py +506 -0
  25. sierra/core/logging.py +3 -2
  26. sierra/core/models/__init__.py +3 -1
  27. sierra/core/models/info.py +19 -0
  28. sierra/core/models/interface.py +52 -122
  29. sierra/core/pipeline/__init__.py +2 -5
  30. sierra/core/pipeline/pipeline.py +228 -126
  31. sierra/core/pipeline/stage1/__init__.py +10 -0
  32. sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
  33. sierra/core/pipeline/stage2/__init__.py +10 -0
  34. sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
  35. sierra/core/pipeline/stage2/runner.py +401 -0
  36. sierra/core/pipeline/stage3/__init__.py +12 -0
  37. sierra/core/pipeline/stage3/gather.py +321 -0
  38. sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
  39. sierra/core/pipeline/stage4/__init__.py +12 -2
  40. sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
  41. sierra/core/pipeline/stage5/__init__.py +12 -0
  42. sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
  43. sierra/core/pipeline/yaml.py +48 -0
  44. sierra/core/plugin.py +529 -62
  45. sierra/core/proc.py +11 -0
  46. sierra/core/prod.py +11 -0
  47. sierra/core/ros1/__init__.py +5 -1
  48. sierra/core/ros1/callbacks.py +22 -21
  49. sierra/core/ros1/cmdline.py +59 -88
  50. sierra/core/ros1/generators.py +159 -175
  51. sierra/core/ros1/variables/__init__.py +3 -0
  52. sierra/core/ros1/variables/exp_setup.py +122 -116
  53. sierra/core/startup.py +106 -76
  54. sierra/core/stat_kernels.py +4 -5
  55. sierra/core/storage.py +13 -32
  56. sierra/core/trampoline.py +30 -0
  57. sierra/core/types.py +116 -71
  58. sierra/core/utils.py +103 -106
  59. sierra/core/variables/__init__.py +1 -1
  60. sierra/core/variables/base_variable.py +12 -17
  61. sierra/core/variables/batch_criteria.py +387 -481
  62. sierra/core/variables/builtin.py +135 -0
  63. sierra/core/variables/exp_setup.py +19 -39
  64. sierra/core/variables/population_size.py +72 -76
  65. sierra/core/variables/variable_density.py +44 -68
  66. sierra/core/vector.py +1 -1
  67. sierra/main.py +256 -88
  68. sierra/plugins/__init__.py +119 -0
  69. sierra/plugins/compare/__init__.py +14 -0
  70. sierra/plugins/compare/graphs/__init__.py +19 -0
  71. sierra/plugins/compare/graphs/cmdline.py +120 -0
  72. sierra/plugins/compare/graphs/comparator.py +291 -0
  73. sierra/plugins/compare/graphs/inter_controller.py +531 -0
  74. sierra/plugins/compare/graphs/inter_scenario.py +297 -0
  75. sierra/plugins/compare/graphs/namecalc.py +53 -0
  76. sierra/plugins/compare/graphs/outputroot.py +73 -0
  77. sierra/plugins/compare/graphs/plugin.py +147 -0
  78. sierra/plugins/compare/graphs/preprocess.py +172 -0
  79. sierra/plugins/compare/graphs/schema.py +37 -0
  80. sierra/plugins/engine/__init__.py +14 -0
  81. sierra/plugins/engine/argos/__init__.py +18 -0
  82. sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
  83. sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
  84. sierra/plugins/engine/argos/generators/engine.py +394 -0
  85. sierra/plugins/engine/argos/plugin.py +393 -0
  86. sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
  87. sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
  88. sierra/plugins/engine/argos/variables/cameras.py +240 -0
  89. sierra/plugins/engine/argos/variables/constant_density.py +112 -0
  90. sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
  91. sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
  92. sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
  93. sierra/plugins/engine/argos/variables/population_size.py +115 -0
  94. sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
  95. sierra/plugins/engine/argos/variables/rendering.py +108 -0
  96. sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
  97. sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
  98. sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
  99. sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
  100. sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
  101. sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
  102. sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
  103. sierra/plugins/engine/ros1robot/__init__.py +18 -0
  104. sierra/plugins/engine/ros1robot/cmdline.py +159 -0
  105. sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
  106. sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
  107. sierra/plugins/engine/ros1robot/plugin.py +410 -0
  108. sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
  109. sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
  110. sierra/plugins/execenv/__init__.py +11 -0
  111. sierra/plugins/execenv/hpc/__init__.py +18 -0
  112. sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
  113. sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
  114. sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
  115. sierra/plugins/execenv/hpc/cmdline.py +137 -0
  116. sierra/plugins/execenv/hpc/local/__init__.py +18 -0
  117. sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
  118. sierra/plugins/execenv/hpc/local/plugin.py +145 -0
  119. sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
  120. sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
  121. sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
  122. sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
  123. sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
  124. sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
  125. sierra/plugins/execenv/prefectserver/__init__.py +18 -0
  126. sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
  127. sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
  128. sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
  129. sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
  130. sierra/plugins/execenv/prefectserver/flow.py +66 -0
  131. sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
  132. sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
  133. sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
  134. sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
  135. sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
  136. sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
  137. sierra/plugins/expdef/__init__.py +14 -0
  138. sierra/plugins/expdef/json/__init__.py +14 -0
  139. sierra/plugins/expdef/json/plugin.py +504 -0
  140. sierra/plugins/expdef/xml/__init__.py +14 -0
  141. sierra/plugins/expdef/xml/plugin.py +386 -0
  142. sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
  143. sierra/plugins/proc/collate/__init__.py +15 -0
  144. sierra/plugins/proc/collate/cmdline.py +47 -0
  145. sierra/plugins/proc/collate/plugin.py +271 -0
  146. sierra/plugins/proc/compress/__init__.py +18 -0
  147. sierra/plugins/proc/compress/cmdline.py +47 -0
  148. sierra/plugins/proc/compress/plugin.py +123 -0
  149. sierra/plugins/proc/decompress/__init__.py +18 -0
  150. sierra/plugins/proc/decompress/plugin.py +96 -0
  151. sierra/plugins/proc/imagize/__init__.py +15 -0
  152. sierra/plugins/proc/imagize/cmdline.py +49 -0
  153. sierra/plugins/proc/imagize/plugin.py +270 -0
  154. sierra/plugins/proc/modelrunner/__init__.py +16 -0
  155. sierra/plugins/proc/modelrunner/plugin.py +250 -0
  156. sierra/plugins/proc/statistics/__init__.py +15 -0
  157. sierra/plugins/proc/statistics/cmdline.py +64 -0
  158. sierra/plugins/proc/statistics/plugin.py +390 -0
  159. sierra/plugins/{hpc → prod}/__init__.py +1 -0
  160. sierra/plugins/prod/graphs/__init__.py +18 -0
  161. sierra/plugins/prod/graphs/cmdline.py +269 -0
  162. sierra/plugins/prod/graphs/collate.py +279 -0
  163. sierra/plugins/prod/graphs/inter/__init__.py +13 -0
  164. sierra/plugins/prod/graphs/inter/generate.py +83 -0
  165. sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
  166. sierra/plugins/prod/graphs/inter/line.py +134 -0
  167. sierra/plugins/prod/graphs/intra/__init__.py +15 -0
  168. sierra/plugins/prod/graphs/intra/generate.py +202 -0
  169. sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
  170. sierra/plugins/prod/graphs/intra/line.py +114 -0
  171. sierra/plugins/prod/graphs/plugin.py +103 -0
  172. sierra/plugins/prod/graphs/targets.py +63 -0
  173. sierra/plugins/prod/render/__init__.py +18 -0
  174. sierra/plugins/prod/render/cmdline.py +72 -0
  175. sierra/plugins/prod/render/plugin.py +282 -0
  176. sierra/plugins/storage/__init__.py +5 -0
  177. sierra/plugins/storage/arrow/__init__.py +18 -0
  178. sierra/plugins/storage/arrow/plugin.py +38 -0
  179. sierra/plugins/storage/csv/__init__.py +9 -0
  180. sierra/plugins/storage/csv/plugin.py +12 -5
  181. sierra/version.py +3 -2
  182. sierra_research-1.5.0.dist-info/METADATA +238 -0
  183. sierra_research-1.5.0.dist-info/RECORD +186 -0
  184. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
  185. sierra/core/experiment/xml.py +0 -454
  186. sierra/core/generators/controller_generator_parser.py +0 -34
  187. sierra/core/generators/exp_creator.py +0 -351
  188. sierra/core/generators/exp_generators.py +0 -142
  189. sierra/core/graphs/scatterplot2D.py +0 -109
  190. sierra/core/graphs/stacked_line_graph.py +0 -251
  191. sierra/core/graphs/stacked_surface_graph.py +0 -220
  192. sierra/core/graphs/summary_line_graph.py +0 -371
  193. sierra/core/hpc/cmdline.py +0 -142
  194. sierra/core/models/graphs.py +0 -87
  195. sierra/core/pipeline/stage2/exp_runner.py +0 -286
  196. sierra/core/pipeline/stage3/imagizer.py +0 -149
  197. sierra/core/pipeline/stage3/run_collator.py +0 -317
  198. sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
  199. sierra/core/pipeline/stage4/graph_collator.py +0 -320
  200. sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
  201. sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
  202. sierra/core/pipeline/stage4/model_runner.py +0 -168
  203. sierra/core/pipeline/stage4/rendering.py +0 -283
  204. sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
  205. sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
  206. sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
  207. sierra/core/platform.py +0 -493
  208. sierra/core/plugin_manager.py +0 -369
  209. sierra/core/root_dirpath_generator.py +0 -241
  210. sierra/plugins/hpc/adhoc/plugin.py +0 -125
  211. sierra/plugins/hpc/local/plugin.py +0 -81
  212. sierra/plugins/hpc/pbs/__init__.py +0 -9
  213. sierra/plugins/hpc/pbs/plugin.py +0 -126
  214. sierra/plugins/hpc/slurm/__init__.py +0 -9
  215. sierra/plugins/hpc/slurm/plugin.py +0 -130
  216. sierra/plugins/platform/__init__.py +0 -9
  217. sierra/plugins/platform/argos/__init__.py +0 -9
  218. sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
  219. sierra/plugins/platform/argos/plugin.py +0 -337
  220. sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
  221. sierra/plugins/platform/argos/variables/cameras.py +0 -243
  222. sierra/plugins/platform/argos/variables/constant_density.py +0 -136
  223. sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
  224. sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
  225. sierra/plugins/platform/argos/variables/population_size.py +0 -102
  226. sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
  227. sierra/plugins/platform/argos/variables/rendering.py +0 -104
  228. sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
  229. sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
  230. sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
  231. sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
  232. sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
  233. sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
  234. sierra/plugins/platform/ros1robot/__init__.py +0 -9
  235. sierra/plugins/platform/ros1robot/cmdline.py +0 -175
  236. sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
  237. sierra/plugins/platform/ros1robot/plugin.py +0 -373
  238. sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
  239. sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
  240. sierra/plugins/robot/__init__.py +0 -9
  241. sierra/plugins/robot/turtlebot3/__init__.py +0 -9
  242. sierra/plugins/robot/turtlebot3/plugin.py +0 -194
  243. sierra_research-1.3.11.data/data/share/man/man1/sierra-cli.1 +0 -2349
  244. sierra_research-1.3.11.data/data/share/man/man7/sierra-examples.7 +0 -508
  245. sierra_research-1.3.11.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
  246. sierra_research-1.3.11.data/data/share/man/man7/sierra-glossary.7 +0 -285
  247. sierra_research-1.3.11.data/data/share/man/man7/sierra-platforms.7 +0 -358
  248. sierra_research-1.3.11.data/data/share/man/man7/sierra-usage.7 +0 -729
  249. sierra_research-1.3.11.data/data/share/man/man7/sierra.7 +0 -78
  250. sierra_research-1.3.11.dist-info/METADATA +0 -492
  251. sierra_research-1.3.11.dist-info/RECORD +0 -133
  252. sierra_research-1.3.11.dist-info/top_level.txt +0 -1
  253. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
  254. {sierra_research-1.3.11.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,297 @@
1
+ # Copyright 2019 John Harwell, All rights reserved.
2
+ #
3
+ # SPDX-License-Identifier: MIT
4
+
5
+ """Classes for comparing deliverables across a set of scenarios.
6
+
7
+ Univariate batch criteria only. The same controller must be used for all
8
+ scenarios.
9
+
10
+ """
11
+
12
+ # Core packages
13
+ import typing as tp
14
+ import argparse
15
+ import logging
16
+ import pathlib
17
+
18
+ # 3rd party packages
19
+
20
+ # Project packages
21
+ from sierra.core.variables import batch_criteria as bc
22
+ import sierra.core.plugin as pm
23
+ from sierra.core import types, utils, config, storage, batchroot, graphs
24
+ from sierra.plugins.compare.graphs import outputroot, preprocess, namecalc, comparator
25
+
26
+
27
+ class UnivarInterScenarioComparator(comparator.BaseComparator):
28
+ """Compares a single controller across a set of scenarios.
29
+
30
+ Graph generation is controlled via a config file parsed in
31
+ :class:`~sierra.core.pipeline.stage5.pipeline_stage5.PipelineStage5`.
32
+
33
+ Univariate batch criteria only.
34
+
35
+ Attributes:
36
+ controller: Controller to use.
37
+
38
+ scenarios: List of scenario names to compare ``controller`` across.
39
+
40
+ sc_csv_root: Absolute directory path to the location scenario CSV
41
+ files should be output to.
42
+
43
+ sc_graph_root: Absolute directory path to the location the generated
44
+ graphs should be output to.
45
+
46
+ cmdopts: Dictionary of parsed cmdline parameters.
47
+
48
+ cli_args: :class:`argparse` object containing the cmdline
49
+ parameters. Needed for
50
+ :class:`~sierra.core.variables.batch_criteria.XVarBatchCriteria`
51
+ generation for each scenario controllers are compared within,
52
+ as batch criteria is dependent on controller+scenario
53
+ definition, and needs to be re-generated for each scenario in
54
+ order to get graph labels/axis ticks to come out right in all
55
+ cases.
56
+
57
+ """
58
+
59
+ def __init__(
60
+ self,
61
+ controller: str,
62
+ scenarios: tp.List[str],
63
+ stage5_roots: outputroot.PathSet,
64
+ cmdopts: types.Cmdopts,
65
+ cli_args: argparse.Namespace,
66
+ main_config: types.YAMLDict,
67
+ ) -> None:
68
+ super().__init__(scenarios, stage5_roots, cmdopts, cli_args, main_config)
69
+ self.logger = logging.getLogger(__name__)
70
+ self.controller = controller
71
+
72
+ def exp_select(self) -> tp.List[batchroot.ExpRoot]:
73
+ """
74
+ Determine if a scenario can be include in the comparison for a controller.
75
+
76
+ """
77
+ selected = []
78
+ for scenario in self.things:
79
+ for candidate in (self.project_root / self.controller / scenario).iterdir():
80
+ root = batchroot.ExpRoot(
81
+ sierra_root=self.cmdopts["sierra_root"],
82
+ project=self.cmdopts["project"],
83
+ controller=self.controller,
84
+ leaf=batchroot.ExpRootLeaf.from_name(candidate.name),
85
+ scenario=scenario,
86
+ )
87
+ if root.to_path().exists():
88
+ selected.append(root)
89
+ return selected
90
+
91
+ def compare(
92
+ self,
93
+ cmdopts: types.Cmdopts,
94
+ graph: types.YAMLDict,
95
+ roots: tp.List[batchroot.ExpRoot],
96
+ legend: tp.List[str],
97
+ ) -> None:
98
+ for scenario in self.things:
99
+ valid_configurations = sum(r.scenario == scenario for r in roots)
100
+ if valid_configurations > 1:
101
+ self.logger.warning(
102
+ "Skipping ambiguous comparison for scenario %s: was run on multiple selected batch roots %s",
103
+ scenario,
104
+ [r.to_str() for r in roots],
105
+ )
106
+ continue
107
+
108
+ if valid_configurations == 0:
109
+ self.logger.warning(
110
+ "Skipping comparison for scenario %s: not run on any selected batch roots %s",
111
+ scenario,
112
+ [r.to_str() for r in roots],
113
+ )
114
+ continue
115
+
116
+ # Each controller should have been run on exactly ONE batch experiment
117
+ # that we selected for controller comparison, by definition.
118
+ root = next(r for r in roots if r.scenario == scenario)
119
+
120
+ # We need to generate the root directory paths for each batch experiment
121
+ # (which lives inside of the scenario dir), because they are all
122
+ # different. We need generate these paths for EACH controller, because
123
+ # the controller is part of the batch root path.
124
+ pathset = batchroot.from_exp(
125
+ sierra_root=self.cli_args.sierra_root,
126
+ project=self.cli_args.project,
127
+ batch_leaf=root.leaf,
128
+ controller=self.controller,
129
+ scenario=root.scenario,
130
+ )
131
+
132
+ # For each scenario, we have to create the batch criteria for it,
133
+ # because they are all different.
134
+ criteria = bc.factory(
135
+ self.main_config,
136
+ cmdopts,
137
+ pathset.input_root,
138
+ self.cli_args,
139
+ root.scenario,
140
+ )
141
+
142
+ self._gen_csvs(
143
+ criteria=criteria,
144
+ pathset=pathset,
145
+ project=self.cli_args.project,
146
+ root=root,
147
+ src_stem=graph["src_stem"],
148
+ dest_stem=graph["dest_stem"],
149
+ index=graph.get("index", -1),
150
+ )
151
+
152
+ self._gen_graph(
153
+ batch_leaf=root.leaf,
154
+ criteria=criteria,
155
+ cmdopts=cmdopts,
156
+ batch_output_root=pathset.output_root,
157
+ dest_stem=graph["dest_stem"],
158
+ title=graph.get("title", None),
159
+ label=graph["label"],
160
+ legend=legend,
161
+ backend=graph.get("backend", cmdopts["graphs_backend"]),
162
+ )
163
+
164
+ def _gen_graph(
165
+ self,
166
+ batch_leaf: batchroot.ExpRootLeaf,
167
+ criteria: bc.XVarBatchCriteria,
168
+ cmdopts: types.Cmdopts,
169
+ batch_output_root: pathlib.Path,
170
+ dest_stem: str,
171
+ title: str,
172
+ label: str,
173
+ legend: tp.List[str],
174
+ backend: str,
175
+ inc_exps: tp.Optional[str] = None,
176
+ ) -> None:
177
+ """Generate graph comparing the specified controller across scenarios."""
178
+ opath_leaf = namecalc.for_sc(batch_leaf, self.things, dest_stem, None)
179
+ info = criteria.graph_info(cmdopts, batch_output_root=batch_output_root)
180
+
181
+ xticklabels = info.xticklabels
182
+ xticks = info.xticks
183
+ if inc_exps is not None:
184
+ xticklabels = utils.exp_include_filter(
185
+ inc_exps, info.xticklabels, criteria.n_exp()
186
+ )
187
+ xticks = utils.exp_include_filter(inc_exps, info.xticks, criteria.n_exp())
188
+
189
+ paths = graphs.PathSet(
190
+ input_root=self.stage5_roots.csv_root,
191
+ output_root=self.stage5_roots.graph_root,
192
+ batchroot=pathlib.Path(
193
+ self.cmdopts["sierra_root"], self.cmdopts["project"]
194
+ ),
195
+ model_root=None,
196
+ )
197
+
198
+ graphs.summary_line(
199
+ paths=paths,
200
+ input_stem=opath_leaf,
201
+ stats=cmdopts["dist_stats"],
202
+ medium=cmdopts["storage"],
203
+ output_stem=opath_leaf,
204
+ title=title,
205
+ xlabel=info.xlabel,
206
+ ylabel=label,
207
+ backend=backend,
208
+ xticks=xticks,
209
+ xticklabels=xticklabels,
210
+ logyscale=cmdopts["plot_log_yscale"],
211
+ large_text=cmdopts["plot_large_text"],
212
+ legend=legend,
213
+ )
214
+
215
+ def _gen_csvs(
216
+ self,
217
+ criteria: bc.XVarBatchCriteria,
218
+ pathset: batchroot.PathSet,
219
+ project: str,
220
+ root: batchroot.ExpRoot,
221
+ index: int,
222
+ src_stem: str,
223
+ dest_stem: str,
224
+ ) -> None:
225
+ """Generate a set of CSV files for use in inter-scenario graph generation.
226
+
227
+ Generates:
228
+
229
+ - ``.mean`` CSV file containing results for each scenario the controller
230
+ is being compared across, 1 per line.
231
+
232
+ - Stastics CSV files containing various statistics for the ``.mean`` CSV
233
+ file, 1 per line.
234
+
235
+ - ``.model`` file containing model predictions for controller behavior
236
+ during each scenario, 1 per line (not generated if models were not run
237
+ the performance measures we are generating graphs for).
238
+
239
+ - ``.legend`` file containing legend values for models to plot (not
240
+ generated if models were not run for the performance measures we are
241
+ generating graphs for).
242
+
243
+ """
244
+
245
+ csv_ipath_stem = pathset.stat_interexp_root / src_stem
246
+
247
+ # Some experiments might not generate the necessary performance measure
248
+ # CSVs for graph generation, which is OK.
249
+ csv_ipath_mean = csv_ipath_stem.with_suffix(config.kStats["mean"].exts["mean"])
250
+ if not utils.path_exists(csv_ipath_mean):
251
+ self.logger.warning(
252
+ "%s missing for controller %s", csv_ipath_mean, self.controller
253
+ )
254
+ return
255
+
256
+ preparer = preprocess.IntraExpPreparer(
257
+ ipath_stem=pathset.stat_interexp_root,
258
+ ipath_leaf=src_stem,
259
+ opath_stem=self.stage5_roots.csv_root,
260
+ criteria=criteria,
261
+ )
262
+ opath_leaf = namecalc.for_sc(root.leaf, self.things, dest_stem, None)
263
+
264
+ preparer.for_sc(
265
+ scenario=root.scenario,
266
+ opath_leaf=opath_leaf,
267
+ index=index,
268
+ inc_exps=None,
269
+ )
270
+
271
+ # Collect performance results models and legends. Append to existing
272
+ # dataframes if they exist, otherwise start new ones.
273
+ # Can't use with_suffix() for opath, because that path contains the
274
+ # controller, which already has a '.' in it.
275
+ # model_istem = pathlib.Path(pathset.model_root, src_stem)
276
+ model_ostem = self.stage5_roots.model_root / (dest_stem + "-" + self.controller)
277
+
278
+ # model_ipath = model_istem.with_suffix(config.kModelsExt["model"])
279
+ model_opath = model_ostem.with_name(
280
+ model_ostem.name + config.kModelsExt["model"]
281
+ )
282
+ # model_df = self._accum_df(criteria, model_ipath, model_opath, src_stem)
283
+ model_df = None
284
+ legend_opath = model_ostem.with_name(
285
+ model_ostem.name + config.kModelsExt["legend"]
286
+ )
287
+
288
+ if model_df is not None:
289
+ storage.df_write(model_df, model_opath, "storage.csv", index=False)
290
+
291
+ with utils.utf8open(legend_opath, "a") as f:
292
+ sgp = pm.module_load_tiered(project=project, path="generators.scenario")
293
+ kw = sgp.to_dict(root.scenario)
294
+ f.write("{0} Model Prediction\n".format(kw["scenario_tag"]))
295
+
296
+
297
+ __all__ = ["UnivarInterScenarioComparator"]
@@ -0,0 +1,53 @@
1
+ #
2
+ # Copyright 2024 John Harwell, All rights reserved.
3
+ #
4
+ # SPDX-License Identifier: MIT
5
+ #
6
+ """Utility module for calculating path names."""
7
+
8
+ # Core packages
9
+ import typing as tp
10
+
11
+ # 3rd party packages
12
+
13
+ # Project packages
14
+ from sierra.core import batchroot
15
+
16
+
17
+ def for_cc(
18
+ leaf: batchroot.ExpRootLeaf, new_stem: str, indices: tp.Union[tp.List[int], None]
19
+ ) -> str:
20
+ """
21
+ Calculate a name suitable for CSVs/graphs in stage 5 to ensure uniqueness.
22
+
23
+ "Name" here is in pathlib terminology. Targets controller comparisons. Since
24
+ controller name is part of the default batchroot path, AND each batchroot
25
+ path is unique, this case is easy.
26
+ """
27
+ name = "{0}-{1}".format(new_stem, leaf.to_path().name)
28
+
29
+ if indices is not None:
30
+ name += "_" + "".join([str(i) for i in indices])
31
+
32
+ return name
33
+
34
+
35
+ def for_sc(
36
+ leaf: batchroot.ExpRootLeaf,
37
+ scenarios: tp.List[str],
38
+ new_stem: str,
39
+ indices: tp.Union[tp.List[int], None],
40
+ ) -> str:
41
+ """
42
+ Calculate a name suitable for CSVs/graphs in stage 5 to ensure uniqueness.
43
+
44
+ "Name" here is in pathlib terminology. Targets scenario comparisons, so we
45
+ need a list of all scenarios in the path to eliminate path collisions in all
46
+ cases.
47
+ """
48
+ name = "{0}-{1}+{2}".format(new_stem, "+".join(scenarios), leaf.to_path())
49
+
50
+ if indices is not None:
51
+ name += "_" + "".join([str(i) for i in indices])
52
+
53
+ return name
@@ -0,0 +1,73 @@
1
+ #
2
+ # Copyright 2024 John Harwell, All rights reserved.
3
+ #
4
+ # SPDX-License Identifier: MIT
5
+ #
6
+ """
7
+ Utility module for functionality for managing all the paths used in stage5.
8
+ """
9
+ # Core packages
10
+ import pathlib
11
+ import typing as tp
12
+
13
+ # 3rd party packages
14
+
15
+ # Project packages
16
+ from sierra.core import types
17
+
18
+
19
+ class PathSet:
20
+ """
21
+ The set of filesystem paths used during stage 5.
22
+
23
+ Collected here in the interest of DRY.
24
+
25
+ Attributes:
26
+ graph_root: The path where all graphs will be created.
27
+
28
+ csv_root: The path where all collated CSVs will be stored.
29
+
30
+ model_root: The path where all CSVs resulting from model execution will
31
+ be stored.
32
+ """
33
+
34
+ def __init__(self,
35
+ cmdopts: types.Cmdopts,
36
+ controllers: tp.List[str],
37
+ scenarios: tp.List[str]) -> None:
38
+ assert not (controllers and scenarios)
39
+
40
+ # We add the controller list to the directory path for the .csv
41
+ # and graph directories so that multiple runs of stage5 with
42
+ # different controller sets do not overwrite each other
43
+ # (i.e. make stage5 more idempotent).
44
+ if controllers:
45
+ self.graph_root = pathlib.Path(cmdopts['sierra_root'],
46
+ cmdopts['project'],
47
+ '+'.join(controllers) + "-cc-graphs")
48
+
49
+ self.csv_root = pathlib.Path(cmdopts['sierra_root'],
50
+ cmdopts['project'],
51
+ '+'.join(controllers) + "-cc-csvs")
52
+
53
+ self.model_root = None
54
+
55
+ if scenarios:
56
+ # We add the scenario list to the directory path for the .csv
57
+ # and graph directories so that multiple runs of stage5 with
58
+ # different scenario sets do not overwrite each other (i.e. make
59
+ # stage5 idempotent).
60
+ self.graph_root = pathlib.Path(cmdopts['sierra_root'],
61
+ cmdopts['project'],
62
+ '+'.join(scenarios) + "-sc-graphs")
63
+ self.csv_root = pathlib.Path(cmdopts['sierra_root'],
64
+ cmdopts['project'],
65
+ '+'.join(scenarios) + "-sc-csvs")
66
+ self.model_root = pathlib.Path(cmdopts['sierra_root'],
67
+ cmdopts['project'],
68
+ '+'.join(scenarios) + "-sc-models")
69
+
70
+
71
+ __all__ = [
72
+ "PathSet"
73
+ ]
@@ -0,0 +1,147 @@
1
+ #
2
+ # Copyright 2025 John Harwell, All rights reserved.
3
+ #
4
+ # SPDX-License Identifier: MIT
5
+ #
6
+ """
7
+ Stage5 plugin to compare graphs across {controllers, scenarios, criterias}.
8
+ """
9
+
10
+ # Core packages
11
+ import logging
12
+ import argparse
13
+ import pathlib
14
+
15
+ # 3rd party packages
16
+ import yaml
17
+
18
+ # Project packages
19
+ from sierra.core import types, utils, config
20
+ from sierra.plugins.compare.graphs import outputroot
21
+ from sierra.plugins.compare.graphs import inter_controller as intercc
22
+ from sierra.plugins.compare.graphs import inter_scenario as intersc
23
+
24
+ _logger = logging.getLogger(__name__)
25
+
26
+
27
+ def proc_exps(
28
+ main_config: types.YAMLDict,
29
+ cmdopts: types.Cmdopts,
30
+ cli_args: argparse.Namespace,
31
+ ) -> None:
32
+ stage5_roots = outputroot.PathSet(
33
+ cmdopts,
34
+ cmdopts["things"].split(",") if cmdopts["across"] == "controllers" else None,
35
+ cmdopts["things"].split(",") if cmdopts["across"] == "scenarios" else None,
36
+ )
37
+
38
+ if stage5_roots.model_root is not None:
39
+ utils.dir_create_checked(stage5_roots.model_root, True)
40
+
41
+ # Create directories for .csv files and graphs
42
+ utils.dir_create_checked(stage5_roots.graph_root, True)
43
+ utils.dir_create_checked(stage5_roots.csv_root, True)
44
+
45
+ assert (
46
+ cmdopts["bc_cardinality"] <= 2
47
+ ), "This plugin only supports batch criteria with cardinality <=2"
48
+
49
+ path = pathlib.Path(cmdopts["project_config_root"], config.kYAML.graphs)
50
+ with utils.utf8open(path) as f:
51
+ graphs_config = yaml.load(f, yaml.FullLoader)
52
+
53
+ if cmdopts["across"] == "controllers":
54
+ _run_cc(main_config, cmdopts, cli_args, stage5_roots, graphs_config)
55
+ elif cmdopts["across"] == "scenarios":
56
+ _run_sc(main_config, cmdopts, cli_args, stage5_roots, graphs_config)
57
+ elif cmdopts["across"] == "criterias":
58
+ raise RuntimeError("Inter-criteria comparison not implemented yet!")
59
+
60
+
61
+ def _run_cc(
62
+ main_config: types.YAMLDict,
63
+ cmdopts: types.Cmdopts,
64
+ cli_args: argparse.Namespace,
65
+ stage5_roots: outputroot.PathSet,
66
+ graphs_config: types.YAMLDict,
67
+ ) -> None:
68
+ controllers = cmdopts["things"].split(",")
69
+
70
+ # Use nice controller names on graph legends if configured
71
+ if cmdopts["things_legend"] is not None:
72
+ legend = cmdopts["things_legend"].split(",")
73
+ else:
74
+ legend = controllers
75
+
76
+ _logger.info("Inter-batch controller comparison of %s...", controllers)
77
+
78
+ if cmdopts["bc_cardinality"] == 1:
79
+ univar = intercc.UnivarInterControllerComparator(
80
+ controllers,
81
+ stage5_roots,
82
+ cmdopts,
83
+ cli_args,
84
+ main_config,
85
+ )
86
+ univar(
87
+ target_graphs=list(graphs_config["inter-controller"]),
88
+ legend=list(legend),
89
+ )
90
+ elif cmdopts["bc_cardinality"] == 2:
91
+ bivar = intercc.BivarInterControllerComparator(
92
+ controllers,
93
+ stage5_roots,
94
+ cmdopts,
95
+ cli_args,
96
+ main_config,
97
+ )
98
+ bivar(
99
+ target_graphs=list(graphs_config["inter-controller"]),
100
+ legend=list(legend),
101
+ )
102
+
103
+ _logger.info("Inter-batch controller comparison complete")
104
+
105
+
106
+ def _run_sc(
107
+ main_config: types.YAMLDict,
108
+ cmdopts: types.Cmdopts,
109
+ cli_args: argparse.Namespace,
110
+ stage5_roots: outputroot.PathSet,
111
+ graphs_config: types.YAMLDict,
112
+ ) -> None:
113
+ scenarios = cmdopts["things"].split(",")
114
+
115
+ # Use nice scenario names on graph legends if configured
116
+ if cmdopts["things_legend"] is not None:
117
+ legend = cmdopts["things_legend"].split(",")
118
+ else:
119
+ legend = scenarios
120
+
121
+ controller = cmdopts["controller"]
122
+
123
+ _logger.info("Inter-batch comparison of %s across %s...", controller, scenarios)
124
+
125
+ assert (
126
+ cmdopts["bc_cardinality"] == 1
127
+ ), "inter-scenario controller comparison only valid for univariate batch criteria"
128
+
129
+ comparator = intersc.UnivarInterScenarioComparator(
130
+ controller,
131
+ scenarios,
132
+ stage5_roots,
133
+ cmdopts,
134
+ cli_args,
135
+ main_config,
136
+ )
137
+
138
+ comparator(
139
+ target_graphs=list(graphs_config["inter-scenario"]),
140
+ legend=list(legend),
141
+ )
142
+
143
+ _logger.info(
144
+ "Inter-batch comparison of %s across %s complete",
145
+ controller,
146
+ scenarios,
147
+ )