iqm-exa-common 25.31__py3-none-any.whl → 25.33__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/__init__.py +1 -0
- exa/common/api/model/parameter_model.py +2 -3
- exa/common/api/model/setting_model.py +2 -3
- exa/common/api/model/setting_node_model.py +2 -3
- exa/common/api/model/sweep_model.py +1 -0
- exa/common/api/proto_serialization/_parameter.py +1 -3
- exa/common/api/proto_serialization/array.py +2 -1
- exa/common/api/proto_serialization/datum.py +5 -3
- exa/common/api/proto_serialization/nd_sweep.py +1 -2
- exa/common/api/proto_serialization/sequence.py +7 -6
- exa/common/api/proto_serialization/setting_node.py +3 -2
- exa/common/control/sweep/exponential_sweep.py +2 -0
- exa/common/control/sweep/fixed_sweep.py +1 -0
- exa/common/control/sweep/function_sweep.py +1 -0
- exa/common/control/sweep/linear_sweep.py +2 -0
- exa/common/control/sweep/option/center_span_base_options.py +1 -0
- exa/common/control/sweep/option/center_span_options.py +1 -0
- exa/common/control/sweep/option/constants.py +1 -0
- exa/common/control/sweep/option/fixed_options.py +1 -0
- exa/common/control/sweep/option/option_converter.py +2 -0
- exa/common/control/sweep/option/start_stop_base_options.py +1 -0
- exa/common/control/sweep/option/start_stop_options.py +1 -0
- exa/common/control/sweep/sweep.py +1 -0
- exa/common/data/parameter.py +7 -1
- exa/common/data/setting_node.py +21 -13
- exa/common/errors/exa_error.py +1 -0
- exa/common/helpers/data_helper.py +1 -0
- exa/common/helpers/numpy_helper.py +1 -0
- exa/common/helpers/software_version_helper.py +3 -2
- exa/common/logger/__init__.py +1 -0
- exa/common/logger/logger.py +5 -5
- exa/common/qcm_data/chad_model.py +5 -0
- exa/common/qcm_data/chip_topology.py +21 -6
- exa/common/qcm_data/qcm_data_client.py +3 -1
- exa/common/sweep/database_serialization.py +12 -4
- exa/common/sweep/util.py +3 -0
- {iqm_exa_common-25.31.dist-info → iqm_exa_common-25.33.dist-info}/METADATA +1 -1
- iqm_exa_common-25.33.dist-info/RECORD +59 -0
- iqm_exa_common-25.31.dist-info/RECORD +0 -59
- {iqm_exa_common-25.31.dist-info → iqm_exa_common-25.33.dist-info}/LICENSE.txt +0 -0
- {iqm_exa_common-25.31.dist-info → iqm_exa_common-25.33.dist-info}/WHEEL +0 -0
- {iqm_exa_common-25.31.dist-info → iqm_exa_common-25.33.dist-info}/top_level.txt +0 -0
exa/common/__init__.py
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Pydantic model for Parameter."""
|
|
16
|
+
|
|
16
17
|
from __future__ import annotations
|
|
17
18
|
|
|
18
19
|
from typing import Optional, Tuple
|
|
@@ -23,9 +24,7 @@ from exa.common.data.parameter import CollectionType, DataType, Parameter
|
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
class ParameterModel(BaseModel):
|
|
26
|
-
"""
|
|
27
|
-
Pydantic parameter model
|
|
28
|
-
"""
|
|
27
|
+
"""Pydantic parameter model""" # noqa: D200
|
|
29
28
|
|
|
30
29
|
name: str
|
|
31
30
|
parent_name: Optional[str] = None
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Pydantic model for Setting."""
|
|
16
|
+
|
|
16
17
|
from __future__ import annotations
|
|
17
18
|
|
|
18
19
|
from typing import Any
|
|
@@ -26,9 +27,7 @@ from exa.common.helpers.numpy_helper import coerce_numpy_type_to_native
|
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
class SettingModel(BaseModel):
|
|
29
|
-
"""
|
|
30
|
-
Pydantic setting model
|
|
31
|
-
"""
|
|
30
|
+
"""Pydantic setting model""" # noqa: D200
|
|
32
31
|
|
|
33
32
|
parameter: ParameterModel
|
|
34
33
|
value: Any = None
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Pydantic model for SettingNode."""
|
|
16
|
+
|
|
16
17
|
from __future__ import annotations
|
|
17
18
|
|
|
18
19
|
from typing import Any, Dict
|
|
@@ -24,9 +25,7 @@ from exa.common.data.setting_node import SettingNode
|
|
|
24
25
|
|
|
25
26
|
|
|
26
27
|
class SettingNodeModel(BaseModel):
|
|
27
|
-
"""
|
|
28
|
-
Pydantic setting node model
|
|
29
|
-
"""
|
|
28
|
+
"""Pydantic setting node model""" # noqa: D200
|
|
30
29
|
|
|
31
30
|
name: str
|
|
32
31
|
settings: Dict[str, SettingModel]
|
|
@@ -13,13 +13,11 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Pack and unpack parameters to protos and back."""
|
|
16
|
+
|
|
16
17
|
import iqm.data_definitions.common.v1.parameter_pb2 as ppb
|
|
17
18
|
|
|
18
19
|
from exa.common.data.parameter import CollectionType, DataType, Parameter
|
|
19
20
|
|
|
20
|
-
# pylint: disable=no-member
|
|
21
|
-
|
|
22
|
-
|
|
23
21
|
_COLLECTION_TYPES = {
|
|
24
22
|
CollectionType.SCALAR: ppb.Parameter.CollectionType.COLLECTION_TYPE_SCALAR,
|
|
25
23
|
CollectionType.LIST: ppb.Parameter.CollectionType.COLLECTION_TYPE_SEQUENCE,
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
"""Convert numpy arrays to protos and back."""
|
|
16
16
|
|
|
17
|
-
# pylint: disable=no-member
|
|
18
17
|
import iqm.data_definitions.common.v1.data_types_pb2 as dpb
|
|
19
18
|
import numpy as np
|
|
20
19
|
|
|
@@ -27,6 +26,7 @@ def pack(array: np.ndarray) -> dpb.Array:
|
|
|
27
26
|
|
|
28
27
|
Returns:
|
|
29
28
|
A protobuf instance that encapsulates `array`.
|
|
29
|
+
|
|
30
30
|
"""
|
|
31
31
|
target = dpb.Array()
|
|
32
32
|
target.shape.MergeFrom(array.shape)
|
|
@@ -65,6 +65,7 @@ def unpack(source: dpb.Array) -> np.ndarray:
|
|
|
65
65
|
|
|
66
66
|
Raises:
|
|
67
67
|
ValueError or google.protobuf.message.DecodeError in case of invalid buffer
|
|
68
|
+
|
|
68
69
|
"""
|
|
69
70
|
kind = source.WhichOneof("kind")
|
|
70
71
|
if kind is None:
|
|
@@ -16,12 +16,10 @@
|
|
|
16
16
|
|
|
17
17
|
from typing import Optional, Sequence, Union
|
|
18
18
|
|
|
19
|
-
# pylint: disable=no-member
|
|
20
19
|
import iqm.data_definitions.common.v1.data_types_pb2 as dpb
|
|
21
20
|
import numpy as np
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
import exa.common.api.proto_serialization.sequence as sequence
|
|
22
|
+
from exa.common.api.proto_serialization import array, sequence
|
|
25
23
|
|
|
26
24
|
|
|
27
25
|
def pack(value: Union[None, bool, str, int, float, complex, np.ndarray, Sequence]) -> dpb.Datum:
|
|
@@ -43,6 +41,7 @@ def pack(value: Union[None, bool, str, int, float, complex, np.ndarray, Sequence
|
|
|
43
41
|
|
|
44
42
|
Raises:
|
|
45
43
|
TypeError in case of unsupported type.
|
|
44
|
+
|
|
46
45
|
"""
|
|
47
46
|
if isinstance(value, np.number):
|
|
48
47
|
raise TypeError(
|
|
@@ -78,6 +77,7 @@ def unpack(source: dpb.Datum) -> Union[None, str, bool, int, float, complex, np.
|
|
|
78
77
|
|
|
79
78
|
Raises:
|
|
80
79
|
TypeError or google.protobuf.message.DecodeError in case of invalid buffer
|
|
80
|
+
|
|
81
81
|
"""
|
|
82
82
|
field_name = source.WhichOneof("kind")
|
|
83
83
|
if field_name == "null_value":
|
|
@@ -107,6 +107,7 @@ def serialize(value: Union[None, bool, str, int, float, complex, np.ndarray, Seq
|
|
|
107
107
|
|
|
108
108
|
Returns:
|
|
109
109
|
Bitstring that encodes `value`.
|
|
110
|
+
|
|
110
111
|
"""
|
|
111
112
|
return pack(value).SerializeToString()
|
|
112
113
|
|
|
@@ -119,6 +120,7 @@ def deserialize(source: bytes) -> Union[None, str, bool, int, float, complex, np
|
|
|
119
120
|
|
|
120
121
|
Returns:
|
|
121
122
|
Deserialized data.
|
|
123
|
+
|
|
122
124
|
"""
|
|
123
125
|
proto = dpb.Datum()
|
|
124
126
|
proto.ParseFromString(source)
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Convert NdSweeps to protos and back."""
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
import iqm.data_definitions.common.v1.sweep_pb2 as spb
|
|
18
18
|
|
|
19
19
|
from exa.common.api.proto_serialization import sequence
|
|
@@ -45,7 +45,6 @@ def unpack(proto: spb.CartesianSweep) -> NdSweep:
|
|
|
45
45
|
|
|
46
46
|
Note: All sweeps will be of type :class:`.FixedSweep`.
|
|
47
47
|
"""
|
|
48
|
-
|
|
49
48
|
nd_sweep = []
|
|
50
49
|
for parallel_proto in reversed(proto.parallel_sweeps):
|
|
51
50
|
parallel = tuple(_unpack_single_sweep(sweep) for sweep in parallel_proto.single_parameter_sweeps)
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
|
|
17
17
|
from typing import Sequence
|
|
18
18
|
|
|
19
|
-
# pylint: disable=no-member
|
|
20
19
|
import iqm.data_definitions.common.v1.data_types_pb2 as dpb
|
|
21
20
|
import numpy as np
|
|
22
21
|
|
|
@@ -32,23 +31,24 @@ def pack(values: Sequence) -> dpb.Sequence:
|
|
|
32
31
|
|
|
33
32
|
Raises:
|
|
34
33
|
ValueError in case of unsupported value.
|
|
34
|
+
|
|
35
35
|
"""
|
|
36
36
|
target = dpb.Sequence()
|
|
37
37
|
if not values:
|
|
38
38
|
return target
|
|
39
39
|
dtype = type(values[0])
|
|
40
|
-
if dtype == complex:
|
|
40
|
+
if dtype == complex: # noqa: E721
|
|
41
41
|
target_field = target.complex128_array
|
|
42
42
|
target_field.real.MergeFrom(np.real(values))
|
|
43
43
|
target_field.imag.MergeFrom(np.imag(values))
|
|
44
44
|
return target
|
|
45
|
-
if dtype == bool:
|
|
45
|
+
if dtype == bool: # noqa: E721
|
|
46
46
|
target_field = target.bool_array
|
|
47
|
-
elif dtype == int:
|
|
47
|
+
elif dtype == int: # noqa: E721
|
|
48
48
|
target_field = target.int64_array
|
|
49
|
-
elif dtype == float:
|
|
49
|
+
elif dtype == float: # noqa: E721
|
|
50
50
|
target_field = target.float64_array
|
|
51
|
-
elif dtype == str:
|
|
51
|
+
elif dtype == str: # noqa: E721
|
|
52
52
|
target_field = target.string_array
|
|
53
53
|
else:
|
|
54
54
|
raise TypeError(f"Unsupported numpy array type {dtype} for a sequence.")
|
|
@@ -68,6 +68,7 @@ def unpack(source: dpb.Sequence) -> list:
|
|
|
68
68
|
|
|
69
69
|
Raises:
|
|
70
70
|
ValueError or google.protobuf.message.DecodeError in case of invalid buffer
|
|
71
|
+
|
|
71
72
|
"""
|
|
72
73
|
kind = source.WhichOneof("kind")
|
|
73
74
|
if kind is None:
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Convert SettingNodes to protos and back."""
|
|
16
|
+
|
|
16
17
|
import iqm.data_definitions.common.v1.setting_pb2 as spb
|
|
17
18
|
|
|
18
19
|
from exa.common.api.proto_serialization import datum
|
|
@@ -21,8 +22,6 @@ from exa.common.data.parameter import DataType, Parameter
|
|
|
21
22
|
from exa.common.data.setting_node import Setting, SettingNode
|
|
22
23
|
from exa.common.helpers.numpy_helper import coerce_numpy_type_to_native
|
|
23
24
|
|
|
24
|
-
# pylint: disable=no-member
|
|
25
|
-
|
|
26
25
|
|
|
27
26
|
def _pack_setting(setting: Setting, optimize: bool) -> spb.SettingNode.Setting:
|
|
28
27
|
"""Convert a Setting into protobuf representation."""
|
|
@@ -66,6 +65,7 @@ def pack(node: SettingNode, minimal: bool) -> spb.SettingNode:
|
|
|
66
65
|
|
|
67
66
|
Returns:
|
|
68
67
|
Protobuf instance that represents `node`.
|
|
68
|
+
|
|
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}
|
|
@@ -81,6 +81,7 @@ def unpack(proto: spb.SettingNode) -> SettingNode:
|
|
|
81
81
|
Returns:
|
|
82
82
|
Unpacked SettingNode. In case `proto` only contains the parameter names (see ``optimize`` in
|
|
83
83
|
:func:`.pack`), dummy Parameters are generated.
|
|
84
|
+
|
|
84
85
|
"""
|
|
85
86
|
settings = {key: _unpack_setting(content) for key, content in proto.settings.items()}
|
|
86
87
|
nodes = {key: unpack(content) for key, content in proto.subnodes.items()}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Sweep specification with exponentially spaced values."""
|
|
16
|
+
|
|
16
17
|
from dataclasses import dataclass, field
|
|
17
18
|
import logging
|
|
18
19
|
import math
|
|
@@ -37,6 +38,7 @@ class ExponentialSweep(Sweep):
|
|
|
37
38
|
|
|
38
39
|
Raises:
|
|
39
40
|
ValueError: Error is raised if `options` is inconsistent.
|
|
41
|
+
|
|
40
42
|
"""
|
|
41
43
|
|
|
42
44
|
logger: logging.Logger = field(init=False)
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Sweep specification with linearly spaced values."""
|
|
16
|
+
|
|
16
17
|
from dataclasses import dataclass
|
|
17
18
|
import math
|
|
18
19
|
from typing import Union
|
|
@@ -34,6 +35,7 @@ class LinearSweep(Sweep):
|
|
|
34
35
|
|
|
35
36
|
Raises:
|
|
36
37
|
ValueError: Error is raised if `options` is inconsistent.
|
|
38
|
+
|
|
37
39
|
"""
|
|
38
40
|
|
|
39
41
|
def __post_init__(self):
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Helper to create a SweepOptions instance from a dict."""
|
|
16
|
+
|
|
16
17
|
import ast
|
|
17
18
|
from typing import Any, Dict, List
|
|
18
19
|
|
|
@@ -45,6 +46,7 @@ def convert_to_options(config: Dict[str, Any]) -> SweepOptions:
|
|
|
45
46
|
|
|
46
47
|
Raises:
|
|
47
48
|
ValueError: Error is raised if config has unsupported structure
|
|
49
|
+
|
|
48
50
|
"""
|
|
49
51
|
config = {k.lower(): v for k, v in config.items()}
|
|
50
52
|
if {OPTIONS_TYPE.get("start"), OPTIONS_TYPE.get("stop")}.issubset(set(config)):
|
exa/common/data/parameter.py
CHANGED
|
@@ -54,6 +54,7 @@ parameter.
|
|
|
54
54
|
True
|
|
55
55
|
|
|
56
56
|
"""
|
|
57
|
+
|
|
57
58
|
from __future__ import annotations
|
|
58
59
|
|
|
59
60
|
import ast
|
|
@@ -250,11 +251,12 @@ class Parameter:
|
|
|
250
251
|
``variables = [(par_x: [1,2,3])], extra_variables=[('y', 2)]`` yields the same 3-by-2 data. ``'y'`` will then be
|
|
251
252
|
a "dimension without coordinate" in xarray terms.
|
|
252
253
|
|
|
253
|
-
|
|
254
|
+
Args:
|
|
254
255
|
variables: Coordinates of the set.
|
|
255
256
|
data: Data Parameter and associated data as a possible nested list.
|
|
256
257
|
attributes: metadata to attach to the whole Dataset.
|
|
257
258
|
extra_variables: Valueless dimensions and their sizes.
|
|
259
|
+
|
|
258
260
|
"""
|
|
259
261
|
variable_names = []
|
|
260
262
|
variable_sizes = []
|
|
@@ -321,6 +323,7 @@ class Parameter:
|
|
|
321
323
|
|
|
322
324
|
Returns:
|
|
323
325
|
corresponding DataArray
|
|
326
|
+
|
|
324
327
|
"""
|
|
325
328
|
if dimensions is None:
|
|
326
329
|
if len(data.shape) == 1:
|
|
@@ -356,6 +359,7 @@ class Parameter:
|
|
|
356
359
|
|
|
357
360
|
Raises:
|
|
358
361
|
InvalidParameterValueError: If ``self`` is not collection-valued.
|
|
362
|
+
|
|
359
363
|
"""
|
|
360
364
|
if self.collection_type is CollectionType.SCALAR:
|
|
361
365
|
raise InvalidParameterValueError(
|
|
@@ -458,6 +462,7 @@ class Setting:
|
|
|
458
462
|
Returns:
|
|
459
463
|
A new set of Settings whose parameters are only found in `first`, and Settings in `first` whose
|
|
460
464
|
values differ from their counterparts in `second`.
|
|
465
|
+
|
|
461
466
|
"""
|
|
462
467
|
diff = first.difference(second)
|
|
463
468
|
for s in first.intersection(second):
|
|
@@ -492,6 +497,7 @@ class Setting:
|
|
|
492
497
|
|
|
493
498
|
Raises:
|
|
494
499
|
ValueError: If ``self`` is not collection-valued.
|
|
500
|
+
|
|
495
501
|
"""
|
|
496
502
|
return self.parameter.create_element_parameter_for(indices)
|
|
497
503
|
|
exa/common/data/setting_node.py
CHANGED
|
@@ -173,6 +173,7 @@ flag is used.
|
|
|
173
173
|
|
|
174
174
|
|
|
175
175
|
"""
|
|
176
|
+
|
|
176
177
|
from __future__ import annotations
|
|
177
178
|
|
|
178
179
|
from collections.abc import Generator, ItemsView, Iterator
|
|
@@ -217,6 +218,7 @@ class SettingNode:
|
|
|
217
218
|
children: The children given as keyword arguments. Each argument must be a :class:`.Setting`,
|
|
218
219
|
:class:`.Parameter`, or a :class:`SettingNode`. The keywords are used as the names of the nodes.
|
|
219
220
|
Parameters will be cast into Settings with the value ``None``.
|
|
221
|
+
|
|
220
222
|
"""
|
|
221
223
|
|
|
222
224
|
def __init__(self, name: str, **children):
|
|
@@ -313,6 +315,7 @@ class SettingNode:
|
|
|
313
315
|
|
|
314
316
|
Returns:
|
|
315
317
|
Iterator that yields the filtered nodes.
|
|
318
|
+
|
|
316
319
|
"""
|
|
317
320
|
node_types = node_types or (Setting, SettingNode)
|
|
318
321
|
iterable = self if recursive else self.children.values()
|
|
@@ -328,6 +331,7 @@ class SettingNode:
|
|
|
328
331
|
|
|
329
332
|
Raises:
|
|
330
333
|
UnknownSettingError: If no setting is found in the children of this tree.
|
|
334
|
+
|
|
331
335
|
"""
|
|
332
336
|
|
|
333
337
|
def list_assign(value, array, indices_list) -> None:
|
|
@@ -342,12 +346,11 @@ class SettingNode:
|
|
|
342
346
|
if item.name == setting.name:
|
|
343
347
|
branch[key] = setting.value
|
|
344
348
|
return
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
return
|
|
349
|
+
elif isinstance(item, Setting) and item.name == setting.parent_name and item.element_indices is None:
|
|
350
|
+
parent_value = item.value.copy()
|
|
351
|
+
list_assign(setting.value, parent_value, setting.element_indices)
|
|
352
|
+
branch[key] = parent_value
|
|
353
|
+
return
|
|
351
354
|
raise UnknownSettingError(
|
|
352
355
|
f'No Setting with name {setting.name} was found in {self.__class__.__name__} "{self.name}".'
|
|
353
356
|
)
|
|
@@ -384,6 +387,7 @@ class SettingNode:
|
|
|
384
387
|
|
|
385
388
|
Returns:
|
|
386
389
|
A SettingNode that has a child `name`.
|
|
390
|
+
|
|
387
391
|
"""
|
|
388
392
|
for branch in self.nodes_by_type(SettingNode, recursive=True):
|
|
389
393
|
for setting in branch.children.values():
|
|
@@ -399,6 +403,7 @@ class SettingNode:
|
|
|
399
403
|
|
|
400
404
|
Returns:
|
|
401
405
|
First found item, or None if nothing is found.
|
|
406
|
+
|
|
402
407
|
"""
|
|
403
408
|
return next((item for item in self if item.name == name), None)
|
|
404
409
|
|
|
@@ -415,6 +420,7 @@ class SettingNode:
|
|
|
415
420
|
|
|
416
421
|
Returns:
|
|
417
422
|
A new SettingNode constructed from arguments.
|
|
423
|
+
|
|
418
424
|
"""
|
|
419
425
|
new = second.copy()
|
|
420
426
|
for key, item in first._settings.items():
|
|
@@ -462,12 +468,13 @@ class SettingNode:
|
|
|
462
468
|
|
|
463
469
|
Args:
|
|
464
470
|
levels: display this many levels, starting from the root.
|
|
471
|
+
|
|
465
472
|
"""
|
|
466
473
|
|
|
467
|
-
def append_lines(key: str, node: SettingNode, lines: List[str], indents: List[bool]):
|
|
474
|
+
def append_lines(key: str, node: SettingNode, lines: List[str], indents: List[bool]): # noqa: F821
|
|
468
475
|
indent = "".join([" ║ " if i else " " for i in indents])
|
|
469
476
|
if len(indents) < levels:
|
|
470
|
-
for key, setting in node._settings.items():
|
|
477
|
+
for key, setting in node._settings.items(): # noqa: PLR1704
|
|
471
478
|
if setting.value is None:
|
|
472
479
|
value = "None (automatic/unspecified)"
|
|
473
480
|
elif setting.parameter.collection_type == CollectionType.NDARRAY:
|
|
@@ -509,6 +516,7 @@ class SettingNode:
|
|
|
509
516
|
|
|
510
517
|
Return:
|
|
511
518
|
A new SettingNode with the same structure as the original, but where node instances are of type `cls`.
|
|
519
|
+
|
|
512
520
|
"""
|
|
513
521
|
new = cls(name=node.name, **node._settings)
|
|
514
522
|
for key, subnode in node._subtrees.items():
|
|
@@ -525,6 +533,7 @@ class SettingNode:
|
|
|
525
533
|
|
|
526
534
|
Raises:
|
|
527
535
|
UnknownSettingError: If the condition of `strict` happens.
|
|
536
|
+
|
|
528
537
|
"""
|
|
529
538
|
for key, value in dct.items():
|
|
530
539
|
if key not in self.children:
|
|
@@ -536,7 +545,7 @@ class SettingNode:
|
|
|
536
545
|
if isinstance(value, dict) and isinstance(self[key], SettingNode):
|
|
537
546
|
self[key].set_from_dict(value)
|
|
538
547
|
else:
|
|
539
|
-
self[key] = self[key].parameter.data_type.cast(value) if type(value) == str else value
|
|
548
|
+
self[key] = self[key].parameter.data_type.cast(value) if type(value) == str else value # noqa: E721
|
|
540
549
|
|
|
541
550
|
def setting_with_path_name(self, setting: Setting) -> Setting:
|
|
542
551
|
"""Get Setting from ``self`` where the name of the parameter is replaced with its path in ``self``.
|
|
@@ -553,6 +562,7 @@ class SettingNode:
|
|
|
553
562
|
|
|
554
563
|
Raises:
|
|
555
564
|
UnknownSettingError: If ``name`` is not found within ``self``.
|
|
565
|
+
|
|
556
566
|
"""
|
|
557
567
|
|
|
558
568
|
def _search(settings: SettingNode, name: str, prefix: str) -> tuple[str, Setting] | tuple[None, None]:
|
|
@@ -566,7 +576,7 @@ class SettingNode:
|
|
|
566
576
|
|
|
567
577
|
path, found_setting = _search(self, setting, "")
|
|
568
578
|
if path is None:
|
|
569
|
-
raise UnknownSettingError(f'{name} not found inside {self.__class__.__name__} "{self.name}".')
|
|
579
|
+
raise UnknownSettingError(f'{name} not found inside {self.__class__.__name__} "{self.name}".') # noqa: F821
|
|
570
580
|
param = found_setting.parameter
|
|
571
581
|
return Setting(
|
|
572
582
|
Parameter(
|
|
@@ -593,12 +603,11 @@ class SettingNode:
|
|
|
593
603
|
|
|
594
604
|
Returns:
|
|
595
605
|
differences from ``self`` to ``other``, in depth-first order
|
|
606
|
+
|
|
596
607
|
"""
|
|
597
608
|
|
|
598
|
-
# pylint: disable=too-many-branches
|
|
599
609
|
def diff_settings(x: Setting, y: Setting, key: str) -> str:
|
|
600
610
|
"""Compare two settings, return the differences."""
|
|
601
|
-
|
|
602
611
|
line = f"{key}:"
|
|
603
612
|
|
|
604
613
|
def compare(x: Any, y: Any, tag: str) -> None:
|
|
@@ -669,7 +678,6 @@ class SettingNode:
|
|
|
669
678
|
|
|
670
679
|
Unit must be a whitelisted SI base unit.
|
|
671
680
|
"""
|
|
672
|
-
|
|
673
681
|
if not isinstance(val, numbers.Real):
|
|
674
682
|
return val, unit
|
|
675
683
|
if unit not in {"Hz", "rad", "s", "V"}:
|
exa/common/errors/exa_error.py
CHANGED
|
@@ -44,8 +44,7 @@ def get_all_software_versions(reload_module: bool = False) -> dict[str, str]:
|
|
|
44
44
|
it is disabled because reloading the module is not thread safe!
|
|
45
45
|
This function should be called with ``reload_module=True`` when IPython autoreload is in use.
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
Example:
|
|
49
48
|
1. You have numpy==1.21.0 installed, and in the notebook you have executed the following IPython magic:
|
|
50
49
|
|
|
51
50
|
.. code-block:: python
|
|
@@ -64,6 +63,7 @@ def get_all_software_versions(reload_module: bool = False) -> dict[str, str]:
|
|
|
64
63
|
Returns: All software components in a dictionary that maps each package name to its version
|
|
65
64
|
information. A package's version information contains the base version, and the string
|
|
66
65
|
"(local editable)" in the case the package is a local editable installation.
|
|
66
|
+
|
|
67
67
|
"""
|
|
68
68
|
python_version = platform.python_version()
|
|
69
69
|
software_versions = {"python": python_version}
|
|
@@ -98,6 +98,7 @@ def get_vcs_description(root_directory: str) -> Optional[str]:
|
|
|
98
98
|
|
|
99
99
|
Raises:
|
|
100
100
|
If the command fails or timeouts, an exception will be raised directly from ``subprocess.check_output``.
|
|
101
|
+
|
|
101
102
|
"""
|
|
102
103
|
# TODO does not seem very robust, consider using the full version number (e.g. 17.0.post1.dev9+g4748363.d20221003)
|
|
103
104
|
# provided by setuptools_scm and accessed using importlib.metadata.version instead, if
|
exa/common/logger/__init__.py
CHANGED
exa/common/logger/logger.py
CHANGED
|
@@ -19,7 +19,7 @@ from typing import Any, Callable, Optional
|
|
|
19
19
|
BRIEF_DATEFMT = "%m-%d %H:%M:%S"
|
|
20
20
|
|
|
21
21
|
BRIEF = "[{asctime};{levelname:.1}{extra_info}] {message}"
|
|
22
|
-
VERBOSE = "[{asctime};{levelname};{processName}({process});{threadName}({thread});{name};{filename}:{lineno}:{funcName}{extra_info}] {message}" # pylint:disable=line-too-long
|
|
22
|
+
VERBOSE = "[{asctime};{levelname};{processName}({process});{threadName}({thread});{name};{filename}:{lineno}:{funcName}{extra_info}] {message}" # pylint:disable=line-too-long # noqa: E501
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class ExtraFormatter(logging.Formatter):
|
|
@@ -71,6 +71,7 @@ def init_loggers(
|
|
|
71
71
|
verbose: If False, :const:``BRIEF`` format will be used for log messages, otherwise :const:``VERBOSE``.
|
|
72
72
|
extra_info_getter: Optional callable to convey extra information to log messages. It will get called before
|
|
73
73
|
each log message emission and the output will get appended to the log message.
|
|
74
|
+
|
|
74
75
|
"""
|
|
75
76
|
loggers = loggers or {}
|
|
76
77
|
|
|
@@ -78,13 +79,12 @@ def init_loggers(
|
|
|
78
79
|
loggers_config: dict[str, Any] = {}
|
|
79
80
|
for logger_name, level in loggers.items():
|
|
80
81
|
if not level:
|
|
81
|
-
level = default_level
|
|
82
|
-
level = level.upper()
|
|
82
|
+
level = default_level # noqa: PLW2901
|
|
83
|
+
level = level.upper() # noqa: PLW2901
|
|
83
84
|
level_num = logging.getLevelName(level)
|
|
84
85
|
if not isinstance(level_num, int):
|
|
85
86
|
raise ValueError(f"Logger name '{logger_name}' has an incorrect level value '{level}'.")
|
|
86
|
-
|
|
87
|
-
lowest_level_num = level_num
|
|
87
|
+
lowest_level_num = min(level_num, lowest_level_num)
|
|
88
88
|
loggers_config[logger_name] = {
|
|
89
89
|
"level": level,
|
|
90
90
|
"handlers": ["stdout", "stderr"],
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Pydantic models for CHAD."""
|
|
16
|
+
|
|
16
17
|
from collections.abc import Collection
|
|
17
18
|
from functools import cached_property
|
|
18
19
|
import re
|
|
@@ -150,6 +151,7 @@ class CHAD(ImmutableBaseModel):
|
|
|
150
151
|
- Tuple of qubits and couplers mapped to their connected default operations.
|
|
151
152
|
The data is in the form of a dict with the keys being `readout`, `drive`, and `flux`,
|
|
152
153
|
and the values the list of component names having that particular operation.
|
|
154
|
+
|
|
153
155
|
"""
|
|
154
156
|
self._validate_input(component_names)
|
|
155
157
|
|
|
@@ -190,6 +192,7 @@ class CHAD(ImmutableBaseModel):
|
|
|
190
192
|
|
|
191
193
|
Raises:
|
|
192
194
|
- ValueError: If the provided qubit name list contains duplicates.
|
|
195
|
+
|
|
193
196
|
"""
|
|
194
197
|
self._validate_input(component_names)
|
|
195
198
|
|
|
@@ -208,6 +211,7 @@ class CHAD(ImmutableBaseModel):
|
|
|
208
211
|
|
|
209
212
|
Args:
|
|
210
213
|
component_names: The qubit names. May contain any number of qubits.
|
|
214
|
+
|
|
211
215
|
"""
|
|
212
216
|
self._validate_input(component_names)
|
|
213
217
|
|
|
@@ -235,6 +239,7 @@ class CHAD(ImmutableBaseModel):
|
|
|
235
239
|
Raises:
|
|
236
240
|
- ValueError: If there were no couplers or more than one coupler connecting the component pair (the latter
|
|
237
241
|
should not be possible in a realistic chip).
|
|
242
|
+
|
|
238
243
|
"""
|
|
239
244
|
coupler_mapping = self.get_coupler_mapping_for([first_component, second_component])
|
|
240
245
|
common_couplers = [
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""Chip topology class for parsing CHAD and other QPU related data into human-usable form."""
|
|
16
|
+
|
|
16
17
|
from __future__ import annotations
|
|
17
18
|
|
|
18
19
|
from collections.abc import Collection, Iterable
|
|
@@ -65,9 +66,9 @@ class ChipTopology:
|
|
|
65
66
|
couplers: mapping from coupler name to names of chip components it connects to.
|
|
66
67
|
probe_lines: mapping from probe line name to names of chip components it connects to.
|
|
67
68
|
variant: identifier of the QPU design variant.
|
|
69
|
+
|
|
68
70
|
"""
|
|
69
71
|
|
|
70
|
-
# pylint: disable=too-many-instance-attributes
|
|
71
72
|
def __init__(
|
|
72
73
|
self,
|
|
73
74
|
qubits: Iterable[str],
|
|
@@ -143,8 +144,10 @@ class ChipTopology:
|
|
|
143
144
|
|
|
144
145
|
Args:
|
|
145
146
|
record: Record as returned by Station control.
|
|
147
|
+
|
|
146
148
|
Returns:
|
|
147
149
|
Corresponding chip topology
|
|
150
|
+
|
|
148
151
|
"""
|
|
149
152
|
return cls.from_chad(CHAD(**record))
|
|
150
153
|
|
|
@@ -156,6 +159,7 @@ class ChipTopology:
|
|
|
156
159
|
chad: parsed CHAD model
|
|
157
160
|
Returns:
|
|
158
161
|
corresponding chip topology
|
|
162
|
+
|
|
159
163
|
"""
|
|
160
164
|
qubits = chad.qubit_names
|
|
161
165
|
computational_resonators = chad.computational_resonator_names
|
|
@@ -178,6 +182,7 @@ class ChipTopology:
|
|
|
178
182
|
components: some chip components, typically qubits and computational resonators
|
|
179
183
|
Returns:
|
|
180
184
|
couplers that connect to at least one of ``components``
|
|
185
|
+
|
|
181
186
|
"""
|
|
182
187
|
couplers: set[str] = set()
|
|
183
188
|
for component in components:
|
|
@@ -195,6 +200,7 @@ class ChipTopology:
|
|
|
195
200
|
components: some chip components, typically qubits and computational resonators
|
|
196
201
|
Returns:
|
|
197
202
|
couplers that connect to only members of ``components``, and to at least two of them
|
|
203
|
+
|
|
198
204
|
"""
|
|
199
205
|
connecting_couplers = set()
|
|
200
206
|
for coupler in self.get_neighbor_couplers(components):
|
|
@@ -213,6 +219,7 @@ class ChipTopology:
|
|
|
213
219
|
the common coupler
|
|
214
220
|
Raises:
|
|
215
221
|
ValueError: the given components have zero or more than one connecting coupler
|
|
222
|
+
|
|
216
223
|
"""
|
|
217
224
|
connecting_couplers = self.get_connecting_couplers((component_1, component_2))
|
|
218
225
|
if (n_couplers := len(connecting_couplers)) != 1:
|
|
@@ -226,6 +233,7 @@ class ChipTopology:
|
|
|
226
233
|
components: some chip components, typically qubits and computational resonators
|
|
227
234
|
Returns:
|
|
228
235
|
components that are connected to ``components`` by a coupler, but not included in them
|
|
236
|
+
|
|
229
237
|
"""
|
|
230
238
|
neighbor_components = set()
|
|
231
239
|
for coupler in self.get_neighbor_couplers(components):
|
|
@@ -248,6 +256,7 @@ class ChipTopology:
|
|
|
248
256
|
|
|
249
257
|
Returns:
|
|
250
258
|
The input dictionary, but only with key-value pairs where the value intersects with `limit_to`.
|
|
259
|
+
|
|
251
260
|
"""
|
|
252
261
|
return {key: values for key, values in dct.items() if any(v in limit_to for v in values)}
|
|
253
262
|
|
|
@@ -283,7 +292,8 @@ class ChipTopology:
|
|
|
283
292
|
name: The name for the gate & implementation this locus mapping represents (typically in the format
|
|
284
293
|
``"<gate name>.<implementation name>"``).
|
|
285
294
|
mapping: The locus mapping to be added.
|
|
286
|
-
|
|
295
|
+
|
|
296
|
+
""" # noqa: E501
|
|
287
297
|
self._validate_locus_mapping(mapping)
|
|
288
298
|
self._locus_mappings[name] = mapping
|
|
289
299
|
|
|
@@ -311,6 +321,7 @@ class ChipTopology:
|
|
|
311
321
|
|
|
312
322
|
Returns:
|
|
313
323
|
The components mapped to the given locus or `None` if locus is not found in the given mapping.
|
|
324
|
+
|
|
314
325
|
"""
|
|
315
326
|
if not name:
|
|
316
327
|
if len(locus) == 1:
|
|
@@ -331,6 +342,7 @@ class ChipTopology:
|
|
|
331
342
|
|
|
332
343
|
Returns:
|
|
333
344
|
The locus mapped to the given components or `None` if the components are not mapped to any locus.
|
|
345
|
+
|
|
334
346
|
"""
|
|
335
347
|
if name not in self._locus_mappings:
|
|
336
348
|
return None
|
|
@@ -353,6 +365,7 @@ class ChipTopology:
|
|
|
353
365
|
|
|
354
366
|
Returns:
|
|
355
367
|
The loci associated with the given gate.
|
|
368
|
+
|
|
356
369
|
"""
|
|
357
370
|
if name not in self._locus_mappings:
|
|
358
371
|
if default_mapping_dimension == 1:
|
|
@@ -365,19 +378,20 @@ class ChipTopology:
|
|
|
365
378
|
"""Convenience method for getting the name of a computational resonator which is connected to both specified
|
|
366
379
|
qubit components via tunable couplers.
|
|
367
380
|
|
|
368
|
-
|
|
381
|
+
Args:
|
|
369
382
|
first_qubit: The name of the first qubit.
|
|
370
383
|
second_qubit: The name of the second qubit.
|
|
371
384
|
The order of qubits does not matter, i.e. the `first_qubit` and `second_qubit` arguments are interchangeable.
|
|
372
385
|
|
|
373
|
-
|
|
386
|
+
Returns:
|
|
374
387
|
- The name of the computational resonator that is connected to both inputted qubits via tunable couplers.
|
|
375
388
|
|
|
376
|
-
|
|
389
|
+
Raises:
|
|
377
390
|
- ValueError: If no computational resonator was found that is connected to both qubits via tunable
|
|
378
391
|
couplers.
|
|
392
|
+
|
|
379
393
|
"""
|
|
380
|
-
neighbor_components = list(self.get_neighbor_locus_components([first_qubit, second_qubit]))
|
|
394
|
+
neighbor_components = list(self.get_neighbor_locus_components([first_qubit, second_qubit])) # noqa: F841
|
|
381
395
|
|
|
382
396
|
resonators = [
|
|
383
397
|
r
|
|
@@ -420,6 +434,7 @@ class ChipTopology:
|
|
|
420
434
|
|
|
421
435
|
Returns:
|
|
422
436
|
Names of the computational resonators neighboring all of ``qubits`` (can be an empty set).
|
|
437
|
+
|
|
423
438
|
"""
|
|
424
439
|
if not qubits:
|
|
425
440
|
return set()
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
|
|
15
15
|
"""QCM (Quantum Computer Management) Data API client implementation."""
|
|
16
|
+
|
|
16
17
|
from collections.abc import Callable
|
|
17
18
|
from functools import cache
|
|
18
19
|
import json
|
|
@@ -42,6 +43,7 @@ class QCMDataClient:
|
|
|
42
43
|
For example, CHAD files should be named {chip_label}.json, like M156_W531_A09_L09.json, and contain
|
|
43
44
|
a list instead of a single object.
|
|
44
45
|
fallback_root_url: Same as `root_url`, used if a query via `root_url` returns nothing.
|
|
46
|
+
|
|
45
47
|
"""
|
|
46
48
|
|
|
47
49
|
def __init__(self, root_url: str, fallback_root_url: str = ""):
|
|
@@ -73,7 +75,6 @@ class QCMDataClient:
|
|
|
73
75
|
Cache for :func:`get_chad` has to be reset when the URL changes.
|
|
74
76
|
"""
|
|
75
77
|
if self._root_url != root_url:
|
|
76
|
-
# pylint: disable=no-member
|
|
77
78
|
self._root_url = root_url
|
|
78
79
|
|
|
79
80
|
def get_chip_design_record(self, chip_label: str) -> dict:
|
|
@@ -84,6 +85,7 @@ class QCMDataClient:
|
|
|
84
85
|
|
|
85
86
|
Returns:
|
|
86
87
|
Data record matching the given chip label.
|
|
88
|
+
|
|
87
89
|
"""
|
|
88
90
|
url_tail = f"/cheddars/{chip_label}?target=in-house"
|
|
89
91
|
try:
|
|
@@ -39,6 +39,7 @@ def encode_nd_sweeps(sweeps: NdSweep, **kwargs) -> str:
|
|
|
39
39
|
|
|
40
40
|
Returns:
|
|
41
41
|
json as a string
|
|
42
|
+
|
|
42
43
|
"""
|
|
43
44
|
kwargs.setdefault("cls", _SweepDataEncoder)
|
|
44
45
|
return json.dumps(sweeps, **kwargs)
|
|
@@ -53,6 +54,7 @@ def encode_return_parameters_legacy(return_parameters: dict[Parameter, Optional[
|
|
|
53
54
|
|
|
54
55
|
Returns:
|
|
55
56
|
json as a string
|
|
57
|
+
|
|
56
58
|
"""
|
|
57
59
|
kwargs.setdefault("cls", _SweepDataEncoder)
|
|
58
60
|
return json.dumps(return_parameters, **kwargs)
|
|
@@ -67,6 +69,7 @@ def encode_return_parameters(return_parameters: dict[Parameter, Optional[NdSweep
|
|
|
67
69
|
|
|
68
70
|
Returns:
|
|
69
71
|
json as a string
|
|
72
|
+
|
|
70
73
|
"""
|
|
71
74
|
kwargs.setdefault("cls", _SweepDataEncoder)
|
|
72
75
|
listed_params = [{"parameter": param, "hard_sweeps": sweeps} for param, sweeps in return_parameters.items()]
|
|
@@ -84,6 +87,7 @@ def decode_and_validate_sweeps(sweeps_json: str) -> Sweeps:
|
|
|
84
87
|
|
|
85
88
|
Raises:
|
|
86
89
|
ValueError if decoded result is not expected return type
|
|
90
|
+
|
|
87
91
|
"""
|
|
88
92
|
decoded = _loads(sweeps_json)
|
|
89
93
|
if not isinstance(decoded, list):
|
|
@@ -118,6 +122,7 @@ def decode_return_parameters_legacy(json_str: str) -> dict[Parameter, Optional[N
|
|
|
118
122
|
|
|
119
123
|
Return:
|
|
120
124
|
a reconstituted, typed ``return_parameters`` structure
|
|
125
|
+
|
|
121
126
|
"""
|
|
122
127
|
|
|
123
128
|
def decode_key(key: str) -> Parameter:
|
|
@@ -152,8 +157,8 @@ def decode_return_parameters(json_str: str) -> dict[Parameter, Optional[NdSweep]
|
|
|
152
157
|
|
|
153
158
|
Return:
|
|
154
159
|
a reconstituted, typed ``return_parameters`` structure
|
|
155
|
-
"""
|
|
156
160
|
|
|
161
|
+
"""
|
|
157
162
|
decoded = _loads(json_str)
|
|
158
163
|
if not isinstance(decoded, list):
|
|
159
164
|
raise ValueError(f"Outer type is not list type when decoding: {json_str}")
|
|
@@ -174,12 +179,13 @@ def decode_settings(json_str: str) -> SettingNode:
|
|
|
174
179
|
|
|
175
180
|
Returns:
|
|
176
181
|
deserialized settings
|
|
182
|
+
|
|
177
183
|
"""
|
|
178
184
|
return SettingNodeModel(**json.loads(json_str)).decode()
|
|
179
185
|
|
|
180
186
|
|
|
181
187
|
def _legacy_return_parameters_to_new_format(
|
|
182
|
-
old: dict[Union[Parameter, Setting], Union[NdSweep, Sweep, int, None]]
|
|
188
|
+
old: dict[Union[Parameter, Setting], Union[NdSweep, Sweep, int, None]],
|
|
183
189
|
) -> dict[Parameter, NdSweep]:
|
|
184
190
|
"""For backwards compatibility, changes values of the return parameters dict to a new,
|
|
185
191
|
more general format: NdSweeps, which is a list of tuples of Sweeps.
|
|
@@ -189,6 +195,7 @@ def _legacy_return_parameters_to_new_format(
|
|
|
189
195
|
|
|
190
196
|
Returns:
|
|
191
197
|
`old` coerced to the new format.
|
|
198
|
+
|
|
192
199
|
"""
|
|
193
200
|
new = {}
|
|
194
201
|
for key, value in old.items():
|
|
@@ -217,6 +224,7 @@ def _loads(*args, **kwargs) -> Any:
|
|
|
217
224
|
Returns:
|
|
218
225
|
python data structure that recovers encoded structure of
|
|
219
226
|
nested tuples and Sweep -objects
|
|
227
|
+
|
|
220
228
|
"""
|
|
221
229
|
|
|
222
230
|
def _decode_json(obj: Any) -> Any:
|
|
@@ -231,7 +239,6 @@ def _loads(*args, **kwargs) -> Any:
|
|
|
231
239
|
class _SweepDataEncoder(json.JSONEncoder):
|
|
232
240
|
"""Extension of json encoder to support handling of Sweep, Parameter, and tuples."""
|
|
233
241
|
|
|
234
|
-
# pylint: disable=arguments-differ
|
|
235
242
|
def default(self, obj: Any) -> Any:
|
|
236
243
|
"""Default encoder
|
|
237
244
|
|
|
@@ -240,6 +247,7 @@ class _SweepDataEncoder(json.JSONEncoder):
|
|
|
240
247
|
|
|
241
248
|
Returns:
|
|
242
249
|
encoded object
|
|
250
|
+
|
|
243
251
|
"""
|
|
244
252
|
if isinstance(obj, Sweep):
|
|
245
253
|
return json.loads(SweepModel.encode(obj).model_dump_json())
|
|
@@ -261,9 +269,9 @@ class _SweepDataEncoder(json.JSONEncoder):
|
|
|
261
269
|
|
|
262
270
|
Returns:
|
|
263
271
|
encoded object
|
|
272
|
+
|
|
264
273
|
"""
|
|
265
274
|
|
|
266
|
-
# pylint: disable=arguments-differ
|
|
267
275
|
def _encode_tuples(item):
|
|
268
276
|
if isinstance(item, tuple):
|
|
269
277
|
return get_json_encoder()[tuple](item)
|
exa/common/sweep/util.py
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"""Generic utilities for converting sweep definitions from
|
|
16
16
|
user-friendly format to canonic ones.
|
|
17
17
|
"""
|
|
18
|
+
|
|
18
19
|
from exa.common.control.sweep.linear_sweep import LinearSweep
|
|
19
20
|
from exa.common.control.sweep.option import StartStopOptions
|
|
20
21
|
from exa.common.control.sweep.sweep import Sweep
|
|
@@ -51,6 +52,7 @@ def convert_sweeps_to_list_of_tuples(sweeps: Sweeps) -> NdSweep:
|
|
|
51
52
|
|
|
52
53
|
Raises:
|
|
53
54
|
ValueError if sweeps parameter does not follow the contract.
|
|
55
|
+
|
|
54
56
|
"""
|
|
55
57
|
new_list = []
|
|
56
58
|
for tuple_or_sweep in sweeps:
|
|
@@ -85,6 +87,7 @@ def linear_index_sweep(parameter: Parameter, length: int) -> list[tuple[LinearSw
|
|
|
85
87
|
Returns:
|
|
86
88
|
A linear sweep over a parameter whose name is ``parameter.name + _index`` and whose data ranges from 0 to
|
|
87
89
|
`length` with steps of 1.
|
|
90
|
+
|
|
88
91
|
"""
|
|
89
92
|
return [
|
|
90
93
|
(
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
exa/common/__init__.py,sha256=AqxwNht57urLqMxFblY7SgxjzkQYW7pRRUUPS1j1Gck,962
|
|
2
|
+
exa/common/api/__init__.py,sha256=PAYujWNG8CtSQX_8U9gnubDh5cwGRhtOfLr0r0xGx3M,587
|
|
3
|
+
exa/common/api/model/__init__.py,sha256=l3JxadYmX2p0ZcdwpdFZGumn9QFufWrGF36ePIqHA2I,635
|
|
4
|
+
exa/common/api/model/parameter_model.py,sha256=9Axf88nDFl2IH1vztBHrOAnliDy0TBwD-vPHegk6Kak,3850
|
|
5
|
+
exa/common/api/model/setting_model.py,sha256=byTM2eKDuqQM7blmjXZaLzdGpXS_dwLq0wmv-SfVDzU,2330
|
|
6
|
+
exa/common/api/model/setting_node_model.py,sha256=O57sttuxNBWrgHWx0zLNMlFD7GRm670cRxiG9RkECzc,2658
|
|
7
|
+
exa/common/api/model/sweep_model.py,sha256=9rVmo2rNN4k3yhVIdnlEuNqVBs79fN6Z1IOEEOZmfVo,2455
|
|
8
|
+
exa/common/api/proto_serialization/__init__.py,sha256=Vn2C79OqovFu5wJus9EHsMtK3Of1JLJDcpg2QZKmXsY,1565
|
|
9
|
+
exa/common/api/proto_serialization/_parameter.py,sha256=ED_wE1JN6EwdGJJxMUSqfYWTAfelsoKDm1XfAAPUw6Y,2837
|
|
10
|
+
exa/common/api/proto_serialization/array.py,sha256=iht5WlfGEkzXM3PcOFDXxd2TgXWFyYNyPt44CMqXnl8,3110
|
|
11
|
+
exa/common/api/proto_serialization/datum.py,sha256=gFIAncWpOhy4V56DKYdKoasEIpGu1yUerSuRQf65unY,4828
|
|
12
|
+
exa/common/api/proto_serialization/nd_sweep.py,sha256=JfEOcISWZyfrVRaTvWkIwGRRlkSGKFwmOHVqbNlNKUw,2866
|
|
13
|
+
exa/common/api/proto_serialization/sequence.py,sha256=yIAxO6zdhsSkrUkJ5XonuLsf3nZQ-hHq8uzCwHkZaDU,2447
|
|
14
|
+
exa/common/api/proto_serialization/setting_node.py,sha256=Ac-WuYKUTiVywRmRJHhdpfoswQWRQEIEgIWsn7IsA_g,3700
|
|
15
|
+
exa/common/control/__init__.py,sha256=00T_xV0lL20QZcEt__vWq81N1oGF0KpJMhTitfAI4VI,629
|
|
16
|
+
exa/common/control/sweep/__init__.py,sha256=GzKoQdQsLutcHhmrLPyPrW1n7Cpg766p3OWDHlRpuTs,607
|
|
17
|
+
exa/common/control/sweep/exponential_sweep.py,sha256=hKAj9_4w9frWzZouvNDGnhsjAjLt4k28fjtR0PXfA9I,3510
|
|
18
|
+
exa/common/control/sweep/fixed_sweep.py,sha256=099H7rTsE9s_tUEopP_5UwGeUo1LDhuDPtBav2Pk4pU,1473
|
|
19
|
+
exa/common/control/sweep/function_sweep.py,sha256=hfi1WafPX6t7U9EcQIOspSPFZgfAlVILTFIDNM-LdiI,1432
|
|
20
|
+
exa/common/control/sweep/linear_sweep.py,sha256=5d5OsCR9P7ujOLdzbjLt2v_5BPuhTuwLxnV_nOPrDLE,3107
|
|
21
|
+
exa/common/control/sweep/sweep.py,sha256=g9RZhMO254ACK51B4zX1i5Y5n-EVyqlRpt6E_6qHufc,1532
|
|
22
|
+
exa/common/control/sweep/utils.py,sha256=9moO0qnuF_xuvWkWuwYjLV2ejXnDXTogARVQz_jESo4,1610
|
|
23
|
+
exa/common/control/sweep/option/__init__.py,sha256=R_KvrmH-FCC1K0ixtFr1QmOTiyS3lhIgFVDmCQBKSuU,951
|
|
24
|
+
exa/common/control/sweep/option/center_span_base_options.py,sha256=ckmzlG430P3JxbPJBPCw-4rwuVxtNOgJsCtfpZIeuoM,2137
|
|
25
|
+
exa/common/control/sweep/option/center_span_options.py,sha256=Y6eKSwQ-hFWyvgMW43OnkwUD1qBkMcSdFwgKwWCzaj4,2111
|
|
26
|
+
exa/common/control/sweep/option/constants.py,sha256=aNzcuLP4YYeCSpF114CDQx8-ZzOIbTTl6ZJydgYtqjg,1423
|
|
27
|
+
exa/common/control/sweep/option/fixed_options.py,sha256=jBB0w0DpN_7skM6JhdT4op6FvBwFfh6iSqJgSEHVsgc,931
|
|
28
|
+
exa/common/control/sweep/option/function_options.py,sha256=9X21CndZK_pubfkKtDvFBIJCOgrBr_t8Jx3suutAb-o,930
|
|
29
|
+
exa/common/control/sweep/option/option_converter.py,sha256=RG9jmRbm-G4isnjBpbWFVT1M56hRVBkKYE2gOM6tJ98,3811
|
|
30
|
+
exa/common/control/sweep/option/start_stop_base_options.py,sha256=a7iIJKNZC1osMsX5kC2Mo6xZ1EzoyFnkgH8C0HQbXRE,1836
|
|
31
|
+
exa/common/control/sweep/option/start_stop_options.py,sha256=aR_ksYJsMlHwXhLqmLweTQq5Ix3sqKrnPVGQMLFnQe0,2498
|
|
32
|
+
exa/common/control/sweep/option/sweep_options.py,sha256=ToyNX9FifKxa-_TTVCuFuTRZIdep8yBtPR86EgbtJrQ,698
|
|
33
|
+
exa/common/data/__init__.py,sha256=F5SRe5QHBTjef4XJVQ63kO5Oxc_AiZnPbV560i7La0Y,644
|
|
34
|
+
exa/common/data/parameter.py,sha256=A4a7hSUhW2eKn_d8ZNPpED2eJK-YyMktb-Z6_he9ImY,20759
|
|
35
|
+
exa/common/data/setting_node.py,sha256=q9lkP60Y8NA0PW_jBbp39vCzwmzuBU6CejbK6xmOMJE,26980
|
|
36
|
+
exa/common/data/settingnode_v2.html.jinja2,sha256=1cADQhBi0c7xewh1ZxWXBQqvTI-jxZNJdEUgS44SPWU,3125
|
|
37
|
+
exa/common/errors/__init__.py,sha256=ArMBdpmx1EUenBpzrSNG63kmUf7PM0gCqSYnaCnL9Qk,597
|
|
38
|
+
exa/common/errors/exa_error.py,sha256=eB_c-Qp1OchcBMr3LSyYitity4SochQh-nAghZmGLJU,975
|
|
39
|
+
exa/common/helpers/__init__.py,sha256=IgtVD3tojIFA4MTV2mT5uYM6jb2qny9kBIIhEZT2PuI,610
|
|
40
|
+
exa/common/helpers/data_helper.py,sha256=vhzJ63g1S2JqnCj0WJJuqWcuiIwKATnQeHdWw_3gkZg,1934
|
|
41
|
+
exa/common/helpers/json_helper.py,sha256=VTcYU8FRgv3tXPifuogUWmVAzt_4JoQ_laTHolyodtA,2672
|
|
42
|
+
exa/common/helpers/numpy_helper.py,sha256=KKKyZ_fD0O1gn7_InEQROYnX3WGMA6C1qHh8KzzjtUI,1062
|
|
43
|
+
exa/common/helpers/software_version_helper.py,sha256=kpuQer4p1p4cj9_CzwziBSCX7wuH-FvfNw8G8U-EI3Y,5162
|
|
44
|
+
exa/common/logger/__init__.py,sha256=1bIsGxHzfujXlkgtcAnWToKMkw3dpU5PEd_7LE_NpgQ,686
|
|
45
|
+
exa/common/logger/logger.py,sha256=McZSKAl3JdfBnqd4RPJrO_mjN5mQ4XMJWSlEiq4fsCs,5716
|
|
46
|
+
exa/common/qcm_data/__init__.py,sha256=VtsYkGoaniSjCkY0oQlqkcYJCtmC2sTDxfrIe_kpqZg,567
|
|
47
|
+
exa/common/qcm_data/chad_model.py,sha256=MQ1xuRODOA6uzb3GJ4fgYx9cXS8z1DeRGw6HYKA9Sio,11223
|
|
48
|
+
exa/common/qcm_data/chip_topology.py,sha256=OJU8-CXV7wfdxrn0HqryNZmxGRoffrg0vi0aMaiYbbY,19328
|
|
49
|
+
exa/common/qcm_data/file_adapter.py,sha256=cqjnRUK-arKWEP4N7wwmH8nUjVZsNhM7aXaLjAQvSoE,2530
|
|
50
|
+
exa/common/qcm_data/immutable_base_model.py,sha256=QXmKIWQbsbWQvovXwKT1d9jtyf2LNJtjQquIwO52zOU,901
|
|
51
|
+
exa/common/qcm_data/qcm_data_client.py,sha256=dSjy_Rz8VDmtaOO698JfVIpNd_bPJ3Td0DG_I8vdXZ8,7676
|
|
52
|
+
exa/common/sweep/__init__.py,sha256=uEKk5AtzSgSnf8Y0geRPwUpqXIBIXpeCxsN64sX7F1o,591
|
|
53
|
+
exa/common/sweep/database_serialization.py,sha256=Qw0SFuT1zRxvDtwpq1aIruGxs4rVNB5AhqYmEVhUquU,9962
|
|
54
|
+
exa/common/sweep/util.py,sha256=P8U93M1kBchpSvfBfDCq5tu0dhZsQYcKlCzUgCwSCJE,3786
|
|
55
|
+
iqm_exa_common-25.33.dist-info/LICENSE.txt,sha256=R6Q7eUrLyoCQgWYorQ8WJmVmWKYU3dxA3jYUp0wwQAw,11332
|
|
56
|
+
iqm_exa_common-25.33.dist-info/METADATA,sha256=P_uXhnzxJfkGYrQtVQTnqsPbRVseE176rT4MEZoHP3o,14548
|
|
57
|
+
iqm_exa_common-25.33.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
58
|
+
iqm_exa_common-25.33.dist-info/top_level.txt,sha256=Clphg2toaZ3_jSFRPhjMNEmLurkMNMc4lkK2EFYsSlM,4
|
|
59
|
+
iqm_exa_common-25.33.dist-info/RECORD,,
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
exa/common/__init__.py,sha256=CCqrg7LHjBeIrjQJvw0nym_Ki6uxoZ7_WSbNDq_d0Lc,961
|
|
2
|
-
exa/common/api/__init__.py,sha256=PAYujWNG8CtSQX_8U9gnubDh5cwGRhtOfLr0r0xGx3M,587
|
|
3
|
-
exa/common/api/model/__init__.py,sha256=l3JxadYmX2p0ZcdwpdFZGumn9QFufWrGF36ePIqHA2I,635
|
|
4
|
-
exa/common/api/model/parameter_model.py,sha256=vrnBKGFC6kDis8ovCWFfuYCxfwVvl4-7ueN7ZaFgkKM,3845
|
|
5
|
-
exa/common/api/model/setting_model.py,sha256=7nNu7DQ3W3G3v3OU7Fq5k9Nu6W24fsBb5Hc0ixIMrms,2325
|
|
6
|
-
exa/common/api/model/setting_node_model.py,sha256=BwKATLQbl9RlQdEbTFXz6Xjt1zFKKVZwAbbbos68evY,2653
|
|
7
|
-
exa/common/api/model/sweep_model.py,sha256=KQ95YwgYAbAp-BrqhKGkCnOS3H1TVImqKLcdwB3NeNQ,2454
|
|
8
|
-
exa/common/api/proto_serialization/__init__.py,sha256=Vn2C79OqovFu5wJus9EHsMtK3Of1JLJDcpg2QZKmXsY,1565
|
|
9
|
-
exa/common/api/proto_serialization/_parameter.py,sha256=StKUU9qsrg1E5QVZ7s3xjgOeERwyAn2NIRJdijb_hrY,2866
|
|
10
|
-
exa/common/api/proto_serialization/array.py,sha256=HC17wqnolM17mDYhNUGvmPcaKJM8QaHtBtQR4cbcyEc,3136
|
|
11
|
-
exa/common/api/proto_serialization/datum.py,sha256=E0N6HSUZmxHRDn1Z8pG1DPsPYky6GK0DrgRveCA635g,4909
|
|
12
|
-
exa/common/api/proto_serialization/nd_sweep.py,sha256=cSdWnmgl6W9ZzIdnSxBwC-Ng1_xyUu6L3nxeS7PEBmQ,2894
|
|
13
|
-
exa/common/api/proto_serialization/sequence.py,sha256=69ebCeTO95EBkfAianww8x7xMHF5WA7SaUhcopZJSBY,2403
|
|
14
|
-
exa/common/api/proto_serialization/setting_node.py,sha256=LZ2hnSCVdAxwCbUAztrMnmHL16dBzR_sXD8EKsJO6nM,3726
|
|
15
|
-
exa/common/control/__init__.py,sha256=00T_xV0lL20QZcEt__vWq81N1oGF0KpJMhTitfAI4VI,629
|
|
16
|
-
exa/common/control/sweep/__init__.py,sha256=GzKoQdQsLutcHhmrLPyPrW1n7Cpg766p3OWDHlRpuTs,607
|
|
17
|
-
exa/common/control/sweep/exponential_sweep.py,sha256=wDhzyQLej9-3rgPWLVHR5tDFvVKXZOl63eEwAcpE410,3508
|
|
18
|
-
exa/common/control/sweep/fixed_sweep.py,sha256=Cfcw2UgRml2XFxq9YjNEPUT3-Z8256y-J51ex4YMwE0,1472
|
|
19
|
-
exa/common/control/sweep/function_sweep.py,sha256=1ce9cblpO6_jeTTkkaW91zSoLAhAVyseb9MboH8VFrI,1431
|
|
20
|
-
exa/common/control/sweep/linear_sweep.py,sha256=aTPDZRpZU9Qpr_KJxtjIzW7i9pyztfPJ2ppgxjReg6k,3105
|
|
21
|
-
exa/common/control/sweep/sweep.py,sha256=nicqYN8_9k4RpD6DLoyom2XD_byjdc9TZvK2kAXJrFI,1531
|
|
22
|
-
exa/common/control/sweep/utils.py,sha256=9moO0qnuF_xuvWkWuwYjLV2ejXnDXTogARVQz_jESo4,1610
|
|
23
|
-
exa/common/control/sweep/option/__init__.py,sha256=R_KvrmH-FCC1K0ixtFr1QmOTiyS3lhIgFVDmCQBKSuU,951
|
|
24
|
-
exa/common/control/sweep/option/center_span_base_options.py,sha256=fNbHheJXGYb_P2fMt8moHoWKOy3db8TsSTcBU8HugM0,2136
|
|
25
|
-
exa/common/control/sweep/option/center_span_options.py,sha256=uqug4eP9bY0ucVcD97FdT3wp2kw5RsSEL_NjpcY1eAc,2110
|
|
26
|
-
exa/common/control/sweep/option/constants.py,sha256=5elNQvsIvJ95WXSywadGqj-X74nuu3gNYaTHi2tsQNA,1422
|
|
27
|
-
exa/common/control/sweep/option/fixed_options.py,sha256=qxgpsJupq5kwrYxO9D9656t3L4XIwJm6E0wzt03zjz8,930
|
|
28
|
-
exa/common/control/sweep/option/function_options.py,sha256=9X21CndZK_pubfkKtDvFBIJCOgrBr_t8Jx3suutAb-o,930
|
|
29
|
-
exa/common/control/sweep/option/option_converter.py,sha256=DDU7rspvOaG3hMPCnLr-kF8_omBFFhYqczLypDN65xg,3809
|
|
30
|
-
exa/common/control/sweep/option/start_stop_base_options.py,sha256=gsB3w92kZCCy-hxXjV0BYGkqodpK20dyIBQyl0nBGXI,1835
|
|
31
|
-
exa/common/control/sweep/option/start_stop_options.py,sha256=sFIQpAfh-gBdfeETEfg7axuCDo28R2-PckQ02DXWqHY,2497
|
|
32
|
-
exa/common/control/sweep/option/sweep_options.py,sha256=ToyNX9FifKxa-_TTVCuFuTRZIdep8yBtPR86EgbtJrQ,698
|
|
33
|
-
exa/common/data/__init__.py,sha256=F5SRe5QHBTjef4XJVQ63kO5Oxc_AiZnPbV560i7La0Y,644
|
|
34
|
-
exa/common/data/parameter.py,sha256=XX6GHY8H9fMarMy0dfXGvLflPnRc8b_MRR567iOsOeM,20754
|
|
35
|
-
exa/common/data/setting_node.py,sha256=8qibht7-25zNxlDjNWhphZwDozhr3CZIWho91OOG5Sc,26995
|
|
36
|
-
exa/common/data/settingnode_v2.html.jinja2,sha256=1cADQhBi0c7xewh1ZxWXBQqvTI-jxZNJdEUgS44SPWU,3125
|
|
37
|
-
exa/common/errors/__init__.py,sha256=ArMBdpmx1EUenBpzrSNG63kmUf7PM0gCqSYnaCnL9Qk,597
|
|
38
|
-
exa/common/errors/exa_error.py,sha256=VApLIK-fxgFGzKuE_2CjuL1znYtXeSR923YenfnOUOs,974
|
|
39
|
-
exa/common/helpers/__init__.py,sha256=IgtVD3tojIFA4MTV2mT5uYM6jb2qny9kBIIhEZT2PuI,610
|
|
40
|
-
exa/common/helpers/data_helper.py,sha256=KkNL-X4Cst5tn24OJ39PlYVyjE231vVFeC9OkLMRF-o,1933
|
|
41
|
-
exa/common/helpers/json_helper.py,sha256=VTcYU8FRgv3tXPifuogUWmVAzt_4JoQ_laTHolyodtA,2672
|
|
42
|
-
exa/common/helpers/numpy_helper.py,sha256=alzUdIHQJxDygvpLaTFCIOizFHo5wRY1eD8o8bnt1rU,1061
|
|
43
|
-
exa/common/helpers/software_version_helper.py,sha256=8DFq7eHnWUsfbPKZauMlXVtJQQ7PoQaPXAzB42r5MgU,5169
|
|
44
|
-
exa/common/logger/__init__.py,sha256=D_fMkDh4oXaoCNVV1sdusCv7W4G_81g-eBJOddEWSxo,685
|
|
45
|
-
exa/common/logger/logger.py,sha256=7yIRbwI8-tft70J3m4nuClJM1B3qKZOvOyy1EaaUCgo,5689
|
|
46
|
-
exa/common/qcm_data/__init__.py,sha256=VtsYkGoaniSjCkY0oQlqkcYJCtmC2sTDxfrIe_kpqZg,567
|
|
47
|
-
exa/common/qcm_data/chad_model.py,sha256=xU2_CZB4OyOSuyVH_9bw0UT7xk3QdlkJ7DE4h7KrkOU,11218
|
|
48
|
-
exa/common/qcm_data/chip_topology.py,sha256=dTTcfhlGy0gaN3bRqB6yl8Geddov2Sax5wUfO1GEx50,19338
|
|
49
|
-
exa/common/qcm_data/file_adapter.py,sha256=cqjnRUK-arKWEP4N7wwmH8nUjVZsNhM7aXaLjAQvSoE,2530
|
|
50
|
-
exa/common/qcm_data/immutable_base_model.py,sha256=QXmKIWQbsbWQvovXwKT1d9jtyf2LNJtjQquIwO52zOU,901
|
|
51
|
-
exa/common/qcm_data/qcm_data_client.py,sha256=r--H5QAmYYbHcl5STsfNwr0TESGall-pscz7YtA4DSs,7713
|
|
52
|
-
exa/common/sweep/__init__.py,sha256=uEKk5AtzSgSnf8Y0geRPwUpqXIBIXpeCxsN64sX7F1o,591
|
|
53
|
-
exa/common/sweep/database_serialization.py,sha256=z9jXM_nkn3V84Y3fAlF3HN9YLjigS0g1BV4AIZTEhRs,10033
|
|
54
|
-
exa/common/sweep/util.py,sha256=46sDCs-tXRCnDY_xeLeDLZ_9918QQ5KreERa3KENkiM,3783
|
|
55
|
-
iqm_exa_common-25.31.dist-info/LICENSE.txt,sha256=R6Q7eUrLyoCQgWYorQ8WJmVmWKYU3dxA3jYUp0wwQAw,11332
|
|
56
|
-
iqm_exa_common-25.31.dist-info/METADATA,sha256=2te2WrS436UONx8hL7LipAHqCbM-bBcNgjEzF7PiwMM,14548
|
|
57
|
-
iqm_exa_common-25.31.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
|
58
|
-
iqm_exa_common-25.31.dist-info/top_level.txt,sha256=Clphg2toaZ3_jSFRPhjMNEmLurkMNMc4lkK2EFYsSlM,4
|
|
59
|
-
iqm_exa_common-25.31.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|