physmap 0.2.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.
- physmap/__init__.py +61 -0
- physmap/_paths.py +69 -0
- physmap/applicability/__init__.py +0 -0
- physmap/applicability/fixtures.py +83 -0
- physmap/applicability/screen.py +99 -0
- physmap/baselines/__init__.py +0 -0
- physmap/benchmarks/__init__.py +0 -0
- physmap/benchmarks/benchmark_report.py +405 -0
- physmap/benchmarks/benchmark_v0_4.py +424 -0
- physmap/benchmarks/compare.py +149 -0
- physmap/benchmarks/registry.py +217 -0
- physmap/benchmarks/report.py +224 -0
- physmap/cli.py +301 -0
- physmap/closures/__init__.py +48 -0
- physmap/closures/data/__init__.py +7 -0
- physmap/closures/data/closure_index.json +2997 -0
- physmap/closures/formulas.py +213 -0
- physmap/closures/geometry_classes.py +109 -0
- physmap/closures/index.py +393 -0
- physmap/closures/registry.py +313 -0
- physmap/compat/__init__.py +0 -0
- physmap/core/__init__.py +0 -0
- physmap/core/mechanism.py +69 -0
- physmap/core/signals.py +50 -0
- physmap/corpus/__init__.py +12 -0
- physmap/corpus/calibration.py +543 -0
- physmap/corpus/data/__init__.py +12 -0
- physmap/corpus/data/corpus_seed.jsonl +15 -0
- physmap/corpus/data/evidence_claims_seed.jsonl +21 -0
- physmap/corpus/data/evidence_sources_seed.jsonl +8 -0
- physmap/corpus/data/premium_coverage.json +60 -0
- physmap/corpus/evidence.py +871 -0
- physmap/explain/__init__.py +0 -0
- physmap/explain/benchmark.py +101 -0
- physmap/explain/causal.py +82 -0
- physmap/guardrail/__init__.py +38 -0
- physmap/guardrail/aggregator_observability.py +187 -0
- physmap/guardrail/classify.py +147 -0
- physmap/guardrail/configs.py +120 -0
- physmap/guardrail/corpus_regimes.py +208 -0
- physmap/guardrail/detector_conformal.py +129 -0
- physmap/guardrail/detector_density.py +74 -0
- physmap/guardrail/enums.py +69 -0
- physmap/guardrail/graph.py +73 -0
- physmap/guardrail/guardrail.py +606 -0
- physmap/guardrail/io.py +201 -0
- physmap/guardrail/regime_observability.py +519 -0
- physmap/guardrail/render.py +159 -0
- physmap/guardrail/weighting_heuristic.py +216 -0
- physmap/infra/__init__.py +23 -0
- physmap/infra/blindspot_oracle.py +356 -0
- physmap/infra/corpus_runtime.py +275 -0
- physmap/integrations/__init__.py +0 -0
- physmap/materiality/__init__.py +0 -0
- physmap/materiality/estimator.py +239 -0
- physmap/materiality/independence.py +92 -0
- physmap/materiality/surrogate_fit.py +293 -0
- physmap/observability/__init__.py +0 -0
- physmap/pipeline/__init__.py +58 -0
- physmap/pipeline/aggregators.py +199 -0
- physmap/pipeline/assessment_v06.py +509 -0
- physmap/pipeline/core.py +442 -0
- physmap/pipeline/defeasible_aggregator.py +324 -0
- physmap/pipeline/detectors.py +309 -0
- physmap/pipeline/observability.py +430 -0
- physmap/pipeline/surrogate.py +251 -0
- physmap/pipeline/validity_signal.py +273 -0
- physmap/pipeline/vehicle_spec.py +287 -0
- physmap/release.py +81 -0
- physmap/stress_tests/__init__.py +9 -0
- physmap/stress_tests/lewis_reuse.py +517 -0
- physmap/substrate/__init__.py +28 -0
- physmap/substrate/corpus_real.py +206 -0
- physmap/substrate/engine.py +209 -0
- physmap/substrate/forrest.py +249 -0
- physmap/substrate/loaders.py +2176 -0
- physmap/substrate/naca_tn1451.py +379 -0
- physmap/substrate/naca_wpd_loader.py +187 -0
- physmap/substrate/stage1_ingest.py +187 -0
- physmap/substrate/vehicle_config.py +407 -0
- physmap-0.2.0.dist-info/METADATA +270 -0
- physmap-0.2.0.dist-info/RECORD +88 -0
- physmap-0.2.0.dist-info/WHEEL +5 -0
- physmap-0.2.0.dist-info/entry_points.txt +2 -0
- physmap-0.2.0.dist-info/licenses/LICENSE +21 -0
- physmap-0.2.0.dist-info/licenses/LICENSE-CORPUS +469 -0
- physmap-0.2.0.dist-info/licenses/NOTICE +77 -0
- physmap-0.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"""The seven benchmark vehicles, and which of them this checkout can rerun.
|
|
2
|
+
|
|
3
|
+
Two different things are tracked here and they must not collapse into one:
|
|
4
|
+
|
|
5
|
+
**The result** — all seven vehicles ran, and every outcome is reported. The banked
|
|
6
|
+
matrix in `data/benchmarks/v0_4/` holds counts, verdicts and thresholds computed from
|
|
7
|
+
our own runs. It contains no third-party measurement values.
|
|
8
|
+
|
|
9
|
+
**The rerun** — only vehicles whose source data is cleared for redistribution ship
|
|
10
|
+
their CSV, so only those can be recomputed from this checkout.
|
|
11
|
+
|
|
12
|
+
A reader must be able to see, per vehicle, both the outcome and whether the number in
|
|
13
|
+
front of them was recomputed here or read from the bank. The public command reruns two
|
|
14
|
+
of seven and says so; it is never described as reproducing the benchmark.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
from dataclasses import dataclass
|
|
20
|
+
from enum import Enum
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"Redistribution",
|
|
24
|
+
"DataQuality",
|
|
25
|
+
"triage_only_ids",
|
|
26
|
+
"licensed_ids",
|
|
27
|
+
"unlicensed_shipped_ids",
|
|
28
|
+
"VehicleRecord",
|
|
29
|
+
"VEHICLES",
|
|
30
|
+
"rerunnable_ids",
|
|
31
|
+
"banked_only_ids",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class Redistribution(str, Enum):
|
|
36
|
+
"""Why each vehicle's source data does or does not ship.
|
|
37
|
+
|
|
38
|
+
Three of these mean "it ships", and they are kept apart on purpose. A reader
|
|
39
|
+
deciding whether to reuse this data needs to know whether it rests on a licence,
|
|
40
|
+
on the absence of a prohibition, or on a risk the project chose to carry. Folding
|
|
41
|
+
them into one CLEAR would hide exactly the distinction that matters.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
#: Affirmative permission exists: public domain, or an explicit open licence.
|
|
45
|
+
CLEAR = "clear"
|
|
46
|
+
|
|
47
|
+
#: No permission and no prohibition. Shipped on the position that measured values
|
|
48
|
+
#: are facts. Defensible, and not backed by a grant.
|
|
49
|
+
NO_LICENCE_FACTS_BASIS = "no_licence_facts_basis"
|
|
50
|
+
|
|
51
|
+
#: Shipped DESPITE an express publisher term forbidding redistribution. A risk the
|
|
52
|
+
#: project accepted with its eyes open, not a determination that the term does not
|
|
53
|
+
#: apply. Removed on objection.
|
|
54
|
+
AGAINST_PUBLISHER_TERMS = "against_publisher_terms"
|
|
55
|
+
|
|
56
|
+
#: Does not ship, by project decision.
|
|
57
|
+
EXCLUDED_BY_DECISION = "excluded_by_decision"
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class DataQuality(str, Enum):
|
|
61
|
+
"""How good the source values are. INDEPENDENT of whether they may be redistributed.
|
|
62
|
+
|
|
63
|
+
A dataset can be perfectly legal to publish and still be unfit to benchmark on.
|
|
64
|
+
Collapsing the two would let a licence clearance launder a data-quality problem.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
#: Properly digitised or transcribed, with stated uncertainty.
|
|
68
|
+
BENCHMARK_GRADE = "benchmark_grade"
|
|
69
|
+
#: The file itself says not to trust it as truth. Published so the weakness is
|
|
70
|
+
#: inspectable rather than hidden behind an outcome nobody can check.
|
|
71
|
+
TRIAGE_ONLY = "triage_only"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
@dataclass(frozen=True)
|
|
75
|
+
class VehicleRecord:
|
|
76
|
+
vehicle_id: str
|
|
77
|
+
domain: str
|
|
78
|
+
failure_variable: str
|
|
79
|
+
source: str
|
|
80
|
+
how_values_were_produced: str
|
|
81
|
+
redistribution: Redistribution
|
|
82
|
+
redistribution_reason: str
|
|
83
|
+
quality: DataQuality = DataQuality.BENCHMARK_GRADE
|
|
84
|
+
quality_note: str = ""
|
|
85
|
+
|
|
86
|
+
SHIPS = frozenset({
|
|
87
|
+
Redistribution.CLEAR,
|
|
88
|
+
Redistribution.NO_LICENCE_FACTS_BASIS,
|
|
89
|
+
Redistribution.AGAINST_PUBLISHER_TERMS,
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def rerunnable(self) -> bool:
|
|
94
|
+
return self.redistribution in VehicleRecord.SHIPS
|
|
95
|
+
|
|
96
|
+
@property
|
|
97
|
+
def licensed(self) -> bool:
|
|
98
|
+
"""True only where affirmative permission exists. Shipping is not licensing."""
|
|
99
|
+
return self.redistribution is Redistribution.CLEAR
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
VEHICLES: tuple[VehicleRecord, ...] = (
|
|
103
|
+
VehicleRecord(
|
|
104
|
+
"naca_tn1451", "thermal-fluids", "x_over_D",
|
|
105
|
+
"NACA TN-1451 (1947), Fig 10, bellmouth entrance",
|
|
106
|
+
"Two-reader visual digitisation",
|
|
107
|
+
Redistribution.CLEAR,
|
|
108
|
+
"US Government work, public domain.",
|
|
109
|
+
),
|
|
110
|
+
VehicleRecord(
|
|
111
|
+
"velazquez_sco2", "thermal-fluids", "ratio_mu_w_b",
|
|
112
|
+
"Velazquez et al. (2026), Appl. Therm. Eng. 285:129206",
|
|
113
|
+
"Verbatim transcription of supplementary Appendix D, Tables D1-D28",
|
|
114
|
+
Redistribution.CLEAR,
|
|
115
|
+
"CC BY 4.0, publisher-deposited. Elsevier states the article licence extends to "
|
|
116
|
+
"supplementary files.",
|
|
117
|
+
),
|
|
118
|
+
VehicleRecord(
|
|
119
|
+
"forrest", "thermal-fluids", "Re",
|
|
120
|
+
"Forrest et al., J. Heat Transfer 138(2):021704",
|
|
121
|
+
"Visual estimates from Fig 5 of the version of record",
|
|
122
|
+
Redistribution.AGAINST_PUBLISHER_TERMS,
|
|
123
|
+
"ASME holds copyright and requires written permission to reproduce. The CC-BY "
|
|
124
|
+
"route does not apply: ASME grants it for accepted manuscripts in INSTITUTIONAL "
|
|
125
|
+
"repositories, the OSTI deposit is a FUNDER repository, and the deposited PDF "
|
|
126
|
+
"carries no Creative Commons marking at all. Shipped anyway, as an accepted "
|
|
127
|
+
"risk. Numbers only.",
|
|
128
|
+
DataQuality.TRIAGE_ONLY,
|
|
129
|
+
"The file's own header: 'VISUAL ESTIMATES ... NOT digitized by WebPlotDigitizer. "
|
|
130
|
+
"Use ONLY as a resolvability triage check.' Its benchmark cell is also "
|
|
131
|
+
"degenerate -- 1 training row, no detector fit -- so its DO_NO_HARM outcome is "
|
|
132
|
+
"short-circuited rather than earned. Published so both weaknesses are visible; "
|
|
133
|
+
"re-digitise Fig 5 properly before treating this cell as evidence.",
|
|
134
|
+
),
|
|
135
|
+
VehicleRecord(
|
|
136
|
+
"casper_hypersonic_transition", "aerospace", "freestream_noise_pct",
|
|
137
|
+
"Casper MS thesis (DTIC ADA504177) and AIAA 2009-4054",
|
|
138
|
+
"Figure digitisation, 600-DPI segmentation, two readers",
|
|
139
|
+
Redistribution.AGAINST_PUBLISHER_TERMS,
|
|
140
|
+
"The rows carrying the result come from the AIAA paper, and AIAA prohibits using "
|
|
141
|
+
"their content to develop machine-learning models without written permission -- "
|
|
142
|
+
"which is what a public ML benchmark is. Shipped anyway, as an accepted risk. "
|
|
143
|
+
"Weaker than Marineau, not equal to it: the OSTI copy carries no copyright "
|
|
144
|
+
"notice AND no public-release marking, just silence. Numbers only.",
|
|
145
|
+
),
|
|
146
|
+
VehicleRecord(
|
|
147
|
+
"marineau_hypersonic_transition", "aerospace", "st_xsw_ratio",
|
|
148
|
+
"Marineau et al., AIAA 2014-3108 / SAND2014-4326C",
|
|
149
|
+
"Transcribed from Table 3",
|
|
150
|
+
Redistribution.NO_LICENCE_FACTS_BASIS,
|
|
151
|
+
"No reuse licence exists, and no prohibition either. The OSTI copy carries no "
|
|
152
|
+
"copyright notice and is marked public-release-unlimited by the controlling "
|
|
153
|
+
"office -- a security determination, not a licence, and OSTI expressly disclaims "
|
|
154
|
+
"granting one. Ships on the position that measured values transcribed from a "
|
|
155
|
+
"published table are facts. Government-funded, government-hosted, transcribed "
|
|
156
|
+
"rather than digitised: the cleanest of the unlicensed three.",
|
|
157
|
+
),
|
|
158
|
+
VehicleRecord(
|
|
159
|
+
"dirker_water", "thermal-fluids", "Ri",
|
|
160
|
+
"Dirker, Meyer & Reid (2018), Exp. Therm. Fluid Sci. 98",
|
|
161
|
+
"Figure digitisation from Figs 17-20",
|
|
162
|
+
Redistribution.AGAINST_PUBLISHER_TERMS,
|
|
163
|
+
"Elsevier's TDM licence forbids substantially or systematically redistributing "
|
|
164
|
+
"the dataset, and the one permissions exemption is drafted to exclude data that "
|
|
165
|
+
"was previously in figure format -- which this was. Shipped anyway, as an "
|
|
166
|
+
"accepted risk. Values are numbers only; no figure, text or PDF is "
|
|
167
|
+
"redistributed. Weakest of the three: read off plots rather than transcribed.",
|
|
168
|
+
),
|
|
169
|
+
VehicleRecord(
|
|
170
|
+
"jin_sco2_buoyancy", "thermal-fluids", "Bu",
|
|
171
|
+
"Jin et al. (2023), Ann. Nucl. Energy 188:109825",
|
|
172
|
+
"Figure digitisation, two readers; Bu and Bo* recomputed",
|
|
173
|
+
Redistribution.AGAINST_PUBLISHER_TERMS,
|
|
174
|
+
"Same Elsevier terms as Dirker, with no open copy anywhere, and the authors were "
|
|
175
|
+
"asked for raw data and declined. Shipped anyway, as an accepted risk. Bu and "
|
|
176
|
+
"Bo* are recomputed from the paper's own equations, so part of this file is "
|
|
177
|
+
"derived work rather than extraction.",
|
|
178
|
+
),
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
_BY_ID = {v.vehicle_id: v for v in VEHICLES}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def get(vehicle_id: str) -> VehicleRecord:
|
|
185
|
+
try:
|
|
186
|
+
return _BY_ID[vehicle_id]
|
|
187
|
+
except KeyError:
|
|
188
|
+
raise KeyError(
|
|
189
|
+
f"unknown vehicle {vehicle_id!r}; known: {sorted(_BY_ID)}"
|
|
190
|
+
) from None
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def rerunnable_ids() -> tuple[str, ...]:
|
|
194
|
+
"""The vehicles this checkout can recompute. Everything else is banked-only."""
|
|
195
|
+
return tuple(v.vehicle_id for v in VEHICLES if v.rerunnable)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def banked_only_ids() -> tuple[str, ...]:
|
|
199
|
+
return tuple(v.vehicle_id for v in VEHICLES if not v.rerunnable)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def licensed_ids() -> tuple[str, ...]:
|
|
203
|
+
"""Vehicles whose data ships under affirmative permission."""
|
|
204
|
+
return tuple(v.vehicle_id for v in VEHICLES if v.licensed)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def unlicensed_shipped_ids() -> tuple[str, ...]:
|
|
208
|
+
"""Vehicles that ship WITHOUT a licence. Removed on objection; see NOTICE."""
|
|
209
|
+
return tuple(
|
|
210
|
+
v.vehicle_id for v in VEHICLES
|
|
211
|
+
if v.rerunnable and not v.licensed
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
def triage_only_ids() -> tuple[str, ...]:
|
|
216
|
+
"""Vehicles whose source values are not benchmark-grade by their own account."""
|
|
217
|
+
return tuple(v.vehicle_id for v in VEHICLES if v.quality is DataQuality.TRIAGE_ONLY)
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"""Render the seven-vehicle benchmark, marking what was recomputed and what was not.
|
|
2
|
+
|
|
3
|
+
The report always shows all seven outcomes. Next to each it states whether that number
|
|
4
|
+
was recomputed in this checkout or read from the banked matrix, because a reader who
|
|
5
|
+
cannot tell the difference has been misled by omission.
|
|
6
|
+
|
|
7
|
+
It also states what the public subset costs in coverage. Losing five of seven vehicles is
|
|
8
|
+
not a uniform thinning -- it removes whole domains and whole outcome classes -- and a
|
|
9
|
+
report that printed two green rows without saying so would be flattering rather than
|
|
10
|
+
accurate.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import json
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
from typing import Any
|
|
18
|
+
|
|
19
|
+
from physmap._paths import checkout_path
|
|
20
|
+
from physmap.benchmarks.registry import (
|
|
21
|
+
VEHICLES,
|
|
22
|
+
DataQuality,
|
|
23
|
+
Redistribution,
|
|
24
|
+
banked_only_ids,
|
|
25
|
+
licensed_ids,
|
|
26
|
+
rerunnable_ids,
|
|
27
|
+
triage_only_ids,
|
|
28
|
+
unlicensed_shipped_ids,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
__all__ = ["load_banked_matrix", "render_report", "coverage_note"]
|
|
32
|
+
|
|
33
|
+
_MATRIX_PARTS = ("data", "benchmarks", "v0_4", "matrix_full_seven.json")
|
|
34
|
+
|
|
35
|
+
_STATUS_LABEL = {
|
|
36
|
+
Redistribution.CLEAR: "ships, licensed",
|
|
37
|
+
Redistribution.NO_LICENCE_FACTS_BASIS: "ships, NOT licensed (facts basis)",
|
|
38
|
+
Redistribution.AGAINST_PUBLISHER_TERMS: "ships, AGAINST publisher terms",
|
|
39
|
+
Redistribution.EXCLUDED_BY_DECISION: "banked only - source data excluded",
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def load_banked_matrix() -> dict[str, Any]:
|
|
44
|
+
"""The committed seven-vehicle result. Counts, verdicts and our own thresholds only;
|
|
45
|
+
it carries no third-party measurement values, which is why it can be published when
|
|
46
|
+
five of the seven source datasets cannot."""
|
|
47
|
+
p = checkout_path(*_MATRIX_PARTS, what="the banked v0.4 benchmark matrix")
|
|
48
|
+
return json.loads(p.read_text("utf-8"))
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def coverage_note() -> str:
|
|
52
|
+
"""What the public subset does and does not cover. Computed, so it cannot drift."""
|
|
53
|
+
matrix = load_banked_matrix()
|
|
54
|
+
cells = {c["vehicle_id"]: c for c in matrix["cells"]}
|
|
55
|
+
rerun = set(rerunnable_ids())
|
|
56
|
+
|
|
57
|
+
def _summarise(ids):
|
|
58
|
+
doms = sorted({cells[i]["domain"] for i in ids if i in cells})
|
|
59
|
+
outs = sorted({cells[i]["empirical_outcome"] for i in ids if i in cells})
|
|
60
|
+
obs = sorted({cells[i]["failure_observability"] for i in ids if i in cells})
|
|
61
|
+
return doms, outs, obs
|
|
62
|
+
|
|
63
|
+
all_d, all_o, all_ob = _summarise(cells)
|
|
64
|
+
pub_d, pub_o, pub_ob = _summarise(rerun)
|
|
65
|
+
|
|
66
|
+
lines = [
|
|
67
|
+
"What the rerunnable subset covers",
|
|
68
|
+
"",
|
|
69
|
+
f" domains full: {', '.join(all_d)}",
|
|
70
|
+
f" public: {', '.join(pub_d)}",
|
|
71
|
+
f" outcomes full: {', '.join(all_o)}",
|
|
72
|
+
f" public: {', '.join(pub_o)}",
|
|
73
|
+
f" observability full: {', '.join(all_ob)}",
|
|
74
|
+
f" public: {', '.join(pub_ob)}",
|
|
75
|
+
]
|
|
76
|
+
triage = set(triage_only_ids())
|
|
77
|
+
degenerate = sorted({
|
|
78
|
+
cells[i]["empirical_outcome"] for i in triage if i in cells
|
|
79
|
+
})
|
|
80
|
+
if degenerate:
|
|
81
|
+
lines.append("")
|
|
82
|
+
lines.append(
|
|
83
|
+
f" Outcome classes whose ONLY vehicle is not benchmark-grade: "
|
|
84
|
+
f"{', '.join(degenerate)}."
|
|
85
|
+
)
|
|
86
|
+
for i in sorted(triage):
|
|
87
|
+
c = cells.get(i)
|
|
88
|
+
if c:
|
|
89
|
+
lines.append(
|
|
90
|
+
f" {c['empirical_outcome']} rests on {i}: "
|
|
91
|
+
f"n_train={c.get('n_train')}, n_test={c.get('n_test')} -- "
|
|
92
|
+
f"{c.get('rationale', c.get('caveat', ''))}"
|
|
93
|
+
)
|
|
94
|
+
lost_d = [d for d in all_d if d not in pub_d]
|
|
95
|
+
lost_o = [o for o in all_o if o not in pub_o]
|
|
96
|
+
if lost_d or lost_o:
|
|
97
|
+
lines.append("")
|
|
98
|
+
lines.append(" The subset is NOT a representative sample of the full matrix.")
|
|
99
|
+
if lost_d:
|
|
100
|
+
lines.append(f" Domains absent from the rerun: {', '.join(lost_d)}")
|
|
101
|
+
if lost_o:
|
|
102
|
+
lines.append(f" Outcome classes absent from the rerun: {', '.join(lost_o)}")
|
|
103
|
+
return "\n".join(lines)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def render_report(rerun_results: dict[str, Any] | None = None) -> str:
|
|
107
|
+
"""The full seven-vehicle table.
|
|
108
|
+
|
|
109
|
+
`rerun_results` maps vehicle_id to a freshly computed cell. Vehicles absent from it
|
|
110
|
+
are reported from the bank and labelled as such.
|
|
111
|
+
"""
|
|
112
|
+
matrix = load_banked_matrix()
|
|
113
|
+
cells = {c["vehicle_id"]: c for c in matrix["cells"]}
|
|
114
|
+
rerun_results = rerun_results or {}
|
|
115
|
+
|
|
116
|
+
n = len(VEHICLES)
|
|
117
|
+
ships, banked = len(rerunnable_ids()), len(banked_only_ids())
|
|
118
|
+
recomputed = len([v for v in rerun_results if v in {x.vehicle_id for x in VEHICLES}])
|
|
119
|
+
|
|
120
|
+
out: list[str] = [matrix["benchmark"], ""]
|
|
121
|
+
|
|
122
|
+
# Computed, never hardcoded. Two different facts live here and a reader needs both:
|
|
123
|
+
# how many datasets SHIP, and how many were actually RECOMPUTED in this invocation.
|
|
124
|
+
# An earlier version asserted "does not reproduce all seven" as a constant; once the
|
|
125
|
+
# last two datasets shipped that sentence became false, which is exactly how a
|
|
126
|
+
# hardcoded honesty claim decays into a lie.
|
|
127
|
+
out.append(
|
|
128
|
+
f"All {n} vehicles are reported. {ships} of {n} ship their source data"
|
|
129
|
+
+ (f"; {banked} are banked only." if banked else " -- all of them.")
|
|
130
|
+
)
|
|
131
|
+
if recomputed == 0:
|
|
132
|
+
out.append("")
|
|
133
|
+
out.append(
|
|
134
|
+
f"NOTHING WAS RECOMPUTED IN THIS RUN. Every number below is read from the "
|
|
135
|
+
f"banked matrix. `physmap benchmark run` recomputes them from this checkout "
|
|
136
|
+
f"and diffs the result against that bank."
|
|
137
|
+
)
|
|
138
|
+
elif recomputed < n:
|
|
139
|
+
out.append("")
|
|
140
|
+
out.append(
|
|
141
|
+
f"THIS RUN RECOMPUTED {recomputed} OF {n} VEHICLES. The rest are read from "
|
|
142
|
+
f"the banked matrix."
|
|
143
|
+
)
|
|
144
|
+
else:
|
|
145
|
+
out.append("")
|
|
146
|
+
out.append(f"All {n} vehicles were recomputed in this run.")
|
|
147
|
+
out.append("")
|
|
148
|
+
|
|
149
|
+
header = f"{'vehicle':34} {'domain':14} {'failure var':22} {'observability':14} {'outcome':17} source"
|
|
150
|
+
out.append(header)
|
|
151
|
+
out.append("-" * len(header))
|
|
152
|
+
|
|
153
|
+
for v in VEHICLES:
|
|
154
|
+
cell = rerun_results.get(v.vehicle_id) or cells.get(v.vehicle_id)
|
|
155
|
+
if cell is None:
|
|
156
|
+
out.append(f"{v.vehicle_id:34} (no banked result)")
|
|
157
|
+
continue
|
|
158
|
+
live = v.vehicle_id in rerun_results
|
|
159
|
+
source = "RECOMPUTED" if live else _STATUS_LABEL[v.redistribution]
|
|
160
|
+
out.append(
|
|
161
|
+
f"{v.vehicle_id:34} {cell['domain']:14} {cell['failure_var']:22} "
|
|
162
|
+
f"{cell['failure_observability']:14} {cell['empirical_outcome']:17} {source}"
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
out.append("")
|
|
166
|
+
out.append(f"observability guards: {'all passed' if matrix['all_guards_passed'] else 'FAILED'}")
|
|
167
|
+
out.append("")
|
|
168
|
+
unlicensed = unlicensed_shipped_ids()
|
|
169
|
+
if unlicensed:
|
|
170
|
+
out.append("Redistribution basis -- read this before reusing any of this data")
|
|
171
|
+
out.append("")
|
|
172
|
+
out.append(
|
|
173
|
+
f" {len(licensed_ids())} of the {len(rerunnable_ids())} shipped datasets "
|
|
174
|
+
f"carry affirmative permission: public domain or an open licence."
|
|
175
|
+
)
|
|
176
|
+
out.append(
|
|
177
|
+
f" {len(unlicensed)} ship WITHOUT a licence: {', '.join(unlicensed)}."
|
|
178
|
+
)
|
|
179
|
+
against = [
|
|
180
|
+
v.vehicle_id for v in VEHICLES
|
|
181
|
+
if v.redistribution is Redistribution.AGAINST_PUBLISHER_TERMS
|
|
182
|
+
]
|
|
183
|
+
out.append(
|
|
184
|
+
" Shipping is not licensing. They rest on the position that measured values"
|
|
185
|
+
)
|
|
186
|
+
out.append(" are facts.")
|
|
187
|
+
if against:
|
|
188
|
+
out.append(
|
|
189
|
+
f" {len(against)} of them are published AGAINST an express publisher"
|
|
190
|
+
)
|
|
191
|
+
out.append(f" term rather than under one: {', '.join(against)}.")
|
|
192
|
+
out.append(
|
|
193
|
+
" Only the numbers are redistributed; no paper, figure or PDF. They are"
|
|
194
|
+
)
|
|
195
|
+
out.append(" removed on objection -- see NOTICE.")
|
|
196
|
+
out.append("")
|
|
197
|
+
triage = triage_only_ids()
|
|
198
|
+
if triage:
|
|
199
|
+
out.append("Data quality -- separate from redistribution, and not implied by it")
|
|
200
|
+
out.append("")
|
|
201
|
+
out.append(f" Not benchmark-grade by their own account: {', '.join(triage)}.")
|
|
202
|
+
out.append(" A dataset can be perfectly legal to publish and still be unfit to")
|
|
203
|
+
out.append(" benchmark on. Their cells are reported so the weakness is")
|
|
204
|
+
out.append(" inspectable, not so it can be cited.")
|
|
205
|
+
out.append("")
|
|
206
|
+
out.append("Provenance and redistribution basis")
|
|
207
|
+
out.append("")
|
|
208
|
+
for v in VEHICLES:
|
|
209
|
+
out.append(f" {v.vehicle_id}")
|
|
210
|
+
out.append(f" source {v.source}")
|
|
211
|
+
out.append(f" values {v.how_values_were_produced}")
|
|
212
|
+
out.append(
|
|
213
|
+
f" ships {'yes' if v.rerunnable else 'no'} ({v.redistribution.value})"
|
|
214
|
+
)
|
|
215
|
+
out.append(f" licensed {'yes' if v.licensed else 'NO'}")
|
|
216
|
+
if v.quality is not DataQuality.BENCHMARK_GRADE:
|
|
217
|
+
out.append(f" QUALITY {v.quality.value.upper()} -- {v.quality_note}")
|
|
218
|
+
out.append(f" basis {v.redistribution_reason}")
|
|
219
|
+
out.append("")
|
|
220
|
+
|
|
221
|
+
out.append(coverage_note())
|
|
222
|
+
out.append("")
|
|
223
|
+
out.append("Full determinations: data/REDISTRIBUTION.md")
|
|
224
|
+
return "\n".join(out)
|