make_design - the ONE canonical Saltelli design for the Tier-2/3 campaign.
Run this ONCE, on ONE machine, and commit the output. Every machine in the
campaign reads the same file; no machine ever generates its own.
Two reasons this is not merely tidy:
1. Saltelli indices are computed from PAIRED rows. S_j pairs f(A_i) against
f(AB_i^(j)). If two machines independently sample, the pairing is
destroyed and the indices are silently WRONG -- not noisy, wrong.
2. Tier 3 is a maximin NESTED SUBSET of the Tier-2 design (plan S4/Tier 3).
A Sobol sequence is nested by construction: the first M base points of a
2^k sequence are themselves a balanced design. Latin hypercube is NOT --
it cannot be extended without rebuilding. The shared theta points between
LF and HF ARE the multi-fidelity discrepancy model, so they must coincide
exactly, which is why theta is referenced by a stable row_id.
Design size: N base samples, p sampled parameters -> N*(p+2) rows per condition
(matrices A, B, and AB_j for j = 1..p).
Usage
-----
python design.py --tier 2 --N 16 --out design/T2_design_v1.csv
python design.py --tier 3 --N 4 --nest-from design/T2_design_v1.csv \
--out design/T3_design_v1.csv
Outputs a CSV with one row per model evaluation:
row_id, matrix, base_idx, param_j, condition, <key_1> ... <key_p>
plus a sidecar .meta.json recording the seed, parameter version, git SHA and a
SHA-256 of the design itself. run_ensemble.py refuses to run against a design
whose hash does not match its sidecar.
| list[dict] design.apply_exclusions |
( |
list[dict] |
params, |
|
|
list[str] |
exclude |
|
) |
| |
Drop parameters this campaign holds FIXED rather than samples.
Kept out of active_params/parameters.json deliberately: an excluded
parameter is excluded *by this design*, not deleted from the model, and it
keeps its prior and its documentation. The exclusion is recorded in the
design's .meta.json, so a Sobol table can never be read as though the
parameter had been varied and found unimportant.
Rev 6 excludes i_mobile and v_mobile: bin_moment fixes them at 50 and 5
(they set the discrete/binned boundary, so sampling them would change the
DISCRETISATION between rows, not just the physics), and run_ensemble refuses
to run bin_moment against a design that still carries them.
Definition at line 78 of file design.py.