dynamic-systems-testing-framework 1.0.1__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.
- dstf/__init__.py +41 -0
- dstf/__main__.py +10 -0
- dstf/authoring/__init__.py +13 -0
- dstf/authoring/builtin/__init__.py +32 -0
- dstf/authoring/builtin/accept.py +205 -0
- dstf/authoring/builtin/edit_criteria.py +479 -0
- dstf/authoring/builtin/edit_family.py +228 -0
- dstf/authoring/builtin/edit_on_plot.py +1354 -0
- dstf/authoring/builtin/edit_tree.py +1399 -0
- dstf/authoring/builtin/enqueue.py +144 -0
- dstf/authoring/capabilities.py +463 -0
- dstf/authoring/errors.py +49 -0
- dstf/authoring/family_rows.py +526 -0
- dstf/authoring/forms.py +631 -0
- dstf/authoring/layout.py +104 -0
- dstf/authoring/live_rows.py +337 -0
- dstf/authoring/live_runs.py +385 -0
- dstf/authoring/needle.py +127 -0
- dstf/authoring/picker_rows.py +92 -0
- dstf/authoring/queue_rows.py +354 -0
- dstf/authoring/session.py +3016 -0
- dstf/authoring/shell/__init__.py +9 -0
- dstf/authoring/shell/actions.py +702 -0
- dstf/authoring/shell/app.py +53 -0
- dstf/authoring/shell/drawer_controls.py +190 -0
- dstf/authoring/shell/family_fold.py +468 -0
- dstf/authoring/shell/figure_hook.py +249 -0
- dstf/authoring/shell/grips.js +1000 -0
- dstf/authoring/shell/header.py +783 -0
- dstf/authoring/shell/live_view.py +93 -0
- dstf/authoring/shell/picker.py +267 -0
- dstf/authoring/shell/placing.py +122 -0
- dstf/authoring/shell/plot_card.py +1171 -0
- dstf/authoring/shell/queue_panel.py +433 -0
- dstf/authoring/shell/rail.py +593 -0
- dstf/authoring/shell/shell.py +528 -0
- dstf/authoring/shell/stats_card.py +501 -0
- dstf/authoring/shell/strip.py +204 -0
- dstf/authoring/shell/style.py +721 -0
- dstf/authoring/shell/suite.py +277 -0
- dstf/authoring/shell/suite_grid.js +414 -0
- dstf/authoring/shell/suite_grid.py +373 -0
- dstf/authoring/shell/tab_theme.py +110 -0
- dstf/authoring/shell/tabstate.py +146 -0
- dstf/authoring/shell/test_list.py +179 -0
- dstf/authoring/shell/test_page.py +1404 -0
- dstf/authoring/shell/tree_card.py +1171 -0
- dstf/authoring/shell/variables_drawer.py +589 -0
- dstf/authoring/shell/widgets.py +188 -0
- dstf/authoring/situation.py +287 -0
- dstf/authoring/spec_document.py +215 -0
- dstf/authoring/spec_preview.py +83 -0
- dstf/authoring/suite_rows.py +99 -0
- dstf/authoring/tree_move.py +516 -0
- dstf/authoring/tree_pointer.py +33 -0
- dstf/authoring/tree_text.py +61 -0
- dstf/authoring/typed_number.js +64 -0
- dstf/authoring/typed_number.py +76 -0
- dstf/authoring/unscorable.py +141 -0
- dstf/authoring/variable_rows.py +216 -0
- dstf/backends/__init__.py +283 -0
- dstf/backends/base.py +1117 -0
- dstf/backends/common/__init__.py +1 -0
- dstf/backends/common/json_driver.py +484 -0
- dstf/backends/common/live_mat.py +369 -0
- dstf/backends/common/mat_reader.py +632 -0
- dstf/backends/common/proc_kill.py +238 -0
- dstf/backends/common/proc_output.py +20 -0
- dstf/backends/common/result_files.py +109 -0
- dstf/backends/common/result_variables.py +329 -0
- dstf/backends/common/statistics.py +39 -0
- dstf/backends/cross_backend.py +193 -0
- dstf/backends/dymola/__init__.py +5 -0
- dstf/backends/dymola/backend.py +776 -0
- dstf/backends/dymola/interface_loader.py +241 -0
- dstf/backends/dymola/log_parser.py +396 -0
- dstf/backends/dymola/persistent_backend.py +949 -0
- dstf/backends/fmpy/__init__.py +11 -0
- dstf/backends/fmpy/backend.py +443 -0
- dstf/backends/julia/__init__.py +27 -0
- dstf/backends/julia/backend.py +156 -0
- dstf/backends/julia/persistent_backend.py +541 -0
- dstf/backends/julia/run_persistent.jl +167 -0
- dstf/backends/julia/run_test.jl +146 -0
- dstf/backends/openmodelica/__init__.py +21 -0
- dstf/backends/openmodelica/backend.py +368 -0
- dstf/backends/openmodelica/init_xml.py +76 -0
- dstf/backends/openmodelica/log_parser.py +119 -0
- dstf/backends/openmodelica/mos_generator.py +228 -0
- dstf/backends/openmodelica/persistent_backend.py +1045 -0
- dstf/backends/openmodelica/session_loader.py +63 -0
- dstf/backends/persistent.py +1811 -0
- dstf/backends/pool.py +602 -0
- dstf/backends/progress.py +395 -0
- dstf/backends/python/__init__.py +11 -0
- dstf/backends/python/backend.py +141 -0
- dstf/backends/python/run_test.py +141 -0
- dstf/backends/run_metadata.py +103 -0
- dstf/backends/types.py +310 -0
- dstf/cli/__init__.py +12 -0
- dstf/cli/author_cmd.py +61 -0
- dstf/cli/baseline_cmds.py +341 -0
- dstf/cli/common.py +231 -0
- dstf/cli/diag_cmds.py +350 -0
- dstf/cli/main.py +561 -0
- dstf/cli/review.py +398 -0
- dstf/cli/run_cmds.py +589 -0
- dstf/cli/spec_cmds.py +123 -0
- dstf/comparison/__init__.py +13 -0
- dstf/comparison/algorithms.py +2127 -0
- dstf/comparison/builtins.py +291 -0
- dstf/comparison/comparator.py +1189 -0
- dstf/comparison/geometry.py +164 -0
- dstf/comparison/handles.py +1194 -0
- dstf/comparison/metric_tree.py +332 -0
- dstf/comparison/mode_schema.py +176 -0
- dstf/comparison/modes.py +788 -0
- dstf/comparison/registry.py +230 -0
- dstf/comparison/seeds.py +281 -0
- dstf/comparison/sides.py +158 -0
- dstf/comparison/snap.py +62 -0
- dstf/comparison/strict_keys.py +246 -0
- dstf/comparison/summaries.py +354 -0
- dstf/comparison/tree_eval.py +868 -0
- dstf/comparison/tree_spec.py +678 -0
- dstf/comparison/types.py +194 -0
- dstf/comparison/validator.py +232 -0
- dstf/config.py +815 -0
- dstf/discovery/__init__.py +0 -0
- dstf/discovery/json_recognizer.py +702 -0
- dstf/discovery/library_state.py +248 -0
- dstf/discovery/mo_parser.py +794 -0
- dstf/discovery/patch_apply.py +308 -0
- dstf/discovery/patch_envelope.py +63 -0
- dstf/discovery/plots.py +318 -0
- dstf/discovery/recognizer.py +103 -0
- dstf/discovery/scan_cache.py +154 -0
- dstf/discovery/spec_parser.py +538 -0
- dstf/discovery/spec_shape.py +122 -0
- dstf/discovery/spec_update.py +493 -0
- dstf/discovery/test_registry.py +488 -0
- dstf/discovery/unit_tests.py +95 -0
- dstf/figures/__init__.py +14 -0
- dstf/figures/assemble.py +48 -0
- dstf/figures/decimate.py +150 -0
- dstf/figures/families.py +289 -0
- dstf/figures/palette.py +170 -0
- dstf/figures/plotly.py +1413 -0
- dstf/figures/view.py +233 -0
- dstf/pipeline.py +435 -0
- dstf/plugins.py +104 -0
- dstf/reporting/__init__.py +0 -0
- dstf/reporting/console_report.py +187 -0
- dstf/reporting/context_builder.py +979 -0
- dstf/reporting/dashboard_render.py +534 -0
- dstf/reporting/junit_report.py +192 -0
- dstf/reporting/overlay_loader.py +708 -0
- dstf/reporting/report_suite.py +1059 -0
- dstf/reporting/rows.py +458 -0
- dstf/reporting/schema_export.py +413 -0
- dstf/reporting/stats_rows.py +321 -0
- dstf/reporting/status.py +388 -0
- dstf/reporting/templates/axes.js +61 -0
- dstf/reporting/templates/dashboard.html +284 -0
- dstf/reporting/templates/dashboard.js +604 -0
- dstf/reporting/templates/filters.js +100 -0
- dstf/reporting/templates/interactive.html +420 -0
- dstf/reporting/templates/report.js +116 -0
- dstf/reporting/templates/vendor/plotly.min.js +8 -0
- dstf/reporting/theme.py +324 -0
- dstf/reporting/tree_rows.py +73 -0
- dstf/reporting/verdicts.py +124 -0
- dstf/storage/__init__.py +0 -0
- dstf/storage/accept.py +216 -0
- dstf/storage/baseline.py +43 -0
- dstf/storage/batch_manifest.py +204 -0
- dstf/storage/ref_index.py +295 -0
- dstf/storage/reference_store.py +661 -0
- dstf/storage/roles.py +576 -0
- dstf/storage/run_stats.py +85 -0
- dynamic_systems_testing_framework-1.0.1.dist-info/METADATA +266 -0
- dynamic_systems_testing_framework-1.0.1.dist-info/RECORD +185 -0
- dynamic_systems_testing_framework-1.0.1.dist-info/WHEEL +4 -0
- dynamic_systems_testing_framework-1.0.1.dist-info/entry_points.txt +2 -0
- dynamic_systems_testing_framework-1.0.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"""Geometry primitives: what a comparison mode scored against, as data.
|
|
2
|
+
|
|
3
|
+
Each :class:`~.types.VariableComparison` carries the primitives its mode
|
|
4
|
+
built while scoring — the tube band on the grid it was enforced on, the
|
|
5
|
+
checkpoint boxes, the declared bounds, the detected events, the spectra.
|
|
6
|
+
They are the single source every figure draws from (``dstf.figures``), so a
|
|
7
|
+
mode cannot draw one envelope and score another.
|
|
8
|
+
|
|
9
|
+
The vocabulary is deliberately small. A new kind of drawing is a new class
|
|
10
|
+
here plus one builder in ``dstf.figures.plotly``; that is cheaper than
|
|
11
|
+
smuggling a shape into :class:`Series`, which is the failure this file's
|
|
12
|
+
size guards against.
|
|
13
|
+
|
|
14
|
+
Ids are addresses. A mode emits LOCAL ids (``tube/band``, ``tube/upper/3``,
|
|
15
|
+
``points/target/0``) — it does not know its leaf — and the evaluator
|
|
16
|
+
prefixes each with the leaf's RFC 6902 path (``/metrics/children/2``)
|
|
17
|
+
through :meth:`Primitive.prefixed`, so a figure handle and a patch op share
|
|
18
|
+
one name. ``kind`` is a free label the figure builder styles on:
|
|
19
|
+
``"result"`` (what was computed), ``"handle"`` (the resolved position of an
|
|
20
|
+
authored parameter — a control point, a bound, a declared peak), ``"grip"``
|
|
21
|
+
(the resolved position of one SIDE of a tolerance; drawn only for the open
|
|
22
|
+
criterion in the tool, never as a trace and never in the report — four more
|
|
23
|
+
dots per checkpoint would sit on every report page), ``"ref"`` / ``"act"``
|
|
24
|
+
(which curve an event or spectrum belongs to), ``"matched"`` / ``"detected"``
|
|
25
|
+
(peak roles), ``"error"`` (the view's error series).
|
|
26
|
+
|
|
27
|
+
A grip's local id is ``<family>/<edge>/<key>`` — ``points/upper/3``,
|
|
28
|
+
``events/late/0``, ``tube/lower/const`` — beside the handle it belongs to
|
|
29
|
+
(``points/target/3``): the edge says which side it is, and
|
|
30
|
+
:func:`grip_axis` / :func:`grip_outward` which way it moves.
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
from dataclasses import dataclass, replace
|
|
36
|
+
from typing import Literal
|
|
37
|
+
|
|
38
|
+
import numpy as np
|
|
39
|
+
|
|
40
|
+
Panel = Literal["time", "spectrum"]
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
44
|
+
class Primitive:
|
|
45
|
+
id: str
|
|
46
|
+
kind: str = "result"
|
|
47
|
+
panel: Panel = "time"
|
|
48
|
+
|
|
49
|
+
def prefixed(self, prefix: str) -> Primitive:
|
|
50
|
+
"""A copy whose id is ``<prefix>/<id>`` — the evaluator's stamp."""
|
|
51
|
+
return replace(self, id=f"{prefix}/{self.id}")
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
55
|
+
class Band(Primitive):
|
|
56
|
+
"""An envelope: ``lower[i] <= y <= upper[i]`` at ``time[i]``."""
|
|
57
|
+
|
|
58
|
+
time: np.ndarray
|
|
59
|
+
lower: np.ndarray
|
|
60
|
+
upper: np.ndarray
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
64
|
+
class Box(Primitive):
|
|
65
|
+
"""A rectangle ``[t0, t1] × [y0, y1]``. ``y0``/``y1`` of ``None`` span the panel."""
|
|
66
|
+
|
|
67
|
+
t0: float
|
|
68
|
+
t1: float
|
|
69
|
+
y0: float | None
|
|
70
|
+
y1: float | None
|
|
71
|
+
passed: bool | None = None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
75
|
+
class Marker(Primitive):
|
|
76
|
+
x: float
|
|
77
|
+
y: float
|
|
78
|
+
passed: bool | None = None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
82
|
+
class HLine(Primitive):
|
|
83
|
+
value: float
|
|
84
|
+
passed: bool | None = None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
88
|
+
class VLine(Primitive):
|
|
89
|
+
time: float
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
#: A grip's edge and the direction along its axis that is OUTWARD from the
|
|
93
|
+
#: target: ``+1`` towards larger values (or later times), ``-1`` the other
|
|
94
|
+
#: way. A lookup, not a default: an edge that is not here raises.
|
|
95
|
+
_GRIP_OUTWARD = {
|
|
96
|
+
"upper": 1,
|
|
97
|
+
"after": 1,
|
|
98
|
+
"late": 1,
|
|
99
|
+
"lower": -1,
|
|
100
|
+
"before": -1,
|
|
101
|
+
"early": -1,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def grip_edge(grip: Primitive) -> str:
|
|
106
|
+
"""A grip's edge: the segment of its id before the last — ``upper`` of
|
|
107
|
+
``…/points/upper/3``."""
|
|
108
|
+
return grip.id.split("/")[-2]
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def grip_group(prim: Primitive) -> str:
|
|
112
|
+
"""The grips that show together — a checkpoint's four, a window's two:
|
|
113
|
+
the id without its edge, ``…/points/3`` of ``…/points/upper/3``. The
|
|
114
|
+
handle they stand around reads the same way (``…/points/target/3``), so
|
|
115
|
+
a ring names the group of its own grips."""
|
|
116
|
+
parts = prim.id.split("/")
|
|
117
|
+
return "/".join(parts[:-2] + parts[-1:])
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
#: What a grip's arrow says of itself — its tooltip in the tool — by its
|
|
121
|
+
#: edge, in the side names the editor's fields use (a tolerance's − / +
|
|
122
|
+
#: read as lower / upper). A lookup, not a default, like `_GRIP_OUTWARD`.
|
|
123
|
+
_GRIP_LABELS = {
|
|
124
|
+
"upper": "Drag to set the upper tolerance",
|
|
125
|
+
"lower": "Drag to set the lower tolerance",
|
|
126
|
+
"before": "Drag to set how much before",
|
|
127
|
+
"after": "Drag to set how much after",
|
|
128
|
+
"early": "Drag to set how much earlier",
|
|
129
|
+
"late": "Drag to set how much later",
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def grip_label(grip: Primitive) -> str:
|
|
134
|
+
"""The one line a grip's arrow says of what dragging it sets."""
|
|
135
|
+
return _GRIP_LABELS[grip_edge(grip)]
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def grip_outward(grip: Primitive) -> int:
|
|
139
|
+
"""``+1`` or ``-1``: which way along :func:`grip_axis` leads AWAY from
|
|
140
|
+
the target — where the grip is drawn, just outside its edge."""
|
|
141
|
+
return _GRIP_OUTWARD[grip_edge(grip)]
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def grip_axis(grip: Marker | VLine) -> Literal["x", "y"]:
|
|
145
|
+
"""The ONE axis a grip moves on. A line stands at a time or a frequency:
|
|
146
|
+
x. A marker's ``upper`` and ``lower`` are the edges of a value: y; its
|
|
147
|
+
``before`` and ``after`` those of a time: x."""
|
|
148
|
+
if isinstance(grip, VLine):
|
|
149
|
+
return "x"
|
|
150
|
+
return "y" if grip_edge(grip) in ("upper", "lower") else "x"
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
154
|
+
class Series(Primitive):
|
|
155
|
+
x: np.ndarray
|
|
156
|
+
y: np.ndarray
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@dataclass(frozen=True, kw_only=True, eq=False)
|
|
160
|
+
class Window(Primitive):
|
|
161
|
+
"""The leaf's time window; either end ``None`` means open on that side."""
|
|
162
|
+
|
|
163
|
+
start: float | None
|
|
164
|
+
end: float | None
|