structure#
Validated and serializable data structures using pydantic
.
In this module we provide pre-configured Pydantic model
and
custom field types
that allow serialization of typical data objects
that we frequently use in quantify-scheduler
, like functions and arrays.
Submodules#
Package Contents#
Classes#
A parent for all data structures. |
|
Pydantic-compatible version of |
|
Pydantic-compatible version of |
- class DataStructure(/, **data: Any)[source]#
Bases:
pydantic.BaseModel
A parent for all data structures.
Data attributes are generated from the class’ type annotations, similarly to dataclasses. If data attributes are JSON-serializable, data structure can be serialized using
json()
method. This string can be deserialized usingparse_raw()
classmethod of a correspondent child class.If required, data fields can be validated, see examples for more information. It is also possible to define custom field types with advanced validation.
This class is a pre-configured pydantic model. See its documentation for details of usage information.
Examples
Initializing a custom data structure:
class ExampleClockResource(DataStructure): """An example clock resource. It has name, frequency and phase. By default phase is zero. Parameters ---------- name Clock name freq Clock frequency [Hz] phase Clock phase, by default 0 [rad]. """ name: str freq: float phase: float = 0 clock = ExampleClockResource(name="q0.01", freq=7e9) print(str(clock)) print(repr(clock))
name='q0.01' freq=7000000000.0 phase=0 ExampleClockResource(name='q0.01', freq=7000000000.0, phase=0)
This data structure can be used within other data structures:
class ExamplePulse(DataStructure): """...""" amplitude: float duration: float clock: ExampleClockResource pulse = ExamplePulse(amplitude=0.1, duration=2e-8, clock=clock) print(str(pulse)) print(repr(pulse))
amplitude=0.1 duration=2e-08 clock=ExampleClockResource(name='q0.01', freq=7000000000.0, phase=0) ExamplePulse(amplitude=0.1, duration=2e-08, clock=ExampleClockResource(name='q0.01', freq=7000000000.0, phase=0))
Serialization, deserialization and comparison are provided from scratch:
pulse_json = pulse.model_dump_json() print(pulse_json) pulse2 = ExamplePulse.model_validate_json(pulse_json) assert pulse == pulse2
{"amplitude":0.1,"duration":2e-8,"clock":{"name":"q0.01","freq":7000000000.0,"phase":0.0}}
User may implement custom validators:
from pydantic import field_validator class ScheduledExamplePulse(DataStructure): """...""" pulse: ExamplePulse start: float @field_validator("start") def _ensure_4ns_grid(cls, value): # pylint: disable=no-self-argument,no-self-use if value % 4e-9 > 1e-12: raise ValueError("Start must be on a 4 ns grid due to hardware limitations") return value # This works fine scheduled_pulse = ScheduledExamplePulse(pulse=pulse, start=8e-9) # This raises a ValidationError scheduled_pulse = ScheduledExamplePulse(pulse=pulse, start=9e-9)
--------------------------------------------------------------------------- ValidationError Traceback (most recent call last) Cell In[5], line 21 19 scheduled_pulse = ScheduledExamplePulse(pulse=pulse, start=8e-9) 20 # This raises a ValidationError ---> 21 scheduled_pulse = ScheduledExamplePulse(pulse=pulse, start=9e-9) File /usr/local/lib/python3.9/site-packages/pydantic/main.py:212, in BaseModel.__init__(self, **data) 210 # `__tracebackhide__` tells pytest and some other tools to omit this function from tracebacks 211 __tracebackhide__ = True --> 212 validated_self = self.__pydantic_validator__.validate_python(data, self_instance=self) 213 if self is not validated_self: 214 warnings.warn( 215 'A custom validator is returning a value other than `self`.\n' 216 "Returning anything other than `self` from a top level model validator isn't supported when validating via `__init__`.\n" 217 'See the `model_validator` docs (https://docs.pydantic.dev/latest/concepts/validators/#model-validators) for more details.', 218 category=None, 219 ) ValidationError: 1 validation error for ScheduledExamplePulse start Value error, Start must be on a 4 ns grid due to hardware limitations [type=value_error, input_value=9e-09, input_type=float] For further information visit https://errors.pydantic.dev/2.9/v/value_error
See pydantic documentation for more usage examples.
- model_config#
Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].
- class Graph(incoming_graph_data=None, **attr)[source]#
Bases:
networkx.Graph
Pydantic-compatible version of
networkx.Graph
.
- class NDArray(shape, dtype=float, buffer=None, offset=0, strides=None, order=None)[source]#
Bases:
numpy.ndarray
Pydantic-compatible version of
numpy.ndarray
.Serialization is implemented using custom methods
to_dict()
andfrom_dict()
. Data array is encoded in Base64.- classmethod from_dict(serialized: collections.abc.Mapping[str, Any]) NDArray [source]#
Construct an instance from a dictionary generated by :meth`to_dict`.
- Parameters:
serialized – Dictionary that has
"data"
,"shape"
and"dtype"
keys.”, where data is a base64-encoded bytes array, shape is a tuple and dtype is a string representation of a Numpy data type.