Skip to content

Config-driven builds

One YAML file per model: which test case and window, which family, how many charts and modes, and what to measure once it is fitted.

python -m qlroms.utils.builder configs/ks1d_chaotic.yml   # [--set rom.K=20] [--set case.params='{"Ntrain": 5000}']
case: {model: ks1d chaos}          # a qlroms.utils.config.CASES name, or ks1d/chaotic
rom:  {kind: qlgalerkin, seed: 0, clustering: {kmeans_method: minibatch}}
check: {n_steps: 1000, compare_global: true}

A case is defined in exactly one place — its own module's TEST_CASES entry, which holds the physics, the windows it is generated with, the \((K, r)\) its ql-ROMs are built at and the timescales its characterization needs. qlroms.utils.config only maps a readable name onto one of those entries (get_case("ks1d chaos") reads it back live), and a config restates none of it: leave rom.K / rom.r or case.params out and the case's own values stand, set them and this run overrides them. Unknown keys fail loudly, dotted --set beats the file, and both the trajectory and the fitted ROM come from the case's cached pipeline. The run prints a JSON summary: representation error, closed-loop mean error and prediction horizon, against the global (\(K=1\)) ROM of the same family when compare_global is on.

From Python the same pipeline is qlroms.utils.builder.load_configbuild_caserun_build; see the qlroms.utils reference.