climate_ref_core.regression._quantise
#
Float quantisation for committed regression bundles.
The regression files include floats whose least-significant digits are platform-dependent (CPU, BLAS, library versions). The last digits churn byte-for-byte between CI and local runs even when the result is numerically identical, producing noisy, unreviewable diffs in the committed bundle.
Rounding every float to a fixed number of significant figures at write time gives
stable, reviewable committed bytes.
We round to seven significant figures: two digits finer than the regression compare tolerance
(rtol=1e-5 in :mod:climate_ref_core.regression.compare),
so the rounding error stays well under tolerance and can never flip a boundary gate verdict.
This affects only the committed bundle.
The native blobs (.nc / .png) and their content-addressed digests are never touched.
DEFAULT_SIG_FIGS = 7
module-attribute
#
Default significant figures for committed-bundle floats.
Deliberately two digits finer than the rtol=1e-5 regression compare tolerance,
so rounding never flips a boundary gate verdict.
round_floats(obj, sig_figs=DEFAULT_SIG_FIGS)
#
Recursively round every float in a JSON-like structure to sig_figs figures.
Walks dicts, lists and tuples, rounding each float via the g format
(float(f"{x:.{sig_figs}g}")) and leaving int, bool, str and None untouched.
bool is a subclass of int (and not of float), so booleans are never rounded.
The operation is idempotent: rounding an already-rounded value is a no-op.
Tuples are returned as lists, matching JSON serialisation semantics (JSON has no tuple type; the standard library serialises tuples as arrays).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Any
|
A JSON-like object: a scalar, or an arbitrarily nested dict / list / tuple. |
required |
sig_figs
|
int
|
The number of significant figures to round each float to. |
DEFAULT_SIG_FIGS
|
Returns:
| Type | Description |
|---|---|
Any
|
A copy of |