Skip to content

A config tabascal writes out cannot be run again: the gain widths are converted in place #233

Description

@chrisfinlay

Every run dumps its resolved config to plot_dir/tab_config_<run_id>.yaml (_run_tabascal_impl.py:499). That file is the natural way to reproduce a run — and feeding it back in silently narrows the gain priors by two orders of magnitude.

validate_gain_scales converts both widths out of their public units and writes the result back into the same dict the runner later dumps (gains.py:132-148):

gains_config["amp_std"] = _positive_scale(
    "amp_std", gp_amp_std,
    lambda std: float(std) / 100 * gains_config["amp_mean"],   # percent -> fraction
    ...
)

amp_std is documented and given as a percentage of amp_mean; phase_std in degrees. After validation the dict holds a fraction and radians. Nothing marks it as converted, so the second pass converts it again.

Measured on the shipped code with amp_std: 10, phase_std: 30:

pass 1 (the config as the runner then dumps it): amp_std = 0.1    phase_std = 0.523599
pass 2 (that dump, loaded and run again):        amp_std = 0.001  phase_std = 0.00913852
  -> amplitude prior narrowed 100x; phase 57x

A 10 % amplitude prior becomes 0.1 %, and a 30° phase prior becomes about half a degree. Both are still perfectly valid numbers, so nothing complains; the run just fits with a prior far tighter than the one written down, and a gain error the fit should have absorbed shows up in the residuals instead.

It bites anyone who does the obvious thing with the file the tool itself wrote — rerunning it, diffing two runs' configs, or lifting a block out of one into a new config.

Suggested shape

Keep config values in their public units and do the conversion where it is consumed: return the converted scale to the component rather than writing it back, or store it under a separate key the validator does not read. Whichever way, a config that has been through validation should still mean the same thing as the one the user wrote — the dumped file is a user-facing artefact.

Worth checking the other sections for the same pattern while fixing it; this one was found by looking, not by a sweep.

How this was found

A retrospective Codex pass over the config surface after the five config-changing PRs (#212, #216, #218, #225, #228), verified by hand against the shipped code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions