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