qlat_utils.json — JSON Serialization for NumPy and Numeric Types¶
Source: qlat-utils/qlat_utils/json.py
Note: Update this document when updating the source file.
Outline¶
Overview¶
The qlat_utils.json module provides json_dumps and json_loads functions
that extend Python’s standard json module to handle NumPy and extended numeric
types commonly used in lattice QCD computations.
Standard json.dumps raises TypeError on numpy.float32, numpy.ndarray,
complex, and similar types. This module encodes them transparently and
decodes them back to their original types, ensuring faithful round-tripping.
import qlat_utils as q
import numpy as np
s = q.json_dumps({"value": np.float32(0.5)})
obj = q.json_loads(s) # recovers np.float32(0.5)
Supported Types¶
Python / NumPy Type |
Round-Trips As |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
All standard JSON types (int, float, str, list, dict, None, bool)
are handled by the standard encoder and pass through unchanged.
numpy.float64 is intentionally not included. On 64-bit platforms,
np.float64 uses the same underlying C type as Python’s built-in float,
and is typically a subclass of float. The standard JSON encoder therefore
handles it natively (outputting a plain JSON number), and the decoder
reconstructs it as a Python float. No precision is lost — both represent
IEEE 754 double-precision values with identical bit patterns.
API¶
json_dumps(obj, *, indent=2) -> str¶
Serialize obj to a JSON string. Extended types are encoded with an
__extended_json_type__ marker (see Encoding Format).
Parameter |
Type |
Default |
Description |
|---|---|---|---|
|
any |
— |
Object to serialize |
|
|
|
JSON indentation; |
s = q.json_dumps({"mass": np.float32(0.5), "corr": np.array([1, 2, 3])})
compact = q.json_dumps({"mass": np.float32(0.5)}, indent=None)
json_loads(s) -> any¶
Deserialize a JSON string back into Python/NumPy objects. Extended types
(encoded with __extended_json_type__) are restored to their original types.
Parameter |
Type |
Description |
|---|---|---|
|
|
JSON string to deserialize |
obj = q.json_loads(s)
Encoding Format¶
Each extended type is stored as a JSON object with an __extended_json_type__
key identifying the original type. The decoder uses this key to restore the
correct Python/NumPy type automatically.
Type |
Encoded Representation |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Plain Python types (int, float, str, list, dict, None, bool) are
encoded by the standard JSON encoder and contain no __extended_json_type__
marker.
Examples¶
Basic Round-Trip¶
import qlat_utils as q
import numpy as np
data = {
"mass": np.float32(0.5),
"energy": complex(1.2, -0.3),
"propagator": np.array([[1+0j, 2+0j], [3+0j, 4+0j]]),
"sweeps": np.int64(1000),
"step_range": range(0, 100, 5),
}
s = q.json_dumps(data)
print(s)
restored = q.json_loads(s)
print(type(restored["mass"])) # <class 'numpy.float32'>
print(type(restored["energy"])) # <class 'complex'>
print(type(restored["propagator"])) # <class 'numpy.ndarray'>
print(type(restored["step_range"])) # <class 'range'>
Saving and Loading Parameters¶
import qlat_utils as q
import numpy as np
params = {
"lattice_size": [16, 16, 16, 32],
"beta": np.float32(6.0),
"mass": np.float32(0.05),
"n_therm": np.int32(100),
"n_traj": np.int64(2000),
}
# Write to file
with open("params.json", "w") as f:
f.write(q.json_dumps(params))
# Read back
with open("params.json") as f:
params = q.json_loads(f.read())
Compact (No Indentation)¶
s = q.json_dumps({"mass": np.float32(0.5)}, indent=None)
Nested Structures¶
data = {
"config_0": {
"plaquette": np.float64(0.58),
"correlator": np.array([1.0, 0.8, 0.6]),
},
"config_1": {
"plaquette": np.float64(0.59),
"correlator": np.array([1.0, 0.79, 0.58]),
},
}
s = q.json_dumps(data)
restored = q.json_loads(s)
# numpy array preserved through nesting; np.float64 round-trips as Python float