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.
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.6.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 -249
  191. sierra/core/graphs/stacked_surface_graph.py +0 -220
  192. sierra/core/graphs/summary_line_graph.py +0 -369
  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 -319
  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.6.data/data/share/man/man1/sierra-cli.1 +0 -2349
  244. sierra_research-1.3.6.data/data/share/man/man7/sierra-examples.7 +0 -488
  245. sierra_research-1.3.6.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
  246. sierra_research-1.3.6.data/data/share/man/man7/sierra-glossary.7 +0 -285
  247. sierra_research-1.3.6.data/data/share/man/man7/sierra-platforms.7 +0 -358
  248. sierra_research-1.3.6.data/data/share/man/man7/sierra-usage.7 +0 -725
  249. sierra_research-1.3.6.data/data/share/man/man7/sierra.7 +0 -78
  250. sierra_research-1.3.6.dist-info/METADATA +0 -500
  251. sierra_research-1.3.6.dist-info/RECORD +0 -133
  252. sierra_research-1.3.6.dist-info/top_level.txt +0 -1
  253. {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
  254. {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -1,989 +0,0 @@
1
- # Copyright 2019 John Harwell, All rights reserved.
2
- #
3
- # SPDX-License-Identifier: MIT
4
-
5
- """Classes for comparing deliverables within the same scenario.
6
-
7
- Univariate and bivariate batch criteria.
8
-
9
- """
10
-
11
- # Core packages
12
- import os
13
- import copy
14
- import glob
15
- import re
16
- import typing as tp
17
- import argparse
18
- import logging
19
- import pathlib
20
-
21
- # 3rd party packages
22
- import pandas as pd
23
-
24
- # Project packages
25
- from sierra.core.graphs.summary_line_graph import SummaryLineGraph
26
- from sierra.core.graphs.stacked_surface_graph import StackedSurfaceGraph
27
- from sierra.core.graphs.heatmap import Heatmap, DualHeatmap
28
- from sierra.core.variables import batch_criteria as bc
29
- import sierra.core.root_dirpath_generator as rdg
30
- from sierra.core import types, utils, config, storage
31
-
32
-
33
- class UnivarIntraScenarioComparator:
34
- """Compares a set of controllers within each of a set of scenarios.
35
-
36
- Graph generation
37
- is controlled via a config file parsed in
38
- :class:`~sierra.core.pipeline.stage5.pipeline_stage5.PipelineStage5`.
39
-
40
- Univariate batch criteria only.
41
-
42
- Attributes:
43
-
44
- controllers: List of controller names to compare.
45
-
46
- cc_csv_root: Absolute directory path to the location controller CSV
47
- files should be output to.
48
-
49
- cc_graph_root: Absolute directory path to the location the generated
50
- graphs should be output to.
51
-
52
- cmdopts: Dictionary of parsed cmdline parameters.
53
-
54
- cli_args: :class:`argparse` object containing the cmdline
55
- parameters. Needed for
56
- :class:`~sierra.core.variables.batch_criteria.BatchCriteria`
57
- generation for each scenario controllers are compared within,
58
- as batch criteria is dependent on controller+scenario
59
- definition, and needs to be re-generated for each scenario in
60
- order to get graph labels/axis ticks to come out right in all
61
- cases.
62
-
63
- """
64
-
65
- def __init__(self,
66
- controllers: tp.List[str],
67
- cc_csv_root: pathlib.Path,
68
- cc_graph_root: pathlib.Path,
69
- cmdopts: types.Cmdopts,
70
- cli_args,
71
- main_config: types.YAMLDict) -> None:
72
- self.controllers = controllers
73
- self.cc_graph_root = cc_graph_root
74
- self.cc_csv_root = cc_csv_root
75
-
76
- self.cmdopts = cmdopts
77
- self.cli_args = cli_args
78
- self.main_config = main_config
79
- self.project_root = pathlib.Path(self.cmdopts['sierra_root'],
80
- self.cmdopts['project'])
81
- self.logger = logging.getLogger(__name__)
82
-
83
- def __call__(self,
84
- graphs: tp.List[types.YAMLDict],
85
- legend: tp.List[str],
86
- comp_type: str) -> None:
87
- # Obtain the list of scenarios to use. We can just take the scenario
88
- # list of the first controllers, because we have already checked that
89
- # all controllers executed the same set scenarios.
90
- batch_leaves = os.listdir(self.project_root / self.controllers[0])
91
-
92
- # For each controller comparison graph we are interested in, generate it
93
- # using data from all scenarios
94
- cmdopts = copy.deepcopy(self.cmdopts)
95
- for graph in graphs:
96
- found = False
97
- for leaf in batch_leaves:
98
- if self._leaf_select(leaf):
99
- self.logger.debug("Generating graph %s from scenario '%s'",
100
- graph,
101
- leaf)
102
- self._compare_in_scenario(cmdopts=cmdopts,
103
- graph=graph,
104
- batch_leaf=leaf,
105
- legend=legend)
106
- found = True
107
- break
108
- if not found:
109
- self.logger.warning("Did not find scenario to compare in for criteria %s",
110
- self.cli_args.batch_criteria)
111
-
112
- def _leaf_select(self, candidate: str) -> bool:
113
- """Determine if a controller can be included in the comparison for a scenario.
114
-
115
- You can only compare controllers within the scenario directly generated
116
- from the value of ``--batch-criteria``; other scenarios will (probably)
117
- cause file not found errors.
118
-
119
- """
120
- template_stem, scenario, _ = rdg.parse_batch_leaf(candidate)
121
- leaf = rdg.gen_batch_leaf(criteria=self.cli_args.batch_criteria,
122
- scenario=scenario,
123
- template_stem=template_stem)
124
- return leaf in candidate
125
-
126
- def _compare_in_scenario(self,
127
- cmdopts: types.Cmdopts,
128
- graph: types.YAMLDict,
129
- batch_leaf: str,
130
- legend: tp.List[str]) -> None:
131
-
132
- for controller in self.controllers:
133
- dirs = [d for d in os.listdir(
134
- self.project_root / controller) if batch_leaf in d]
135
- if len(dirs) == 0:
136
- self.logger.warning("Controller %s was not run on experiment %s",
137
- controller,
138
- batch_leaf)
139
- continue
140
-
141
- batch_leaf = dirs[0]
142
- _, scenario, _ = rdg.parse_batch_leaf(batch_leaf)
143
-
144
- # We need to generate the root directory paths for each batch
145
- # experiment (which # lives inside of the scenario dir), because
146
- # they are all different. We need generate these paths for EACH
147
- # controller, because the controller is part of the batch root path.
148
- paths = rdg.regen_from_exp(sierra_rpath=self.cli_args.sierra_root,
149
- project=self.cli_args.project,
150
- batch_leaf=batch_leaf,
151
- controller=controller)
152
- cmdopts.update(paths)
153
-
154
- # For each scenario, we have to create the batch criteria for it,
155
- # because they are all different.
156
-
157
- criteria = bc.factory(self.main_config,
158
- cmdopts,
159
- self.cli_args,
160
- scenario)
161
-
162
- self._gen_csv(batch_leaf=batch_leaf,
163
- criteria=criteria,
164
- cmdopts=cmdopts,
165
- controller=controller,
166
- src_stem=graph['src_stem'],
167
- dest_stem=graph['dest_stem'],
168
- inc_exps=graph.get('include_exp', None))
169
-
170
- self._gen_graph(batch_leaf=batch_leaf,
171
- criteria=criteria,
172
- cmdopts=cmdopts,
173
- dest_stem=graph['dest_stem'],
174
- title=graph.get('title', ''),
175
- label=graph.get('label', ''),
176
- inc_exps=graph.get('include_exp', None),
177
- legend=legend)
178
-
179
- def _gen_csv(self,
180
- batch_leaf: str,
181
- criteria: bc.IConcreteBatchCriteria,
182
- cmdopts: types.Cmdopts,
183
- controller: str,
184
- src_stem: str,
185
- dest_stem: str,
186
- inc_exps: tp.Optional[str]) -> None:
187
- """Generate a set of CSV files for use in intra-scenario graph generation.
188
-
189
- 1 CSV per controller.
190
-
191
- """
192
- self.logger.debug("Gathering data for '%s' from %s -> %s",
193
- controller, src_stem, dest_stem)
194
- ipath = pathlib.Path(cmdopts['batch_stat_collate_root'],
195
- src_stem + config.kStats['mean'].exts['mean'])
196
-
197
- # Some experiments might not generate the necessary performance measure
198
- # .csvs for graph generation, which is OK.
199
- if not utils.path_exists(ipath):
200
- self.logger.warning("%s missing for controller %s",
201
- ipath,
202
- controller)
203
- return
204
-
205
- preparer = StatsPreparer(ipath_stem=cmdopts['batch_stat_collate_root'],
206
- ipath_leaf=src_stem,
207
- opath_stem=self.cc_csv_root,
208
- n_exp=criteria.n_exp())
209
- opath_leaf = LeafGenerator.from_batch_leaf(batch_leaf, dest_stem, None)
210
- preparer.across_rows(opath_leaf=opath_leaf, index=0, inc_exps=inc_exps)
211
-
212
- def _gen_graph(self,
213
- batch_leaf: str,
214
- criteria: bc.IConcreteBatchCriteria,
215
- cmdopts: types.Cmdopts,
216
- dest_stem: str,
217
- title: str,
218
- label: str,
219
- inc_exps: tp.Optional[str],
220
- legend: tp.List[str]) -> None:
221
- """Generate a graph comparing the specified controllers within a scenario.
222
- """
223
- opath_leaf = LeafGenerator.from_batch_leaf(batch_leaf, dest_stem, None)
224
-
225
- xticks = criteria.graph_xticks(cmdopts)
226
- xtick_labels = criteria.graph_xticklabels(cmdopts)
227
-
228
- if inc_exps is not None:
229
- xtick_labels = utils.exp_include_filter(
230
- inc_exps, xtick_labels, criteria.n_exp())
231
- xticks = utils.exp_include_filter(
232
- inc_exps, xticks, criteria.n_exp())
233
-
234
- opath = self.cc_graph_root / (opath_leaf + config.kImageExt)
235
-
236
- SummaryLineGraph(stats_root=self.cc_csv_root,
237
- input_stem=opath_leaf,
238
- output_fpath=opath,
239
- stats=cmdopts['dist_stats'],
240
- title=title,
241
- xlabel=criteria.graph_xlabel(cmdopts),
242
- ylabel=label,
243
- xtick_labels=xtick_labels,
244
- xticks=xticks,
245
- logyscale=cmdopts['plot_log_yscale'],
246
- large_text=self.cmdopts['plot_large_text'],
247
- legend=legend).generate()
248
-
249
-
250
- class BivarIntraScenarioComparator:
251
- """Compares a set of controllers within each of a set of scenarios.
252
-
253
- Graph generation is controlled via a config file
254
- parsed in
255
- :class:`~sierra.core.pipeline.stage5.pipeline_stage5.PipelineStage5`.
256
-
257
- Bivariate batch criteria only.
258
-
259
- Attributes:
260
-
261
- controllers: List of controller names to compare.
262
-
263
- cc_csv_root: Absolute directory path to the location controller CSV
264
- files should be output to.
265
-
266
- cc_graph_root: Absolute directory path to the location the generated
267
- graphs should be output to.
268
-
269
- cmdopts: Dictionary of parsed cmdline parameters.
270
-
271
- cli_args: :class:`argparse` object containing the cmdline
272
- parameters. Needed for
273
- :class:`~sierra.core.variables.batch_criteria.BatchCriteria`
274
- generation for each scenario controllers are compared within,
275
- as batch criteria is dependent on controller+scenario
276
- definition, and needs to be re-generated for each scenario in
277
- order to get graph labels/axis ticks to come out right in all
278
- cases.
279
-
280
- """
281
-
282
- def __init__(self,
283
- controllers: tp.List[str],
284
- cc_csv_root: pathlib.Path,
285
- cc_graph_root: pathlib.Path,
286
- cmdopts: types.Cmdopts,
287
- cli_args: argparse.Namespace,
288
- main_config: types.YAMLDict) -> None:
289
- self.controllers = controllers
290
- self.cc_csv_root = cc_csv_root
291
- self.cc_graph_root = cc_graph_root
292
- self.cmdopts = cmdopts
293
- self.cli_args = cli_args
294
- self.main_config = main_config
295
- self.logger = logging.getLogger(__name__)
296
-
297
- self.logger.debug("csv_root=%s", str(self.cc_csv_root))
298
- self.logger.debug("graph_root=%s", str(self.cc_graph_root))
299
-
300
- self.project_root = pathlib.Path(self.cmdopts['sierra_root'],
301
- self.cmdopts['project'])
302
-
303
- def __call__(self,
304
- graphs: tp.List[types.YAMLDict],
305
- legend: tp.List[str],
306
- comp_type: str) -> None:
307
-
308
- # Obtain the list of scenarios to use. We can just take the scenario
309
- # list of the first controllers, because we have already checked that
310
- # all controllers executed the same set scenarios.
311
- batch_leaves = os.listdir(self.project_root / self.controllers[0])
312
-
313
- cmdopts = copy.deepcopy(self.cmdopts)
314
- for graph in graphs:
315
- found = False
316
- for leaf in batch_leaves:
317
- if self._leaf_select(leaf):
318
- self.logger.debug("Generating graph %s from scenario '%s'",
319
- graph,
320
- leaf)
321
- self._compare_in_scenario(cmdopts=cmdopts,
322
- graph=graph,
323
- batch_leaf=leaf,
324
- legend=legend,
325
- comp_type=comp_type)
326
- found = True
327
- break
328
- if not found:
329
- self.logger.warning("Did not find scenario to compare in for criteria '%s'",
330
- self.cli_args.batch_criteria)
331
-
332
- def _leaf_select(self, candidate: str) -> bool:
333
- """Determine if a controller can be included in the comparison for a scenario.
334
-
335
- You can only compare controllers within the scenario directly generated
336
- from the value of ``--batch-criteria``; other scenarios will (probably)
337
- cause file not found errors.
338
-
339
- """
340
- template_stem, scenario, _ = rdg.parse_batch_leaf(candidate)
341
- leaf = rdg.gen_batch_leaf(criteria=self.cli_args.batch_criteria,
342
- scenario=scenario,
343
- template_stem=template_stem)
344
- return leaf in candidate
345
-
346
- def _compare_in_scenario(self,
347
- cmdopts: types.Cmdopts,
348
- graph: types.YAMLDict,
349
- batch_leaf: str,
350
- legend: tp.List[str],
351
- comp_type: str) -> None:
352
- """Compare all controllers within the specified scenario.
353
-
354
- Generates CSV files and graphs according to configuration.
355
- """
356
- for controller in self.controllers:
357
- dirs = [d for d in os.listdir(
358
- self.project_root / controller) if batch_leaf in d]
359
-
360
- if len(dirs) == 0:
361
- self.logger.warning("Controller '%s' was not run on scenario '%s'",
362
- controller,
363
- batch_leaf)
364
- continue
365
-
366
- batch_leaf = dirs[0]
367
- _, scenario, _ = rdg.parse_batch_leaf(batch_leaf)
368
-
369
- # We need to generate the root directory paths for each batch
370
- # experiment (which # lives inside of the scenario dir), because
371
- # they are all different. We need generate these paths for EACH
372
- # controller, because the controller is part of the batch root path.
373
- paths = rdg.regen_from_exp(sierra_rpath=self.cli_args.sierra_root,
374
- project=self.cli_args.project,
375
- batch_leaf=batch_leaf,
376
- controller=controller)
377
-
378
- cmdopts.update(paths)
379
-
380
- # For each scenario, we have to create the batch criteria for it,
381
- # because they are all different.
382
- criteria = bc.factory(self.main_config,
383
- cmdopts,
384
- self.cli_args,
385
- scenario)
386
-
387
- if comp_type == 'LNraw':
388
- self._gen_csvs_for_1D(cmdopts=cmdopts,
389
- criteria=criteria,
390
- controller=controller,
391
- batch_leaf=batch_leaf,
392
- src_stem=graph['src_stem'],
393
- dest_stem=graph['dest_stem'],
394
- primary_axis=graph.get('primary_axis', 0),
395
- inc_exps=graph.get('include_exp', None))
396
-
397
- elif 'HM' in comp_type or 'SU' in comp_type:
398
- self._gen_csvs_for_2D_or_3D(cmdopts=cmdopts,
399
- controller=controller,
400
- batch_leaf=batch_leaf,
401
- src_stem=graph['src_stem'],
402
- dest_stem=graph['dest_stem'])
403
-
404
- if comp_type == 'LNraw':
405
- self._gen_graphs1D(batch_leaf=batch_leaf,
406
- criteria=criteria,
407
- cmdopts=cmdopts,
408
- dest_stem=graph['dest_stem'],
409
- title=graph.get('title', ''),
410
- label=graph.get('label', ''),
411
- primary_axis=graph.get('primary_axis', 0),
412
- inc_exps=graph.get('include_exp', None),
413
- legend=legend)
414
- elif 'HM' in comp_type:
415
- self._gen_graphs2D(batch_leaf=batch_leaf,
416
- criteria=criteria,
417
- cmdopts=cmdopts,
418
- dest_stem=graph['dest_stem'],
419
- title=graph.get('title', ''),
420
- label=graph.get('label', ''),
421
- legend=legend,
422
- comp_type=comp_type)
423
-
424
- elif 'SU' in comp_type:
425
- self._gen_graph3D(batch_leaf=batch_leaf,
426
- criteria=criteria,
427
- cmdopts=cmdopts,
428
- dest_stem=graph['dest_stem'],
429
- title=graph.get('title', ''),
430
- zlabel=graph.get('label', ''),
431
- legend=legend,
432
- comp_type=comp_type)
433
-
434
- def _gen_csvs_for_2D_or_3D(self,
435
- cmdopts: types.Cmdopts,
436
- batch_leaf: str,
437
- controller: str,
438
- src_stem: str,
439
- dest_stem: str) -> None:
440
- """Generate a set of CSV files for use in intra-scenario graph generation.
441
-
442
- 1 CSV per controller, for 2D/3D comparison types only. Because each CSV
443
- file corresponding to performance measures are 2D arrays, we actually
444
- just copy and rename the performance measure CSV files for each
445
- controllers into :attr:`cc_csv_root`.
446
-
447
- :class:`~sierra.core.graphs.stacked_surface_graph.StackedSurfaceGraph`
448
- expects an ``_[0-9]+.csv`` pattern for each 2D surfaces to graph in
449
- order to disambiguate which files belong to which controller without
450
- having the controller name in the filepath (contains dots), so we do
451
- that here. :class:`~sierra.core.graphs.heatmap.Heatmap` does not require
452
- that, but for the heatmap set we generate it IS helpful to have an easy
453
- way to differentiate primary vs. other controllers, so we do it
454
- unconditionally here to handle both cases.
455
-
456
- """
457
- self.logger.debug("Gathering data for '%s' from %s -> %s",
458
- controller, src_stem, dest_stem)
459
-
460
- csv_ipath = pathlib.Path(cmdopts['batch_stat_collate_root'],
461
- src_stem + config.kStats['mean'].exts['mean'])
462
-
463
- # Some experiments might not generate the necessary performance measure
464
- # .csvs for graph generation, which is OK.
465
- if not utils.path_exists(csv_ipath):
466
- self.logger.warning("%s missing for controller '%s'",
467
- csv_ipath,
468
- controller)
469
- return
470
-
471
- df = storage.DataFrameReader('storage.csv')(csv_ipath)
472
-
473
- opath_leaf = LeafGenerator.from_batch_leaf(batch_leaf,
474
- dest_stem,
475
- [self.controllers.index(controller)])
476
-
477
- opath_stem = self.cc_csv_root / opath_leaf
478
- opath = opath_stem.with_name(
479
- opath_stem.name + config.kStats['mean'].exts['mean'])
480
- writer = storage.DataFrameWriter('storage.csv')
481
- writer(df, opath, index=False)
482
-
483
- def _gen_csvs_for_1D(self,
484
- cmdopts: types.Cmdopts,
485
- criteria: bc.IConcreteBatchCriteria,
486
- batch_leaf: str,
487
- controller: str,
488
- src_stem: str,
489
- dest_stem: str,
490
- primary_axis: int,
491
- inc_exps: tp.Optional[str]) -> None:
492
- """Generate a set of CSV files for use in intra-scenario graph generation.
493
-
494
- Because we are targeting linegraphs, we draw the the i-th row/col (as
495
- configured) from the performance results of each controller .csv, and
496
- concatenate them into a new .csv file which can be given to
497
- :class:`~sierra.core.graphs.summary_line_graph.SummaryLineGraph`.
498
-
499
- """
500
- self.logger.debug("Gathering data for '%s' from %s -> %s",
501
- controller, src_stem, dest_stem)
502
-
503
- csv_ipath = pathlib.Path(cmdopts['batch_stat_collate_root'],
504
- src_stem + config.kStats['mean'].exts['mean'])
505
-
506
- # Some experiments might not generate the necessary performance measure
507
- # .csvs for graph generation, which is OK.
508
- if not utils.path_exists(csv_ipath):
509
- self.logger.warning("%s missing for controller '%s'",
510
- csv_ipath,
511
- controller)
512
- return
513
-
514
- if cmdopts['dist_stats'] != 'none':
515
- self.logger.warning(("--dist-stats is not supported with "
516
- "1D CSVs sliced from 2D CSV for linegraph "
517
- "generation: no stats will be included"))
518
-
519
- if primary_axis == 0:
520
- preparer = StatsPreparer(ipath_stem=cmdopts['batch_stat_collate_root'],
521
- ipath_leaf=src_stem,
522
- opath_stem=self.cc_csv_root,
523
- n_exp=criteria.criteria2.n_exp())
524
-
525
- reader = storage.DataFrameReader('storage.csv')
526
- ipath = pathlib.Path(cmdopts['batch_stat_collate_root'],
527
- src_stem + config.kStats['mean'].exts['mean'])
528
- n_rows = len(reader(ipath).index)
529
-
530
- for i in range(0, n_rows):
531
- opath_leaf = LeafGenerator.from_batch_leaf(batch_leaf,
532
- dest_stem,
533
- [i])
534
- preparer.across_rows(opath_leaf=opath_leaf,
535
- index=i,
536
- inc_exps=inc_exps)
537
- else:
538
- preparer = StatsPreparer(ipath_stem=cmdopts['batch_stat_collate_root'],
539
- ipath_leaf=src_stem,
540
- opath_stem=self.cc_csv_root,
541
- n_exp=criteria.criteria1.n_exp())
542
-
543
- exp_dirs = criteria.gen_exp_names(cmdopts)
544
- xlabels, ylabels = utils.bivar_exp_labels_calc(exp_dirs)
545
- xlabels = utils.exp_include_filter(
546
- inc_exps, xlabels, criteria.criteria1.n_exp())
547
-
548
- for col in ylabels:
549
- col_index = ylabels.index(col)
550
- opath_leaf = LeafGenerator.from_batch_leaf(
551
- batch_leaf, dest_stem, [col_index])
552
- preparer.across_cols(opath_leaf=opath_leaf,
553
- col_index=col_index,
554
- all_cols=xlabels,
555
- inc_exps=inc_exps)
556
-
557
- def _gen_graphs1D(self,
558
- batch_leaf: str,
559
- criteria: bc.BivarBatchCriteria,
560
- cmdopts: types.Cmdopts,
561
- dest_stem: str,
562
- title: str,
563
- label: str,
564
- primary_axis: int,
565
- inc_exps: tp.Optional[str],
566
- legend: tp.List[str]) -> None:
567
- oleaf = LeafGenerator.from_batch_leaf(batch_leaf, dest_stem, None)
568
- csv_stem_root = self.cc_csv_root / oleaf
569
- pattern = str(csv_stem_root) + '*' + config.kStats['mean'].exts['mean']
570
- paths = [f for f in glob.glob(pattern) if re.search('_[0-9]+', f)]
571
-
572
- for i in range(0, len(paths)):
573
- opath_leaf = LeafGenerator.from_batch_leaf(
574
- batch_leaf, dest_stem, [i])
575
- img_opath = self.cc_graph_root / (opath_leaf + config.kImageExt)
576
-
577
- if primary_axis == 0:
578
- n_exp = criteria.criteria1.n_exp()
579
- xticks = utils.exp_include_filter(inc_exps,
580
- criteria.graph_yticks(
581
- cmdopts),
582
- n_exp)
583
- xtick_labels = utils.exp_include_filter(inc_exps,
584
- criteria.graph_yticklabels(
585
- cmdopts),
586
- n_exp)
587
- xlabel = criteria.graph_ylabel(cmdopts)
588
- else:
589
- n_exp = criteria.criteria2.n_exp()
590
- xticks = utils.exp_include_filter(inc_exps,
591
- criteria.graph_xticks(
592
- cmdopts),
593
- n_exp)
594
- xtick_labels = utils.exp_include_filter(inc_exps,
595
- criteria.graph_xticklabels(
596
- cmdopts),
597
- n_exp)
598
- xlabel = criteria.graph_xlabel(cmdopts)
599
-
600
- # TODO: Fix no statistics support for these graphs
601
- SummaryLineGraph(stats_root=self.cc_csv_root,
602
- input_stem=opath_leaf,
603
- stats='none',
604
- output_fpath=img_opath,
605
- model_root=cmdopts['batch_model_root'],
606
- title=title,
607
- xlabel=xlabel,
608
- ylabel=label,
609
- xticks=xticks,
610
- xtick_labels=xtick_labels,
611
- legend=legend,
612
- logyscale=cmdopts['plot_log_yscale'],
613
- large_text=cmdopts['plot_large_text']).generate()
614
-
615
- def _gen_graphs2D(self,
616
- batch_leaf: str,
617
- criteria: bc.BivarBatchCriteria,
618
- cmdopts: types.Cmdopts,
619
- dest_stem: str,
620
- title: str,
621
- label: str,
622
- legend: tp.List[str],
623
- comp_type: str) -> None:
624
- if comp_type in ['HMscale', 'HMdiff']:
625
- self._gen_paired_heatmaps(batch_leaf,
626
- criteria,
627
- cmdopts,
628
- dest_stem,
629
- title,
630
- label,
631
- comp_type)
632
- elif comp_type == 'HMraw':
633
- self._gen_dual_heatmaps(batch_leaf,
634
- criteria,
635
- cmdopts,
636
- dest_stem,
637
- title,
638
- label,
639
- legend,
640
- comp_type)
641
-
642
- def _gen_paired_heatmaps(self,
643
- batch_leaf: str,
644
- criteria: bc.BivarBatchCriteria,
645
- cmdopts: types.Cmdopts,
646
- dest_stem: str,
647
- title: str,
648
- label: str,
649
- comp_type: str) -> None:
650
- """Generate a set of :class:`~sierra.core.graphs.heatmap.Heatmap` graphs.
651
-
652
- Uses a configured controller of primary interest against all other
653
- controllers (one graph per pairing), after input files have been
654
- gathered from each controller into :attr:`cc_csv_root`.
655
-
656
- """
657
- opath_leaf = LeafGenerator.from_batch_leaf(batch_leaf, dest_stem, None)
658
- opath = self.cc_graph_root / (opath_leaf + config.kImageExt)
659
- pattern = self.cc_csv_root / (opath_leaf + '*' +
660
- config.kStats['mean'].exts['mean'])
661
-
662
- paths = [pathlib.Path(f) for f in glob.glob(str(pattern))
663
- if re.search(r'_[0-9]+\.', f)]
664
-
665
- self.logger.debug("Generating paired heatmaps in %s -> %s",
666
- pattern,
667
- [str(f.relative_to(self.cc_csv_root)) for f in paths])
668
-
669
- if len(paths) < 2:
670
- self.logger.warning(("Not enough matches from pattern='%s'--"
671
- "skipping paired heatmap generation"),
672
- pattern)
673
- return
674
-
675
- reader = storage.DataFrameReader('storage.csv')
676
- ref_df = reader(paths[0])
677
-
678
- for i in range(1, len(paths)):
679
- df = reader(paths[i])
680
- if comp_type == 'HMscale':
681
- plot_df = df / ref_df
682
- elif comp_type == 'HMdiff':
683
- plot_df = df - ref_df
684
-
685
- # Have to add something before the .mean to ensure that the diff CSV
686
- # does not get picked up by the regex above as each controller is
687
- # treated in turn as the primary.
688
- leaf = LeafGenerator.from_batch_leaf(batch_leaf,
689
- dest_stem,
690
- [0, i]) + '_paired'
691
- ipath = self.cc_csv_root / (leaf + config.kStats['mean'].exts['mean'])
692
- opath = self.cc_graph_root / (leaf + config.kImageExt)
693
-
694
- writer = storage.DataFrameWriter('storage.csv')
695
- writer(plot_df, ipath, index=False)
696
-
697
- Heatmap(input_fpath=ipath,
698
- output_fpath=opath,
699
- title=title,
700
- transpose=self.cmdopts['plot_transpose_graphs'],
701
- zlabel=self._gen_zaxis_label(label, comp_type),
702
- xlabel=criteria.graph_xlabel(cmdopts),
703
- ylabel=criteria.graph_ylabel(cmdopts),
704
- xtick_labels=criteria.graph_xticklabels(cmdopts),
705
- ytick_labels=criteria.graph_yticklabels(cmdopts)).generate()
706
-
707
- def _gen_dual_heatmaps(self,
708
- batch_leaf: str,
709
- criteria: bc.BivarBatchCriteria,
710
- cmdopts: types.Cmdopts,
711
- dest_stem: str,
712
- title: str,
713
- label: str,
714
- legend: tp.List[str],
715
- comp_type: str) -> None:
716
- """Generate a set of :class:`~sierra.core.graphs.heatmap.DualHeatmap` graphs.
717
-
718
- Graphs contain all pairings of (primary controller, other), one per
719
- graph, within the specified scenario after input files have been
720
- gathered from each controller into :attr:`cc_csv_root`. Only valid if
721
- the comparison type is ``HMraw``.
722
-
723
- """
724
- opath_leaf = LeafGenerator.from_batch_leaf(batch_leaf, dest_stem, None)
725
- opath = self.cc_graph_root / (opath_leaf + config.kImageExt)
726
- pattern = self.cc_csv_root / (opath_leaf + '*' +
727
- config.kStats['mean'].exts['mean'])
728
-
729
- paths = [pathlib.Path(f) for f in glob.glob(str(pattern))
730
- if re.search('_[0-9]+', f)]
731
-
732
- self.logger.debug("Generating dual heatmaps in %s -> %s",
733
- pattern,
734
- [str(f.relative_to(self.cc_csv_root)) for f in paths])
735
-
736
- DualHeatmap(ipaths=paths,
737
- output_fpath=opath,
738
- title=title,
739
- large_text=cmdopts['plot_large_text'],
740
- zlabel=self._gen_zaxis_label(label, comp_type),
741
- xlabel=criteria.graph_xlabel(cmdopts),
742
- ylabel=criteria.graph_ylabel(cmdopts),
743
- legend=legend,
744
- xtick_labels=criteria.graph_xticklabels(cmdopts),
745
- ytick_labels=criteria.graph_yticklabels(cmdopts)).generate()
746
-
747
- def _gen_graph3D(self,
748
- batch_leaf: str,
749
- criteria: bc.BivarBatchCriteria,
750
- cmdopts: types.Cmdopts,
751
- dest_stem: str,
752
- title: str,
753
- zlabel: str,
754
- legend: tp.List[str],
755
- comp_type: str) -> None:
756
- """Generate a graph comparing the specified controllers within a scenario.
757
-
758
- Graph contains the specified controllers within thes pecified scenario
759
- after input files have been gathered from each controllers into
760
- :attr:`cc_csv_root`.
761
-
762
- """
763
- opath_leaf = LeafGenerator.from_batch_leaf(batch_leaf, dest_stem, None)
764
- opath = self.cc_graph_root / (opath_leaf + config.kImageExt)
765
- pattern = self.cc_csv_root / (opath_leaf + '*' +
766
- config.kStats['mean'].exts['mean'])
767
-
768
- paths = [pathlib.Path(f) for f in glob.glob(
769
- str(pattern)) if re.search('_[0-9]+', f)]
770
-
771
- self.logger.debug("Generating stacked surface graphs in %s -> %s",
772
- pattern,
773
- [str(f.relative_to(self.cc_csv_root)) for f in paths])
774
-
775
- StackedSurfaceGraph(ipaths=paths,
776
- output_fpath=opath,
777
- title=title,
778
- ylabel=criteria.graph_xlabel(cmdopts),
779
- xlabel=criteria.graph_ylabel(cmdopts),
780
- zlabel=self._gen_zaxis_label(zlabel, comp_type),
781
- xtick_labels=criteria.graph_yticklabels(cmdopts),
782
- ytick_labels=criteria.graph_xticklabels(cmdopts),
783
- legend=legend,
784
- comp_type=comp_type).generate()
785
-
786
- def _gen_zaxis_label(self, label: str, comp_type: str) -> str:
787
- """If the comparison type is not "raw", put it on the graph as Z axis title.
788
-
789
- """
790
- if 'scale' in comp_type:
791
- return label + ' (Scaled)'
792
- elif 'diff' in comp_type:
793
- return label + ' (Difference Comparison)'
794
- return label
795
-
796
-
797
- class StatsPreparer():
798
- """Prepare statistics generated from controllers for graph generation.
799
-
800
- If the batch criteria is univariate, then only :meth:`across_rows` is valid;
801
- for bivariate batch criteria, either :meth:`across_rows` or
802
- :meth:`across_cols` is valid, depending on what the primary axis is.
803
-
804
- """
805
-
806
- def __init__(self,
807
- ipath_stem: pathlib.Path,
808
- ipath_leaf: str,
809
- opath_stem: pathlib.Path,
810
- n_exp: int):
811
- self.ipath_stem = ipath_stem
812
- self.ipath_leaf = ipath_leaf
813
- self.opath_stem = opath_stem
814
- self.n_exp = n_exp
815
-
816
- def across_cols(self,
817
- opath_leaf: str,
818
- all_cols: tp.List[str],
819
- col_index: int,
820
- inc_exps: tp.Optional[str]) -> None:
821
- """Prepare statistics in column-major batch criteria.
822
-
823
- The criteria of interest varies across the rows of controller CSVs. We
824
- take row `index` from a given dataframe and take the rows specified by
825
- the `inc_exps` and append them to a results dataframe column-wise, which
826
- we then write the file system.
827
-
828
- """
829
- exts = config.kStats['mean'].exts
830
- exts.update(config.kStats['conf95'].exts)
831
- exts.update(config.kStats['bw'].exts)
832
-
833
- for k in exts:
834
- stat_ipath = pathlib.Path(self.ipath_stem,
835
- self.ipath_leaf + exts[k])
836
- stat_opath = pathlib.Path(self.opath_stem,
837
- opath_leaf + exts[k])
838
- df = self._accum_df_by_col(stat_ipath,
839
- stat_opath,
840
- all_cols,
841
- col_index,
842
- inc_exps)
843
-
844
- if df is not None:
845
- writer = storage.DataFrameWriter('storage.csv')
846
- opath = self.opath_stem / (opath_leaf + exts[k])
847
- writer(df, opath, index=False)
848
-
849
- def across_rows(self,
850
- opath_leaf: str,
851
- index: int,
852
- inc_exps: tp.Optional[str]) -> None:
853
- """Prepare statistics in row-major batch criteria.
854
-
855
- The criteria of interest varies across the columns of controller
856
- CSVs. We take row `index` from a given dataframe and take the columns
857
- specified by the `inc_exps` and append them to a results dataframe
858
- row-wise, which we then write the file system.
859
-
860
- """
861
- exts = config.kStats['mean'].exts
862
- exts.update(config.kStats['conf95'].exts)
863
- exts.update(config.kStats['bw'].exts)
864
-
865
- for k in exts:
866
- stat_ipath = pathlib.Path(self.ipath_stem,
867
- self.ipath_leaf + exts[k])
868
- stat_opath = pathlib.Path(self.opath_stem,
869
- opath_leaf + exts[k])
870
- df = self._accum_df_by_row(stat_ipath, stat_opath, index, inc_exps)
871
-
872
- if df is not None:
873
- writer = storage.DataFrameWriter('storage.csv')
874
- writer(df,
875
- self.opath_stem / (opath_leaf + exts[k]),
876
- index=False)
877
-
878
- def _accum_df_by_col(self,
879
- ipath: pathlib.Path,
880
- opath: pathlib.Path,
881
- all_cols: tp.List[str],
882
- col_index: int,
883
- inc_exps: tp.Optional[str]) -> pd.DataFrame:
884
- reader = storage.DataFrameReader('storage.csv')
885
-
886
- if utils.path_exists(opath):
887
- cum_df = reader(opath)
888
- else:
889
- cum_df = None
890
-
891
- if utils.path_exists(ipath):
892
- t = reader(ipath)
893
-
894
- if inc_exps is not None:
895
- cols_from_index = utils.exp_include_filter(inc_exps,
896
- list(t.index),
897
- self.n_exp)
898
- else:
899
- cols_from_index = slice(None, None, None)
900
-
901
- if cum_df is None:
902
- cum_df = pd.DataFrame(columns=all_cols)
903
-
904
- # We need to turn each column of the .csv on the filesystem into a
905
- # row in the .csv which we want to write out, so we transpose, fix
906
- # the index, and then set the columns of the new transposed
907
- # dataframe.
908
- tp_df = t.transpose()
909
- tp_df = tp_df.reset_index(drop=True)
910
- tp_df = tp_df[cols_from_index]
911
- tp_df.columns = all_cols
912
-
913
- # Series are columns, so we have to transpose before concatenating
914
- cum_df = pd.concat([cum_df,
915
- tp_df.loc[col_index, :].to_frame().T])
916
-
917
- # cum_df = pd.concat([cum_df, tp_df.loc[col_index, :]])
918
- return cum_df
919
-
920
- return None
921
-
922
- def _accum_df_by_row(self,
923
- ipath: pathlib.Path,
924
- opath: pathlib.Path,
925
- index: int,
926
- inc_exps: tp.Optional[str]) -> pd.DataFrame:
927
- reader = storage.DataFrameReader('storage.csv')
928
- if utils.path_exists(opath):
929
- cum_df = reader(opath)
930
- else:
931
- cum_df = None
932
-
933
- if utils.path_exists(ipath):
934
- t = reader(ipath)
935
-
936
- if inc_exps is not None:
937
- cols = utils.exp_include_filter(inc_exps,
938
- list(t.columns),
939
- self.n_exp)
940
- else:
941
- cols = t.columns
942
-
943
- if cum_df is None:
944
- cum_df = pd.DataFrame(columns=cols)
945
-
946
- # Series are columns, so we have to transpose before concatenating
947
- cum_df = pd.concat([cum_df,
948
- t.loc[index, cols].to_frame().T])
949
- return cum_df
950
-
951
- return None
952
-
953
-
954
- class LeafGenerator():
955
- @staticmethod
956
- def from_controller(batch_root: pathlib.Path,
957
- graph_stem: str,
958
- controllers: tp.List[str],
959
- controller: str) -> str:
960
- _, batch_leaf, _ = rdg.parse_batch_leaf(str(batch_root))
961
- leaf = graph_stem + "-" + batch_leaf + \
962
- '_' + str(controllers.index(controller))
963
- return leaf
964
-
965
- @staticmethod
966
- def from_batch_root(batch_root: pathlib.Path,
967
- graph_stem: str,
968
- index: tp.Union[int, None]):
969
- _, scenario, _ = rdg.parse_batch_leaf(str(batch_root))
970
- leaf = graph_stem + "-" + scenario
971
-
972
- if index is not None:
973
- leaf += '_' + str(index)
974
-
975
- return leaf
976
-
977
- @staticmethod
978
- def from_batch_leaf(batch_leaf: str,
979
- graph_stem: str,
980
- indices: tp.Union[tp.List[int], None]):
981
- leaf = graph_stem + "-" + batch_leaf
982
-
983
- if indices is not None:
984
- leaf += '_' + ''.join([str(i) for i in indices])
985
-
986
- return leaf
987
-
988
-
989
- __api__ = ['UnivarIntraScenarioComparator', 'BivarIntraScenarioComparator']