Inspect, export and restore a codebook
Retain these items together:
Symbol sequence, including the exact Unicode characters.
Starting value in the same units used during fitting.
parameters.centersandparameters.alphabets.Original sample count, fitting configuration and package version for provenance.
Any external normalization statistics, timestamps or channel metadata.
Model.to_dict() returns an independent JSON-compatible object with
schema_version=1. Model.from_dict() validates finite centers, positive
lengths and a unique single-character alphabet. It rejects unsupported schema
versions. This schema covers the univariate fABBA codebook; JABBA and QABBA
have different model objects and are not interchangeable with it.
Complete portable roundtrip
"""Export symbols + starting value + codebook to JSON, then decode without fitting."""
import json
import tempfile
from pathlib import Path
import numpy as np
from fABBA import fABBA, Model, __version__
def main():
x = 5 + np.sin(np.linspace(0, 4 * np.pi, 200))
model = fABBA(tol=0.01, alpha=0.1, verbose=0)
symbols = model.fit_transform(x)
payload = {
"fabba_version": __version__,
"config": {"tol": model.tol, "alpha": model.alpha, "scl": model.scl,
"sorting": model.sorting, "max_len": model.max_len},
"start": float(x[0]), "n_samples": len(x), "symbols": symbols,
"codebook": model.parameters.to_dict(),
}
# Replace this temporary path with Path("signal.json") to retain the export.
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "signal.json"
path.write_text(json.dumps(payload, indent=2, ensure_ascii=False, allow_nan=False), encoding="utf-8")
restored = json.loads(path.read_text(encoding="utf-8"))
parameters = Model.from_dict(restored["codebook"])
decoder = fABBA(verbose=0)
y = np.asarray(decoder.inverse_transform(restored["symbols"],
start=restored["start"], parameters=parameters))
np.testing.assert_allclose(y, model.inverse_transform(symbols, x[0]))
assert len(y) == restored["n_samples"]
print("JSON roundtrip verified; alphabet size:", len(parameters.alphabets))
print("Reconstruction RMSE:", np.sqrt(np.mean((x - y) ** 2)))
model.print_parameters()
if __name__ == "__main__":
main()
The example uses a temporary directory. To keep the export, use a persistent
Path("signal.json"). Decoding with an explicit restored codebook does not
require fit and does not restore the original training signal. The JSON
stores a lossy representation, not residuals.
A codebook is not a trained nearest-center encoder
The univariate fABBA class has fit and fit_transform. Refitting learns
a new codebook. For encoding held-out series against fixed training centers,
use JABBA.transform as shown in Multiple series with a shared JABBA codebook.
Legacy pickle support
model.dump(path) saves only the codebook. model.load(path) returns it;
model.load(path, replace=True) installs it in that estimator. These methods
do not retain symbols, starting values or preprocessing metadata. Pickle can
execute code during loading: only load trusted files. JSON is preferable for
inspection and exchange; neither format should be assumed compatible with
future schema changes without checking its version.