Summary
Add a csauto doe command that generates the design-of-experiments CSV from
parameter ranges/levels, instead of requiring the user to hand-write it. Support the
standard sampling strategies: full factorial, Latin Hypercube (LHS),
Sobol sequences, and central composite design (CCD).
Motivation
The tool is named after design of experiments, yet today the DOE table (doe.csv) is a
manual input: the user writes every row by hand (or in Excel) before csauto prepare
consumes it (csauto/doe.py, load_doe). This is exactly the step a DOE tool should own.
Hand-writing the table:
- doesn't scale (a 3-parameter × 5-level full factorial = 125 rows to type),
- is error-prone (typos, missing combinations, non-reproducible),
- forces users into Excel, which introduces the BOM/whitespace/locale issues we already
see in header parsing.
Generating the plan makes campaigns reproducible (same spec → same table) and unlocks
proper space-filling designs (LHS/Sobol) that a human can't produce by hand.
Proposed solution
A new subcommand that reads a parameter specification and writes a doe.csv compatible
with the existing prepare pipeline (same header = parameter names, one row per case,
plus the reserved case_id handling already in doe.py).
CLI sketch
# From an inline/TOML/YAML spec describing each parameter
csauto doe spec.toml doe.csv --method lhs --samples 40 --seed 42
# Full factorial from discrete levels
csauto doe spec.toml doe.csv --method factorial
Parameter spec
Two kinds of parameters:
- Continuous — sampled within
[min, max] (LHS / Sobol / CCD):
[parameters.u_inlet]
min = 0.5
max = 5.0
[parameters.density_value]
min = 1.0
max = 1.3
- Discrete / categorical — enumerated levels (factorial, or held fixed / crossed):
[parameters.turbulence_model]
levels = ["k-epsilon", "k-omega-sst"]
Sampling methods
| Method |
Use case |
Notes |
factorial |
All combinations of discrete levels |
Pure stdlib (itertools.product) |
lhs |
Space-filling, --samples N points |
Needs a QMC backend (see below) |
sobol |
Low-discrepancy quasi-random |
--samples should be a power of 2 |
ccd |
Response-surface / RSM designs |
Center + axial + factorial points |
Output
- Writes a standard
doe.csv (UTF-8, no BOM, trimmed headers) directly usable by
csauto prepare doe.csv TEMPLATE RUNS.
- Continuous values rounded to a configurable precision (
--round, default 6).
- Optionally emits a sibling
doe.spec.toml copy / a header comment recording the
method + seed for provenance and reproducibility.
Technical considerations
- Zero-dependency philosophy. The project advertises "no external dependencies for
core features (pure standard library)". factorial and ccd are trivially pure-Python.
LHS and Sobol are best served by scipy.stats.qmc (LatinHypercube, Sobol).
→ Propose an optional extra: pip install "csauto[doe]" pulling numpy/scipy,
and a clear error message ("csauto doe --method lhs requires the doe extra") when
it's missing — mirroring how the web extra already gates FastAPI in pyproject.toml.
A minimal pure-Python LHS fallback is feasible if we want lhs in the core.
- Determinism.
--seed must make LHS/Sobol reproducible (assert same spec + seed →
identical CSV). Note: the codebase forbids random/Math.random-style nondeterminism
in some contexts — the seed should be explicit and threaded through.
- Reuse existing validation. The generated CSV should pass
load_doe without warnings:
no duplicate columns, valid case_ids, no empty rows. Good opportunity to also fix the
header-hardening issues (utf-8-sig, strip()) so generation + parsing stay consistent.
- Categorical × continuous mixing. Define the semantics: discrete params are crossed
(factorial) while continuous params are sampled per combination, or all params share one
sampling scheme. Suggest: continuous → chosen method, discrete levels → outer product,
documented explicitly.
Open questions
- Spec format: TOML (consistent with
csauto.toml), YAML, or CLI-only for simple cases?
Summary
Add a
csauto doecommand that generates the design-of-experiments CSV fromparameter ranges/levels, instead of requiring the user to hand-write it. Support the
standard sampling strategies: full factorial, Latin Hypercube (LHS),
Sobol sequences, and central composite design (CCD).
Motivation
The tool is named after design of experiments, yet today the DOE table (
doe.csv) is amanual input: the user writes every row by hand (or in Excel) before
csauto prepareconsumes it (
csauto/doe.py,load_doe). This is exactly the step a DOE tool should own.Hand-writing the table:
see in header parsing.
Generating the plan makes campaigns reproducible (same spec → same table) and unlocks
proper space-filling designs (LHS/Sobol) that a human can't produce by hand.
Proposed solution
A new subcommand that reads a parameter specification and writes a
doe.csvcompatiblewith the existing
preparepipeline (same header = parameter names, one row per case,plus the reserved
case_idhandling already indoe.py).CLI sketch
Parameter spec
Two kinds of parameters:
[min, max](LHS / Sobol / CCD):Sampling methods
factorialitertools.product)lhs--samplesN pointssobol--samplesshould be a power of 2ccdOutput
doe.csv(UTF-8, no BOM, trimmed headers) directly usable bycsauto prepare doe.csv TEMPLATE RUNS.--round, default 6).doe.spec.tomlcopy / a header comment recording themethod + seed for provenance and reproducibility.
Technical considerations
core features (pure standard library)".
factorialandccdare trivially pure-Python.LHS and Sobol are best served by
scipy.stats.qmc(LatinHypercube,Sobol).→ Propose an optional extra:
pip install "csauto[doe]"pullingnumpy/scipy,and a clear error message ("
csauto doe --method lhsrequires thedoeextra") whenit's missing — mirroring how the
webextra already gates FastAPI inpyproject.toml.A minimal pure-Python LHS fallback is feasible if we want
lhsin the core.--seedmust make LHS/Sobol reproducible (assert same spec + seed →identical CSV). Note: the codebase forbids
random/Math.random-style nondeterminismin some contexts — the seed should be explicit and threaded through.
load_doewithout warnings:no duplicate columns, valid
case_ids, no empty rows. Good opportunity to also fix theheader-hardening issues (
utf-8-sig,strip()) so generation + parsing stay consistent.(factorial) while continuous params are sampled per combination, or all params share one
sampling scheme. Suggest: continuous → chosen method, discrete levels → outer product,
documented explicitly.
Open questions
csauto.toml), YAML, or CLI-only for simple cases?