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.
Files changed (42) hide show
  1. exa/common/__init__.py +1 -0
  2. exa/common/api/model/parameter_model.py +2 -3
  3. exa/common/api/model/setting_model.py +2 -3
  4. exa/common/api/model/setting_node_model.py +2 -3
  5. exa/common/api/model/sweep_model.py +1 -0
  6. exa/common/api/proto_serialization/_parameter.py +1 -3
  7. exa/common/api/proto_serialization/array.py +2 -1
  8. exa/common/api/proto_serialization/datum.py +5 -3
  9. exa/common/api/proto_serialization/nd_sweep.py +1 -2
  10. exa/common/api/proto_serialization/sequence.py +7 -6
  11. exa/common/api/proto_serialization/setting_node.py +3 -2
  12. exa/common/control/sweep/exponential_sweep.py +2 -0
  13. exa/common/control/sweep/fixed_sweep.py +1 -0
  14. exa/common/control/sweep/function_sweep.py +1 -0
  15. exa/common/control/sweep/linear_sweep.py +2 -0
  16. exa/common/control/sweep/option/center_span_base_options.py +1 -0
  17. exa/common/control/sweep/option/center_span_options.py +1 -0
  18. exa/common/control/sweep/option/constants.py +1 -0
  19. exa/common/control/sweep/option/fixed_options.py +1 -0
  20. exa/common/control/sweep/option/option_converter.py +2 -0
  21. exa/common/control/sweep/option/start_stop_base_options.py +1 -0
  22. exa/common/control/sweep/option/start_stop_options.py +1 -0
  23. exa/common/control/sweep/sweep.py +1 -0
  24. exa/common/data/parameter.py +7 -1
  25. exa/common/data/setting_node.py +21 -13
  26. exa/common/errors/exa_error.py +1 -0
  27. exa/common/helpers/data_helper.py +1 -0
  28. exa/common/helpers/numpy_helper.py +1 -0
  29. exa/common/helpers/software_version_helper.py +3 -2
  30. exa/common/logger/__init__.py +1 -0
  31. exa/common/logger/logger.py +5 -5
  32. exa/common/qcm_data/chad_model.py +5 -0
  33. exa/common/qcm_data/chip_topology.py +21 -6
  34. exa/common/qcm_data/qcm_data_client.py +3 -1
  35. exa/common/sweep/database_serialization.py +12 -4
  36. exa/common/sweep/util.py +3 -0
  37. {iqm_exa_common-25.31.dist-info → iqm_exa_common-25.33.dist-info}/METADATA +1 -1
  38. iqm_exa_common-25.33.dist-info/RECORD +59 -0
  39. iqm_exa_common-25.31.dist-info/RECORD +0 -59
  40. {iqm_exa_common-25.31.dist-info → iqm_exa_common-25.33.dist-info}/LICENSE.txt +0 -0
  41. {iqm_exa_common-25.31.dist-info → iqm_exa_common-25.33.dist-info}/WHEEL +0 -0
  42. {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
  """Shared errors, helpers, control structures, settings, API models etc."""
16
+
16
17
  from importlib.metadata import PackageNotFoundError, version
17
18
 
18
19
  try:
@@ -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,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Pydantic model for Sweep."""
16
+
16
17
  from __future__ import annotations
17
18
 
18
19
  from typing import Any
@@ -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
- import exa.common.api.proto_serialization.array as array
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
- # pylint: disable=no-member
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 arbitrary values."""
16
+
16
17
  from dataclasses import dataclass
17
18
 
18
19
  import numpy as np
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Sweep specification with generated parameter values based on callable object."""
16
+
16
17
  from dataclasses import dataclass
17
18
 
18
19
  from exa.common.control.sweep.option import FunctionOptions
@@ -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
  """Range specification used with ExponentialSweep."""
16
+
16
17
  from dataclasses import dataclass
17
18
  from typing import Union
18
19
 
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Range specification to define a range around a center value."""
16
+
16
17
  from dataclasses import dataclass
17
18
  from typing import Union
18
19
 
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Helper constants for SweepOptions classes."""
16
+
16
17
  from typing import Any, Dict
17
18
 
18
19
  #: Default value for `count` value in options.
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Range specification for arbitrary set of values."""
16
+
16
17
  from dataclasses import dataclass
17
18
  from typing import List, Union
18
19
 
@@ -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)):
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Range specification used with ExponentialSweep."""
16
+
16
17
  from dataclasses import dataclass
17
18
  from typing import Union
18
19
 
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Range specification to define a linearly spaced interval."""
16
+
16
17
  from dataclasses import dataclass
17
18
  from typing import Union
18
19
 
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Base immutable class for sweeps specifications."""
16
+
16
17
  from dataclasses import dataclass, field
17
18
  from typing import Any, List, Union
18
19
 
@@ -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
- Args:
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
 
@@ -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
- else:
346
- if isinstance(item, Setting) and item.name == setting.parent_name and item.element_indices is None:
347
- parent_value = item.value.copy()
348
- list_assign(setting.value, parent_value, setting.element_indices)
349
- branch[key] = parent_value
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"}:
@@ -3,6 +3,7 @@ class ExaError(Exception):
3
3
 
4
4
  Attributes:
5
5
  message: Error message.
6
+
6
7
  """
7
8
 
8
9
  def __init__(self, message: str, *args):
@@ -33,6 +33,7 @@ def add_data_array(ds: xr.Dataset, da: xr.DataArray, name: Optional[str] = None)
33
33
 
34
34
  Returns:
35
35
  The updated dataset.
36
+
36
37
  """
37
38
  if name is None:
38
39
  if da.name is not None:
@@ -13,6 +13,7 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Coercion of numpy types."""
16
+
16
17
  from typing import Any
17
18
 
18
19
  import numpy as np
@@ -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
- Example:
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
@@ -13,4 +13,5 @@
13
13
  # limitations under the License.
14
14
 
15
15
  """Helper to initialize loggers to the specified logging level."""
16
+
16
17
  from exa.common.logger.logger import init_loggers
@@ -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
- if level_num < lowest_level_num:
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
- Args:
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
- Returns:
386
+ Returns:
374
387
  - The name of the computational resonator that is connected to both inputted qubits via tunable couplers.
375
388
 
376
- Raises:
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
  (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iqm-exa-common
3
- Version: 25.31
3
+ Version: 25.33
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
@@ -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,,