iqm-exa-common 26.26.0__py3-none-any.whl → 26.28.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- exa/common/api/proto_serialization/_parameter.py +19 -19
- exa/common/api/proto_serialization/array.py +4 -4
- exa/common/api/proto_serialization/datum.py +16 -15
- exa/common/api/proto_serialization/nd_sweep.py +11 -9
- exa/common/api/proto_serialization/sequence.py +4 -4
- exa/common/api/proto_serialization/setting_node.py +10 -10
- exa/common/control/sweep/option/center_span_base_options.py +1 -1
- exa/common/control/sweep/option/constants.py +1 -3
- exa/common/control/sweep/option/option_converter.py +13 -13
- exa/common/control/sweep/option/start_stop_options.py +1 -1
- exa/common/control/sweep/sweep.py +2 -2
- exa/common/data/parameter.py +32 -6
- exa/common/data/setting_node.py +35 -8
- exa/common/helpers/data_helper.py +1 -1
- exa/common/helpers/software_version_helper.py +1 -1
- exa/common/py.typed +0 -0
- exa/common/qcm_data/chad_model.py +1 -1
- exa/common/qcm_data/chip_topology.py +2 -0
- {iqm_exa_common-26.26.0.dist-info → iqm_exa_common-26.28.0.dist-info}/METADATA +4 -1
- {iqm_exa_common-26.26.0.dist-info → iqm_exa_common-26.28.0.dist-info}/RECORD +23 -22
- {iqm_exa_common-26.26.0.dist-info → iqm_exa_common-26.28.0.dist-info}/LICENSE.txt +0 -0
- {iqm_exa_common-26.26.0.dist-info → iqm_exa_common-26.28.0.dist-info}/WHEEL +0 -0
- {iqm_exa_common-26.26.0.dist-info → iqm_exa_common-26.28.0.dist-info}/top_level.txt +0 -0
|
@@ -14,36 +14,36 @@
|
|
|
14
14
|
|
|
15
15
|
"""Pack and unpack parameters to protos and back."""
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
from iqm.data_definitions.common.v1.parameter_pb2 import Parameter as ppb_Parameter
|
|
18
18
|
|
|
19
19
|
from exa.common.data.parameter import CollectionType, DataType, Parameter
|
|
20
20
|
|
|
21
21
|
_COLLECTION_TYPES = {
|
|
22
|
-
CollectionType.SCALAR:
|
|
23
|
-
CollectionType.LIST:
|
|
24
|
-
CollectionType.NDARRAY:
|
|
22
|
+
CollectionType.SCALAR: ppb_Parameter.CollectionType.COLLECTION_TYPE_SCALAR,
|
|
23
|
+
CollectionType.LIST: ppb_Parameter.CollectionType.COLLECTION_TYPE_SEQUENCE,
|
|
24
|
+
CollectionType.NDARRAY: ppb_Parameter.CollectionType.COLLECTION_TYPE_ARRAY,
|
|
25
25
|
}
|
|
26
26
|
_collection_types_inv = {v: k for k, v in _COLLECTION_TYPES.items()}
|
|
27
27
|
|
|
28
28
|
_DATA_TYPES = {
|
|
29
|
-
DataType.ANYTHING:
|
|
30
|
-
DataType.NUMBER:
|
|
31
|
-
DataType.STRING:
|
|
32
|
-
DataType.COMPLEX:
|
|
33
|
-
DataType.BOOLEAN:
|
|
34
|
-
DataType.INT:
|
|
35
|
-
DataType.FLOAT:
|
|
29
|
+
DataType.ANYTHING: ppb_Parameter.DataType.DATA_TYPE_UNSPECIFIED,
|
|
30
|
+
DataType.NUMBER: ppb_Parameter.DataType.DATA_TYPE_FLOAT64, # Deprecated
|
|
31
|
+
DataType.STRING: ppb_Parameter.DataType.DATA_TYPE_STRING,
|
|
32
|
+
DataType.COMPLEX: ppb_Parameter.DataType.DATA_TYPE_COMPLEX128,
|
|
33
|
+
DataType.BOOLEAN: ppb_Parameter.DataType.DATA_TYPE_BOOL,
|
|
34
|
+
DataType.INT: ppb_Parameter.DataType.DATA_TYPE_INT64,
|
|
35
|
+
DataType.FLOAT: ppb_Parameter.DataType.DATA_TYPE_FLOAT64,
|
|
36
36
|
}
|
|
37
37
|
_data_types_inv = {v: k for k, v in _DATA_TYPES.items() if k != DataType.NUMBER}
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def pack(parameter: Parameter) ->
|
|
40
|
+
def pack(parameter: Parameter) -> ppb_Parameter:
|
|
41
41
|
"""Convert Parameter into protobuf representation."""
|
|
42
|
-
return
|
|
42
|
+
return ppb_Parameter(
|
|
43
43
|
name=parameter.name,
|
|
44
44
|
label=parameter.label,
|
|
45
45
|
unit=parameter.unit,
|
|
46
|
-
data_type=_DATA_TYPES.get(parameter.data_type,
|
|
46
|
+
data_type=_DATA_TYPES.get(parameter.data_type, ppb_Parameter.DataType.DATA_TYPE_UNSPECIFIED), # type: ignore[arg-type]
|
|
47
47
|
collection_type=_COLLECTION_TYPES[parameter.collection_type],
|
|
48
48
|
element_indices=parameter.element_indices,
|
|
49
49
|
parent_name=parameter.parent_name,
|
|
@@ -51,21 +51,21 @@ def pack(parameter: Parameter) -> ppb.Parameter:
|
|
|
51
51
|
)
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
def unpack(proto:
|
|
54
|
+
def unpack(proto: ppb_Parameter) -> Parameter:
|
|
55
55
|
"""Convert protobuf representation into a Parameter."""
|
|
56
56
|
if not proto.element_indices:
|
|
57
57
|
return Parameter(
|
|
58
58
|
name=proto.name,
|
|
59
59
|
label=proto.label,
|
|
60
60
|
unit=proto.unit,
|
|
61
|
-
data_type=_data_types_inv.get(proto.data_type),
|
|
62
|
-
collection_type=_collection_types_inv.get(proto.collection_type),
|
|
61
|
+
data_type=_data_types_inv.get(proto.data_type), # type: ignore[arg-type]
|
|
62
|
+
collection_type=_collection_types_inv.get(proto.collection_type), # type: ignore[arg-type]
|
|
63
63
|
)
|
|
64
64
|
return Parameter(
|
|
65
65
|
name=proto.parent_name,
|
|
66
66
|
label=proto.parent_label,
|
|
67
67
|
unit=proto.unit,
|
|
68
|
-
data_type=_data_types_inv.get(proto.data_type),
|
|
69
|
-
collection_type=_collection_types_inv.get(proto.collection_type),
|
|
68
|
+
data_type=_data_types_inv.get(proto.data_type), # type: ignore[arg-type]
|
|
69
|
+
collection_type=_collection_types_inv.get(proto.collection_type), # type: ignore[arg-type]
|
|
70
70
|
element_indices=list(proto.element_indices),
|
|
71
71
|
)
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
|
|
15
15
|
"""Convert numpy arrays to protos and back."""
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
from iqm.data_definitions.common.v1.data_types_pb2 import Array as dpb_Array
|
|
18
18
|
import numpy as np
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def pack(array: np.ndarray) ->
|
|
21
|
+
def pack(array: np.ndarray) -> dpb_Array:
|
|
22
22
|
"""Packs a numeric numpy array into protobuf format.
|
|
23
23
|
|
|
24
24
|
Args:
|
|
@@ -28,7 +28,7 @@ def pack(array: np.ndarray) -> dpb.Array:
|
|
|
28
28
|
A protobuf instance that encapsulates `array`.
|
|
29
29
|
|
|
30
30
|
"""
|
|
31
|
-
target =
|
|
31
|
+
target = dpb_Array()
|
|
32
32
|
target.shape.MergeFrom(array.shape)
|
|
33
33
|
if not array.size: # MergeFrom throws with 0-sized iterables
|
|
34
34
|
return target
|
|
@@ -54,7 +54,7 @@ def pack(array: np.ndarray) -> dpb.Array:
|
|
|
54
54
|
return target
|
|
55
55
|
|
|
56
56
|
|
|
57
|
-
def unpack(source:
|
|
57
|
+
def unpack(source: dpb_Array) -> np.ndarray:
|
|
58
58
|
"""Unpacks protobuf to array. Reverse operation of :func:`.pack`.
|
|
59
59
|
|
|
60
60
|
Args:
|
|
@@ -16,13 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
from collections.abc import Sequence
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
from iqm.data_definitions.common.v1.data_types_pb2 import Complex128 as dpb_Complex128
|
|
20
|
+
from iqm.data_definitions.common.v1.data_types_pb2 import Datum as dpb_Datum
|
|
20
21
|
import numpy as np
|
|
21
22
|
|
|
22
23
|
from exa.common.api.proto_serialization import array, sequence
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def pack(value: None | bool | str | int | float | complex | np.ndarray | Sequence) ->
|
|
26
|
+
def pack(value: None | bool | str | int | float | complex | np.ndarray | Sequence) -> dpb_Datum:
|
|
26
27
|
"""Packs a string, numerical value, or an array thereof into protobuf format.
|
|
27
28
|
|
|
28
29
|
Supported data types are:
|
|
@@ -48,25 +49,25 @@ def pack(value: None | bool | str | int | float | complex | np.ndarray | Sequenc
|
|
|
48
49
|
f"Encoding of numpy type '{type(value)}' is not supported. Cast the value into a native type first."
|
|
49
50
|
)
|
|
50
51
|
if value is None:
|
|
51
|
-
return
|
|
52
|
+
return dpb_Datum(null_value=True)
|
|
52
53
|
if isinstance(value, bool):
|
|
53
|
-
return
|
|
54
|
+
return dpb_Datum(bool_value=value)
|
|
54
55
|
if isinstance(value, str):
|
|
55
|
-
return
|
|
56
|
+
return dpb_Datum(string_value=value)
|
|
56
57
|
if isinstance(value, int):
|
|
57
|
-
return
|
|
58
|
+
return dpb_Datum(sint64_value=value)
|
|
58
59
|
if isinstance(value, float):
|
|
59
|
-
return
|
|
60
|
+
return dpb_Datum(float64_value=value)
|
|
60
61
|
if isinstance(value, complex):
|
|
61
|
-
return
|
|
62
|
+
return dpb_Datum(complex128_value=dpb_Complex128(real=value.real, imag=value.imag))
|
|
62
63
|
if isinstance(value, np.ndarray):
|
|
63
|
-
return
|
|
64
|
+
return dpb_Datum(array=array.pack(value))
|
|
64
65
|
if isinstance(value, Sequence):
|
|
65
|
-
return
|
|
66
|
+
return dpb_Datum(sequence=sequence.pack(value))
|
|
66
67
|
raise TypeError(f"Encoding of type '{type(value)}' is not supported.")
|
|
67
68
|
|
|
68
69
|
|
|
69
|
-
def unpack(source:
|
|
70
|
+
def unpack(source: dpb_Datum) -> None | str | bool | int | float | complex | np.ndarray | list:
|
|
70
71
|
"""Unpacks a protobuf into a native Python type or a numpy array. Reverse operation of :func:`.pack`.
|
|
71
72
|
|
|
72
73
|
Args:
|
|
@@ -122,19 +123,19 @@ def deserialize(source: bytes) -> None | str | bool | int | float | complex | np
|
|
|
122
123
|
Deserialized data.
|
|
123
124
|
|
|
124
125
|
"""
|
|
125
|
-
proto =
|
|
126
|
+
proto = dpb_Datum()
|
|
126
127
|
proto.ParseFromString(source)
|
|
127
128
|
return unpack(proto)
|
|
128
129
|
|
|
129
130
|
|
|
130
|
-
def _pack_complex128(value: np.complex128 | complex, target:
|
|
131
|
+
def _pack_complex128(value: np.complex128 | complex, target: dpb_Complex128 | None = None) -> dpb_Complex128:
|
|
131
132
|
"""Packs a numpy complex128 to the respective protobuf type."""
|
|
132
|
-
target = target or
|
|
133
|
+
target = target or dpb_Complex128()
|
|
133
134
|
target.real = value.real
|
|
134
135
|
target.imag = value.imag
|
|
135
136
|
return target
|
|
136
137
|
|
|
137
138
|
|
|
138
|
-
def _unpack_complex128_value(complex128_value:
|
|
139
|
+
def _unpack_complex128_value(complex128_value: dpb_Complex128) -> complex:
|
|
139
140
|
"""Unpack a protobuf to a native complex number."""
|
|
140
141
|
return complex(complex128_value.real, complex128_value.imag)
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
"""Convert NdSweeps to protos and back."""
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
from iqm.data_definitions.common.v1.sweep_pb2 import CartesianSweep as spb_CartesianSweep
|
|
18
|
+
from iqm.data_definitions.common.v1.sweep_pb2 import ParallelSweep as spb_ParallelSweep
|
|
19
|
+
from iqm.data_definitions.common.v1.sweep_pb2 import SingleParameterSweep as spb_SingleParameterSweep
|
|
18
20
|
|
|
19
21
|
from exa.common.api.proto_serialization import sequence
|
|
20
22
|
import exa.common.api.proto_serialization._parameter as param_proto
|
|
@@ -23,22 +25,22 @@ from exa.common.data.parameter import DataType, Parameter
|
|
|
23
25
|
from exa.common.sweep.util import NdSweep
|
|
24
26
|
|
|
25
27
|
|
|
26
|
-
def pack(nd_sweep: NdSweep, minimal: bool = True) ->
|
|
28
|
+
def pack(nd_sweep: NdSweep, minimal: bool = True) -> spb_CartesianSweep:
|
|
27
29
|
"""Convert an NdSweep into protobuf representation.
|
|
28
30
|
|
|
29
31
|
Note: The protobuf does not make any distinction between different types of Sweeps, so the type information is lost.
|
|
30
32
|
"""
|
|
31
33
|
parallels = []
|
|
32
34
|
for parallel in nd_sweep:
|
|
33
|
-
parallel_proto =
|
|
35
|
+
parallel_proto = spb_ParallelSweep()
|
|
34
36
|
parallel_proto.single_parameter_sweeps.MergeFrom((_pack_single_sweep(sweep, minimal) for sweep in parallel))
|
|
35
37
|
parallels.append(parallel_proto)
|
|
36
|
-
proto =
|
|
38
|
+
proto = spb_CartesianSweep()
|
|
37
39
|
proto.parallel_sweeps.MergeFrom(reversed(parallels)) # In data-definitions, order is outermost loop first
|
|
38
40
|
return proto
|
|
39
41
|
|
|
40
42
|
|
|
41
|
-
def unpack(proto:
|
|
43
|
+
def unpack(proto: spb_CartesianSweep) -> NdSweep:
|
|
42
44
|
"""Convert protobuf representation into a NdSweep. Reverse operation of :func:`.pack`."""
|
|
43
45
|
nd_sweep = []
|
|
44
46
|
for parallel_proto in reversed(proto.parallel_sweeps):
|
|
@@ -47,14 +49,14 @@ def unpack(proto: spb.CartesianSweep) -> NdSweep:
|
|
|
47
49
|
return nd_sweep
|
|
48
50
|
|
|
49
51
|
|
|
50
|
-
def _pack_single_sweep(sweep: Sweep, minimal: bool) ->
|
|
51
|
-
kwargs = {"parameter_name": sweep.parameter.name, "values": sequence.pack(sweep.data)}
|
|
52
|
+
def _pack_single_sweep(sweep: Sweep, minimal: bool) -> spb_SingleParameterSweep:
|
|
53
|
+
kwargs = {"parameter_name": sweep.parameter.name, "values": sequence.pack(sweep.data)} # type: ignore[arg-type]
|
|
52
54
|
if not minimal:
|
|
53
55
|
kwargs["parameter"] = param_proto.pack(sweep.parameter)
|
|
54
|
-
return
|
|
56
|
+
return spb_SingleParameterSweep(**kwargs)
|
|
55
57
|
|
|
56
58
|
|
|
57
|
-
def _unpack_single_sweep(proto:
|
|
59
|
+
def _unpack_single_sweep(proto: spb_SingleParameterSweep) -> Sweep:
|
|
58
60
|
sweep_values = sequence.unpack(proto.values)
|
|
59
61
|
if proto.HasField("parameter"):
|
|
60
62
|
parameter = param_proto.unpack(proto.parameter)
|
|
@@ -16,11 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
from collections.abc import Sequence
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
from iqm.data_definitions.common.v1.data_types_pb2 import Sequence as dpb_Sequence
|
|
20
20
|
import numpy as np
|
|
21
21
|
|
|
22
22
|
|
|
23
|
-
def pack(values: Sequence) ->
|
|
23
|
+
def pack(values: Sequence) -> dpb_Sequence:
|
|
24
24
|
"""Packs a sequence of native Python types into protobuf format.
|
|
25
25
|
|
|
26
26
|
Args:
|
|
@@ -33,7 +33,7 @@ def pack(values: Sequence) -> dpb.Sequence:
|
|
|
33
33
|
ValueError in case of unsupported value.
|
|
34
34
|
|
|
35
35
|
"""
|
|
36
|
-
target =
|
|
36
|
+
target = dpb_Sequence()
|
|
37
37
|
if not values:
|
|
38
38
|
return target
|
|
39
39
|
dtype = type(values[0])
|
|
@@ -57,7 +57,7 @@ def pack(values: Sequence) -> dpb.Sequence:
|
|
|
57
57
|
return target
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
def unpack(source:
|
|
60
|
+
def unpack(source: dpb_Sequence) -> list:
|
|
61
61
|
"""Unpacks protobuf to list. Reverse operation of :func:`.pack`.
|
|
62
62
|
|
|
63
63
|
Args:
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
"""Convert SettingNodes to protos and back."""
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
from iqm.data_definitions.common.v1.setting_pb2 import SettingNode as spb_SettingNode
|
|
18
18
|
|
|
19
19
|
from exa.common.api.proto_serialization import datum
|
|
20
20
|
import exa.common.api.proto_serialization._parameter as param_proto
|
|
@@ -23,7 +23,7 @@ from exa.common.data.setting_node import Setting, SettingNode
|
|
|
23
23
|
from exa.common.helpers.numpy_helper import coerce_numpy_type_to_native
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def _pack_setting(setting: Setting, optimize: bool) ->
|
|
26
|
+
def _pack_setting(setting: Setting, optimize: bool) -> spb_SettingNode.Setting:
|
|
27
27
|
"""Convert a Setting into protobuf representation."""
|
|
28
28
|
value = coerce_numpy_type_to_native(setting.value)
|
|
29
29
|
try:
|
|
@@ -33,11 +33,11 @@ def _pack_setting(setting: Setting, optimize: bool) -> spb.SettingNode.Setting:
|
|
|
33
33
|
f"Failed to convert a value to protobuf. Value={setting.value}, Parameter={setting.parameter}."
|
|
34
34
|
) from err
|
|
35
35
|
if optimize:
|
|
36
|
-
return
|
|
37
|
-
return
|
|
36
|
+
return spb_SettingNode.Setting(parameter_name=setting.name, value=packed)
|
|
37
|
+
return spb_SettingNode.Setting(parameter=param_proto.pack(setting.parameter), value=packed)
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def _unpack_setting(proto:
|
|
40
|
+
def _unpack_setting(proto: spb_SettingNode.Setting) -> Setting:
|
|
41
41
|
"""Convert protobuf representation into a Setting."""
|
|
42
42
|
if proto.WhichOneof("parameter_desc") == "parameter":
|
|
43
43
|
parameter = param_proto.unpack(proto.parameter)
|
|
@@ -48,10 +48,10 @@ def _unpack_setting(proto: spb.SettingNode.Setting) -> Setting:
|
|
|
48
48
|
except Exception as err:
|
|
49
49
|
raise AttributeError(f"Unpacking of {parameter} {proto.value} failed.") from err
|
|
50
50
|
|
|
51
|
-
return Setting(parameter, value)
|
|
51
|
+
return Setting(parameter, value) # type: ignore[arg-type]
|
|
52
52
|
|
|
53
53
|
|
|
54
|
-
def pack(node: SettingNode, minimal: bool) ->
|
|
54
|
+
def pack(node: SettingNode, minimal: bool) -> spb_SettingNode:
|
|
55
55
|
"""Convert a SettingNode into protobuf representation.
|
|
56
56
|
|
|
57
57
|
Silently coerces some datatypes to be compatible with the proto definition of ``Datum``:
|
|
@@ -69,10 +69,10 @@ def pack(node: SettingNode, minimal: bool) -> spb.SettingNode:
|
|
|
69
69
|
"""
|
|
70
70
|
settings = {key: _pack_setting(item, minimal) for key, item in node.child_settings}
|
|
71
71
|
nodes = {key: pack(item, minimal) for key, item in node.child_nodes}
|
|
72
|
-
return
|
|
72
|
+
return spb_SettingNode(name=node.name, settings=settings, subnodes=nodes)
|
|
73
73
|
|
|
74
74
|
|
|
75
|
-
def unpack(proto:
|
|
75
|
+
def unpack(proto: spb_SettingNode) -> SettingNode:
|
|
76
76
|
"""Convert protobuf representation into a SettingNode. Reverse operation of :func:`.pack`
|
|
77
77
|
|
|
78
78
|
Args:
|
|
@@ -87,4 +87,4 @@ def unpack(proto: spb.SettingNode) -> SettingNode:
|
|
|
87
87
|
nodes = {key: unpack(content) for key, content in proto.subnodes.items()}
|
|
88
88
|
# Names are currently NEVER aligned with the paths when deserializing. This is safe to do, since currently nothing
|
|
89
89
|
# in the server-side assumes path==name, but if such logic is added this needs to be reconsidered.
|
|
90
|
-
return SettingNode(name=proto.name, **(settings | nodes), align_name=False)
|
|
90
|
+
return SettingNode(name=proto.name, **(settings | nodes), align_name=False) # type: ignore[arg-type] # type: ignore[arg-type] # type: ignore[arg-type]
|
|
@@ -57,4 +57,4 @@ class CenterSpanBaseOptions(SweepOptions):
|
|
|
57
57
|
start = self.center - (self.span / 2)
|
|
58
58
|
stop = self.center + (self.span / 2)
|
|
59
59
|
(start, stop) = (start, stop) if self.asc else (stop, start)
|
|
60
|
-
return StartStopBaseOptions(start, stop, count=self.count, base=self.base).data
|
|
60
|
+
return StartStopBaseOptions(start, stop, count=self.count, base=self.base).data # type:ignore[arg-type,return-value]
|
|
@@ -14,14 +14,12 @@
|
|
|
14
14
|
|
|
15
15
|
"""Helper constants for SweepOptions classes."""
|
|
16
16
|
|
|
17
|
-
from typing import Any
|
|
18
|
-
|
|
19
17
|
#: Default value for `count` value in options.
|
|
20
18
|
DEFAULT_COUNT: int = 101
|
|
21
19
|
#: Default value for `base` value in options.
|
|
22
20
|
DEFAULT_BASE: int = 10
|
|
23
21
|
#: Dictionary with all possible types of options
|
|
24
|
-
OPTIONS_TYPE: dict[str,
|
|
22
|
+
OPTIONS_TYPE: dict[str, str | list[str]] = {
|
|
25
23
|
"start": "start",
|
|
26
24
|
"stop": "stop",
|
|
27
25
|
"center": "center",
|
|
@@ -45,24 +45,24 @@ def convert_to_options(config: dict[str, Any]) -> SweepOptions:
|
|
|
45
45
|
|
|
46
46
|
"""
|
|
47
47
|
config = {k.lower(): v for k, v in config.items()}
|
|
48
|
-
if {OPTIONS_TYPE.get("start"), OPTIONS_TYPE.get("stop")}.issubset(set(config)):
|
|
49
|
-
updated_config = __update_config(config, OPTIONS_TYPE.get("start_stop_list"))
|
|
48
|
+
if {OPTIONS_TYPE.get("start"), OPTIONS_TYPE.get("stop")}.issubset(set(config)): # type:ignore[arg-type]
|
|
49
|
+
updated_config = __update_config(config, OPTIONS_TYPE.get("start_stop_list")) # type:ignore[arg-type]
|
|
50
50
|
return StartStopOptions(**updated_config)
|
|
51
|
-
elif {OPTIONS_TYPE.get("start_exp"), OPTIONS_TYPE.get("stop_exp")}.issubset(set(config)):
|
|
52
|
-
__rename_key(config, OPTIONS_TYPE.get("start_exp"), OPTIONS_TYPE.get("start"))
|
|
53
|
-
__rename_key(config, OPTIONS_TYPE.get("stop_exp"), OPTIONS_TYPE.get("stop"))
|
|
54
|
-
updated_config = __update_config(config, OPTIONS_TYPE.get("start_stop_base_list"))
|
|
51
|
+
elif {OPTIONS_TYPE.get("start_exp"), OPTIONS_TYPE.get("stop_exp")}.issubset(set(config)): # type:ignore[arg-type]
|
|
52
|
+
__rename_key(config, OPTIONS_TYPE.get("start_exp"), OPTIONS_TYPE.get("start")) # type:ignore[arg-type]
|
|
53
|
+
__rename_key(config, OPTIONS_TYPE.get("stop_exp"), OPTIONS_TYPE.get("stop")) # type:ignore[arg-type]
|
|
54
|
+
updated_config = __update_config(config, OPTIONS_TYPE.get("start_stop_base_list")) # type:ignore[arg-type]
|
|
55
55
|
return StartStopBaseOptions(**updated_config)
|
|
56
|
-
elif {OPTIONS_TYPE.get("center"), OPTIONS_TYPE.get("span")}.issubset(set(config)):
|
|
57
|
-
updated_config = __update_config(config, OPTIONS_TYPE.get("center_span_list"))
|
|
56
|
+
elif {OPTIONS_TYPE.get("center"), OPTIONS_TYPE.get("span")}.issubset(set(config)): # type:ignore[arg-type]
|
|
57
|
+
updated_config = __update_config(config, OPTIONS_TYPE.get("center_span_list")) # type:ignore[arg-type]
|
|
58
58
|
return CenterSpanOptions(**updated_config)
|
|
59
|
-
elif {OPTIONS_TYPE.get("center_exp"), OPTIONS_TYPE.get("span_exp")}.issubset(set(config)):
|
|
60
|
-
__rename_key(config, OPTIONS_TYPE.get("center_exp"), OPTIONS_TYPE.get("center"))
|
|
61
|
-
__rename_key(config, OPTIONS_TYPE.get("span_exp"), OPTIONS_TYPE.get("span"))
|
|
62
|
-
updated_config = __update_config(config, OPTIONS_TYPE.get("center_span_base_list"))
|
|
59
|
+
elif {OPTIONS_TYPE.get("center_exp"), OPTIONS_TYPE.get("span_exp")}.issubset(set(config)): # type:ignore[arg-type]
|
|
60
|
+
__rename_key(config, OPTIONS_TYPE.get("center_exp"), OPTIONS_TYPE.get("center")) # type:ignore[arg-type]
|
|
61
|
+
__rename_key(config, OPTIONS_TYPE.get("span_exp"), OPTIONS_TYPE.get("span")) # type:ignore[arg-type]
|
|
62
|
+
updated_config = __update_config(config, OPTIONS_TYPE.get("center_span_base_list")) # type:ignore[arg-type]
|
|
63
63
|
return CenterSpanBaseOptions(**updated_config)
|
|
64
64
|
elif OPTIONS_TYPE.get("fixed") in set(config):
|
|
65
|
-
updated_config = __update_config(config, OPTIONS_TYPE.get("fixed"))
|
|
65
|
+
updated_config = __update_config(config, OPTIONS_TYPE.get("fixed")) # type:ignore[arg-type]
|
|
66
66
|
return FixedOptions(**updated_config)
|
|
67
67
|
else:
|
|
68
68
|
raise ValueError(f"Config {config} cannot be converted to range options")
|
|
@@ -66,7 +66,7 @@ class StartStopOptions(SweepOptions):
|
|
|
66
66
|
data = self._generate_by_count(count)
|
|
67
67
|
else:
|
|
68
68
|
data = self._generate_by_count(self.count if self.count is not None else DEFAULT_COUNT)
|
|
69
|
-
return data
|
|
69
|
+
return data # type: ignore[return-value]
|
|
70
70
|
|
|
71
71
|
def _generate_by_count(self, count: int) -> SweepValues:
|
|
72
72
|
return np.linspace(self.start, self.stop, count, endpoint=True).tolist()
|
|
@@ -55,7 +55,7 @@ class Sweep(BaseModel):
|
|
|
55
55
|
else:
|
|
56
56
|
data = options.data
|
|
57
57
|
|
|
58
|
-
super().__init__(parameter=parameter, data=data, **kwargs)
|
|
58
|
+
super().__init__(parameter=parameter, data=data, **kwargs) # type: ignore[call-arg] # type: ignore[call-arg]
|
|
59
59
|
|
|
60
60
|
def model_post_init(self, __context: Any) -> None:
|
|
61
61
|
if not all(self.parameter.validate(value) for value in self.data):
|
|
@@ -71,7 +71,7 @@ class Sweep(BaseModel):
|
|
|
71
71
|
def __from_start_stop(cls, parameter: Parameter, options: StartStopOptions) -> SweepValues:
|
|
72
72
|
cls._validate_value(parameter, options.start, "start")
|
|
73
73
|
cls._validate_value(parameter, options.stop, "stop")
|
|
74
|
-
cls._validate_value(parameter, options.step, "step")
|
|
74
|
+
cls._validate_value(parameter, options.step, "step") # type: ignore[arg-type]
|
|
75
75
|
return options.data
|
|
76
76
|
|
|
77
77
|
@staticmethod
|
exa/common/data/parameter.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
# mypy: ignore-errors
|
|
16
|
+
|
|
15
17
|
"""Physical quantities and instrument settings.
|
|
16
18
|
|
|
17
19
|
A basic data structure in EXA is the :class:`~exa.common.data.parameter.Parameter`, which represents
|
|
@@ -61,7 +63,7 @@ import ast
|
|
|
61
63
|
from collections.abc import Hashable
|
|
62
64
|
import copy
|
|
63
65
|
from enum import IntEnum
|
|
64
|
-
from typing import Any, Self
|
|
66
|
+
from typing import Any, Self, TypeAlias
|
|
65
67
|
import warnings
|
|
66
68
|
|
|
67
69
|
import numpy as np
|
|
@@ -73,7 +75,9 @@ from exa.common.data.base_model import BaseModel
|
|
|
73
75
|
from exa.common.data.value import ObservationValue
|
|
74
76
|
from exa.common.errors.station_control_errors import ValidationError
|
|
75
77
|
|
|
76
|
-
CastType = str | list["CastType"] | None
|
|
78
|
+
CastType: TypeAlias = str | list["CastType"] | None
|
|
79
|
+
SourceType: TypeAlias = None | BaseModel | dict[str, Any]
|
|
80
|
+
"""Type for Setting sources."""
|
|
77
81
|
|
|
78
82
|
|
|
79
83
|
class DataType(IntEnum):
|
|
@@ -135,7 +139,7 @@ class DataType(IntEnum):
|
|
|
135
139
|
raise TypeError("Boolean data types can only be 'false', 'true, '0' or '1' (case-insensitive)")
|
|
136
140
|
elif self is DataType.STRING:
|
|
137
141
|
return value
|
|
138
|
-
else:
|
|
142
|
+
else: # TODO: can this be removed?
|
|
139
143
|
try:
|
|
140
144
|
return ast.literal_eval(value)
|
|
141
145
|
except (SyntaxError, ValueError): # if the value can not be evaluated, return the original value
|
|
@@ -407,12 +411,19 @@ class Setting(BaseModel):
|
|
|
407
411
|
path: str = ""
|
|
408
412
|
"""Path in the settings tree (starting from the root ``SettingNode``) for this setting."""
|
|
409
413
|
|
|
414
|
+
_source: SourceType = None
|
|
415
|
+
"""The source for this Setting value. May contain an observation (ObservationDefinition or ObservationData)
|
|
416
|
+
or a source-dict (e.g. ``{"type": "configuration_source", "configurator": "defaults_from_yml"}``). By default,
|
|
417
|
+
``None``, which denotes the source not being specified (e.g. hardcoded defaults). The source is stored in a private
|
|
418
|
+
attribute and thus is never serialized (the source field can contain non-serializable data such as Callables)."""
|
|
419
|
+
|
|
410
420
|
def __init__(
|
|
411
421
|
self,
|
|
412
422
|
parameter: Parameter | None = None,
|
|
413
423
|
value: ObservationValue | None = None,
|
|
414
424
|
read_only: bool = False,
|
|
415
425
|
path: str = "",
|
|
426
|
+
source: SourceType = None,
|
|
416
427
|
**kwargs,
|
|
417
428
|
) -> None:
|
|
418
429
|
super().__init__(
|
|
@@ -422,6 +433,7 @@ class Setting(BaseModel):
|
|
|
422
433
|
path=path,
|
|
423
434
|
**kwargs,
|
|
424
435
|
)
|
|
436
|
+
self._source = source
|
|
425
437
|
|
|
426
438
|
@model_validator(mode="after")
|
|
427
439
|
def validate_parameter_value_after(self) -> Self:
|
|
@@ -435,8 +447,17 @@ class Setting(BaseModel):
|
|
|
435
447
|
raise ValidationError(f"Invalid value '{self.value}' for parameter '{self.parameter}'.")
|
|
436
448
|
return self
|
|
437
449
|
|
|
438
|
-
def update(self, value: ObservationValue) -> Setting:
|
|
439
|
-
"""Create a new setting object with updated
|
|
450
|
+
def update(self, value: ObservationValue, source: SourceType = None) -> Setting:
|
|
451
|
+
"""Create a new setting object with updated value and source.
|
|
452
|
+
|
|
453
|
+
Args:
|
|
454
|
+
value: New value for the setting.
|
|
455
|
+
source: New source for the setting.
|
|
456
|
+
|
|
457
|
+
Returns:
|
|
458
|
+
Copy of ``self`` with modified properties.
|
|
459
|
+
|
|
460
|
+
"""
|
|
440
461
|
if self.read_only:
|
|
441
462
|
raise ValueError(
|
|
442
463
|
f"Can't update the value of {self.parameter.name} to {value} since the setting is read-only."
|
|
@@ -445,7 +466,7 @@ class Setting(BaseModel):
|
|
|
445
466
|
value = np.array(value)
|
|
446
467
|
# Need to create a new Setting here instead of using Pydantic model_copy().
|
|
447
468
|
# model_copy() can't handle backdoor settings without errors, i.e. values with a list of 2 elements.
|
|
448
|
-
return Setting(self.parameter, value, self.read_only, self.path)
|
|
469
|
+
return Setting(self.parameter, value, self.read_only, self.path, source=source)
|
|
449
470
|
|
|
450
471
|
@property
|
|
451
472
|
def name(self):
|
|
@@ -477,6 +498,11 @@ class Setting(BaseModel):
|
|
|
477
498
|
"""Element-wise indices of the parameter in ``self``."""
|
|
478
499
|
return self.parameter.element_indices
|
|
479
500
|
|
|
501
|
+
@property
|
|
502
|
+
def source(self) -> SourceType:
|
|
503
|
+
"""Return the source for this Setting's value."""
|
|
504
|
+
return self._source
|
|
505
|
+
|
|
480
506
|
@staticmethod
|
|
481
507
|
def get_by_name(name: str, values: set[Setting]) -> Setting | None:
|
|
482
508
|
return next((setting for setting in values if setting.parameter.name == name), None)
|
exa/common/data/setting_node.py
CHANGED
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
# mypy: ignore-errors
|
|
16
|
+
|
|
15
17
|
"""A tree-structured container for :class:`Settings <exa.common.data.parameter.Setting>`.
|
|
16
18
|
|
|
17
19
|
The :class:`.SettingNode` class combines a bunch of Settings together.
|
|
@@ -217,7 +219,7 @@ import jinja2
|
|
|
217
219
|
import numpy as np
|
|
218
220
|
|
|
219
221
|
from exa.common.data.base_model import BaseModel
|
|
220
|
-
from exa.common.data.parameter import CollectionType, Parameter, Setting
|
|
222
|
+
from exa.common.data.parameter import CollectionType, Parameter, Setting, SourceType
|
|
221
223
|
from exa.common.errors.exa_error import UnknownSettingError
|
|
222
224
|
from exa.common.qcm_data.chip_topology import sort_components
|
|
223
225
|
|
|
@@ -603,7 +605,7 @@ class SettingNode(BaseModel):
|
|
|
603
605
|
"""
|
|
604
606
|
for key, item in other.settings.items():
|
|
605
607
|
if key in self.settings and (prioritize_other or (self[key].value is None)):
|
|
606
|
-
self.settings[key] = Setting(self.settings[key].parameter, item.value)
|
|
608
|
+
self.settings[key] = Setting(self.settings[key].parameter, item.value, source=self.settings[key].source)
|
|
607
609
|
for key, item in other.subtrees.items():
|
|
608
610
|
if key in self.subtrees:
|
|
609
611
|
self.subtrees[key].merge_values(copy(item), prioritize_other)
|
|
@@ -678,16 +680,22 @@ class SettingNode(BaseModel):
|
|
|
678
680
|
new.subtrees[key] = cls.transform_node_types(subnode)
|
|
679
681
|
return new
|
|
680
682
|
|
|
681
|
-
def set_from_dict(
|
|
683
|
+
def set_from_dict(
|
|
684
|
+
self,
|
|
685
|
+
dct: dict[str, Any],
|
|
686
|
+
strict: bool = False,
|
|
687
|
+
source: SourceType = None,
|
|
688
|
+
) -> None:
|
|
682
689
|
"""Recursively set values to Settings, taking values from a dictionary that has similar tree structure.
|
|
683
|
-
Keys that are not found in self are ignored, unless
|
|
690
|
+
Keys that are not found in self are ignored, unless ``strict`` is True.
|
|
684
691
|
|
|
685
692
|
Args:
|
|
686
693
|
dct: Dictionary containing the new values to use.
|
|
687
|
-
strict: If True, will raise error if
|
|
694
|
+
strict: If True, will raise error if ``dct`` contains a setting that is not found in ``self``.
|
|
695
|
+
source: Source for the settings (this same source is applied to all settings from the dict).
|
|
688
696
|
|
|
689
697
|
Raises:
|
|
690
|
-
UnknownSettingError: If the condition of
|
|
698
|
+
UnknownSettingError: If the condition of ``strict`` happens.
|
|
691
699
|
|
|
692
700
|
"""
|
|
693
701
|
for key, value in dct.items():
|
|
@@ -704,9 +712,10 @@ class SettingNode(BaseModel):
|
|
|
704
712
|
self.settings[key].name,
|
|
705
713
|
self.settings[key].parameter.data_type.cast(value),
|
|
706
714
|
path=self.settings[key].path,
|
|
715
|
+
source=source,
|
|
707
716
|
)
|
|
708
717
|
else:
|
|
709
|
-
self.settings[key] = self.settings[key].update(value)
|
|
718
|
+
self.settings[key] = self.settings[key].update(value, source=source)
|
|
710
719
|
|
|
711
720
|
def setting_with_path_name(self, setting: Setting) -> Setting | None:
|
|
712
721
|
"""Get a copy of a setting with its name replaced with the path name."""
|
|
@@ -858,6 +867,7 @@ class SettingNode(BaseModel):
|
|
|
858
867
|
nodes: Iterable[Setting | Parameter | SettingNode] | dict[str, Setting | Parameter | SettingNode],
|
|
859
868
|
path: str,
|
|
860
869
|
override_values: dict[str, Any] | None = None,
|
|
870
|
+
override_source: SourceType = None,
|
|
861
871
|
) -> None:
|
|
862
872
|
"""Add nodes to ``self`` while creating the missing nodes in-between.
|
|
863
873
|
|
|
@@ -873,6 +883,8 @@ class SettingNode(BaseModel):
|
|
|
873
883
|
found in self, the associated nodes will be created automatically.
|
|
874
884
|
override_values: Optionally override the values for the `Settings` corresponding to ``nodes``. This dict
|
|
875
885
|
should have the same structure as ``nodes``, including matching names.
|
|
886
|
+
override_source: Optionally override the source for the ``Settings`` corresponding to ``nodes``. All the
|
|
887
|
+
settings will then have this same source.
|
|
876
888
|
|
|
877
889
|
"""
|
|
878
890
|
override_values = override_values or {}
|
|
@@ -899,9 +911,10 @@ class SettingNode(BaseModel):
|
|
|
899
911
|
latest_node[key] = node
|
|
900
912
|
else:
|
|
901
913
|
default_value = node.value if isinstance(node, Setting) else None
|
|
914
|
+
source = override_source or (node.source if isinstance(node, Setting) else None)
|
|
902
915
|
parameter = node.parameter if isinstance(node, Setting) else node
|
|
903
916
|
value = override_values.get(node.name) if override_values.get(node.name) is not None else default_value
|
|
904
|
-
latest_node[key] = Setting(parameter, value)
|
|
917
|
+
latest_node[key] = Setting(parameter, value, source=source)
|
|
905
918
|
|
|
906
919
|
def get_default_implementation_name(self, gate: str, locus: str | Iterable[str]) -> str:
|
|
907
920
|
"""Get the default implementation name for a given gate and locus.
|
|
@@ -1034,6 +1047,20 @@ class SettingNode(BaseModel):
|
|
|
1034
1047
|
|
|
1035
1048
|
raise ValueError(f"Locus {locus} cannot be found in the gate properties characterization settings.")
|
|
1036
1049
|
|
|
1050
|
+
def set_source(self, source: SourceType, ignore_nones: bool = True) -> None:
|
|
1051
|
+
"""Set source recursively to all Settings in ``self``.
|
|
1052
|
+
|
|
1053
|
+
Args:
|
|
1054
|
+
source: The source to set.
|
|
1055
|
+
ignore_nones: If ``True``, the source will not be set for Settings with ``None`` value.
|
|
1056
|
+
|
|
1057
|
+
"""
|
|
1058
|
+
for setting in self.settings.values():
|
|
1059
|
+
if not ignore_nones or setting.value is not None:
|
|
1060
|
+
setting._source = source
|
|
1061
|
+
for subtree in self.subtrees.values():
|
|
1062
|
+
subtree.set_source(source, ignore_nones=ignore_nones)
|
|
1063
|
+
|
|
1037
1064
|
def _get_symmetric_loci(self, gate: str, implementation: str, locus: str | Iterable[str]) -> list[str]:
|
|
1038
1065
|
if not isinstance(locus, str):
|
|
1039
1066
|
if self.gate_definitions[gate][implementation].symmetric.value:
|
|
@@ -38,7 +38,7 @@ def add_data_array(ds: xr.Dataset, da: xr.DataArray, name: Hashable | None = Non
|
|
|
38
38
|
"""
|
|
39
39
|
if name is None:
|
|
40
40
|
if da.name is not None:
|
|
41
|
-
name = da.name
|
|
41
|
+
name = da.name # type: ignore[assignment]
|
|
42
42
|
else:
|
|
43
43
|
raise ValueError("No name was given to the dataArray.")
|
|
44
44
|
# Attributes of Dataset coordinates are dropped/replaced when adding a DataArray
|
exa/common/py.typed
ADDED
|
File without changes
|
|
@@ -168,7 +168,7 @@ class CHAD(ImmutableBaseModel):
|
|
|
168
168
|
launchers = {launcher.name: launcher for launcher in self.components.launchers}
|
|
169
169
|
|
|
170
170
|
component: Qubit | Coupler
|
|
171
|
-
for component in [*self.components.qubits, *self.components.couplers]:
|
|
171
|
+
for component in [*self.components.qubits, *self.components.couplers]: # type:ignore[assignment]
|
|
172
172
|
component_type = "qubit" if isinstance(component, Qubit) else "coupler"
|
|
173
173
|
if component.name in component_names:
|
|
174
174
|
for connection in component.connections:
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
|
+
# mypy: ignore-errors
|
|
16
|
+
|
|
15
17
|
"""Chip topology class for parsing CHAD and other QPU related data into human-usable form."""
|
|
16
18
|
|
|
17
19
|
from __future__ import annotations
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: iqm-exa-common
|
|
3
|
-
Version: 26.
|
|
3
|
+
Version: 26.28.0
|
|
4
4
|
Summary: Framework for control and measurement of superconducting qubits: common library
|
|
5
5
|
Author-email: IQM Finland Oy <info@meetiqm.com>
|
|
6
6
|
License: Apache License
|
|
@@ -219,9 +219,12 @@ Requires-Dist: pydantic <3.0,>=2.10.4
|
|
|
219
219
|
Requires-Dist: python-dotenv ==0.21.1
|
|
220
220
|
Requires-Dist: xarray ==2024.10.0
|
|
221
221
|
Requires-Dist: requests ==2.32.3
|
|
222
|
+
Requires-Dist: types-requests
|
|
222
223
|
Requires-Dist: ruamel-yaml ==0.17.32
|
|
223
224
|
Requires-Dist: ruamel-yaml-clib ==0.2.8
|
|
224
225
|
Requires-Dist: jinja2 ==3.0.3
|
|
226
|
+
Requires-Dist: six ==1.16.0
|
|
227
|
+
Requires-Dist: types-six
|
|
225
228
|
|
|
226
229
|
EXA-common
|
|
227
230
|
==========
|
|
@@ -1,57 +1,58 @@
|
|
|
1
1
|
exa/common/__init__.py,sha256=AqxwNht57urLqMxFblY7SgxjzkQYW7pRRUUPS1j1Gck,962
|
|
2
|
+
exa/common/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
3
|
exa/common/api/__init__.py,sha256=PAYujWNG8CtSQX_8U9gnubDh5cwGRhtOfLr0r0xGx3M,587
|
|
3
4
|
exa/common/api/proto_serialization/__init__.py,sha256=Vn2C79OqovFu5wJus9EHsMtK3Of1JLJDcpg2QZKmXsY,1565
|
|
4
|
-
exa/common/api/proto_serialization/_parameter.py,sha256=
|
|
5
|
-
exa/common/api/proto_serialization/array.py,sha256=
|
|
6
|
-
exa/common/api/proto_serialization/datum.py,sha256=
|
|
7
|
-
exa/common/api/proto_serialization/nd_sweep.py,sha256=
|
|
8
|
-
exa/common/api/proto_serialization/sequence.py,sha256=
|
|
9
|
-
exa/common/api/proto_serialization/setting_node.py,sha256=
|
|
5
|
+
exa/common/api/proto_serialization/_parameter.py,sha256=d_LHc_Tl3OqiQmTGe6Y6mkHvQkknzFl5KPEJauPEKPM,3050
|
|
6
|
+
exa/common/api/proto_serialization/array.py,sha256=CvuOV5jNyFAAdqrYsh_z4DeQA6kYvfidW9bEv_M7Ugo,3127
|
|
7
|
+
exa/common/api/proto_serialization/datum.py,sha256=x9PJi3iiqAcG7aMUhBaho6vTNBQsm7pzY0HCFxB_zfM,4915
|
|
8
|
+
exa/common/api/proto_serialization/nd_sweep.py,sha256=5Wi_iz4XqQE9GgSzt3vUTpYKwO5uCPGBa2OqwOMOXcQ,2912
|
|
9
|
+
exa/common/api/proto_serialization/sequence.py,sha256=4yQgdTUenbsY8yNu7JqSQSq2Ushd1zlzuciaqmyP7OY,2568
|
|
10
|
+
exa/common/api/proto_serialization/setting_node.py,sha256=oAlJOmkQTmMSd6wpofoDLz3YIlkiqxX7kY84WnZZ4b4,4073
|
|
10
11
|
exa/common/control/__init__.py,sha256=00T_xV0lL20QZcEt__vWq81N1oGF0KpJMhTitfAI4VI,629
|
|
11
12
|
exa/common/control/sweep/__init__.py,sha256=GzKoQdQsLutcHhmrLPyPrW1n7Cpg766p3OWDHlRpuTs,607
|
|
12
13
|
exa/common/control/sweep/exponential_sweep.py,sha256=OIGqSifkAgQcS2EdffDpIjibB80XteLVF82kS63vPro,2121
|
|
13
14
|
exa/common/control/sweep/fixed_sweep.py,sha256=QXO5lrllHHlhLiA95s8iTE82QkAEzgjJ2dA0flRJLhs,1493
|
|
14
15
|
exa/common/control/sweep/linear_sweep.py,sha256=fX7OuZDYtUSGcAJLsGTVHcCIRkUHkZNLy5YSe_kgb8M,1966
|
|
15
|
-
exa/common/control/sweep/sweep.py,sha256=
|
|
16
|
+
exa/common/control/sweep/sweep.py,sha256=CeCd7-nh0nIlaay4ggMICu61anVxlg3MISGhkK44-VQ,3520
|
|
16
17
|
exa/common/control/sweep/sweep_values.py,sha256=c868qpnh3SP6DYN3eAt0SLaePuzzQwxTWYwnQwL4A-I,2277
|
|
17
18
|
exa/common/control/sweep/option/__init__.py,sha256=Z01JS0FpchMvR8zfWBCs3jcPjh2H8X29YkN0SFxWLTY,906
|
|
18
|
-
exa/common/control/sweep/option/center_span_base_options.py,sha256=
|
|
19
|
+
exa/common/control/sweep/option/center_span_base_options.py,sha256=uHWt4euQVF7EVXJid8wnIXo8PtJnyUdydxxAXPEMnV4,2558
|
|
19
20
|
exa/common/control/sweep/option/center_span_options.py,sha256=WJ9tNaORsnSYojwx5qy3mSoHRmsV2cKMXP6LTRU41Zo,2482
|
|
20
|
-
exa/common/control/sweep/option/constants.py,sha256=
|
|
21
|
+
exa/common/control/sweep/option/constants.py,sha256=pHWOLQicxL-qX0iHQXlhPVNBGHPjvxZ9JBIZQDxEpCY,1405
|
|
21
22
|
exa/common/control/sweep/option/fixed_options.py,sha256=SyGSiEanD3xz4Wcy1rd9r2wj7hNaG3lQYH67WQDc72I,1047
|
|
22
|
-
exa/common/control/sweep/option/option_converter.py,sha256=
|
|
23
|
+
exa/common/control/sweep/option/option_converter.py,sha256=CsiMY8-pnvdLsD7iLHPIkjbLUnfTnhZY8UxEdWuOaN4,3974
|
|
23
24
|
exa/common/control/sweep/option/start_stop_base_options.py,sha256=09P03pexASngGWSSltVh8Ty-BsBmRkQ3iYODsr0ij5I,2145
|
|
24
|
-
exa/common/control/sweep/option/start_stop_options.py,sha256=
|
|
25
|
+
exa/common/control/sweep/option/start_stop_options.py,sha256=vJottC6QX80MhVyg9_R9UFx6W1ijSHOVRzU9fDO3FLA,3113
|
|
25
26
|
exa/common/control/sweep/option/sweep_options.py,sha256=BhKB7RHP0VXJ9iUQKVzeQOM4j_x9AsMhRJgoR3gkiaY,933
|
|
26
27
|
exa/common/data/__init__.py,sha256=F5SRe5QHBTjef4XJVQ63kO5Oxc_AiZnPbV560i7La0Y,644
|
|
27
28
|
exa/common/data/base_model.py,sha256=U508YCtvZabBGnKe1fqUimunmwGulOTM6DOKTUqnYp8,1835
|
|
28
|
-
exa/common/data/parameter.py,sha256=
|
|
29
|
-
exa/common/data/setting_node.py,sha256=
|
|
29
|
+
exa/common/data/parameter.py,sha256=AQxeTvItMjOvT2QUvhKCn9aK5ibrfaN8LI_Oc68ZzII,24420
|
|
30
|
+
exa/common/data/setting_node.py,sha256=yZU8lltzK5qV4L5Xte3AOcG85Tgdg-3mrxCiTpwbW7Q,44548
|
|
30
31
|
exa/common/data/settingnode_v2.html.jinja2,sha256=mo-rlLLmU-Xxf6znJAisispAZK8sbV-2C13byKAtj_Q,3166
|
|
31
32
|
exa/common/data/value.py,sha256=mtMws5UPGx1pCADK6Q2Tx4BwCXznvVRSNQRfcQ3NMmY,1853
|
|
32
33
|
exa/common/errors/__init__.py,sha256=ArMBdpmx1EUenBpzrSNG63kmUf7PM0gCqSYnaCnL9Qk,597
|
|
33
34
|
exa/common/errors/exa_error.py,sha256=iw8ueZgqx1JXkfjRoJfPUsSE7cfhzIWpdDaFuka9Ss0,990
|
|
34
35
|
exa/common/errors/station_control_errors.py,sha256=NEVW9QC-jJM36CQ8b9IIg9hZv5Utph9LXirxk5ZiuNM,4122
|
|
35
36
|
exa/common/helpers/__init__.py,sha256=IgtVD3tojIFA4MTV2mT5uYM6jb2qny9kBIIhEZT2PuI,610
|
|
36
|
-
exa/common/helpers/data_helper.py,sha256
|
|
37
|
+
exa/common/helpers/data_helper.py,sha256=-AP0vwrf7WgyumLsicDtNP2VP5rhG4_oiOZgG4alNb4,2001
|
|
37
38
|
exa/common/helpers/deprecation.py,sha256=nY8484iun63JOBfBeh49Q6VD5xZ4_gT9fjPmH1RAXoI,397
|
|
38
39
|
exa/common/helpers/json_helper.py,sha256=LoTrL6FREML1o0X3Zznf1baI4kn0kh03NE1nqBHgYss,2699
|
|
39
40
|
exa/common/helpers/numpy_helper.py,sha256=KKKyZ_fD0O1gn7_InEQROYnX3WGMA6C1qHh8KzzjtUI,1062
|
|
40
|
-
exa/common/helpers/software_version_helper.py,sha256=
|
|
41
|
+
exa/common/helpers/software_version_helper.py,sha256=BUozde38-7X_NVh0lRY8VR2fvTEPLTz3nyEwSopEJEU,5174
|
|
41
42
|
exa/common/helpers/yaml_helper.py,sha256=wLy-7Nyit597FoWBemduUilYP2VCk_aDDT8y62i3ox8,1626
|
|
42
43
|
exa/common/logger/__init__.py,sha256=1bIsGxHzfujXlkgtcAnWToKMkw3dpU5PEd_7LE_NpgQ,686
|
|
43
44
|
exa/common/logger/logger.py,sha256=0aSjkx4pXy_CCKtspOnFgwMmhZVFAZUlopQ6HUjBMko,5689
|
|
44
45
|
exa/common/qcm_data/__init__.py,sha256=VtsYkGoaniSjCkY0oQlqkcYJCtmC2sTDxfrIe_kpqZg,567
|
|
45
|
-
exa/common/qcm_data/chad_model.py,sha256=
|
|
46
|
-
exa/common/qcm_data/chip_topology.py,sha256
|
|
46
|
+
exa/common/qcm_data/chad_model.py,sha256=s8p9zaQsoo1douqXAuLbAV5hjOCbrhEJFNzi5Yq9y98,11263
|
|
47
|
+
exa/common/qcm_data/chip_topology.py,sha256=-IsWh0hev_vnAWs0z3iWBvProe6LypgKs1Erp8HCb0M,20027
|
|
47
48
|
exa/common/qcm_data/file_adapter.py,sha256=U1XZm_PEswkW7kAztbWFLMufz4mPKPupWbh5yJXdZCI,2263
|
|
48
49
|
exa/common/qcm_data/immutable_base_model.py,sha256=QXmKIWQbsbWQvovXwKT1d9jtyf2LNJtjQquIwO52zOU,901
|
|
49
50
|
exa/common/qcm_data/qcm_data_client.py,sha256=Rze6yQd0xUeH6eUMv3wduYbiDCTP3C4WECtCe7ONmyc,6061
|
|
50
51
|
exa/common/sweep/__init__.py,sha256=uEKk5AtzSgSnf8Y0geRPwUpqXIBIXpeCxsN64sX7F1o,591
|
|
51
52
|
exa/common/sweep/database_serialization.py,sha256=NUu1umxRQZpKtRmw1vNDsSbnofqbHvKFg_xQ2mdhY6k,7469
|
|
52
53
|
exa/common/sweep/util.py,sha256=-QE2AaH-WDkYAVH5-Z-30leLgY0x4efmby4kc1JTCgY,3732
|
|
53
|
-
iqm_exa_common-26.
|
|
54
|
-
iqm_exa_common-26.
|
|
55
|
-
iqm_exa_common-26.
|
|
56
|
-
iqm_exa_common-26.
|
|
57
|
-
iqm_exa_common-26.
|
|
54
|
+
iqm_exa_common-26.28.0.dist-info/LICENSE.txt,sha256=R6Q7eUrLyoCQgWYorQ8WJmVmWKYU3dxA3jYUp0wwQAw,11332
|
|
55
|
+
iqm_exa_common-26.28.0.dist-info/METADATA,sha256=KISV_HQf4F7z7rwX36K7ux-nHUrpqSqZRS72K9YlnA8,14742
|
|
56
|
+
iqm_exa_common-26.28.0.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
57
|
+
iqm_exa_common-26.28.0.dist-info/top_level.txt,sha256=Clphg2toaZ3_jSFRPhjMNEmLurkMNMc4lkK2EFYsSlM,4
|
|
58
|
+
iqm_exa_common-26.28.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|