Saving and Loading Fits
BING provides two helper functions in bing.io for persisting the
outputs of an MCMC fit and reading them back without having to re-run the
inference. The design follows the project conventions:
large numerical arrays are written with
numpy.savez()to<outroot>.npz;small inputs and simple stats are written as JSON to
<outroot>.json.
The two files share a basename so a fit is identified by a single
outroot path (without extension).
File layout
<outroot>.npz
<outroot>.json
Key |
Contents |
|---|---|
|
Value of |
|
|
|
Concatenated parameter names (absorption first). |
|
Full parameter named-tuple, converted to a JSON-safe
dict. All radiative-transfer flags live here, so
|
|
Flat list of prior dicts (absorption then backscattering). |
|
Output of |
|
|
|
|
Saving a fit
After running a single-spectrum MCMC fit (for example with
bing.fitting.l23.fit_one()), call bing.io.save_fit():
from bing import io as bing_io
from bing.fitting import l23 as fit_l23
from bing.parameters import standard
p = standard.expb_pow(satellite='PACE', nsteps=40000, nburn=1000)
chains, models, prep_dict, idx, extras = fit_l23.fit_one(p, idx=170)
npz_path, json_path = bing_io.save_fit(
'fits/L23_170', p, models, chains,
p0=prep_dict['p0'],
Rrs=prep_dict['model_Rrs'],
varRrs=prep_dict['model_varRrs'],
)
The rt_dict used during reconstruction is derived from the parameter
named-tuple via bing.rt.defs.rt_dict_from_p(), so callers do not
have to provide it.
If you have a pre-LM initial guess that you would like to keep around
for reproducibility, pass it via the optional p0_init argument:
bing_io.save_fit(outroot, p, models, chains,
p0=p0_post_lm, p0_init=p0_pre_lm,
Rrs=Rrs, varRrs=varRrs)
Loading a fit
bing.io.load_fit() returns a single dictionary with every saved
field plus three convenience entries built on the fly:
models— re-instantiated absorption / backscattering models with their priors re-attached, ready foreval_a()/eval_bb().rt_dict— regenerated from the saved parameters.p— the parameter named-tuple, rebuilt viabing.parameters.p_ntuple.gen().
loaded = bing_io.load_fit('fits/L23_170')
chains = loaded['chains']
models = loaded['models']
rt_dict = loaded['rt_dict']
# Re-evaluate IOPs on the original wavelength grid
a = models[0].eval_a(chains[..., :models[0].nparam])
Percentile choices
By default bing.io.save_fit() calls
bing.evaluate.calc_stats() with perc=(14, 86) and
bing.evaluate.reconstruct_from_chains() with perc=(5, 95).
Both choices are recorded in the JSON file under stats_perc and
recon_perc so the meaning of the saved percentile arrays is never
ambiguous.
Pass stats_perc / recon_perc to override the defaults.