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.centers and parameters.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.