sierra-research 1.3.6__py3-none-any.whl → 1.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sierra/__init__.py +3 -3
- sierra/core/__init__.py +3 -3
- sierra/core/batchroot.py +223 -0
- sierra/core/cmdline.py +681 -1057
- sierra/core/compare.py +11 -0
- sierra/core/config.py +96 -88
- sierra/core/engine.py +306 -0
- sierra/core/execenv.py +380 -0
- sierra/core/expdef.py +11 -0
- sierra/core/experiment/__init__.py +1 -0
- sierra/core/experiment/bindings.py +150 -101
- sierra/core/experiment/definition.py +414 -245
- sierra/core/experiment/spec.py +83 -85
- sierra/core/exproot.py +44 -0
- sierra/core/generators/__init__.py +10 -0
- sierra/core/generators/experiment.py +528 -0
- sierra/core/generators/generator_factory.py +138 -137
- sierra/core/graphs/__init__.py +23 -0
- sierra/core/graphs/bcbridge.py +94 -0
- sierra/core/graphs/heatmap.py +245 -324
- sierra/core/graphs/pathset.py +27 -0
- sierra/core/graphs/schema.py +77 -0
- sierra/core/graphs/stacked_line.py +341 -0
- sierra/core/graphs/summary_line.py +506 -0
- sierra/core/logging.py +3 -2
- sierra/core/models/__init__.py +3 -1
- sierra/core/models/info.py +19 -0
- sierra/core/models/interface.py +52 -122
- sierra/core/pipeline/__init__.py +2 -5
- sierra/core/pipeline/pipeline.py +228 -126
- sierra/core/pipeline/stage1/__init__.py +10 -0
- sierra/core/pipeline/stage1/pipeline_stage1.py +45 -31
- sierra/core/pipeline/stage2/__init__.py +10 -0
- sierra/core/pipeline/stage2/pipeline_stage2.py +8 -11
- sierra/core/pipeline/stage2/runner.py +401 -0
- sierra/core/pipeline/stage3/__init__.py +12 -0
- sierra/core/pipeline/stage3/gather.py +321 -0
- sierra/core/pipeline/stage3/pipeline_stage3.py +37 -84
- sierra/core/pipeline/stage4/__init__.py +12 -2
- sierra/core/pipeline/stage4/pipeline_stage4.py +36 -354
- sierra/core/pipeline/stage5/__init__.py +12 -0
- sierra/core/pipeline/stage5/pipeline_stage5.py +33 -208
- sierra/core/pipeline/yaml.py +48 -0
- sierra/core/plugin.py +529 -62
- sierra/core/proc.py +11 -0
- sierra/core/prod.py +11 -0
- sierra/core/ros1/__init__.py +5 -1
- sierra/core/ros1/callbacks.py +22 -21
- sierra/core/ros1/cmdline.py +59 -88
- sierra/core/ros1/generators.py +159 -175
- sierra/core/ros1/variables/__init__.py +3 -0
- sierra/core/ros1/variables/exp_setup.py +122 -116
- sierra/core/startup.py +106 -76
- sierra/core/stat_kernels.py +4 -5
- sierra/core/storage.py +13 -32
- sierra/core/trampoline.py +30 -0
- sierra/core/types.py +116 -71
- sierra/core/utils.py +103 -106
- sierra/core/variables/__init__.py +1 -1
- sierra/core/variables/base_variable.py +12 -17
- sierra/core/variables/batch_criteria.py +387 -481
- sierra/core/variables/builtin.py +135 -0
- sierra/core/variables/exp_setup.py +19 -39
- sierra/core/variables/population_size.py +72 -76
- sierra/core/variables/variable_density.py +44 -68
- sierra/core/vector.py +1 -1
- sierra/main.py +256 -88
- sierra/plugins/__init__.py +119 -0
- sierra/plugins/compare/__init__.py +14 -0
- sierra/plugins/compare/graphs/__init__.py +19 -0
- sierra/plugins/compare/graphs/cmdline.py +120 -0
- sierra/plugins/compare/graphs/comparator.py +291 -0
- sierra/plugins/compare/graphs/inter_controller.py +531 -0
- sierra/plugins/compare/graphs/inter_scenario.py +297 -0
- sierra/plugins/compare/graphs/namecalc.py +53 -0
- sierra/plugins/compare/graphs/outputroot.py +73 -0
- sierra/plugins/compare/graphs/plugin.py +147 -0
- sierra/plugins/compare/graphs/preprocess.py +172 -0
- sierra/plugins/compare/graphs/schema.py +37 -0
- sierra/plugins/engine/__init__.py +14 -0
- sierra/plugins/engine/argos/__init__.py +18 -0
- sierra/plugins/{platform → engine}/argos/cmdline.py +144 -151
- sierra/plugins/{platform/argos/variables → engine/argos/generators}/__init__.py +5 -0
- sierra/plugins/engine/argos/generators/engine.py +394 -0
- sierra/plugins/engine/argos/plugin.py +393 -0
- sierra/plugins/{platform/argos/generators → engine/argos/variables}/__init__.py +5 -0
- sierra/plugins/engine/argos/variables/arena_shape.py +183 -0
- sierra/plugins/engine/argos/variables/cameras.py +240 -0
- sierra/plugins/engine/argos/variables/constant_density.py +112 -0
- sierra/plugins/engine/argos/variables/exp_setup.py +82 -0
- sierra/plugins/{platform → engine}/argos/variables/physics_engines.py +83 -87
- sierra/plugins/engine/argos/variables/population_constant_density.py +178 -0
- sierra/plugins/engine/argos/variables/population_size.py +115 -0
- sierra/plugins/engine/argos/variables/population_variable_density.py +123 -0
- sierra/plugins/engine/argos/variables/rendering.py +108 -0
- sierra/plugins/engine/ros1gazebo/__init__.py +18 -0
- sierra/plugins/engine/ros1gazebo/cmdline.py +175 -0
- sierra/plugins/{platform/ros1robot → engine/ros1gazebo}/generators/__init__.py +5 -0
- sierra/plugins/engine/ros1gazebo/generators/engine.py +125 -0
- sierra/plugins/engine/ros1gazebo/plugin.py +404 -0
- sierra/plugins/engine/ros1gazebo/variables/__init__.py +15 -0
- sierra/plugins/engine/ros1gazebo/variables/population_size.py +214 -0
- sierra/plugins/engine/ros1robot/__init__.py +18 -0
- sierra/plugins/engine/ros1robot/cmdline.py +159 -0
- sierra/plugins/{platform/ros1gazebo → engine/ros1robot}/generators/__init__.py +4 -0
- sierra/plugins/engine/ros1robot/generators/engine.py +95 -0
- sierra/plugins/engine/ros1robot/plugin.py +410 -0
- sierra/plugins/{hpc/local → engine/ros1robot/variables}/__init__.py +5 -0
- sierra/plugins/engine/ros1robot/variables/population_size.py +146 -0
- sierra/plugins/execenv/__init__.py +11 -0
- sierra/plugins/execenv/hpc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/__init__.py +18 -0
- sierra/plugins/execenv/hpc/adhoc/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/adhoc/plugin.py +131 -0
- sierra/plugins/execenv/hpc/cmdline.py +137 -0
- sierra/plugins/execenv/hpc/local/__init__.py +18 -0
- sierra/plugins/execenv/hpc/local/cmdline.py +31 -0
- sierra/plugins/execenv/hpc/local/plugin.py +145 -0
- sierra/plugins/execenv/hpc/pbs/__init__.py +18 -0
- sierra/plugins/execenv/hpc/pbs/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/pbs/plugin.py +121 -0
- sierra/plugins/execenv/hpc/slurm/__init__.py +18 -0
- sierra/plugins/execenv/hpc/slurm/cmdline.py +30 -0
- sierra/plugins/execenv/hpc/slurm/plugin.py +133 -0
- sierra/plugins/execenv/prefectserver/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/dockerremote/cmdline.py +66 -0
- sierra/plugins/execenv/prefectserver/dockerremote/plugin.py +132 -0
- sierra/plugins/execenv/prefectserver/flow.py +66 -0
- sierra/plugins/execenv/prefectserver/local/__init__.py +18 -0
- sierra/plugins/execenv/prefectserver/local/cmdline.py +29 -0
- sierra/plugins/execenv/prefectserver/local/plugin.py +133 -0
- sierra/plugins/{hpc/adhoc → execenv/robot}/__init__.py +1 -0
- sierra/plugins/execenv/robot/turtlebot3/__init__.py +18 -0
- sierra/plugins/execenv/robot/turtlebot3/plugin.py +204 -0
- sierra/plugins/expdef/__init__.py +14 -0
- sierra/plugins/expdef/json/__init__.py +14 -0
- sierra/plugins/expdef/json/plugin.py +504 -0
- sierra/plugins/expdef/xml/__init__.py +14 -0
- sierra/plugins/expdef/xml/plugin.py +386 -0
- sierra/{core/hpc → plugins/proc}/__init__.py +1 -1
- sierra/plugins/proc/collate/__init__.py +15 -0
- sierra/plugins/proc/collate/cmdline.py +47 -0
- sierra/plugins/proc/collate/plugin.py +271 -0
- sierra/plugins/proc/compress/__init__.py +18 -0
- sierra/plugins/proc/compress/cmdline.py +47 -0
- sierra/plugins/proc/compress/plugin.py +123 -0
- sierra/plugins/proc/decompress/__init__.py +18 -0
- sierra/plugins/proc/decompress/plugin.py +96 -0
- sierra/plugins/proc/imagize/__init__.py +15 -0
- sierra/plugins/proc/imagize/cmdline.py +49 -0
- sierra/plugins/proc/imagize/plugin.py +270 -0
- sierra/plugins/proc/modelrunner/__init__.py +16 -0
- sierra/plugins/proc/modelrunner/plugin.py +250 -0
- sierra/plugins/proc/statistics/__init__.py +15 -0
- sierra/plugins/proc/statistics/cmdline.py +64 -0
- sierra/plugins/proc/statistics/plugin.py +390 -0
- sierra/plugins/{hpc → prod}/__init__.py +1 -0
- sierra/plugins/prod/graphs/__init__.py +18 -0
- sierra/plugins/prod/graphs/cmdline.py +269 -0
- sierra/plugins/prod/graphs/collate.py +279 -0
- sierra/plugins/prod/graphs/inter/__init__.py +13 -0
- sierra/plugins/prod/graphs/inter/generate.py +83 -0
- sierra/plugins/prod/graphs/inter/heatmap.py +86 -0
- sierra/plugins/prod/graphs/inter/line.py +134 -0
- sierra/plugins/prod/graphs/intra/__init__.py +15 -0
- sierra/plugins/prod/graphs/intra/generate.py +202 -0
- sierra/plugins/prod/graphs/intra/heatmap.py +74 -0
- sierra/plugins/prod/graphs/intra/line.py +114 -0
- sierra/plugins/prod/graphs/plugin.py +103 -0
- sierra/plugins/prod/graphs/targets.py +63 -0
- sierra/plugins/prod/render/__init__.py +18 -0
- sierra/plugins/prod/render/cmdline.py +72 -0
- sierra/plugins/prod/render/plugin.py +282 -0
- sierra/plugins/storage/__init__.py +5 -0
- sierra/plugins/storage/arrow/__init__.py +18 -0
- sierra/plugins/storage/arrow/plugin.py +38 -0
- sierra/plugins/storage/csv/__init__.py +9 -0
- sierra/plugins/storage/csv/plugin.py +12 -5
- sierra/version.py +3 -2
- sierra_research-1.5.0.dist-info/METADATA +238 -0
- sierra_research-1.5.0.dist-info/RECORD +186 -0
- {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info}/WHEEL +1 -2
- sierra/core/experiment/xml.py +0 -454
- sierra/core/generators/controller_generator_parser.py +0 -34
- sierra/core/generators/exp_creator.py +0 -351
- sierra/core/generators/exp_generators.py +0 -142
- sierra/core/graphs/scatterplot2D.py +0 -109
- sierra/core/graphs/stacked_line_graph.py +0 -249
- sierra/core/graphs/stacked_surface_graph.py +0 -220
- sierra/core/graphs/summary_line_graph.py +0 -369
- sierra/core/hpc/cmdline.py +0 -142
- sierra/core/models/graphs.py +0 -87
- sierra/core/pipeline/stage2/exp_runner.py +0 -286
- sierra/core/pipeline/stage3/imagizer.py +0 -149
- sierra/core/pipeline/stage3/run_collator.py +0 -317
- sierra/core/pipeline/stage3/statistics_calculator.py +0 -478
- sierra/core/pipeline/stage4/graph_collator.py +0 -319
- sierra/core/pipeline/stage4/inter_exp_graph_generator.py +0 -240
- sierra/core/pipeline/stage4/intra_exp_graph_generator.py +0 -317
- sierra/core/pipeline/stage4/model_runner.py +0 -168
- sierra/core/pipeline/stage4/rendering.py +0 -283
- sierra/core/pipeline/stage4/yaml_config_loader.py +0 -103
- sierra/core/pipeline/stage5/inter_scenario_comparator.py +0 -328
- sierra/core/pipeline/stage5/intra_scenario_comparator.py +0 -989
- sierra/core/platform.py +0 -493
- sierra/core/plugin_manager.py +0 -369
- sierra/core/root_dirpath_generator.py +0 -241
- sierra/plugins/hpc/adhoc/plugin.py +0 -125
- sierra/plugins/hpc/local/plugin.py +0 -81
- sierra/plugins/hpc/pbs/__init__.py +0 -9
- sierra/plugins/hpc/pbs/plugin.py +0 -126
- sierra/plugins/hpc/slurm/__init__.py +0 -9
- sierra/plugins/hpc/slurm/plugin.py +0 -130
- sierra/plugins/platform/__init__.py +0 -9
- sierra/plugins/platform/argos/__init__.py +0 -9
- sierra/plugins/platform/argos/generators/platform_generators.py +0 -383
- sierra/plugins/platform/argos/plugin.py +0 -337
- sierra/plugins/platform/argos/variables/arena_shape.py +0 -145
- sierra/plugins/platform/argos/variables/cameras.py +0 -243
- sierra/plugins/platform/argos/variables/constant_density.py +0 -136
- sierra/plugins/platform/argos/variables/exp_setup.py +0 -113
- sierra/plugins/platform/argos/variables/population_constant_density.py +0 -175
- sierra/plugins/platform/argos/variables/population_size.py +0 -102
- sierra/plugins/platform/argos/variables/population_variable_density.py +0 -132
- sierra/plugins/platform/argos/variables/rendering.py +0 -104
- sierra/plugins/platform/ros1gazebo/__init__.py +0 -9
- sierra/plugins/platform/ros1gazebo/cmdline.py +0 -213
- sierra/plugins/platform/ros1gazebo/generators/platform_generators.py +0 -137
- sierra/plugins/platform/ros1gazebo/plugin.py +0 -335
- sierra/plugins/platform/ros1gazebo/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1gazebo/variables/population_size.py +0 -204
- sierra/plugins/platform/ros1robot/__init__.py +0 -9
- sierra/plugins/platform/ros1robot/cmdline.py +0 -175
- sierra/plugins/platform/ros1robot/generators/platform_generators.py +0 -112
- sierra/plugins/platform/ros1robot/plugin.py +0 -373
- sierra/plugins/platform/ros1robot/variables/__init__.py +0 -10
- sierra/plugins/platform/ros1robot/variables/population_size.py +0 -146
- sierra/plugins/robot/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/__init__.py +0 -9
- sierra/plugins/robot/turtlebot3/plugin.py +0 -194
- sierra_research-1.3.6.data/data/share/man/man1/sierra-cli.1 +0 -2349
- sierra_research-1.3.6.data/data/share/man/man7/sierra-examples.7 +0 -488
- sierra_research-1.3.6.data/data/share/man/man7/sierra-exec-envs.7 +0 -331
- sierra_research-1.3.6.data/data/share/man/man7/sierra-glossary.7 +0 -285
- sierra_research-1.3.6.data/data/share/man/man7/sierra-platforms.7 +0 -358
- sierra_research-1.3.6.data/data/share/man/man7/sierra-usage.7 +0 -725
- sierra_research-1.3.6.data/data/share/man/man7/sierra.7 +0 -78
- sierra_research-1.3.6.dist-info/METADATA +0 -500
- sierra_research-1.3.6.dist-info/RECORD +0 -133
- sierra_research-1.3.6.dist-info/top_level.txt +0 -1
- {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info}/entry_points.txt +0 -0
- {sierra_research-1.3.6.dist-info → sierra_research-1.5.0.dist-info/licenses}/LICENSE +0 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
#
|
2
|
+
# Copyright 2025 John Harwell, All rights reserved.
|
3
|
+
#
|
4
|
+
# SPDX-License Identifier: MIT
|
5
|
+
#
|
6
|
+
"""
|
7
|
+
YAML schemas for graphs.
|
8
|
+
"""
|
9
|
+
# Core packages
|
10
|
+
|
11
|
+
# 3rd party packages
|
12
|
+
import strictyaml
|
13
|
+
|
14
|
+
# Project packages
|
15
|
+
|
16
|
+
|
17
|
+
heatmap = strictyaml.Map(
|
18
|
+
{
|
19
|
+
"src_stem": strictyaml.Str(),
|
20
|
+
"dest_stem": strictyaml.Str(),
|
21
|
+
"type": strictyaml.Str(),
|
22
|
+
strictyaml.Optional("col"): strictyaml.Str(),
|
23
|
+
strictyaml.Optional("title"): strictyaml.Str(),
|
24
|
+
strictyaml.Optional("zlabel"): strictyaml.Str(),
|
25
|
+
strictyaml.Optional("xlabel"): strictyaml.Str(),
|
26
|
+
strictyaml.Optional("ylabel"): strictyaml.Str(),
|
27
|
+
strictyaml.Optional("index"): strictyaml.Int(),
|
28
|
+
strictyaml.Optional("x"): strictyaml.Str(),
|
29
|
+
strictyaml.Optional("y"): strictyaml.Str(),
|
30
|
+
strictyaml.Optional("z"): strictyaml.Str(),
|
31
|
+
strictyaml.Optional("backend"): strictyaml.Str(),
|
32
|
+
}
|
33
|
+
)
|
34
|
+
"""
|
35
|
+
Schema for :func:`~sierra.core.graphs.heatmap` graphs.
|
36
|
+
"""
|
37
|
+
|
38
|
+
stacked_line = strictyaml.Map(
|
39
|
+
{
|
40
|
+
"src_stem": strictyaml.Str(),
|
41
|
+
"dest_stem": strictyaml.Str(),
|
42
|
+
"type": strictyaml.Str(),
|
43
|
+
# Only optional for intra-exp, but there's not a simple way to mark it
|
44
|
+
# as such at this level.
|
45
|
+
strictyaml.Optional("cols"): strictyaml.Seq(strictyaml.Str()),
|
46
|
+
strictyaml.Optional("title"): strictyaml.Str(),
|
47
|
+
strictyaml.Optional("legend"): strictyaml.Seq(strictyaml.Str()),
|
48
|
+
strictyaml.Optional("xlabel"): strictyaml.Str(),
|
49
|
+
strictyaml.Optional("ylabel"): strictyaml.Str(),
|
50
|
+
strictyaml.Optional("points"): strictyaml.Bool(),
|
51
|
+
strictyaml.Optional("logy"): strictyaml.Bool(),
|
52
|
+
strictyaml.Optional("backend"): strictyaml.Str(),
|
53
|
+
}
|
54
|
+
)
|
55
|
+
"""
|
56
|
+
Schema for :func:`~sierra.core.graphs.stacked_line` graphs.
|
57
|
+
"""
|
58
|
+
|
59
|
+
summary_line = strictyaml.Map(
|
60
|
+
{
|
61
|
+
"src_stem": strictyaml.Str(),
|
62
|
+
"dest_stem": strictyaml.Str(),
|
63
|
+
"col": strictyaml.Str(),
|
64
|
+
strictyaml.Optional("legend"): strictyaml.Seq(strictyaml.Str()),
|
65
|
+
strictyaml.Optional("title"): strictyaml.Str(),
|
66
|
+
strictyaml.Optional("type"): strictyaml.Str(),
|
67
|
+
strictyaml.Optional("xlabel"): strictyaml.Str(),
|
68
|
+
strictyaml.Optional("ylabel"): strictyaml.Str(),
|
69
|
+
strictyaml.Optional("points"): strictyaml.Bool(),
|
70
|
+
strictyaml.Optional("index"): strictyaml.Int(),
|
71
|
+
strictyaml.Optional("logy"): strictyaml.Bool(),
|
72
|
+
strictyaml.Optional("backend"): strictyaml.Str(),
|
73
|
+
}
|
74
|
+
)
|
75
|
+
"""
|
76
|
+
Schema for :func:`~sierra.core.graphs.summary_line` graphs.
|
77
|
+
"""
|
@@ -0,0 +1,341 @@
|
|
1
|
+
# Copyright 2018 John Harwell, All rights reserved.
|
2
|
+
#
|
3
|
+
# SPDX-License-Identifier: MIT
|
4
|
+
#
|
5
|
+
"""
|
6
|
+
Intra-experiment line graph generation classes for stage{4,5}.
|
7
|
+
"""
|
8
|
+
|
9
|
+
# Core packages
|
10
|
+
import typing as tp
|
11
|
+
import logging
|
12
|
+
import pathlib
|
13
|
+
|
14
|
+
# 3rd party packages
|
15
|
+
import pandas as pd
|
16
|
+
import holoviews as hv
|
17
|
+
import matplotlib.pyplot as plt
|
18
|
+
import bokeh
|
19
|
+
|
20
|
+
# Project packages
|
21
|
+
from sierra.core import config, utils, storage, models
|
22
|
+
from . import pathset
|
23
|
+
|
24
|
+
_logger = logging.getLogger(__name__)
|
25
|
+
|
26
|
+
|
27
|
+
def _ofile_ext(backend: str) -> tp.Optional[str]:
|
28
|
+
if backend == "matplotlib":
|
29
|
+
return config.kStaticImageType
|
30
|
+
elif backend == "bokeh":
|
31
|
+
return config.kInteractiveImageType
|
32
|
+
|
33
|
+
return None
|
34
|
+
|
35
|
+
|
36
|
+
def generate(
|
37
|
+
paths: pathset.PathSet,
|
38
|
+
input_stem: str,
|
39
|
+
output_stem: str,
|
40
|
+
title: str,
|
41
|
+
medium: str,
|
42
|
+
backend: str,
|
43
|
+
xticks: tp.Optional[tp.List[float]] = None,
|
44
|
+
stats: str = "none",
|
45
|
+
xlabel: tp.Optional[str] = None,
|
46
|
+
ylabel: tp.Optional[str] = None,
|
47
|
+
points: tp.Optional[bool] = False,
|
48
|
+
large_text: bool = False,
|
49
|
+
legend: tp.Optional[tp.List[str]] = None,
|
50
|
+
xticklabels: tp.Optional[tp.List[str]] = None,
|
51
|
+
cols: tp.Optional[tp.List[str]] = None,
|
52
|
+
logyscale: bool = False,
|
53
|
+
ext: str = config.kStats["mean"].exts["mean"],
|
54
|
+
) -> bool:
|
55
|
+
"""Generate a line graph from a set of columns in a file.
|
56
|
+
|
57
|
+
If the necessary data file does not exist, the graph is not generated.
|
58
|
+
|
59
|
+
If the .stddev file that goes with the .mean does not exist, then no error
|
60
|
+
bars are plotted.
|
61
|
+
|
62
|
+
If the .model file that goes with the .mean does not exist, then no model
|
63
|
+
predictions are plotted.
|
64
|
+
|
65
|
+
Ideally, model predictions/stddev calculations would be in derived classes,
|
66
|
+
but I can't figure out a good way to easily pull that stuff out of here.
|
67
|
+
"""
|
68
|
+
hv.extension(backend)
|
69
|
+
|
70
|
+
input_fpath = paths.input_root / (input_stem + ext)
|
71
|
+
output_fpath = paths.output_root / "SLN-{0}.{1}".format(
|
72
|
+
output_stem, _ofile_ext(backend)
|
73
|
+
)
|
74
|
+
|
75
|
+
if large_text:
|
76
|
+
text_size = config.kGraphs["text_size_large"]
|
77
|
+
else:
|
78
|
+
text_size = config.kGraphs["text_size_small"]
|
79
|
+
|
80
|
+
if not utils.path_exists(input_fpath):
|
81
|
+
_logger.debug(
|
82
|
+
"Not generating <batchroot>/%s: <batchroot>/%s does not exist",
|
83
|
+
output_fpath.relative_to(paths.batchroot),
|
84
|
+
input_fpath.relative_to(paths.batchroot),
|
85
|
+
)
|
86
|
+
return False
|
87
|
+
|
88
|
+
df = storage.df_read(input_fpath, medium)
|
89
|
+
|
90
|
+
# Use xticks if provided, otherwise default to using the dataframe index as
|
91
|
+
# the xticks.
|
92
|
+
dfcols = df.columns.tolist()
|
93
|
+
df["xticks"] = xticks if xticks is not None else df.index.to_list()
|
94
|
+
dataset = hv.Dataset(
|
95
|
+
# Make index a column so we can use it as kdim
|
96
|
+
data=df.reset_index(),
|
97
|
+
kdims=["index"],
|
98
|
+
vdims=cols if cols else dfcols,
|
99
|
+
)
|
100
|
+
|
101
|
+
assert len(df.index) == len(
|
102
|
+
df["xticks"]
|
103
|
+
), "Length mismatch between xticks,# data points: {0} vs {1}".format(
|
104
|
+
len(df["xticks"]), len(df.index)
|
105
|
+
)
|
106
|
+
|
107
|
+
model = _read_models(paths.model_root, input_stem, medium)
|
108
|
+
stat_dfs = _read_stats(stats, paths.input_root, input_stem, medium)
|
109
|
+
|
110
|
+
# Plot stats if they have been computed FIRST, so they appear behind the
|
111
|
+
# actual data.
|
112
|
+
if "conf95" in stats and "stddev" in stat_dfs:
|
113
|
+
plot = _plot_stats_stddev(dataset, stat_dfs["stddev"])
|
114
|
+
plot *= _plot_selected_cols(dataset, model, legend, points, backend)
|
115
|
+
elif "bw" in stats and all(k in stat_dfs.keys() for k in config.kStats["bw"].exts):
|
116
|
+
# 2025-10-06 [JRH]: This is a limitation of hv (I think). Manually
|
117
|
+
# specifying bw plots around each datapoint on a graph can easily exceed
|
118
|
+
# the max # of things that can be in a single overlay.
|
119
|
+
_logger.warning("bw statistics not implemented for stacked_line graphs")
|
120
|
+
plot = _plot_selected_cols(dataset, model, legend, points, backend)
|
121
|
+
else:
|
122
|
+
# Plot specified columns from dataframe.
|
123
|
+
plot = _plot_selected_cols(dataset, model, legend, points, backend)
|
124
|
+
|
125
|
+
# Let the backend decide # of columns; can override with
|
126
|
+
# legend_cols=N in the future if desired.
|
127
|
+
plot.opts(legend_position="bottom")
|
128
|
+
|
129
|
+
# Add title
|
130
|
+
plot.opts(title=title)
|
131
|
+
|
132
|
+
# Add X,Y labels
|
133
|
+
if xlabel is not None:
|
134
|
+
plot.opts(xlabel=xlabel)
|
135
|
+
|
136
|
+
if ylabel is not None:
|
137
|
+
plot.opts(ylabel=ylabel)
|
138
|
+
|
139
|
+
# Set fontsizes
|
140
|
+
plot.opts(
|
141
|
+
fontsize={
|
142
|
+
"title": text_size["title"],
|
143
|
+
"labels": text_size["xyz_label"],
|
144
|
+
"ticks": text_size["tick_label"],
|
145
|
+
"legend": text_size["legend_label"],
|
146
|
+
},
|
147
|
+
)
|
148
|
+
|
149
|
+
if logyscale:
|
150
|
+
_min = min(dataset[vdim].min() for vdim in dataset.vdims)
|
151
|
+
_max = max(dataset[vdim].max() for vdim in dataset.vdims)
|
152
|
+
|
153
|
+
plot.opts(
|
154
|
+
logy=True,
|
155
|
+
ylim=(
|
156
|
+
_min * 0.9,
|
157
|
+
_max * 1.1,
|
158
|
+
),
|
159
|
+
)
|
160
|
+
|
161
|
+
_save(plot, output_fpath, backend)
|
162
|
+
_logger.debug(
|
163
|
+
"Graph written to <batchroot>/%s",
|
164
|
+
output_fpath.relative_to(paths.batchroot),
|
165
|
+
)
|
166
|
+
return True
|
167
|
+
|
168
|
+
|
169
|
+
def _save(plot: hv.Overlay, output_fpath: pathlib.Path, backend: str) -> None:
|
170
|
+
if backend == "matplotlib":
|
171
|
+
hv.save(
|
172
|
+
plot.opts(fig_inches=config.kGraphs["base_size"]),
|
173
|
+
output_fpath,
|
174
|
+
fig=config.kStaticImageType,
|
175
|
+
dpi=config.kGraphs["dpi"],
|
176
|
+
)
|
177
|
+
plt.close("all")
|
178
|
+
elif backend == "bokeh":
|
179
|
+
fig = hv.render(plot)
|
180
|
+
fig.width = int(config.kGraphs["dpi"] * config.kGraphs["base_size"])
|
181
|
+
fig.height = int(config.kGraphs["dpi"] * config.kGraphs["base_size"])
|
182
|
+
html = bokeh.embed.file_html(fig, resources=bokeh.resources.INLINE)
|
183
|
+
with open(output_fpath, "w") as f:
|
184
|
+
f.write(html)
|
185
|
+
|
186
|
+
|
187
|
+
def _plot_selected_cols(
|
188
|
+
dataset: hv.Dataset,
|
189
|
+
model_info: models.ModelInfo,
|
190
|
+
legend: tp.List[str],
|
191
|
+
show_points: bool,
|
192
|
+
backend: str,
|
193
|
+
) -> hv.NdOverlay:
|
194
|
+
"""
|
195
|
+
Plot the selected columns in a dataframe.
|
196
|
+
"""
|
197
|
+
# Always plot the data
|
198
|
+
plot = hv.Overlay(
|
199
|
+
[
|
200
|
+
hv.Curve(
|
201
|
+
dataset,
|
202
|
+
dataset.kdims[0],
|
203
|
+
vdim.name,
|
204
|
+
label=legend[dataset.vdims.index(vdim)] if legend else "",
|
205
|
+
)
|
206
|
+
for vdim in dataset.vdims
|
207
|
+
]
|
208
|
+
)
|
209
|
+
# Plot the points for each curve if configured to do so, OR if there aren't
|
210
|
+
# that many. If you print them and there are a lot, you essentially get
|
211
|
+
# really fat lines which doesn't look good.
|
212
|
+
plot *= hv.Overlay(
|
213
|
+
[
|
214
|
+
hv.Points((dataset[dataset.kdims[0]], dataset[v]))
|
215
|
+
for v in dataset.vdims
|
216
|
+
if len(dataset[v]) <= 50 or show_points
|
217
|
+
]
|
218
|
+
)
|
219
|
+
|
220
|
+
if backend == "matplotlib":
|
221
|
+
opts = {
|
222
|
+
"linestyle": "--",
|
223
|
+
}
|
224
|
+
elif backend == "bokeh":
|
225
|
+
opts = {"line_dash": [6, 3]}
|
226
|
+
|
227
|
+
# Plot models if they have been computed
|
228
|
+
if model_info.dataset:
|
229
|
+
plot *= hv.Overlay(
|
230
|
+
[
|
231
|
+
hv.Curve(
|
232
|
+
model_info.dataset,
|
233
|
+
model_info.dataset.kdims[0],
|
234
|
+
vdim.name,
|
235
|
+
label=model_info.legend[model_info.dataset.vdims.index(vdim)],
|
236
|
+
).opts(**opts)
|
237
|
+
for vdim in model_info.dataset.vdims
|
238
|
+
]
|
239
|
+
)
|
240
|
+
# Plot the points for each curve
|
241
|
+
plot *= hv.Overlay(
|
242
|
+
[
|
243
|
+
hv.Points(
|
244
|
+
(
|
245
|
+
model_info.dataset[model_info.dataset.kdims[0]],
|
246
|
+
model_info.dataset[v],
|
247
|
+
)
|
248
|
+
)
|
249
|
+
for v in model_info.dataset.vdims
|
250
|
+
if len(model_info.dataset[v]) <= 50 or show_points
|
251
|
+
]
|
252
|
+
)
|
253
|
+
|
254
|
+
return plot
|
255
|
+
|
256
|
+
|
257
|
+
def _plot_stats_stddev(dataset: hv.Dataset, stddev_df: pd.DataFrame) -> hv.NdOverlay:
|
258
|
+
"""Plot the stddev for all columns in the dataset."""
|
259
|
+
stddevs = pd.DataFrame()
|
260
|
+
for c in dataset.vdims:
|
261
|
+
stddevs[f"{c}_stddev_l"] = dataset[c] - 2 * stddev_df[c.name].abs()
|
262
|
+
stddevs[f"{c}_stddev_u"] = dataset[c] + 2 * stddev_df[c.name].abs()
|
263
|
+
|
264
|
+
# To plot area between lines, you need to add the stddev columns to the
|
265
|
+
# dataset
|
266
|
+
dataset.data = pd.concat([dataset.dframe(), stddevs], axis=1)
|
267
|
+
|
268
|
+
return hv.Overlay(
|
269
|
+
[
|
270
|
+
hv.Area(
|
271
|
+
dataset, vdims=[f"{vdim.name}_stddev_l", f"{vdim.name}_stddev_u"]
|
272
|
+
).opts(
|
273
|
+
alpha=0.5,
|
274
|
+
)
|
275
|
+
for vdim in dataset.vdims
|
276
|
+
]
|
277
|
+
)
|
278
|
+
|
279
|
+
|
280
|
+
def _read_stats(
|
281
|
+
setting: str, stats_root: pathlib.Path, input_stem: str, medium: str
|
282
|
+
) -> tp.Dict[str, pd.DataFrame]:
|
283
|
+
dfs = {} # type: tp.Dict[str, pd.DataFrame]
|
284
|
+
settings = []
|
285
|
+
|
286
|
+
if setting == "none":
|
287
|
+
return dfs
|
288
|
+
|
289
|
+
if setting == "all":
|
290
|
+
settings = ["conf95", "bw"]
|
291
|
+
else:
|
292
|
+
settings = [setting]
|
293
|
+
|
294
|
+
if setting in settings:
|
295
|
+
exts = config.kStats[setting].exts
|
296
|
+
|
297
|
+
for k in exts:
|
298
|
+
ipath = stats_root / (input_stem + exts[k])
|
299
|
+
if utils.path_exists(ipath):
|
300
|
+
dfs[k] = storage.df_read(ipath, medium)
|
301
|
+
else:
|
302
|
+
_logger.warning("%s not found for '%s'", exts[k], input_stem)
|
303
|
+
|
304
|
+
return dfs
|
305
|
+
|
306
|
+
|
307
|
+
# 2024/09/13 [JRH]: The union is for compatability with type checkers in
|
308
|
+
# python {3.8,3.11}.
|
309
|
+
def _read_models(
|
310
|
+
model_root: tp.Optional[pathlib.Path], input_stem: str, medium: str
|
311
|
+
) -> models.ModelInfo:
|
312
|
+
|
313
|
+
if model_root is None:
|
314
|
+
return models.ModelInfo()
|
315
|
+
|
316
|
+
modelf = model_root / (input_stem + config.kModelsExt["model"])
|
317
|
+
legendf = model_root / (input_stem + config.kModelsExt["legend"])
|
318
|
+
|
319
|
+
if not utils.path_exists(modelf):
|
320
|
+
_logger.trace("Model file %s missing for graph", str(modelf))
|
321
|
+
return models.ModelInfo()
|
322
|
+
|
323
|
+
info = models.ModelInfo()
|
324
|
+
df = storage.df_read(modelf, medium)
|
325
|
+
cols = df.columns.tolist()
|
326
|
+
|
327
|
+
info.dataset = hv.Dataset(data=df.reset_index(), kdims=["index"], vdims=cols)
|
328
|
+
|
329
|
+
with utils.utf8open(legendf, "r") as f:
|
330
|
+
info.legend = f.read().splitlines()
|
331
|
+
|
332
|
+
_logger.trace(
|
333
|
+
"Loaded model='%s',legend='%s'", # type: ignore
|
334
|
+
modelf.relative_to(model_root),
|
335
|
+
legendf.relative_to(model_root),
|
336
|
+
)
|
337
|
+
|
338
|
+
return info
|
339
|
+
|
340
|
+
|
341
|
+
__all__ = ["generate"]
|