Serialization#
PyAnsys Units can save quantities and units to dictionaries, JSON, strings, and pickle files, and restore them.
Dictionaries#
to_dict() returns built-in Python types only. Array values become nested lists,
and extra fields given to the Quantity constructor are kept:
from ansys.units import Quantity, Unit
q = Quantity([1.0, 2.0], "m s^-1", source="sensor")
data = q.to_dict() # {'value': [1.0, 2.0], 'units': 'm s^-1', 'source': 'sensor'}
Quantity.from_dict(data) # Quantity ([1. 2.], "m s^-1")
Unit("kg m^-3").to_dict() # {'units': 'kg m^-3'}
Unit.from_dict({"units": "kg m^-3"}) # Unit("kg m^-3")
JSON#
Quantity works as a field in Pydantic models,
which use the same dictionary format:
from pydantic import BaseModel, ConfigDict
from ansys.units import Quantity
class Measurement(BaseModel):
# Keep NaN and infinity, which are written as null by default.
model_config = ConfigDict(ser_json_inf_nan="constants")
length: Quantity
text = Measurement(length=Quantity(2.0, "m")).model_dump_json()
Measurement.model_validate_json(text).length # Quantity (2.0, "m")
Without Pydantic, use the json module with to_dict() and from_dict():
import json
from ansys.units import Quantity
text = json.dumps(Quantity(2.0, "m").to_dict())
Quantity.from_dict(json.loads(text)) # Quantity (2.0, "m")
Strings#
Quantity.from_string() parses the output of str(quantity):
from ansys.units import Quantity
Quantity.from_string("5.0 m s^-1") # Quantity (5.0, "m s^-1")
Quantity.from_string(str(Quantity([1.0, 2.0], "kg"))) # Quantity ([1. 2.], "kg")
NumPy shortens the string of large arrays with .... Such strings can’t be
parsed, so use to_dict() for large arrays.
Pickle#
Units are pickled by name and resolved again when loaded from a pickle. Pickle files created with earlier versions of PyAnsys Units can still be loaded.
Custom units#
Units are stored by name. Custom units registered with
UnitRegistry.register_unit() are also stored with their
definition, so they can be restored without the registry:
from ansys.units import Quantity, UnitRegistry
ureg = UnitRegistry()
ureg.register_unit(unit="micron", composition="m", factor=1e-6)
data = ureg.Quantity(3.0, "micron").to_dict()
# {'value': 3.0, 'units': 'micron',
# 'unit_definition': {'composition': 'm', 'factor': 1e-06}}
Quantity.from_dict(data).to("m") # Quantity (3e-06, "m")
When loading, a unit name is looked up in this order:
The
registryargument offrom_dict()orfrom_string().The registry set with
set_application_registry(). Loading from a pickle also uses this registry.The built-in units.
import pickle
from ansys.units import Quantity, UnitRegistry, set_application_registry
ureg = UnitRegistry()
ureg.register_unit(unit="micron", composition="m", factor=1e-6)
set_application_registry(ureg)
Quantity.from_string("3.0 micron") # Quantity (3.0, "micron")
pickle.loads(pickle.dumps(ureg.Quantity(3.0, "micron"))) # Quantity (3.0, "micron")
If the stored definition of a custom unit differs from the unit with the same name
in the registry, loading raises a ConflictingUnitDefinition error rather than
returning wrong values. A unit name that can’t be resolved raises an
UnresolvableUnit error.